~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/blenkernel/intern/rigidbody.c

  • Committer: Reinhard Tartler
  • Date: 2014-05-31 01:50:05 UTC
  • mfrom: (14.2.27 sid)
  • Revision ID: siretart@tauware.de-20140531015005-ml6druahuj82nsav
mergeĀ fromĀ debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
225
225
/* ************************************** */
226
226
/* Setup Utilities - Validate Sim Instances */
227
227
 
 
228
/* get the appropriate DerivedMesh based on rigid body mesh source */
 
229
static DerivedMesh *rigidbody_get_mesh(Object *ob)
 
230
{
 
231
        if (ob->rigidbody_object->mesh_source == RBO_MESH_DEFORM) {
 
232
                return ob->derivedDeform;
 
233
        }
 
234
        else if (ob->rigidbody_object->mesh_source == RBO_MESH_FINAL) {
 
235
                return ob->derivedFinal;
 
236
        }
 
237
        else {
 
238
                return CDDM_from_mesh(ob->data);
 
239
        }
 
240
}
 
241
 
228
242
/* create collision shape of mesh - convex hull */
229
243
static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob, float margin, bool *can_embed)
230
244
{
231
245
        rbCollisionShape *shape = NULL;
232
 
        Mesh *me = NULL;
 
246
        DerivedMesh *dm = NULL;
 
247
        MVert *mvert = NULL;
 
248
        int totvert = 0;
233
249
 
234
250
        if (ob->type == OB_MESH && ob->data) {
235
 
                me = ob->data;
 
251
                dm = rigidbody_get_mesh(ob);
 
252
                mvert   = (dm) ? dm->getVertArray(dm) : NULL;
 
253
                totvert = (dm) ? dm->getNumVerts(dm) : 0;
236
254
        }
237
255
        else {
238
256
                printf("ERROR: cannot make Convex Hull collision shape for non-Mesh object\n");
239
257
        }
240
258
 
241
 
        if (me && me->totvert) {
242
 
                shape = RB_shape_new_convex_hull((float *)me->mvert, sizeof(MVert), me->totvert, margin, can_embed);
 
259
        if (totvert) {
 
260
                shape = RB_shape_new_convex_hull((float *)mvert, sizeof(MVert), totvert, margin, can_embed);
243
261
        }
244
262
        else {
245
263
                printf("ERROR: no vertices to define Convex Hull collision shape with\n");
246
264
        }
247
265
 
 
266
        if (dm && ob->rigidbody_object->mesh_source == RBO_MESH_BASE)
 
267
                dm->release(dm);
 
268
 
248
269
        return shape;
249
270
}
250
271
 
256
277
        rbCollisionShape *shape = NULL;
257
278
 
258
279
        if (ob->type == OB_MESH) {
259
 
                DerivedMesh *dm = CDDM_from_mesh(ob->data, ob);
260
 
 
 
280
                DerivedMesh *dm = NULL;
261
281
                MVert *mvert;
262
282
                MFace *mface;
263
283
                int totvert;
264
284
                int totface;
 
285
                int tottris = 0;
 
286
                int triangle_index = 0;
 
287
 
 
288
                dm = rigidbody_get_mesh(ob);
265
289
 
266
290
                /* ensure mesh validity, then grab data */
 
291
                if (dm == NULL)
 
292
                        return NULL;
 
293
 
267
294
                DM_ensure_tessface(dm);
268
295
 
269
296
                mvert   = (dm) ? dm->getVertArray(dm) : NULL;
278
305
                else {
279
306
                        rbMeshData *mdata;
280
307
                        int i;
 
308
                        
 
309
                        /* count triangles */
 
310
                        for (i = 0; i < totface; i++) {
 
311
                                (mface[i].v4) ? (tottris += 2) : (tottris += 1);
 
312
                        }
281
313
 
282
314
                        /* init mesh data for collision shape */
283
 
                        mdata = RB_trimesh_data_new();
 
315
                        mdata = RB_trimesh_data_new(tottris, totvert);
 
316
                        
 
317
                        RB_trimesh_add_vertices(mdata, (float *)mvert, totvert, sizeof(MVert));
284
318
 
285
319
                        /* loop over all faces, adding them as triangles to the collision shape
286
320
                         * (so for some faces, more than triangle will get added)
287
321
                         */
288
322
                        for (i = 0; (i < totface) && (mface) && (mvert); i++, mface++) {
289
323
                                /* add first triangle - verts 1,2,3 */
290
 
                                {
291
 
                                        MVert *va = (mface->v1 < totvert) ? (mvert + mface->v1) : (mvert);
292
 
                                        MVert *vb = (mface->v2 < totvert) ? (mvert + mface->v2) : (mvert);
293
 
                                        MVert *vc = (mface->v3 < totvert) ? (mvert + mface->v3) : (mvert);
294
 
 
295
 
                                        RB_trimesh_add_triangle(mdata, va->co, vb->co, vc->co);
296
 
                                }
 
324
                                RB_trimesh_add_triangle_indices(mdata, triangle_index, mface->v1, mface->v2, mface->v3);
 
325
                                triangle_index++;
297
326
 
298
327
                                /* add second triangle if needed - verts 1,3,4 */
299
328
                                if (mface->v4) {
300
 
                                        MVert *va = (mface->v1 < totvert) ? (mvert + mface->v1) : (mvert);
301
 
                                        MVert *vb = (mface->v3 < totvert) ? (mvert + mface->v3) : (mvert);
302
 
                                        MVert *vc = (mface->v4 < totvert) ? (mvert + mface->v4) : (mvert);
303
 
 
304
 
                                        RB_trimesh_add_triangle(mdata, va->co, vb->co, vc->co);
 
329
                                        RB_trimesh_add_triangle_indices(mdata, triangle_index, mface->v1, mface->v3, mface->v4);
 
330
                                        triangle_index++;
305
331
                                }
306
332
                        }
 
333
                        RB_trimesh_finish(mdata);
307
334
 
308
335
                        /* construct collision shape
309
336
                         *
323
350
                }
324
351
 
325
352
                /* cleanup temp data */
326
 
                if (dm) {
 
353
                if (dm && ob->rigidbody_object->mesh_source == RBO_MESH_BASE) {
327
354
                        dm->release(dm);
328
355
                }
329
356
        }
337
364
/* Create new physics sim collision shape for object and store it,
338
365
 * or remove the existing one first and replace...
339
366
 */
340
 
void BKE_rigidbody_validate_sim_shape(Object *ob, short rebuild)
 
367
static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
341
368
{
342
369
        RigidBodyOb *rbo = ob->rigidbody_object;
343
370
        rbCollisionShape *new_shape = NULL;
425
452
                rbo->physics_shape = new_shape;
426
453
                RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo));
427
454
        }
428
 
        else { /* otherwise fall back to box shape */
 
455
        /* use box shape if we can't fall back to old shape */
 
456
        else if (rbo->physics_shape == NULL) {
429
457
                rbo->shape = RB_SHAPE_BOX;
430
 
                BKE_rigidbody_validate_sim_shape(ob, true);
 
458
                rigidbody_validate_sim_shape(ob, true);
431
459
        }
432
460
}
433
461
 
436
464
/* Create physics sim representation of object given RigidBody settings
437
465
 * < rebuild: even if an instance already exists, replace it
438
466
 */
439
 
void BKE_rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, short rebuild)
 
