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