softbody update
authorJens Ole Wund <bjornmose@gmx.net>
Fri, 13 Oct 2006 21:27:43 +0000 (21:27 +0000)
committerJens Ole Wund <bjornmose@gmx.net>
Fri, 13 Oct 2006 21:27:43 +0000 (21:27 +0000)
nicer kinematics in self collision -> blending to complete inelastic impact
now does something close to real physics

first steps towards aerodynamics
anisotropic friction
springs 'see' their movement in media
--> see surrrounding  media does not move and/or reacts on wind
(*for now  needs to have a pseudo collider araound  -> that is: add a cube in the same layer
and make it a deflector  *)

source/blender/blenkernel/intern/softbody.c
source/blender/makesdna/DNA_object_force.h
source/blender/src/buttons_object.c

index 7245819564ca34765ad7c3a8e22c75e7e56d5383..4c97db1d7c73ceae298aa6355858a4aa553c572f 100644 (file)
@@ -846,6 +846,14 @@ static void free_softbody_intern(SoftBody *sb)
 ** since that would only valid for 'slow' moving collision targets and dito particles
 */
 
+/* aye this belongs to arith.c */
+static void Vec3PlusStVec(float *v, float s, float *v1)
+{
+       v[0] += s*v1[0];
+       v[1] += s*v1[1];
+       v[2] += s*v1[2];
+}
+
 /* BEGIN the spring external section*/
 
 //#if (0)
@@ -996,9 +1004,12 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp
 void scan_for_ext_spring_forces(Object *ob)
 {
        SoftBody *sb = ob->soft;
+       ListBase *do_effector;
        int a;
        float damp; /* note, damp is mute here, but might be weight painted in future */
        float feedback[3];
+       do_effector= pdInitEffectors(ob,NULL);
+
        if (sb && sb->totspring){
                for(a=0; a<sb->totspring; a++) {
                        BodySpring *bs = &sb->bspring[a];
@@ -1014,15 +1025,41 @@ void scan_for_ext_spring_forces(Object *ob)
                                        bs->flag |= BSF_INTERSECT;
                                        
                                }
-                       }
                        /* ---- springs colliding */
 
                        /* +++ springs seeing wind ... n stuff depending on their orientation*/
-                       /* nothing here yet, but get the idea */
-                       /* --- springs seeing wind */
+                               if(sb->aeroedge){
+                                               float vel[3],sp[3],pr[3],force[3];
+                                               float f,windfactor  = 1.0f;   
+                /*see if we have wind*/
+                   if(do_effector) {
+                                  float speed[3],pos[3];
+                                  VecMidf(pos, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
+                   VecMidf(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec);
+                                  pdDoEffectors(do_effector, pos, force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+                                  VecMulf(speed,windfactor); /*oh_ole*/
+                                  VecAddf(vel,vel,speed);
+                               }
+                               /* media in rest */
+                               else{
+               VECADD(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec);
+                               }
+                          f = Normalise(vel);
+                          f = -0.0001f*f*f*sb->aeroedge;
+
+               VECSUB(sp, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
+                          Projf(pr,vel,sp);
+                          VECSUB(vel,vel,pr);
+                          Normalise(vel);
+                          Vec3PlusStVec(bs->ext_force,f,vel);
+                               }
 
+                       /* --- springs seeing wind */
+                       }
                }
        }
+       if(do_effector)
+               pdEndEffectors(do_effector);
 }
 /* END the spring external section*/
 
@@ -1175,13 +1212,6 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
 }
 
 
