Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/rigidbody.c
| Show First 20 Lines • Show All 1,615 Lines • ▼ Show 20 Lines | if (is_selected && (G.moving & G_TRANSFORM_OBJ)) { | ||||
| RB_body_set_mass(rbo->shared->physics_object, 0.0f); | RB_body_set_mass(rbo->shared->physics_object, 0.0f); | ||||
| } | } | ||||
| /* update rigid body location and rotation for kinematic bodies */ | /* update rigid body location and rotation for kinematic bodies */ | ||||
| if (rbo->flag & RBO_FLAG_KINEMATIC || (is_selected && (G.moving & G_TRANSFORM_OBJ))) { | if (rbo->flag & RBO_FLAG_KINEMATIC || (is_selected && (G.moving & G_TRANSFORM_OBJ))) { | ||||
| RB_body_activate(rbo->shared->physics_object); | RB_body_activate(rbo->shared->physics_object); | ||||
| RB_body_set_loc_rot(rbo->shared->physics_object, loc, rot); | RB_body_set_loc_rot(rbo->shared->physics_object, loc, rot); | ||||
| } | } | ||||
| /* update influence of effectors - but don't do it on an effector */ | /* NOTE: passive objects don't need to be updated since they don't move */ | ||||
| /* only dynamic bodies need effector update */ | |||||
| else if (rbo->type == RBO_TYPE_ACTIVE && | /* NOTE: no other settings need to be explicitly updated here, | ||||
| ((ob->pd == NULL) || (ob->pd->forcefield == PFIELD_NULL))) { | * since RNA setters take care of the rest :) | ||||
| */ | |||||
| } | |||||
| static void rigidbody_update_sim_ob_effectors( | |||||
| Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo) | |||||
| { | |||||
| if (rbo->type == RBO_TYPE_ACTIVE) { | |||||
| EffectorWeights *effector_weights = rbw->effector_weights; | EffectorWeights *effector_weights = rbw->effector_weights; | ||||
| EffectedPoint epoint; | EffectedPoint epoint; | ||||
| ListBase *effectors; | ListBase *effectors; | ||||
| /* get effectors present in the group specified by effector_weights */ | /* get effectors present in the group specified by effector_weights */ | ||||
| effectors = BKE_effectors_create(depsgraph, ob, NULL, effector_weights); | effectors = BKE_effectors_create(depsgraph, ob, NULL, effector_weights); | ||||
| if (effectors) { | if (effectors) { | ||||
| float eff_force[3] = {0.0f, 0.0f, 0.0f}; | float eff_force[3] = {0.0f, 0.0f, 0.0f}; | ||||
| float eff_loc[3], eff_vel[3]; | float eff_loc[3], eff_vel[3]; | ||||
| /* create dummy 'point' which represents last known position of object as result of sim */ | /* create dummy 'point' which represents last known position of object as result of sim */ | ||||
| /* XXX: this can create some inaccuracies with sim position, | /* XXX: this can create some inaccuracies with sim position, | ||||
| * but is probably better than using un-simulated values? */ | * but is probably better than using un-simulated values? */ | ||||
| RB_body_get_position(rbo->shared->physics_object, eff_loc); | RB_body_get_position(rbo->shared->physics_object, eff_loc); | ||||
| RB_body_get_linear_velocity(rbo->shared->physics_object, eff_vel); | RB_body_get_linear_velocity(rbo->shared->physics_object, eff_vel); | ||||
| pd_point_from_loc(scene, eff_loc, eff_vel, 0, &epoint); | pd_point_from_loc(scene, eff_loc, eff_vel, 0, &epoint); | ||||
| /* Calculate net force of effectors, and apply to sim object: | /* Calculate net force of effectors, and apply to sim object: | ||||
| * - we use 'central force' since apply force requires a "relative position" | * - we use 'central force' since apply force requires a "relative position" | ||||
weasel: `epoint.charge = ob->pd ? ob->pd->f_strength : 0;` works perfectly | |||||
| * which we don't have... */ | * which we don't have... */ | ||||
| BKE_effectors_apply(effectors, NULL, effector_weights, &epoint, eff_force, NULL); | BKE_effectors_apply(effectors, NULL, effector_weights, &epoint, eff_force, NULL); | ||||
| if (G.f & G_DEBUG) { | if (G.f & G_DEBUG) { | ||||
| printf("\tapplying force (%f,%f,%f) to '%s'\n", | printf("\tapplying force (%f,%f,%f) to '%s'\n", | ||||
| eff_force[0], | eff_force[0], | ||||
| eff_force[1], | eff_force[1], | ||||
| eff_force[2], | eff_force[2], | ||||
| ob->id.name + 2); | ob->id.name + 2); | ||||
| } | } | ||||
| /* activate object in case it is deactivated */ | /* activate object in case it is deactivated */ | ||||
| if (!is_zero_v3(eff_force)) { | if (!is_zero_v3(eff_force)) { | ||||
| RB_body_activate(rbo->shared->physics_object); | RB_body_activate(rbo->shared->physics_object); | ||||
| } | } | ||||
| RB_body_apply_central_force(rbo->shared->physics_object, eff_force); | RB_body_apply_central_force(rbo->shared->physics_object, eff_force); | ||||
| } | } | ||||
| else if (G.f & G_DEBUG) { | else if (G.f & G_DEBUG) { | ||||
| printf("\tno forces to apply to '%s'\n", ob->id.name + 2); | printf("\tno forces to apply to '%s'\n", ob->id.name + 2); | ||||
| } | } | ||||
| /* cleanup */ | /* cleanup */ | ||||
| BKE_effectors_free(effectors); | BKE_effectors_free(effectors); | ||||
| } | } | ||||
| /* NOTE: passive objects don't need to be updated since they don't move */ | |||||
| /* NOTE: no other settings need to be explicitly updated here, | |||||
| * since RNA setters take care of the rest :) | |||||
| */ | |||||
| } | } | ||||
| /** | /** | ||||
| * Updates and validates world, bodies and shapes. | * Updates and validates world, bodies and shapes. | ||||
| * | * | ||||
| * \param rebuild: Rebuild entire simulation | * \param rebuild: Rebuild entire simulation | ||||
| */ | */ | ||||
| static void rigidbody_update_simulation(Depsgraph *depsgraph, | static void rigidbody_update_simulation(Depsgraph *depsgraph, | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | if (ob->type == OB_MESH) { | ||||
| rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE); | rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE); | ||||
| /* update simulation object... */ | /* update simulation object... */ | ||||
| rigidbody_update_sim_ob(depsgraph, scene, rbw, ob, rbo); | rigidbody_update_sim_ob(depsgraph, scene, rbw, ob, rbo); | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | ||||
| /* update forces */ | |||||
| FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, ob) { | |||||
| if (ob->type == OB_MESH) { | |||||
| /* validate that we've got valid object set up here... */ | |||||
| RigidBodyOb *rbo = ob->rigidbody_object; | |||||
| /* TODO remove this whole block once we are sure we never get NULL rbo here anymore. */ | |||||
| /* This cannot be done in CoW evaluation context anymore... */ | |||||
| if (rbo == NULL) { | |||||
| BLI_assert(!"CoW object part of RBW object collection without RB object data, " | |||||
| "should not happen.\n"); | |||||
| } | |||||
| /* update effectors influence */ | |||||
| rigidbody_update_sim_ob_effectors(depsgraph, scene, rbw, ob, rbo); | |||||
| } | |||||
| } | |||||
| FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | |||||
| /* update constraints */ | /* update constraints */ | ||||
| if (rbw->constraints == NULL) { /* no constraints, move on */ | if (rbw->constraints == NULL) { /* no constraints, move on */ | ||||
| return; | return; | ||||
| } | } | ||||
| FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, ob) { | FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, ob) { | ||||
| /* validate that we've got valid object set up here... */ | /* validate that we've got valid object set up here... */ | ||||
| RigidBodyCon *rbc = ob->rigidbody_constraint; | RigidBodyCon *rbc = ob->rigidbody_constraint; | ||||
| ▲ Show 20 Lines • Show All 419 Lines • Show Last 20 Lines | |||||
epoint.charge = ob->pd ? ob->pd->f_strength : 0; works perfectly