467
static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool rebuild)
440
468
{
441
469
        RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
442
470
        float loc[3];
451
479
        /* make sure collision shape exists */
452
480
        /* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects, but it's needed for constraints to update correctly */
453
481
        if (rbo->physics_shape == NULL || rebuild)
454
 
                BKE_rigidbody_validate_sim_shape(ob, true);
 
482
                rigidbody_validate_sim_shape(ob, true);
455
483
 
456
 
        if (rbo->physics_object) {
457
 
                if (rebuild == false)
458
 
                        RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
 
484
        if (rbo->physics_object && rebuild == false) {
 
485
                RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
459
486
        }
460
487
        if (!rbo->physics_object || rebuild) {
461
488
                /* remove rigid body if it already exists before creating a new one */
500
527
/* Create physics sim representation of constraint given rigid body constraint settings
501
528
 * < rebuild: even if an instance already exists, replace it
502
529
 */
503
 
void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, short rebuild)
 
530
static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, bool rebuild)
504
531
{
505
532
        RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
506
533
        float loc[3];
527
554
                return;
528
555
        }
529
556
 
530
 
        if (rbc->physics_constraint) {
531
 
                if (rebuild == false)
532
 
                        RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
 
557
        if (rbc->physics_constraint && rebuild == false) {
 
558
                RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
533
559
        }
534
560
        if (rbc->physics_constraint == NULL || rebuild) {
535
561
                rbRigidBody *rb1 = rbc->ob1->rigidbody_object->physics_object;
672
698
 
673
699
/* Create physics sim world given RigidBody world settings */
674
700
// NOTE: this does NOT update object references that the scene uses, in case those aren't ready yet!
675
 
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, short rebuild)
 
701
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild)
676
702
{
677
703
        /* sanity checks */
678
704
        if (rbw == NULL)
798
824
        else
799
825
                rbo->shape = RB_SHAPE_TRIMESH;
800
826
 
 
827
        rbo->mesh_source = RBO_MESH_DEFORM;
 
828
 
801
829
        /* set initial transform */
802
830
        mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
803
831
 
1000
1028
        if (rbo->physics_object == NULL)
1001
1029
                return;
1002
1030
 
 
1031
        if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) {
 
1032
                DerivedMesh *dm = ob->derivedDeform;
 
1033
                if (dm) {
 
1034
                        MVert *mvert = dm->getVertArray(dm);
 
1035
                        int totvert = dm->getNumVerts(dm);
 
1036
                        BoundBox *bb = BKE_object_boundbox_get(ob);
 
1037
 
 
1038
                        RB_shape_trimesh_update(rbo->physics_shape, (float *)mvert, totvert, sizeof(MVert), bb->vec[0], bb->vec[6]);
 
1039
                }
 
1040
        }
 
1041
 
1003
1042
        mat4_decompose(loc, rot, scale, ob->obmat);
1004
1043
 
1005
1044
        /* update scale for all objects */
1027
1066
                ListBase *effectors;
1028
1067
 
1029
1068
                /* get effectors present in the group specified by effector_weights */
1030
 
                effectors = pdInitEffectors(scene, ob, NULL, effector_weights);
 
1069
                effectors = pdInitEffectors(scene, ob, NULL, effector_weights, true);
1031
1070
                if (effectors) {
1032
1071
                        float eff_force[3] = {0.0f, 0.0f, 0.0f};
1033
1072
                        float eff_loc[3], eff_vel[3];
1066
1105
/* Updates and validates world, bodies and shapes.
1067
1106
 * < rebuild: rebuild entire simulation
1068
1107
 */
1069
 
static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, int rebuild)
 
1108
static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool rebuild)
1070
1109
{
1071
1110
        GroupObject *go;
1072
1111
 
1091
1130
                                 *      - assume object to be active? That is the default for newly added settings...
1092
1131
                                 */
1093
1132
                                ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, RBO_TYPE_ACTIVE);
