Commit: 3bdb65f5ed1a51ed7838ec897a707a990e0687d4 Author: Martin Felke Date: Thu Aug 10 18:55:07 2017 +0200 Branches: fracture_modifier https://developer.blender.org/rB3bdb65f5ed1a51ed7838ec897a707a990e0687d4
performance regression fix which reduces some static-static collision checking =================================================================== M intern/rigidbody/RBI_api.h M intern/rigidbody/rb_bullet_api.cpp M source/blender/blenkernel/intern/rigidbody.c =================================================================== diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h index 02447f8d1b8..da997a38f24 100644 --- a/intern/rigidbody/RBI_api.h +++ b/intern/rigidbody/RBI_api.h @@ -89,7 +89,7 @@ void RB_dworld_init_compounds(rbDynamicsWorld *world); /* Create a new dynamics world instance */ // TODO: add args to set the type of constraint solvers, etc. -rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, void *blenderScene, int (*callback)(void*, void*, void*, void*, void*), +rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, void *blenderScene, int (*callback)(void*, void*, void*, void*, void*, bool), void (*contactCallback)(rbContactPoint*, void *), void (*idCallbackOut)(void*, void*, int*, int*), void (*tickCallback)(float, void *)); diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp index ef6941bd5a5..e67a88c7631 100644 --- a/intern/rigidbody/rb_bullet_api.cpp +++ b/intern/rigidbody/rb_bullet_api.cpp @@ -717,13 +717,13 @@ struct myResultCallback : public btCollisionWorld::ClosestRayResultCallback struct rbFilterCallback : public btOverlapFilterCallback { - int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2); + int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2, bool activate); - rbFilterCallback(int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2)) { + rbFilterCallback(int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2, bool activate)) { this->callback = callback; } - bool check_collision(rbRigidBody* rb0, rbRigidBody* rb1, bool collides) const + bool check_collision(rbRigidBody* rb0, rbRigidBody* rb1, bool activate, bool collides) const { if (!rb0 || !rb1) return collides; @@ -802,7 +802,7 @@ struct rbFilterCallback : public btOverlapFilterCallback collides = collides && (bool)result; #endif - result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb); + result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb, activate); collides = collides && (bool)result; } @@ -811,8 +811,8 @@ struct rbFilterCallback : public btOverlapFilterCallback virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const { - //rbRigidBody *rb0 = (rbRigidBody *)((btFractureBody *)proxy0->m_clientObject)->getUserPointer(); - //rbRigidBody *rb1 = (rbRigidBody *)((btFractureBody *)proxy1->m_clientObject)->getUserPointer(); + rbRigidBody *rb0 = (rbRigidBody *)((btFractureBody *)proxy0->m_clientObject)->getUserPointer(); + rbRigidBody *rb1 = (rbRigidBody *)((btFractureBody *)proxy1->m_clientObject)->getUserPointer(); bool collides; collides = (proxy0->m_collisionFilterGroup & @@ -822,7 +822,8 @@ struct rbFilterCallback : public btOverlapFilterCallback (proxy0->m_collisionFilterMask | btBroadphaseProxy::StaticFilter | btBroadphaseProxy::KinematicFilter)); - return collides; //this->check_collision(rb0, rb1, collides); + //only apply to trigger and triggered, to improve performance, but do not actually activate + return this->check_collision(rb0, rb1, false, collides); } }; @@ -927,14 +928,14 @@ bool CollisionFilterDispatcher::needsCollision(const btCollisionObject *body0, c if (this->filterCallback) { - return this->filterCallback->check_collision(rb0, rb1, true); + return this->filterCallback->check_collision(rb0, rb1, true, true); } return true; } //yuck, but need a handle for the world somewhere for collision callback... -rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, void* blenderScene, int (*callback)(void *, void *, void *, void *, void *), +rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, void* blenderScene, int (*callback)(void *, void *, void *, void *, void *, bool), void (*contactCallback)(rbContactPoint* cp, void *bworld), void (*idCallbackOut)(void*, void*, int*, int*), void (*tickCallback)(float timestep, void *bworld)) { diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index a6f010b824e..33c0c09314a 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -2073,11 +2073,12 @@ static bool colgroup_check(int group1, int group2) return false; } -static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBodyWorld *rbw, MeshIsland *mi_trigger) +static bool do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBodyWorld *rbw, MeshIsland *mi_trigger, bool activate) { FractureModifierData *fmd; bool valid = true; bool antiValid = ob2->rigidbody_object->flag & RBO_FLAG_ANTI_TRIGGER; + bool wouldActivate = false; MeshIsland *mi; fmd = (FractureModifierData*)modifiers_findByType(ob, eModifierType_Fracture); @@ -2103,12 +2104,14 @@ static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBo if ((((rbo->flag & RBO_FLAG_KINEMATIC) || different_cluster) && ((mi_compare == mi) || (same_cluster && !dissolve))) && valid) { - if (rbo->physics_object) { + if (rbo->physics_object && activate) { activateRigidbody(rbo, rbw, mi, ob); } + + wouldActivate = true; } - if ((mi_compare == mi) && antiValid) + if ((mi_compare == mi) && antiValid && activate) { if (rbo->physics_object) { BKE_deactivateRigidbody(rbo); @@ -2122,16 +2125,19 @@ static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBo bool antiValid = ob2->rigidbody_object->flag & RBO_FLAG_ANTI_TRIGGER; RigidBodyOb* rbo = ob->rigidbody_object; - if (rbo && valid) + if (rbo && valid && activate) { activateRigidbody(rbo, rbw, NULL, ob); + wouldActivate = true; } - if (rbo && antiValid) + if (rbo && antiValid && activate) { BKE_deactivateRigidbody(rbo); } } + + return wouldActivate; } static int check_colgroup_ghost(Object* ob1, Object *ob2) @@ -2185,12 +2191,12 @@ static bool check_constraint_island(FractureModifierData* fmd, MeshIsland *mi1, } /* this allows partial object activation, only some shards will be activated, called from bullet(!) */ -static int filterCallback(void* world, void* island1, void* island2, void *blenderOb1, void* blenderOb2) { +static int filterCallback(void* world, void* island1, void* island2, void *blenderOb1, void* blenderOb2, bool activate) { MeshIsland* mi1, *mi2; RigidBodyWorld *rbw = (RigidBodyWorld*)world; Object* ob1, *ob2; int ob_index1 = -1, ob_index2 = -1; - bool validOb = true; + bool validOb = true, check_activate = false; mi1 = (MeshIsland*)island1; mi2 = (MeshIsland*)island2; @@ -2271,12 +2277,12 @@ static int filterCallback(void* world, void* island1, void* island2, void *blend { if (ob1->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION) { - do_activate(ob1, ob2, mi1, rbw, mi2); + check_activate = do_activate(ob1, ob2, mi1, rbw, mi2, activate); } if (ob2->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION) { - do_activate(ob2, ob1, mi2, rbw, mi1); + check_activate = do_activate(ob2, ob1, mi2, rbw, mi1, activate); } } @@ -2284,7 +2290,18 @@ static int filterCallback(void* world, void* island1, void* island2, void *blend fake_dynamic_collide(ob1, ob2, mi1, mi2, rbw); fake_dynamic_collide(ob2, ob1, mi2, mi1, rbw); - return check_colgroup_ghost(ob1, ob2) && ((check_constraint_island(fmd1, mi1, mi2) && check_constraint_island(fmd2, mi2, mi1)) || (ob1 != ob2)); + validOb = ((ob1->rigidbody_object->flag & RBO_FLAG_KINEMATIC) == 0) || ((ob2->rigidbody_object->flag & RBO_FLAG_KINEMATIC) == 0); + validOb = validOb || ((ob1->rigidbody_object->flag & RBO_FLAG_KINEMATIC) == 0) || ((mi2 && mi2->rigidbody->flag & RBO_FLAG_KINEMATIC) == 0); + validOb = validOb || ((mi1 && (mi1->rigidbody->flag & RBO_FLAG_KINEMATIC) == 0)) || ((ob2->rigidbody_object->flag & RBO_FLAG_KINEMATIC) == 0); + validOb = validOb || ((mi1 && (mi1->rigidbody->flag & RBO_FLAG_KINEMATIC) == 0)) || ((mi2 && mi2->rigidbody->flag & RBO_FLAG_KINEMATIC) == 0); + + if (validOb) + { + //always allow when atleast one object is not kinematic + check_activate = true; + } + + return check_activate && check_colgroup_ghost(ob1, ob2) && ((check_constraint_island(fmd1, mi1, mi2) && check_constraint_island(fmd2, mi2, mi1)) || (ob1 != ob2)); } static bool can_break(Object* collider, Object* ob, bool limit) @@ -4696,7 +4713,7 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) rbo = ob->rigidbody_object; /* keep original transform for kinematic and passive objects */ - if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE) + if (ELEM(NULL, rbw, rbo) || (((rbo->flag & RBO_FLAG_KINEMATIC) && ((rbo->flag & RBO_FLAG_KINEMATIC_REBUILD) == 0)) || rbo->type == RBO_TYPE_PASSIVE)) return; /* use rigid body transform after cache start frame if objects is not being transformed */ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs