diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/rigidbody.c | 44 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 7 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_rigidbody_types.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object_force.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_rigidbody.c | 6 |
6 files changed, 63 insertions, 1 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, diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 95fa4018392..b0f1d3f37ed 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5021,6 +5021,8 @@ static void lib_link_scene(FileData *fd, Main *main) RigidBodyWorld *rbw = sce->rigidbody_world; if (rbw->group) rbw->group = newlibadr(fd, sce->id.lib, rbw->group); + if (rbw->effector_weights) + rbw->effector_weights->group = newlibadr(fd, sce->id.lib, rbw->effector_weights->group); } if (sce->nodetree) { @@ -5296,6 +5298,11 @@ static void direct_link_scene(FileData *fd, Scene *sce) rbw->physics_world = NULL; rbw->objects = NULL; rbw->numbodies = 0; + + /* set effector weights */ + rbw->effector_weights = newdataadr(fd, rbw->effector_weights); + if (!rbw->effector_weights) + rbw->effector_weights = BKE_add_effector_weights(NULL); } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index a52e4e28981..da50a05a3d9 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2306,6 +2306,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase) /* writing RigidBodyWorld data to the blend file */ if (sce->rigidbody_world) { writestruct(wd, DATA, "RigidBodyWorld", 1, sce->rigidbody_world); + writestruct(wd, DATA, "EffectorWeights", 1, sce->rigidbody_world->effector_weights); } sce= sce->id.next; diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h index 8c66a5b2333..43c2cdb227a 100644 --- a/source/blender/makesdna/DNA_rigidbody_types.h +++ b/source/blender/makesdna/DNA_rigidbody_types.h @@ -37,6 +37,8 @@ struct Group; +struct EffectorWeights; + /* ******************************** */ /* RigidBody World */ @@ -46,6 +48,8 @@ struct Group; */ typedef struct RigidBodyWorld { /* Sim World Settings ------------------------------------------------------------- */ + struct EffectorWeights *effector_weights; /* effectors info */ + struct Group *group; /* Group containing objects to use for Rigid Bodies */ struct Object **objects; /* Array to access group objects by index, only used at runtime */ diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 0c2944b3966..873ea49824c 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -1182,7 +1182,7 @@ static void rna_def_field(BlenderRNA *brna) prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "f_strength"); - RNA_def_property_range(prop, -1000.0f, 1000.0f); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_text(prop, "Strength", "Strength of force field"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index c7d6324b881..cd8b63cd0de 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -345,6 +345,12 @@ static void rna_def_rigidbody_world(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyWorld_split_impulse_set"); RNA_def_property_ui_text(prop, "Split Impulse", "Reduces extra velocity that can build up when objects collide (lowers simulation stabilty a litte so use only when necessary)"); RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset"); + + /* effector weights */ + prop = RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "EffectorWeights"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Effector Weights", ""); } static void rna_def_rigidbody_object(BlenderRNA *brna) |