bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports) { RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); if (ob->type != OB_MESH) { BKE_report(reports, RPT_ERROR, "Can't add Rigid Body to non mesh object"); return false; } /* Add rigid body world and group if they don't exist for convenience */ if (rbw == NULL) { rbw = BKE_rigidbody_create_world(scene); if (rbw == NULL) { BKE_report(reports, RPT_ERROR, "Can't create Rigid Body world"); return false; } BKE_rigidbody_validate_sim_world(scene, rbw, false); scene->rigidbody_world = rbw; } if (rbw->group == NULL) { rbw->group = BKE_group_add(bmain, "RigidBodyWorld"); } /* make rigidbody object settings */ if (ob->rigidbody_object == NULL) { ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, type); } ob->rigidbody_object->type = type; ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE; /* add object to rigid body group */ BKE_group_object_add(rbw->group, ob, scene, NULL); DAG_relations_tag_update(bmain); DAG_id_tag_update(&ob->id, OB_RECALC_OB); return true; }
/* Updates and validates world, bodies and shapes. * < rebuild: rebuild entire simulation */ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool rebuild) { GroupObject *go; /* update world */ if (rebuild) BKE_rigidbody_validate_sim_world(scene, rbw, true); rigidbody_update_sim_world(scene, rbw); /* update objects */ for (go = rbw->group->gobject.first; go; go = go->next) { Object *ob = go->ob; if (ob && ob->type == OB_MESH) { /* validate that we've got valid object set up here... */ RigidBodyOb *rbo = ob->rigidbody_object; /* update transformation matrix of the object so we don't get a frame of lag for simple animations */ BKE_object_where_is_calc(scene, ob); if (rbo == NULL) { /* Since this object is included in the sim group but doesn't have * rigid body settings (perhaps it was added manually), add! * - assume object to be active? That is the default for newly added settings... */ ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, RBO_TYPE_ACTIVE); rigidbody_validate_sim_object(rbw, ob, true); rbo = ob->rigidbody_object; } else { /* perform simulation data updates as tagged */ /* refresh object... */ if (rebuild) { /* World has been rebuilt so rebuild object */ rigidbody_validate_sim_object(rbw, ob, true); } else if (rbo->flag & RBO_FLAG_NEEDS_VALIDATE) { rigidbody_validate_sim_object(rbw, ob, false); } /* refresh shape... */ if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) { /* mesh/shape data changed, so force shape refresh */ rigidbody_validate_sim_shape(ob, true); /* now tell RB sim about it */ // XXX: we assume that this can only get applied for active/passive shapes that will be included as rigidbodies RB_body_set_collision_shape(rbo->physics_object, rbo->physics_shape); } rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE); } /* update simulation object... */ rigidbody_update_sim_ob(scene, rbw, ob, rbo); } } /* update constraints */ if (rbw->constraints == NULL) /* no constraints, move on */ return; for (go = rbw->constraints->gobject.first; go; go = go->next) { Object *ob = go->ob; if (ob) { /* validate that we've got valid object set up here... */ RigidBodyCon *rbc = ob->rigidbody_constraint; /* update transformation matrix of the object so we don't get a frame of lag for simple animations */ BKE_object_where_is_calc(scene, ob); if (rbc == NULL) { /* Since this object is included in the group but doesn't have * constraint settings (perhaps it was added manually), add! */ ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED); rigidbody_validate_sim_constraint(rbw, ob, true); rbc = ob->rigidbody_constraint; } else { /* perform simulation data updates as tagged */ if (rebuild) { /* World has been rebuilt so rebuild constraint */ rigidbody_validate_sim_constraint(rbw, ob, true); } else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) { rigidbody_validate_sim_constraint(rbw, ob, false); } rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE; } } } }