Revision: 58492
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58492
Author:   sergof
Date:     2013-07-22 07:20:30 +0000 (Mon, 22 Jul 2013)
Log Message:
-----------
rigidbody: Add support for compound shapes

Compounds are defined implicitly by the parenting hierarchy.

TODO: Take more one level of the hierarchy is taken into account when
creating compound shapes.

Modified Paths:
--------------
    branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h
    branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp
    
branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/pointcache.c
    
branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c
    
branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h

Modified: branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h
===================================================================
--- branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h 2013-07-22 
07:20:28 UTC (rev 58491)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h 2013-07-22 
07:20:30 UTC (rev 58492)
@@ -205,6 +205,10 @@
 /* Get RigidBody's orientation as quaternion */
 void RB_body_get_orientation(rbRigidBody *body, float v_out[4]);
 
+void RB_body_get_compound_position(rbRigidBody *object, rbCollisionShape 
*child_shape, float v_out[3]);
+
+void RB_body_get_compound_orientation(rbRigidBody *object, rbCollisionShape 
*child_shape, float v_out[4]);
+
 /* ............ */
 
 extern void RB_body_apply_central_force(rbRigidBody *body, const float 
v_in[3]);
@@ -234,7 +238,10 @@
 /* 2b - GImpact Meshes */
 extern rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh);
 
+/* Compound Shapes ------------------- */
+extern void RB_shape_add_compound_child(rbRigidBody *parent, rbCollisionShape 
*child, float child_pos[3], float child_orn[4]);
 
+
 /* Cleanup --------------------------- */
 
 extern void RB_shape_delete(rbCollisionShape *shape);

Modified: branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp
===================================================================
--- branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp 
2013-07-22 07:20:28 UTC (rev 58491)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp 
2013-07-22 07:20:30 UTC (rev 58492)
@@ -671,6 +671,44 @@
        copy_quat_btquat(v_out, body->getWorldTransform().getRotation());
 }
 
+void RB_body_get_compound_position(rbRigidBody *object, rbCollisionShape 
*child_shape, float v_out[3])
+{
+       btRigidBody *body = object->body;
+       btCompoundShape *compound = (btCompoundShape*)body->getCollisionShape();
+       btTransform transform = body->getWorldTransform();
+       btTransform child_transform;
+       
+       for (int i = 0; i < compound->getNumChildShapes(); i++) {
+               if (child_shape->compound == compound->getChildShape(i)) {
+                       child_transform = compound->getChildTransform(i);
+                       break;
+               }
+       }
+       transform *= child_transform;
+       btVector3 pos = transform.getOrigin();;
+       
+       copy_v3_btvec3(v_out, pos);
+}
+
+void RB_body_get_compound_orientation(rbRigidBody *object, rbCollisionShape 
*child_shape, float v_out[4])
+{
+       btRigidBody *body = object->body;
+       btCompoundShape *compound = (btCompoundShape*)body->getCollisionShape();
+       btTransform transform = body->getWorldTransform();
+       btTransform child_transform;
+       
+       for (int i = 0; i < compound->getNumChildShapes(); i++) {
+               if (child_shape->compound == compound->getChildShape(i)) {
+                       child_transform = compound->getChildTransform(i);
+                       break;
+               }
+       }
+       transform *= child_transform;
+       btQuaternion orn = transform.getRotation();
+       
+       copy_quat_btquat(v_out, orn);
+}
+
 /* ............ */
 /* Overrides for simulation */
 
@@ -828,6 +866,17 @@
        return shape;
 }
 
+void RB_shape_add_compound_child(rbRigidBody *parent, rbCollisionShape *child, 
float child_pos[3], float child_orn[4])
+{
+       btCompoundShape *compound = 
(btCompoundShape*)parent->body->getCollisionShape();
+       btTransform parent_transform = 
parent->body->getCenterOfMassTransform(); // TODO center of mass?
+       btTransform transform;
+       transform.setOrigin(btVector3(child_pos[0], child_pos[1], 
child_pos[2]));
+       transform.setRotation(btQuaternion(child_orn[1], child_orn[2], 
child_orn[3], child_orn[0]));
+       transform = parent_transform.inverse() * transform;
+       compound->addChildShape(transform, child->compound);
+}
+
 /* Cleanup --------------------------- */
 
 void RB_shape_delete(rbCollisionShape *shape)

Modified: 
branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/pointcache.c
===================================================================
--- 
branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/pointcache.c  
    2013-07-22 07:20:28 UTC (rev 58491)
+++ 
branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/pointcache.c  
    2013-07-22 07:20:30 UTC (rev 58492)
@@ -976,8 +976,14 @@
                
                if (rbo->type == RBO_TYPE_ACTIVE) {
 #ifdef WITH_BULLET
-                       RB_body_get_position(rbo->physics_object, rbo->pos);
-                       RB_body_get_orientation(rbo->physics_object, rbo->orn);
+                       if (ob->parent && ob->parent->rigidbody_object && 
ob->parent->flag) {
+                               
RB_body_get_compound_position(ob->parent->rigidbody_object->physics_object, 
rbo->physics_shape, rbo->pos);
+                               
RB_body_get_compound_orientation(ob->parent->rigidbody_object->physics_object, 
rbo->physics_shape, rbo->orn);
+                       }
+                       else {
+                               RB_body_get_position(rbo->physics_object, 
rbo->pos);
+                               RB_body_get_orientation(rbo->physics_object, 
rbo->orn);
+                       }
 #endif
                        PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, rbo->pos);
                        PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, rbo->orn);