1094
 
                                BKE_rigidbody_validate_sim_object(rbw, ob, true);
 
1133
                                rigidbody_validate_sim_object(rbw, ob, true);
1095
1134
 
1096
1135
                                rbo = ob->rigidbody_object;
1097
1136
                        }
1100
1139
                                /* refresh object... */
1101
1140
                                if (rebuild) {
1102
1141
                                        /* World has been rebuilt so rebuild object */
1103
 
                                        BKE_rigidbody_validate_sim_object(rbw, ob, true);
 
1142
                                        rigidbody_validate_sim_object(rbw, ob, true);
1104
1143
                                }
1105
1144
                                else if (rbo->flag & RBO_FLAG_NEEDS_VALIDATE) {
1106
 
                                        BKE_rigidbody_validate_sim_object(rbw, ob, false);
 
1145
                                        rigidbody_validate_sim_object(rbw, ob, false);
1107
1146
                                }
1108
1147
                                /* refresh shape... */
1109
1148
                                if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) {
1110
1149
                                        /* mesh/shape data changed, so force shape refresh */
1111
 
                                        BKE_rigidbody_validate_sim_shape(ob, true);
 
1150
                                        rigidbody_validate_sim_shape(ob, true);
1112
1151
                                        /* now tell RB sim about it */
1113
1152
                                        // XXX: we assume that this can only get applied for active/passive shapes that will be included as rigidbodies
1114
1153
                                        RB_body_set_collision_shape(rbo->physics_object, rbo->physics_shape);
1137
1176
                                 * constraint settings (perhaps it was added manually), add!
1138
1177
                                 */
1139
1178
                                ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED);
1140
 
                                BKE_rigidbody_validate_sim_constraint(rbw, ob, true);
 
1179
                                rigidbody_validate_sim_constraint(rbw, ob, true);
1141
1180
 
1142
1181
                                rbc = ob->rigidbody_constraint;
1143
1182
                        }
1145
1184
                                /* perform simulation data updates as tagged */
1146
1185
                                if (rebuild) {
1147
1186
                                        /* World has been rebuilt so rebuild constraint */
1148
 
                                        BKE_rigidbody_validate_sim_constraint(rbw, ob, true);
 
1187
                                        rigidbody_validate_sim_constraint(rbw, ob, true);
1149
1188
                                }
1150
1189
                                else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
1151
 
                                        BKE_rigidbody_validate_sim_constraint(rbw, ob, false);
 
1190
                                        rigidbody_validate_sim_constraint(rbw, ob, false);
1152
1191
                                }
1153
1192
                                rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
1154
1193
                        }
1211
1250
        }
1212
1251
}
1213
1252
 
1214
 
/* Used when cancelling transforms - return rigidbody and object to initial states */
 
1253
/* Used when canceling transforms - return rigidbody and object to initial states */
1215
1254
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
1216
1255
{
1217
1256
        RigidBodyOb *rbo = ob->rigidbody_object;
1268
1307
                cache->flag |= PTCACHE_OUTDATED;
1269
1308
        }
1270
1309
 
1271
 
        if (ctime <= startframe + 1 && rbw->ltime == startframe) {
 
1310
        if (ctime == startframe + 1 && rbw->ltime == startframe) {
1272
1311
                if (cache->flag & PTCACHE_OUTDATED) {
1273
1312
                        BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
1274
1313
                        rigidbody_update_simulation(scene, rbw, true);
1355
1394
struct RigidBodyOb *BKE_rigidbody_copy_object(Object *ob) { return NULL; }
1356
1395
struct RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob) { return NULL; }
1357
1396
void BKE_rigidbody_relink_constraint(RigidBodyCon *rbc) {}
1358
 
void BKE_rigidbody_validate_sim_shape(Object *ob, short rebuild) {}
1359
 
void BKE_rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, short rebuild) {}
1360
 
void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, short rebuild) {}
1361
 
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, short rebuild) {}
 
1397
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) {}
1362
1398
struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene) { return NULL; }
1363
1399
struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw) { return NULL; }
1364
1400
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {}