Commit: 1fb3642cdaa1bc5871df28266d10977fe1ff829d
Author: Martin Felke
Date:   Thu Nov 6 12:39:58 2014 +0100
Branches: fracture_modifier
https://developer.blender.org/rB1fb3642cdaa1bc5871df28266d10977fe1ff829d

added a new "Triggered" checkbox to rigidbodies, which allows them to be 
triggered in case they are kinematic. this will reset the kinematic state and 
make them dynamic

===================================================================

M       intern/rigidbody/RBI_api.h
M       intern/rigidbody/rb_bullet_api.cpp
M       release/scripts/startup/bl_ui/properties_physics_rigidbody.py
M       source/blender/blenkernel/intern/rigidbody.c
M       source/blender/makesdna/DNA_rigidbody_types.h
M       source/blender/makesrna/intern/rna_rigidbody.c

===================================================================

diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 08e6b90..4e21ebf 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -66,6 +66,17 @@ typedef struct rbMeshData rbMeshData;
 /* Constraint */
 typedef struct rbConstraint rbConstraint;
 
+/* Collision feedback (manifolds and contact points */
+typedef struct rbContactPoint {
+       float contact_force;
+       void *contact_bodyA;
+       void *contact_bodyB;
+       float contact_pos_world_onA[3];
+       float contact_pos_world_onB[3];
+} rbContactPoint;
+
+typedef struct rbContactCallback rbContactCallback;
+
 /* ********************************** */
 /* Dynamics World Methods */
 
@@ -73,7 +84,8 @@ typedef struct rbConstraint rbConstraint;
 
 /* 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, int 
(*callback)(void *, void *, void *));
+rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, int 
(*callback)(void *, void *, void *),
+                                                            void 
(*contactCallback)(rbContactPoint *, void *));
 
 /* Delete the given dynamics world, and free any extra data it may require */
 void RB_dworld_delete(rbDynamicsWorld *world);
diff --git a/intern/rigidbody/rb_bullet_api.cpp 
b/intern/rigidbody/rb_bullet_api.cpp
index fe92f38..dcd1582 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -81,6 +81,7 @@ struct rbDynamicsWorld {
        btConstraintSolver *constraintSolver;
        btOverlapFilterCallback *filterCallback;
        void *blenderWorld;
+       struct rbContactCallback *contactCallback;
 };
 struct rbRigidBody {
        btRigidBody *body;
@@ -149,13 +150,59 @@ static inline void copy_quat_btquat(float quat[4], const 
btQuaternion &btquat)
        quat[3] = btquat.getZ();
 }
 
+/*Contact Handling*/
+typedef void (*cont_callback)(rbContactPoint *cp, void* bworld);
+
+struct rbContactCallback
+{
+       static cont_callback callback;
+       static void* bworld;
+       rbContactCallback(cont_callback cp, void* bworld);
+       static bool handle_contacts(btManifoldPoint& point, btCollisionObject* 
body0, btCollisionObject* body1);
+};
+
+rbContactCallback::rbContactCallback(cont_callback callback, void *bworld){
+       rbContactCallback::callback = callback;
+       rbContactCallback::bworld = bworld;
+       gContactProcessedCallback = 
(ContactProcessedCallback)&rbContactCallback::handle_contacts;
+}
+
+cont_callback rbContactCallback::callback = 0;
+void* rbContactCallback::bworld = NULL;
+
+bool rbContactCallback::handle_contacts(btManifoldPoint& point, 
btCollisionObject* body0, btCollisionObject* body1)
+{
+       if (rbContactCallback::callback)
+       {
+               rbContactPoint *cp = new rbContactPoint;
+               btRigidBody* bodyA = (btRigidBody*)(body0);
+               btRigidBody* bodyB = (btRigidBody*)(body1);
+               rbRigidBody* rbA = (rbRigidBody*)(bodyA->getUserPointer());
+               rbRigidBody* rbB = (rbRigidBody*)(bodyB->getUserPointer());
+               if (rbA)
+                       cp->contact_bodyA = rbA->meshIsland;
+
+               if (rbB)
+                       cp->contact_bodyB = rbB->meshIsland;
+
+               cp->contact_force = point.getAppliedImpulse();
+               copy_v3_btvec3(cp->contact_pos_world_onA, 
point.getPositionWorldOnA());
+               copy_v3_btvec3(cp->contact_pos_world_onB, 
point.getPositionWorldOnB());
+
+               rbContactCallback::callback(cp, rbContactCallback::bworld);
+
+               delete cp;
+       }
+}
+
 /* ********************************** */
 /* Dynamics World Methods */
 
 /* Setup ---------------------------- */
 
 //yuck, but need a handle for the world somewhere for collision callback...
-rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, int 
(*callback)(void *, void *, void *))
+rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, int 
(*callback)(void *, void *, void *),
+                                                          void 
(*contactCallback)(rbContactPoint * cp, void *bworld))
 {
        rbDynamicsWorld *world = new rbDynamicsWorld;
        
@@ -181,6 +228,12 @@ rbDynamicsWorld *RB_dworld_new(const float gravity[3], 
void* blenderWorld, int (
        world->blenderWorld = blenderWorld;
 
        RB_dworld_set_gravity(world, gravity);
+
+       /*contact callback */
+       if (contactCallback)
+       {
+               world->contactCallback = new rbContactCallback(contactCallback, 
world->blenderWorld);
+       }
        
        return world;
 }
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py 
b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
index 5f589c4..7d62fee 100644
--- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
@@ -48,6 +48,8 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, 
Panel):
             if rbo.type == 'ACTIVE':
                 row.prop(rbo, "enabled", text="Dynamic")
             row.prop(rbo, "kinematic", text="Animated")
+            if rbo.type == 'ACTIVE':
+                row.prop(rbo, "use_kinematic_deactivation", text="Triggered")
 
             if rbo.type == 'ACTIVE':
                 layout.prop(rbo, "mass")
diff --git a/source/blender/blenkernel/intern/rigidbody.c 
b/source/blender/blenkernel/intern/rigidbody.c
index 9225099..3b9675b 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1617,48 +1617,127 @@ static int filterCallback(void* world, void* island1, 
void* island2) {
        ob_index1 = rbw->cache_offset_map[mi1->linear_index];
        ob_index2 = rbw->cache_offset_map[mi2->linear_index];
 
-       if (ob_index1 != ob_index2 &&
+       if (ob_index1 != ob_index2 && (mi1->rigidbody->col_groups == 
mi2->rigidbody->col_groups) &&
           ((mi1->rigidbody->flag & RBO_FLAG_KINEMATIC) ||
           (mi2->rigidbody->flag & RBO_FLAG_KINEMATIC)))
        {
-               float linvel[3], angvel[3];
                MeshIsland *mi;
                ob1 = rbw->objects[ob_index1];
-               fmd1 = (FractureModifierData*)modifiers_findByType(ob1, 
eModifierType_Fracture);
-               RB_body_get_linear_velocity(mi1->rigidbody->physics_object, 
linvel);
-               RB_body_get_angular_velocity(mi1->rigidbody->physics_object, 
angvel);
-               for (mi = fmd1->meshIslands.first; mi; mi = mi->next)
+               if (ob1->rigidbody_object->flag & 
RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
                {
-                       RigidBodyOb* rbo = mi->rigidbody;
-                       if (mi->rigidbody->flag & RBO_FLAG_KINEMATIC)
+                       fmd1 = (FractureModifierData*)modifiers_findByType(ob1, 
eModifierType_Fracture);
+                       for (mi = fmd1->meshIslands.first; mi; mi = mi->next)
                        {
-                               rbo->flag &= ~RBO_FLAG_KINEMATIC;
-                               rbo->flag |= RBO_FLAG_KINEMATIC_REBUILD;
-                               
RB_body_set_linear_velocity(rbo->physics_object, linvel);
-                               
RB_body_set_angular_velocity(rbo->physics_object, angvel);
+                               RigidBodyOb* rbo = mi->rigidbody;
+                               if (mi->rigidbody->flag & RBO_FLAG_KINEMATIC)
+                               {
+                                       rbo->flag &= ~RBO_FLAG_KINEMATIC;
+                                       rbo->flag |= RBO_FLAG_KINEMATIC_REBUILD;
+                                       rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
+                               }
                        }
                }
 
                ob2 = rbw->objects[ob_index2];
-               fmd2 = (FractureModifierData*)modifiers_findByType(ob2, 
eModifierType_Fracture);
-               RB_body_get_linear_velocity(mi2->rigidbody->physics_object, 
linvel);
-               RB_body_get_angular_velocity(mi2->rigidbody->physics_object, 
angvel);
-
-               for (mi = fmd2->meshIslands.first; mi; mi = mi->next)
+               if (ob2->rigidbody_object->flag & 
RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
                {
-                       RigidBodyOb* rbo = mi->rigidbody;
+                       fmd2 = (FractureModifierData*)modifiers_findByType(ob2, 
eModifierType_Fracture);
 
-                       if (mi->rigidbody->flag & RBO_FLAG_KINEMATIC)
+                       for (mi = fmd2->meshIslands.first; mi; mi = mi->next)
                        {
-                               rbo->flag &= ~RBO_FLAG_KINEMATIC;
-                               rbo->flag |= RBO_FLAG_KINEMATIC_REBUILD;
-                               
RB_body_set_linear_velocity(rbo->physics_object, linvel);
-                               
RB_body_set_angular_velocity(rbo->physics_object, angvel);
+                               RigidBodyOb* rbo = mi->rigidbody;
+
+                               if (mi->rigidbody->flag & RBO_FLAG_KINEMATIC)
+                               {
+                                       rbo->flag &= ~RBO_FLAG_KINEMATIC;
+                                       rbo->flag |= RBO_FLAG_KINEMATIC_REBUILD;
+                                       rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
+                               }
                        }
                }
        }
 
-       return 1;
+       return mi1->rigidbody->col_groups == mi2->rigidbody->col_groups;
+}
+
+static void contactCallback(rbContactPoint* cp, void* world)
+{
+       MeshIsland* mi1, *mi2;
+       RigidBodyWorld *rbw = (RigidBodyWorld*)world;
+       Object* ob1, *ob2;
+       int ob_index1, ob_index2;
+       FractureModifierData *fmd1, *fmd2;
+       float force = cp->contact_force;
+
+       mi1 = (MeshIsland*)cp->contact_bodyA;
+       mi2 = (MeshIsland*)cp->contact_bodyB;
+
+       if (rbw == NULL)
+       {
+               return;
+       }
+
+       if ((mi1 == NULL) || (mi2 == NULL)) {
+               return;
+       }
+
+       //cache offset map is a dull name for that...
+       ob_index1 = rbw->cache_offset_map[mi1->linear_index];
+       ob_index2 = rbw->cache_offset_map[mi2->linear_index];
+
+       if (ob_index1 != ob_index2) // &&
+          //((mi1->rigidbody->flag & RBO_FLAG_KINEMATIC) ||
+          //(mi2->rigidbody->flag & RBO_FLAG_KINEMATIC)))
+       {
+               float linvel[3], angvel[3];
+               MeshIsland *mi;
+               ob1 = rbw->objects[ob_index1];
+               if (ob1->rigidbody_object->flag & 
RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
+               {
+                       fmd1 = (FractureModifierData*)modifiers_findByType(ob1, 
eModifierType_Fracture);
+                       
RB_body_get_linear_velocity(mi1->rigidbody->physics_object, linvel);
+                       
RB_body_get_angular_velocity(mi1->rigidbody->physics_object, angvel);
+
+                       mul_v3_fl(linvel, force);
+                       mul_v3_fl(angvel, force);
+
+                       for (mi = fmd1->meshIslands.first; mi; mi = mi->next)
+                       {
+                               RigidBodyOb* rbo = mi->rigidbody;
+                               //if (mi->rigidbody->flag & RBO_FLAG_KINEMATIC)
+                               {
+                                       //rbo->flag &= ~RBO_FLAG_KINEMATIC;
+                                       //rbo->flag |= 
RBO_FLAG_KINEMATIC_REBUILD;
+                                       
RB_body_set_linear_velocity(rbo->physics_object, linvel);
+                                       
RB_body_set_angular_velocity(rbo->physics_object, angvel);
+                               }
+                       }
+               }
+
+               ob2 = rbw->objects[ob_index2];
+               if (ob2->rigidbody_object->flag & 
RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
+               {
+                       fmd2 = (FractureModifierData*)modifiers_findByType(ob2, 
eModifierType_Fracture);
+                       
RB_body_get_linear_velocity(mi2->rigidbody->physics_object, linvel);
+                       
RB_body_get_angular_velocity(mi2->rigidbody->physics_object, angvel);
+
+                       mul_v3_fl(linvel, force);
+                       mul_v3_fl(angvel, force);
+
+                       for (mi = fmd2->meshIslands.first; mi; mi = mi->next)
+                       {
+                               RigidBodyOb* rbo = mi->rigidbody;
+
+                               //if (mi->rigidbody->flag & RBO_FLAG_KINEMATIC)
+                               {
+                                       //rbo->flag &= ~RBO_FLAG_KINEMATIC;
+                                       //rbo-

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to