bool ED_rigidbody_constraint_add(Scene *scene, Object *ob, int type, ReportList *reports) { RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); /* check that object doesn't already have a constraint */ if (ob->rigidbody_constraint) { BKE_reportf(reports, RPT_INFO, "Object '%s' already has a Rigid Body Constraint", ob->id.name + 2); return false; } /* create constraint group if it doesn't already exits */ if (rbw->constraints == NULL) { rbw->constraints = BKE_group_add(G.main, "RigidBodyConstraints"); } /* make rigidbody constraint settings */ ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, type); ob->rigidbody_constraint->flag |= RBC_FLAG_NEEDS_VALIDATE; /* add constraint to rigid body constraint group */ BKE_group_object_add(rbw->constraints, ob, scene, NULL); 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; } } } }