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:
authorSergej Reich <sergej.reich@googlemail.com>2013-01-23 09:56:27 +0400
committerSergej Reich <sergej.reich@googlemail.com>2013-01-23 09:56:27 +0400
commitfc377c17e3d4803ef4db7a72daae629a322ffde8 (patch)
treec43f307994e27dbcc6bd84775a7a97112fd27350
parent27601aaf017263bf356dce37a4b90a764a819ee7 (diff)
rigidbody: Add force field support
Force fields work with rigid bodies just like they do with other simulations. Increase min and max strength of force fields so they can influence heavy rigid bodies. TODO: Adjust force field strength based on the time step taken. Part of GSoC 2010 and 2012. Authors: Joshua Leung (aligorith), Sergej Reich (sergof)
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c44
-rw-r--r--source/blender/blenloader/intern/readfile.c7
-rw-r--r--source/blender/blenloader/intern/writefile.c1
-rw-r--r--source/blender/makesdna/DNA_rigidbody_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c2
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c6
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)