Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/rigidbody.c')
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index e6f6c9a9a98..90200fd6742 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -97,6 +97,10 @@ void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
if (rbw->objects)
free(rbw->objects);
+ /* free effector weights */
+ if (rbw->effector_weights)
+ MEM_freeN(rbw->effector_weights);
+
/* free rigidbody world itself */
MEM_freeN(rbw);
}
@@ -459,6 +463,8 @@ RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
rbw = MEM_callocN(sizeof(RigidBodyWorld), "RigidBodyWorld");
/* set default settings */
+ rbw->effector_weights = BKE_add_effector_weights(NULL);
+
rbw->ltime = PSFRA;
rbw->time_scale = 1.0f;
@@ -596,6 +602,7 @@ static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
/* adjust gravity to take effector weights into account */
if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
copy_v3_v3(adj_gravity, scene->physics_settings.gravity);
+ mul_v3_fl(adj_gravity, rbw->effector_weights->global_gravity * rbw->effector_weights->weight[0]);
}
else {
zero_v3(adj_gravity);
@@ -631,6 +638,43 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o
RB_body_activate(rbo->physics_object);
RB_body_set_loc_rot(rbo->physics_object, loc, rot);
}
+ /* update influence of effectors - but don't do it on an effector */
+ /* only dynamic bodies need effector update */
+ else if (rbo->type == RBO_TYPE_ACTIVE && ((ob->pd == NULL) || (ob->pd->forcefield == PFIELD_NULL))) {
+ EffectorWeights *effector_weights = rbw->effector_weights;
+ EffectedPoint epoint;
+ ListBase *effectors;
+
+ /* get effectors present in the group specified by effector_weights */
+ effectors = pdInitEffectors(scene, ob, NULL, effector_weights);
+ if (effectors) {
+ float force[3] = {0.0f, 0.0f, 0.0f};
+ float loc[3], vel[3];
+
+ /* create dummy 'point' which represents last known position of object as result of sim */
+ // XXX: this can create some inaccuracies with sim position, but is probably better than using unsimulated vals?
+ RB_body_get_position(rbo->physics_object, loc);
+ RB_body_get_linear_velocity(rbo->physics_object, vel);
+
+ pd_point_from_loc(scene, loc, vel, 0, &epoint);
+
+ /* calculate net force of effectors, and apply to sim object
+ * - we use 'central force' since apply force requires a "relative position" which we don't have...
+ */
+ pdDoEffectors(effectors, NULL, effector_weights, &epoint, force, NULL);
+ if (G.f & G_DEBUG)
+ printf("\tapplying force (%f,%f,%f) to '%s'\n", force[0], force[1], force[2], ob->id.name + 2);
+ /* activate object in case it is deactivated */
+ if (!is_zero_v3(force))
+ RB_body_activate(rbo->physics_object);
+ RB_body_apply_central_force(rbo->physics_object, force);
+ }
+ else if (G.f & G_DEBUG)
+ printf("\tno forces to apply to '%s'\n", ob->id.name + 2);
+
+ /* cleanup */
+ pdEndEffectors(&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,