Revision: 54021
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54021
Author:   sergof
Date:     2013-01-23 05:56:27 +0000 (Wed, 23 Jan 2013)
Log Message:
-----------
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)

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/rigidbody.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/makesdna/DNA_rigidbody_types.h
    trunk/blender/source/blender/makesrna/intern/rna_object_force.c
    trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c

Modified: trunk/blender/source/blender/blenkernel/intern/rigidbody.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/rigidbody.c  2013-01-23 
05:56:22 UTC (rev 54020)
+++ trunk/blender/source/blender/blenkernel/intern/rigidbody.c  2013-01-23 
05:56:27 UTC (rev 54021)
@@ -97,6 +97,10 @@
        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 @@
        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 @@
        /* 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 @@
                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,

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c   2013-01-23 
05:56:22 UTC (rev 54020)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c   2013-01-23 
05:56:27 UTC (rev 54021)
@@ -5021,6 +5021,8 @@
                                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 @@
                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);
        }
 }
 

Modified: trunk/blender/source/blender/blenloader/intern/writefile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/writefile.c  2013-01-23 
05:56:22 UTC (rev 54020)
+++ trunk/blender/source/blender/blenloader/intern/writefile.c  2013-01-23 
05:56:27 UTC (rev 54021)
@@ -2306,6 +2306,7 @@
                /* 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;

Modified: trunk/blender/source/blender/makesdna/DNA_rigidbody_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_rigidbody_types.h 2013-01-23 
05:56:22 UTC (rev 54020)
+++ trunk/blender/source/blender/makesdna/DNA_rigidbody_types.h 2013-01-23 
05:56:27 UTC (rev 54021)
@@ -37,6 +37,8 @@
 
 struct Group;
 
+struct EffectorWeights;
+
 /* ******************************** */
 /* RigidBody World */
 
@@ -46,6 +48,8 @@
  */
 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 */
        

Modified: trunk/blender/source/blender/makesrna/intern/rna_object_force.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_object_force.c     
2013-01-23 05:56:22 UTC (rev 54020)
+++ trunk/blender/source/blender/makesrna/intern/rna_object_force.c     
2013-01-23 05:56:27 UTC (rev 54021)
@@ -1182,7 +1182,7 @@
        
        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");
 

Modified: trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c        
2013-01-23 05:56:22 UTC (rev 54020)
+++ trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c        
2013-01-23 05:56:27 UTC (rev 54021)
@@ -345,6 +345,12 @@
        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)

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to