Modified: 
branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c
===================================================================
--- 
branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c   
    2013-07-22 07:20:28 UTC (rev 58491)
+++ 
branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c   
    2013-07-22 07:20:30 UTC (rev 58492)
@@ -346,6 +346,58 @@
        return shape;
 }
 
+/* check parent child relationships to construct compound shapes */
+static void rigidbody_prepare_compounds(RigidBodyWorld *rbw)
+{
+       GroupObject *go;
+       for (go = rbw->group->gobject.first; go; go = go->next) {
+               Object *ob = go->ob;
+               RigidBodyOb *rbo = ob ? ob->rigidbody_object : NULL;
+               if (rbo == NULL)
+                       continue;
+
+               if (ob->parent && ob->parent->rigidbody_object) {
+                       rbo->flag |= RBO_FLAG_COMPOUND_CHILD;
+                       ob->parent->rigidbody_object->flag |= 
RBO_FLAG_COMPOUND_PARENT;
+               }
+       }
+}
+
+/* note, object must be a compound shape parent */
+static void rigidbody_compound_shape_add_children(RigidBodyWorld *rbw, Object 
*ob)
+{
+       GroupObject *go;
+
+       RigidBodyOb *rbo = ob->rigidbody_object;
+       if (rbo == NULL)
+               return;
+
+       // RB_TODO check entire parent hirarchy not only one level.
+       for (go = rbw->group->gobject.first; go; go = go->next) {
+               Object *child_ob = go->ob;
+               RigidBodyOb *child_rbo = child_ob ? child_ob->rigidbody_object 
: NULL;
+
+               if (child_rbo && child_rbo->flag & RBO_FLAG_COMPOUND_CHILD) {
+                       if (child_ob->parent == ob) {
+                               float pos[3], orn[4];
+                               mat4_to_loc_quat(pos, orn, child_ob->obmat);
+                               
RB_shape_add_compound_child(rbo->physics_object, child_rbo->physics_shape, pos, 
orn);
+                       }
+               }
+       }
+}
+
+static void rigidbody_update_compounds(RigidBodyWorld *rbw)
+{
+       GroupObject *go;
+       for (go = rbw->group->gobject.first; go; go = go->next) {
+               Object *ob = go->ob;
+               RigidBodyOb *rbo = ob ? ob->rigidbody_object : NULL;
+               if (rbo && rbo->flag & RBO_FLAG_COMPOUND_PARENT)
+                       rigidbody_compound_shape_add_children(rbw, ob);
+       }
+}
+
 /* Create new physics sim collision shape for object and store it,
  * or remove the existing one first and replace...
  */
@@ -513,7 +565,7 @@
                RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & 
RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
        }
 
-       if (rbw && rbw->physics_world)
+       if (rbw && rbw->physics_world && (rbo->flag & RBO_FLAG_COMPOUND_CHILD) 
== 0) // RB_TODO find better solution for compound shapes
                RB_dworld_add_body(rbw->physics_world, rbo->physics_object, 
rbo->col_groups);
 }
 
@@ -1096,8 +1148,11 @@
        if (rebuild)
                BKE_rigidbody_validate_sim_world(scene, rbw, true);
        rigidbody_update_sim_world(scene, rbw);
-
+       
        /* update objects */
+       if (rebuild)
+               rigidbody_prepare_compounds(rbw);
+       
        for (go = rbw->group->gobject.first; go; go = go->next) {
                Object *ob = go->ob;
 
@@ -1142,6 +1197,10 @@
                        rigidbody_update_sim_ob(scene, rbw, ob, rbo);
                }
        }
+       
+       if (rebuild)
+               rigidbody_update_compounds(rbw);
+       
        /* update constraints */
        if (rbw->constraints == NULL) /* no constraints, move on */
                return;

Modified: 
branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h
===================================================================
--- 
branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h  
    2013-07-22 07:20:28 UTC (rev 58491)
+++ 
branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h  
    2013-07-22 07:20:30 UTC (rev 58492)
@@ -148,7 +148,10 @@
        /* rigidbody is not dynamically simulated */
        RBO_FLAG_DISABLED                       = (1 << 5),
        /* collision margin is not embedded (only used by convex hull shapes 
for now) */
-       RBO_FLAG_USE_MARGIN                     = (1 << 6)
+       RBO_FLAG_USE_MARGIN                     = (1 << 6),
+       /* compound shape flags, should not be set manually */
+       RBO_FLAG_COMPOUND_PARENT        = (1 << 7),
+       RBO_FLAG_COMPOUND_CHILD         = (1 << 8)
 } eRigidBodyOb_Flag;
 
 /* RigidBody Collision Shape */

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

Reply via email to