-/* aye this belongs to arith.c */
-static void Vec3PlusStVec(float *v, float s, float *v1)
-{
-       v[0] += s*v1[0];
-       v[1] += s*v1[1];
-       v[2] += s*v1[2];
-}
 
 static int sb_deflect_face(Object *ob,float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *force,float *cf)
 {
@@ -1248,7 +1278,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
                                int attached;
                                BodyPoint   *obp;
                                int c,b;
-                               float def[3];
+                               float velcenter[3],dvel[3],def[3];
                                float tune = sb->ballstiff;
                                float distance;
                                float compare;
@@ -1271,11 +1301,29 @@ static void softbody_calc_forces(Object *ob, float forcetime)
                                                        /* would need another UI parameter defining fricton on self contact */
                                                        float ccfriction = sb->balldamp;
                                                        float f = tune/(distance) + tune/(compare*compare)*distance - 2.0f*tune/compare ;
-                                                       Vec3PlusStVec(bp->force,f,def);
-                                                       if (bp->contactfrict == 0.0f) bp->contactfrict = ccfriction*compare/distance; 
+
+                                       VecMidf(velcenter, bp->vec, obp->vec);
+                                       VecSubf(dvel,velcenter,bp->vec);
+                                       VecMulf(dvel,sb->nodemass);
+
+                                       Vec3PlusStVec(bp->force,ccfriction,dvel);
+                                       Vec3PlusStVec(bp->force,f*(1.0f-ccfriction),def);
+                                                       /* exploit force(a,b) == force(b,a) part2/2 */
+                                       
+                                       VecSubf(dvel,velcenter,obp->vec);
+                                       VecMulf(dvel,sb->nodemass);
+
+                                       Vec3PlusStVec(obp->force,ccfriction,dvel);
+                                       Vec3PlusStVec(obp->force,-f*(1.0f-ccfriction),def);
+
+
+
+
+                                                       //Vec3PlusStVec(bp->force,f,def);
+                                                       //if (bp->contactfrict == 0.0f) bp->contactfrict = ccfriction*compare/distance; 
                                                        /* exploit force(a,b) == force(b,a) part2/2 */
-                                                       Vec3PlusStVec(obp->force,-f,def);
-                                                       if (obp->contactfrict == 0.0f) obp->contactfrict = ccfriction*compare/distance;
+                                                       //Vec3PlusStVec(obp->force,-f,def);
+                                                       //if (obp->contactfrict == 0.0f) obp->contactfrict = ccfriction*compare/distance;
                                                }
                                        }
                                }
index c060f88371264891ad26f40357a904df98ff0b06..567e1d7c42fb0add8a1b3f93b9696bd97122959c 100644 (file)
@@ -104,7 +104,8 @@ typedef struct SoftBody {
        float balldamp;         /* cooling down collision response  */
        float ballstiff;        /* pressure the ball is loaded with  */
        short sbc_mode;
-    short pad3, /* alias vg_ballsize, weight painting collision balls not implemented yet, but easy peasy to do */
+    short aeroedge,
+               /* alias vg_ballsize, weight painting collision balls not implemented yet, but easy peasy to do */
                pad4,pad5;     /* could be vg_balldamp,vg_ballstiff :) ahh, well vg_nodemass is missing too*/
 
 } SoftBody;
index b82e05af0372080bc36d98cbe88a8199dbae75d9..c6ee52fe2542af1f5b5388d9ae4628a7fdf48160 100644 (file)
@@ -2331,6 +2331,7 @@ static void object_softbodies(Object *ob)
                                uiDefButS(block, ROW, B_DIFF, "AvMiMa",250,150,60,20, &sb->sbc_mode, 4.0,(float)4, 0, 0, "(Min+Max)/2 * Ball Size");
                                uiDefButF(block, NUM, B_DIFF, "B Stiff:", 10,130,150,20, &sb->ballstiff, 0.001,  100.0, 10, 0, "");
                                uiDefButF(block, NUM, B_DIFF, "B Damp:", 160,130,150,20, &sb->balldamp,  0.001,  1.0, 10, 0, "");
+                               uiDefButS(block, NUM, B_DIFF, "Aero:", 160,110,150,20, &sb->aeroedge,  0.00,  30000.0, 10, 0, "");
                                uiBlockEndAlign(block);
 
                                }