Skip to content

Commit

Permalink
Correctly flush dirty bodies.
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreaCatania committed Aug 7, 2020
1 parent 241e709 commit f11c623
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 18 deletions.
34 changes: 31 additions & 3 deletions modules/bullet/collision_object_bullet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,36 @@ bool CollisionObjectBullet::has_collision_exception(const CollisionObjectBullet
return !bt_collision_object->checkCollideWith(p_otherCollisionObject->bt_collision_object);
}

void CollisionObjectBullet::set_collision_layer(uint32_t p_layer) {
if (collisionLayer != p_layer) {
collisionLayer = p_layer;
needs_collision_filters_reload = true;
if (likely(space)) {
space->add_to_dirty_queue(this);
}
}
}

void CollisionObjectBullet::set_collision_mask(uint32_t p_mask) {
if (collisionMask != p_mask) {
collisionMask = p_mask;
needs_collision_filters_reload = true;
if (likely(space)) {
space->add_to_dirty_queue(this);
}
}
}

void CollisionObjectBullet::reload_body() {
needs_body_reload = true;
if (likely(space)) {
space->add_to_dirty_queue(this);
}
}

void CollisionObjectBullet::dispatch_callbacks() {}

void CollisionObjectBullet::pre_process() {
void CollisionObjectBullet::flush_dirty() {
if (needs_body_reload) {
do_reload_body();
} else if (needs_collision_filters_reload) {
Expand All @@ -181,6 +204,8 @@ void CollisionObjectBullet::pre_process() {
needs_collision_filters_reload = false;
}

void CollisionObjectBullet::pre_process() {}

void CollisionObjectBullet::set_collision_enabled(bool p_enabled) {
collisionsEnabled = p_enabled;
if (collisionsEnabled) {
Expand Down Expand Up @@ -342,12 +367,12 @@ bool RigidCollisionObjectBullet::is_shape_disabled(int p_index) {
return !shapes[p_index].active;
}

void RigidCollisionObjectBullet::pre_process() {
void RigidCollisionObjectBullet::flush_dirty() {
if (need_shape_reload) {
do_reload_shapes();
need_shape_reload = false;
}
CollisionObjectBullet::pre_process();
CollisionObjectBullet::flush_dirty();
}

void RigidCollisionObjectBullet::shape_changed(int p_shape_index) {
Expand All @@ -361,6 +386,9 @@ void RigidCollisionObjectBullet::shape_changed(int p_shape_index) {

void RigidCollisionObjectBullet::reload_shapes() {
need_shape_reload = true;
if (likely(space)) {
space->add_to_dirty_queue(this);
}
}

void RigidCollisionObjectBullet::do_reload_shapes() {
Expand Down
18 changes: 5 additions & 13 deletions modules/bullet/collision_object_bullet.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class CollisionObjectBullet : public RIDBullet {
public:
bool is_in_world = false;
bool is_in_flush_queue = false;
bool is_in_dirty_queue = false;

public:
CollisionObjectBullet(Type p_type);
Expand Down Expand Up @@ -171,20 +172,10 @@ class CollisionObjectBullet : public RIDBullet {
bool has_collision_exception(const CollisionObjectBullet *p_otherCollisionObject) const;
_FORCE_INLINE_ const VSet<RID> &get_exceptions() const { return exceptions; }

_FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) {
if (collisionLayer != p_layer) {
collisionLayer = p_layer;
needs_collision_filters_reload = true;
}
}
void set_collision_layer(uint32_t p_layer);
_FORCE_INLINE_ uint32_t get_collision_layer() const { return collisionLayer; }

_FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) {
if (collisionMask != p_mask) {
collisionMask = p_mask;
needs_collision_filters_reload = true;
}
}
void set_collision_mask(uint32_t p_mask);
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collisionMask; }

virtual void do_reload_collision_filters() = 0;
Expand All @@ -207,6 +198,7 @@ class CollisionObjectBullet : public RIDBullet {
virtual void on_collision_checker_end() = 0;

virtual void dispatch_callbacks();
virtual void flush_dirty();
virtual void pre_process();

void set_collision_enabled(bool p_enabled);
Expand Down Expand Up @@ -264,7 +256,7 @@ class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwn
void set_shape_disabled(int p_index, bool p_disabled);
bool is_shape_disabled(int p_index);

virtual void pre_process() override;
virtual void flush_dirty() override;

virtual void shape_changed(int p_shape_index) override;
virtual void reload_shapes() override;
Expand Down
10 changes: 8 additions & 2 deletions modules/bullet/rigid_body_bullet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) {
space->register_collision_object(this);
reload_body();
space->add_to_flush_queue(this);
space->add_to_dirty_queue(this);
}
}

Expand Down Expand Up @@ -362,14 +363,16 @@ void RigidBodyBullet::dispatch_callbacks() {
previousActiveState = btBody->isActive();
}

void RigidBodyBullet::pre_process() {
RigidCollisionObjectBullet::pre_process();
void RigidBodyBullet::flush_dirty() {
RigidCollisionObjectBullet::flush_dirty();

if (isScratchedSpaceOverrideModificator || 0 < countGravityPointSpaces) {
isScratchedSpaceOverrideModificator = false;
reload_space_override_modificator();
}
}

void RigidBodyBullet::pre_process() {
if (is_active()) {
/// Lock axis
btBody->setLinearVelocity(btBody->getLinearVelocity() * btBody->getLinearFactor());
Expand All @@ -393,6 +396,9 @@ void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const String

void RigidBodyBullet::scratch_space_override_modificator() {
isScratchedSpaceOverrideModificator = true;
if (likely(space)) {
space->add_to_dirty_queue(this);
}
}

void RigidBodyBullet::do_reload_collision_filters() {
Expand Down
1 change: 1 addition & 0 deletions modules/bullet/rigid_body_bullet.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ class RigidBodyBullet : public RigidCollisionObjectBullet {
virtual void set_space(SpaceBullet *p_space) override;

virtual void dispatch_callbacks() override;
virtual void flush_dirty() override;
virtual void pre_process() override;
void set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
void scratch_space_override_modificator();
Expand Down
33 changes: 33 additions & 0 deletions modules/bullet/space_bullet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, Shape
GodotAllContactResultCallback btResult(&collision_object_point, r_results, p_result_max, &p_exclude, p_collide_with_bodies, p_collide_with_areas);
btResult.m_collisionFilterGroup = 0;
btResult.m_collisionFilterMask = p_collision_mask;
space->flush_dirty();
space->dynamicsWorld->contactTest(&collision_object_point, btResult);

// The results is already populated by GodotAllConvexResultCallback
Expand All @@ -98,6 +99,7 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V
btResult.m_collisionFilterMask = p_collision_mask;
btResult.m_pickRay = p_pick_ray;

space->flush_dirty();
space->dynamicsWorld->rayTest(btVec_from, btVec_to, btResult);
if (btResult.hasHit()) {
B_TO_G(btResult.m_hitPointWorld, r_result.position);
Expand Down Expand Up @@ -145,6 +147,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
btQuery.m_collisionFilterGroup = 0;
btQuery.m_collisionFilterMask = p_collision_mask;
btQuery.m_closestDistanceThreshold = 0;
space->flush_dirty();
space->dynamicsWorld->contactTest(&collision_object, btQuery);

shape->destroy_bt_shape(btShape);
Expand Down Expand Up @@ -185,6 +188,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
btResult.m_collisionFilterGroup = 0;
btResult.m_collisionFilterMask = p_collision_mask;

space->flush_dirty();
space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, space->dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration);

if (btResult.hasHit()) {
Expand Down Expand Up @@ -240,6 +244,8 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &
btQuery.m_collisionFilterGroup = 0;
btQuery.m_collisionFilterMask = p_collision_mask;
btQuery.m_closestDistanceThreshold = 0;

space->flush_dirty();
space->dynamicsWorld->contactTest(&collision_object, btQuery);

r_result_count = btQuery.m_count;
Expand Down Expand Up @@ -272,6 +278,8 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh
btQuery.m_collisionFilterGroup = 0;
btQuery.m_collisionFilterMask = p_collision_mask;
btQuery.m_closestDistanceThreshold = 0;

space->flush_dirty();
space->dynamicsWorld->contactTest(&collision_object, btQuery);

shape->destroy_bt_shape(btShape);
Expand Down Expand Up @@ -317,6 +325,7 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_

input.m_transformB = body_transform * child_transform;

space->flush_dirty();
btPointCollector result;
btGjkPairDetector gjk_pair_detector(&point_shape, convex_shape, space->gjk_simplex_solver, space->gjk_epa_pen_solver);
gjk_pair_detector.getClosestPoints(input, result, nullptr);
Expand Down Expand Up @@ -363,12 +372,23 @@ void SpaceBullet::add_to_flush_queue(CollisionObjectBullet *p_co) {
}
}

void SpaceBullet::add_to_dirty_queue(CollisionObjectBullet *p_co) {
if (p_co->is_in_dirty_queue == false) {
p_co->is_in_dirty_queue = true;
queue_dirty.push_back(p_co);
}
}

void SpaceBullet::remove_from_any_queue(CollisionObjectBullet *p_co) {
if (p_co->is_in_flush_queue) {
p_co->is_in_flush_queue = false;
queue_pre_flush.erase(p_co);
queue_flush.erase(p_co);
}
if (p_co->is_in_dirty_queue) {
p_co->is_in_dirty_queue = false;
queue_dirty.erase(p_co);
}
}

void SpaceBullet::flush_queries() {
Expand All @@ -384,7 +404,17 @@ void SpaceBullet::flush_queries() {
queue_flush.clear();
}

void SpaceBullet::flush_dirty() {
for (uint32_t i = 0; i < queue_dirty.size(); i += 1) {
queue_dirty[i]->flush_dirty();
queue_dirty[i]->is_in_dirty_queue = false;
}
queue_dirty.clear();
}

void SpaceBullet::step(real_t p_delta_time) {
flush_dirty();

for (uint32_t i = 0; i < collision_objects.size(); i += 1) {
collision_objects[i]->pre_process();
}
Expand Down Expand Up @@ -982,6 +1012,9 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
}
#endif

ERR_FAIL_COND_V_MSG(p_body->get_space() == nullptr, false, "The body is not part of any space.");
p_body->get_space()->flush_dirty();

btTransform body_transform;
G_TO_B(p_from, body_transform);
UNSCALE_BT_BASIS(body_transform);
Expand Down
3 changes: 3 additions & 0 deletions modules/bullet/space_bullet.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class SpaceBullet : public RIDBullet {

LocalVector<CollisionObjectBullet *> queue_pre_flush;
LocalVector<CollisionObjectBullet *> queue_flush;
LocalVector<CollisionObjectBullet *> queue_dirty;
LocalVector<CollisionObjectBullet *> collision_objects;
LocalVector<AreaBullet *> areas;

Expand All @@ -125,9 +126,11 @@ class SpaceBullet : public RIDBullet {

void add_to_flush_queue(CollisionObjectBullet *p_co);
void add_to_pre_flush_queue(CollisionObjectBullet *p_co);
void add_to_dirty_queue(CollisionObjectBullet *p_co);
void remove_from_any_queue(CollisionObjectBullet *p_co);

void flush_queries();
void flush_dirty();
real_t get_delta_time() { return delta_time; }
void step(real_t p_delta_time);

Expand Down

0 comments on commit f11c623

Please sign in to comment.