diff options
author | Sergej Reich <sergej.reich@googlemail.com> | 2013-09-06 21:59:09 +0400 |
---|---|---|
committer | Sergej Reich <sergej.reich@googlemail.com> | 2013-09-06 21:59:09 +0400 |
commit | c6f361432987804837028ede2118d83ca6a69fdb (patch) | |
tree | 8a7ffc1991a023dcf3902eacf368457dedbd691d /source/blender/blenkernel/intern/rigidbody.c | |
parent | bf2d4f55de6719e8f75386b3fe9feceb09fc3abb (diff) |
rigidbody: Add effector weights for individual rigid bodies
There's a need for more fine grained control over how individual rigid
bodies are affected by force fields.
Having effector weights for both the world and bodies might be too much.
If so, we could drop it from the world and copy the world settings to
the body setting for old files.
Diffstat (limited to 'source/blender/blenkernel/intern/rigidbody.c')
-rw-r--r-- | source/blender/blenkernel/intern/rigidbody.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 1ac49b2b224..48dcedfe0d3 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -144,6 +144,10 @@ void BKE_rigidbody_free_object(Object *ob) rbo->physics_shape = NULL; } + /* free effector weights */ + if (rbo->effector_weights) + MEM_freeN(rbo->effector_weights); + /* free data itself */ MEM_freeN(rbo); ob->rigidbody_object = NULL; @@ -178,11 +182,15 @@ void BKE_rigidbody_free_constraint(Object *ob) RigidBodyOb *BKE_rigidbody_copy_object(Object *ob) { + RigidBodyOb *rbo = ob->rigidbody_object; RigidBodyOb *rboN = NULL; - if (ob->rigidbody_object) { + if (rbo) { /* just duplicate the whole struct first (to catch all the settings) */ - rboN = MEM_dupallocN(ob->rigidbody_object); + rboN = MEM_dupallocN(rbo); + + if (rbo->effector_weights) + rboN->effector_weights = MEM_dupallocN(rbo->effector_weights); /* tag object as needing to be verified */ rboN->flag |= RBO_FLAG_NEEDS_VALIDATE; @@ -959,6 +967,8 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) /* create new settings data, and link it up */ rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb"); + rbo->effector_weights = BKE_add_effector_weights(NULL); + /* set default settings */ rbo->type = type; @@ -1211,13 +1221,16 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o /* 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; + ListBase *effectors_local; + ListBase *effectors_global; /* get effectors present in the group specified by effector_weights */ - effectors = pdInitEffectors(scene, ob, NULL, effector_weights); - if (effectors) { + effectors_local = pdInitEffectors(scene, ob, NULL, rbo->effector_weights); + effectors_global = pdInitEffectors(scene, ob, NULL, rbw->effector_weights); + if (effectors_local && effectors_global) { + float eff_force_local[3] = {0.0f, 0.0f, 0.0f}; + float eff_force_global[3] = {0.0f, 0.0f, 0.0f}; float eff_force[3] = {0.0f, 0.0f, 0.0f}; float eff_loc[3], eff_vel[3]; @@ -1231,7 +1244,10 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o /* 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, eff_force, NULL); + pdDoEffectors(effectors_local, NULL, rbo->effector_weights, &epoint, eff_force_local, NULL); + pdDoEffectors(effectors_global, NULL, rbw->effector_weights, &epoint, eff_force_global, NULL); + add_v3_v3v3(eff_force, eff_force_global, eff_force_local); + mul_v3_fl(eff_force, 0.5f); /* activate object in case it is deactivated */ if (!is_zero_v3(eff_force)) RB_body_activate(rbo->physics_object); @@ -1239,7 +1255,8 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o } /* cleanup */ - pdEndEffectors(&effectors); + pdEndEffectors(&effectors_global); + pdEndEffectors(&effectors_local); } /* NOTE: passive objects don't need to be updated since they don't move */ |