70
73
static int ED_operator_rigidbody_active_poll(bContext *C)
72
75
if (ED_operator_object_active_editable(C)) {
73
Object *ob = CTX_data_active_object(C);
76
Object *ob = ED_object_active_context(C);
74
77
return (ob && ob->rigidbody_object);
80
static int ED_operator_rigidbody_add_poll(bContext *C)
82
if (ED_operator_object_active_editable(C)) {
83
Object *ob = CTX_data_active_object(C);
84
return (ob && ob->type == OB_MESH);
90
83
/* ----------------- */
92
void ED_rigidbody_ob_add(wmOperator *op, Scene *scene, Object *ob, int type)
85
bool ED_rigidbody_object_add(Scene *scene, Object *ob, int type, ReportList *reports)
94
87
RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
96
89
if (ob->type != OB_MESH) {
97
BKE_report(op->reports, RPT_ERROR, "Can't add Rigid Body to non mesh object");
90
BKE_report(reports, RPT_ERROR, "Can't add Rigid Body to non mesh object");
100
93
if (((Mesh *)ob->data)->totpoly == 0) {
101
BKE_report(op->reports, RPT_ERROR, "Can't create Rigid Body from mesh with no polygons");
94
BKE_report(reports, RPT_ERROR, "Can't create Rigid Body from mesh with no polygons");
105
98
/* Add rigid body world and group if they don't exist for convenience */
106
99
if (rbw == NULL) {
107
100
rbw = BKE_rigidbody_create_world(scene);
102
BKE_report(reports, RPT_ERROR, "Can't create Rigid Body world");
108
105
BKE_rigidbody_validate_sim_world(scene, rbw, false);
109
106
scene->rigidbody_world = rbw;
111
108
if (rbw->group == NULL) {
112
rbw->group = add_group(G.main, "RigidBodyWorld");
109
rbw->group = BKE_group_add(G.main, "RigidBodyWorld");
115
112
/* make rigidbody object settings */
120
117
ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE;
122
119
/* add object to rigid body group */
123
add_to_group(rbw->group, ob, scene, NULL);
120
BKE_group_object_add(rbw->group, ob, scene, NULL);
125
122
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
128
void ED_rigidbody_ob_remove(Scene *scene, Object *ob)
127
void ED_rigidbody_object_remove(Scene *scene, Object *ob)
130
129
RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
132
131
BKE_rigidbody_remove_object(scene, ob);
134
rem_from_group(rbw->group, ob, scene, NULL);
133
BKE_group_object_unlink(rbw->group, ob, scene, NULL);
136
135
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
142
141
/* ************ Add Rigid Body ************** */
144
static int rigidbody_ob_add_exec(bContext *C, wmOperator *op)
143
static int rigidbody_object_add_exec(bContext *C, wmOperator *op)
146
145
Scene *scene = CTX_data_scene(C);
147
Object *ob = (scene) ? OBACT : NULL;
146
Object *ob = ED_object_active_context(C);
148
147
int type = RNA_enum_get(op->ptr, "type");
150
150
/* apply to active object */
151
ED_rigidbody_ob_add(op, scene, ob, type);
154
DAG_ids_flush_update(CTX_data_main(C), 0);
156
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
159
return OPERATOR_FINISHED;
151
change = ED_rigidbody_object_add(scene, ob, type, op->reports);
155
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
156
WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
159
return OPERATOR_FINISHED;
162
return OPERATOR_CANCELLED;
162
166
void RIGIDBODY_OT_object_add(wmOperatorType *ot)
167
171
ot->description = "Add active object as Rigid Body";
170
ot->exec = rigidbody_ob_add_exec;
171
ot->poll = ED_operator_rigidbody_add_poll;
174
ot->exec = rigidbody_object_add_exec;
175
ot->poll = ED_operator_object_active_editable_mesh;
174
178
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
177
ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_ob_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", "");
181
ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_object_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", "");
180
184
/* ************ Remove Rigid Body ************** */
182
static int rigidbody_ob_remove_exec(bContext *C, wmOperator *op)
186
static int rigidbody_object_remove_exec(bContext *C, wmOperator *op)
184
188
Scene *scene = CTX_data_scene(C);
185
Object *ob = (scene) ? OBACT : NULL;
189
return OPERATOR_CANCELLED;
189
Object *ob = ED_object_active_context(C);
191
192
/* apply to active object */
192
if (ELEM(NULL, ob, ob->rigidbody_object)) {
193
if (!ELEM(NULL, ob, ob->rigidbody_object)) {
194
ED_rigidbody_object_remove(scene, ob);
200
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
201
WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
204
return OPERATOR_FINISHED;
193
207
BKE_report(op->reports, RPT_ERROR, "Object has no Rigid Body settings to remove");
194
208
return OPERATOR_CANCELLED;
197
ED_rigidbody_ob_remove(scene, ob);
200
DAG_ids_flush_update(CTX_data_main(C), 0);
202
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
205
return OPERATOR_FINISHED;
208
212
void RIGIDBODY_OT_object_remove(wmOperatorType *ot)
226
230
/* ************ Add Rigid Bodies ************** */
228
static int rigidbody_obs_add_exec(bContext *C, wmOperator *op)
232
static int rigidbody_objects_add_exec(bContext *C, wmOperator *op)
230
234
Scene *scene = CTX_data_scene(C);
231
235
int type = RNA_enum_get(op->ptr, "type");
235
BKE_report(op->reports, RPT_ERROR, "No Scene to add Rigid Bodies to");
236
return OPERATOR_CANCELLED;
238
238
/* create rigid body objects and add them to the world's group */
239
239
CTX_DATA_BEGIN(C, Object *, ob, selected_objects) {
240
ED_rigidbody_ob_add(op, scene, ob, type);
240
change |= ED_rigidbody_object_add(scene, ob, type, op->reports);
245
DAG_ids_flush_update(CTX_data_main(C), 0);
247
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
248
WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
251
return OPERATOR_FINISHED;
246
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
247
WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
250
return OPERATOR_FINISHED;
253
return OPERATOR_CANCELLED;
254
257
void RIGIDBODY_OT_objects_add(wmOperatorType *ot)
259
262
ot->description = "Add selected objects as Rigid Bodies";
262
ot->exec = rigidbody_obs_add_exec;
263
ot->poll = ED_operator_rigidbody_add_poll;
265
ot->exec = rigidbody_objects_add_exec;
266
ot->poll = ED_operator_object_active_editable_mesh;
266
269
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
269
ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_ob_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", "");
272
ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_object_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", "");
272
275
/* ************ Remove Rigid Bodies ************** */
274
static int rigidbody_obs_remove_exec(bContext *C, wmOperator *UNUSED(op))
277
static int rigidbody_objects_remove_exec(bContext *C, wmOperator *UNUSED(op))
276
279
Scene *scene = CTX_data_scene(C);
280
return OPERATOR_CANCELLED;
282
282
/* apply this to all selected objects... */
283
283
CTX_DATA_BEGIN(C, Object *, ob, selected_objects)
285
285
if (ob->rigidbody_object) {
286
ED_rigidbody_ob_remove(scene, ob);
286
ED_rigidbody_object_remove(scene, ob);
292
DAG_ids_flush_update(CTX_data_main(C), 0);
294
WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
297
return OPERATOR_FINISHED;
294
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
295
WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
298
return OPERATOR_FINISHED;
301
return OPERATOR_CANCELLED;
300
305
void RIGIDBODY_OT_objects_remove(wmOperatorType *ot)
382
390
* 3) http://www.avlandesign.com/density_metal.htm
384
392
static rbMaterialDensityItem RB_MATERIAL_DENSITY_TABLE[] = {
385
{"Air", 1.0f}, /* not quite; adapted from 1.43 for oxygen for use as default */
386
{"Acrylic", 1400.0f},
387
{"Asphalt (Crushed)", 721.0f},
389
{"Beans (Cocoa)", 593.0f},
390
{"Beans (Soy)", 721.0f},
391
{"Brick (Pressed)", 2400.0f},
392
{"Brick (Common)", 2000.0f},
393
{"Brick (Soft)", 1600.0f},
396
{"Carbon (Solid)", 2146.0f},
397
{"Cardboard", 689.0f},
398
{"Cast Iron", 7150.0f},
399
//{"Cement", 1442.0f},
400
{"Chalk (Solid)", 2499.0f},
401
//{"Coffee (Fresh/Roast)", ~500},
402
{"Concrete", 2320.0f},
403
{"Charcoal", 208.0f},
407
{"Glass (Broken)", 1940.0f},
408
{"Glass (Solid)", 2190.0f},
410
{"Granite (Broken)", 1650.0f},
411
{"Granite (Solid)", 2691.0f},
413
{"Ice (Crushed)", 593.0f},
414
{"Ice (Solid)", 919.0f},
417
{"Limestone (Broken)", 1554.0f},
418
{"Limestone (Solid)", 2611.0f},
419
{"Marble (Broken)", 1570.0f},
420
{"Marble (Solid)", 2563.0f},
422
{"Peanuts (Shelled)", 641.0f},
423
{"Peanuts (Not Shelled)", 272.0f},
425
{"Plastic", 1200.0f},
426
{"Polystyrene", 1050.0f},
428
{"Silver", 10501.0f},
431
{"Stone (Crushed)", 1602.0f},
393
{N_("Air"), 1.0f}, /* not quite; adapted from 1.43 for oxygen for use as default */
394
{N_("Acrylic"), 1400.0f},
395
{N_("Asphalt (Crushed)"), 721.0f},
396
{N_("Bark"), 240.0f},
397
{N_("Beans (Cocoa)"), 593.0f},
398
{N_("Beans (Soy)"), 721.0f},
399
{N_("Brick (Pressed)"), 2400.0f},
400
{N_("Brick (Common)"), 2000.0f},
401
{N_("Brick (Soft)"), 1600.0f},
402
{N_("Brass"), 8216.0f},
403
{N_("Bronze"), 8860.0f},
404
{N_("Carbon (Solid)"), 2146.0f},
405
{N_("Cardboard"), 689.0f},
406
{N_("Cast Iron"), 7150.0f},
407
/* {N_("Cement"), 1442.0f}, */
408
{N_("Chalk (Solid)"), 2499.0f},
409
/* {N_("Coffee (Fresh/Roast)"), ~500}, */
410
{N_("Concrete"), 2320.0f},
411
{N_("Charcoal"), 208.0f},
412
{N_("Cork"), 240.0f},
413
{N_("Copper"), 8933.0f},
414
{N_("Garbage"), 481.0f},
415
{N_("Glass (Broken)"), 1940.0f},
416
{N_("Glass (Solid)"), 2190.0f},
417
{N_("Gold"), 19282.0f},
418
{N_("Granite (Broken)"), 1650.0f},
419
{N_("Granite (Solid)"), 2691.0f},
420
{N_("Gravel"), 2780.0f},
421
{N_("Ice (Crushed)"), 593.0f},
422
{N_("Ice (Solid)"), 919.0f},
423
{N_("Iron"), 7874.0f},
424
{N_("Lead"), 11342.0f},
425
{N_("Limestone (Broken)"), 1554.0f},
426
{N_("Limestone (Solid)"), 2611.0f},
427
{N_("Marble (Broken)"), 1570.0f},
428
{N_("Marble (Solid)"), 2563.0f},
429
{N_("Paper"), 1201.0f},
430
{N_("Peanuts (Shelled)"), 641.0f},
431
{N_("Peanuts (Not Shelled)"), 272.0f},
432
{N_("Plaster"), 849.0f},
433
{N_("Plastic"), 1200.0f},
434
{N_("Polystyrene"), 1050.0f},
435
{N_("Rubber"), 1522.0f},
436
{N_("Silver"), 10501.0f},
437
{N_("Steel"), 7860.0f},
438
{N_("Stone"), 2515.0f},
439
{N_("Stone (Crushed)"), 1602.0f},
440
{N_("Timber"), 610.0f}
434
442
static const int NUM_RB_MATERIAL_PRESETS = sizeof(RB_MATERIAL_DENSITY_TABLE) / sizeof(rbMaterialDensityItem);
437
445
/* dynamically generate list of items
438
446
* - Although there is a runtime cost, this has a lower maintenance cost
439
* in the long run than other two-list solutions...
447
* in the long run than other two-list solutions...
441
449
static EnumPropertyItem *rigidbody_materials_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)