提供: wiki
移動先: 案内検索
This page need a major cleanup of the mentioned code examples and equations. They have not survived the conversion from the previous wiki at all :-/ --Hoehrer

Softbody Integration


Each Object in Blender can get a "Soft Body" effect applied (Mesh implemented only now. No! Lattices and curves can be soft to (bjornmose) ). Once applied, the softbody system converts vertex locations to free moving particles. Depending on Object type, also springs can be added to keep the particles together on fixed distances.

There are two main methods to control the soft body effect.

The "Goal" defines how much motion from an animation system (Ipos, Parents, Armatures, Lattices, etc) gets applied. For each vertex you can define this by using a weight value, where "0" means complete free dynamical motion, and "1" means completely attached to the animated position. How vertices try to reach their goal is based on physics laws, e.g. using spring forces and damping. The individual "goal" value can be set using a Vertex Group.

The "Edge springs" define how much the particles try to restore the original shape. For example, by adding diagonal edges within a cube you can make that cube less "yello".

= Softbody in 2.6x = [BM] Setting it up

  • On the physics TAB enable the soft body option
  • Default is stay in 'goal' mode. That is stick to the original position with the global spring settings.
  • So .. if you want to get it free falling .. disable 'Soft Body Goal'
  • Well but most experienced users will like the default; it just adds that little jiggle he/she needs to make things look more vivid .. and that is what soft bodies are for! It needs a complete physics engine and it needs some kind of collision to interact believable .. but after all it is the art of faking.
  • so remember: most of the module is able to do is a 'can' but not a 'must'
  • What is 'Estimate Matrix' hum and yes there was progress in 2010 .. wow why code when nobody really needs it. The function could be used in any situation someone needs the global or local movement of a cloud of points ...

Softbody in older versions

Setting it up

  • Set the Softbody options in Object buttons (F7) Softbody Panel.
  • Create, in Editmode, a Vertex Group using Edit buttons (F9) and name it "SOFTGOAL". ( exact name not relly needed any more, since you can choose 'goal' group on UI [BM] ) Assign all vertices an initial value. Leave Editmode, and Enter Weight Paint mode to define which vertices should freely move (blue) and which should stick to the animation (red)
  • Step through frame with and arrows, or press AltA to see the effect.

Refresh rules

Softbody calculations are only done on forward time steps of fewer than 10 frames. In all other situations the simulation system is refreshed, setting all forces and motion to zero.


  • Baking option, to store a permanent copy of the simulation. The 'baked' result should have a possibility to edit it (cutting off begin/end) or being layered (in NLA)
  • Support for Lattice, Curve, Surface, etc
  • Review of usage of vertex groups. Maybe an additional automatic method can be found (using texture coordinates) or an option to set a default weight value


General options

  • Enable Soft Body Makes object using point masses and springs for soft body effect.
  • Friction General "media" friction, for damping of overall motion over vertices.
  • Mass Mass value for vertices. Larger mass makes slower motion.
  • Grav Use gravity effect, a force pointing at negative Z direction.
  • RKL The Runge-Kutta limit, actual defines the step size during simulation. Small values give higher accuracy, but takes more calculation time.
  • PostDef Make the soft body effect working after deformation, like caused by Lattices or Armatures.

Goal options

  • Use Goal Softbodies use as input the motion from animation (Ipo, Deform, Parents, etc). The "Goal" is the desired end-position for vertices based on this animation. How a softbody tries to achieve this goal can be defined using spring forces and damping.
  • GSpring The spring constant for Goal. A low value means very weak springs, a high value is a strong spring.
  • GFrict The friction coefficient for Goal. High values give damping of the spring effect.
  • GMin GMax When you paint the values in vertex-groups (Using WeightPaint mode), you can use the GMin and Gmax to fine-tune the weight values. The lowest vertex-weight (blue) will become GMin, the highest value becomes GMax.

Edge options

  • Use Edges The edges in a Mesh Object (if there are, check Editing->Mesh Panel) can become springs as well.
  • Stiff Quads For quad faces, the diagonals are added as Springs as well.
  • ESpring The spring constant for edges. A low value means very weak springs, a high value is a strong spring.
  • EFrict The friction coefficient for edge springs. High values give damping of the spring effect.

New stuff 27/4/2005 needs docu

  • time control
  • force fields
  • wind
  • collison detection

hints on using softbodies

  • Tune RKL as high as possible for speed but as low as needed to keep dynamics stable. In fact this is the error allowed for one integration step and if this is exceeded the system will try (more) smaller steps to hold the limit. So this is why this is called adaptive step size.
  • Use 'Postdef' option if SB-object is rigged .. says parented to armature or uses hooks

Softbodies WIP



How Softbodies really work:

First let's state: All of the physics enginge developed for softbodies assumes a valid softbody and nothing more. So if the object originally is a mesh, lattice or what ever does not really matter. All that needs to be coded to have softbody functionality for a specific object class is 'specific object to softbody object'-function and back.

typedef struct BodyPoint {
    float origS[3], origE[3], origT[3], pos[3], vec[3], force[3];
    float weight, goal;
} BodyPoint;
  • origS: Position of the vertex in original mesh at frame n-1
  • origE: Position of the vertex in original mesh at frame n
  • origT: Position of the vertex in original linear interpolated ( needed for timesteps smaller than 1 frame)
  • pos: Position of the 'soft' vertex
  • vec: Actual velocity of the 'soft' vertex
  • force: Force accumulator for the 'soft' vertex
  • goal: painted factor to control the goal effect

when a softbody object is created, the goals are clipped by the softbody parameters goal_min <= goal <= goal_max i found them usesfull to try the effect of goal settings without going through the painting process for all vertices.

evolution in time:


dt = small time step
a(t) = force(t)/mass;
vec(t+dt) = vec(t) + a(t) * dt
pos(t+dt) = pos(t) + vec(t) * dt

Heun,Runge-Kutta,Heon,Midpoint method ( wow 4 names for 1 one thing! ): does basicly the same as euler does but uses a clever trial and error system to find optimal 'dt's: concept make dt as big as possible while keeping physics stable.


when a BodyPoint has goal == 1.0
pos = origT
vec = origE-origS

All the following forces are added per BodyPoint in the


goals, elastic force and friction force model something like a cars shock absorber with zero length mounted between pos and origT

goals elastic force:

Elastic force pulling pos to origT

ks = 1.0/(1.0- goal * goal_spring_constant)-1.0 , 0 < goal_spring_constant < 0.999

so when goal_spring_constant goes close to 1.0 we have very strong forces holding the softbody position very close to origT.

force = ks * (origT - pos);

goals friction:

This is damping the motion of pos relative to it's also moving origT goal velocity is estimated by

velgoal= bp->origS - bp->origE
force=goal_friction_constant * (velgoal -vec)

springs elastic force and friction force model something like a cars shock absorber with non zero length mounted between pos and whatever the other end of the spring is attached to.

springs elastic force:

d  : vector paralell to the spring (edge) with lenght one 
rl : rest length of the spring ( zero force lenght )
al : actual lenght of the spring
iks  = 1.0/(1.0-inner_spring_constant)-1.0f , 0 < inner_spring_constant < 0.999
force = iks * (rl-al) * d

springs friction:

d   : vector paralell to the velocity difference of both spring ends, with lenght one 
sd  : vector paralell to the spring (edge) with lenght one 
ad  : scalar velocity difference of both spring ends
p = inner_product(d,sd) , projection of velocity difference in spring direction
force=inner_friction_constant * p * ad * d

'Global' forces


force[y] = gravitation_factor * mass

media friction: is fricton against the global embedding media (air,water,oil)

force = -media_friction_constant * vec


For better reading the factors rescale_grav_to_framerate, rescale_friction_to_framerate were omitted.

API is a simple as this:


object_to_softbody(Object *ob, float ctime)

to create an instance of the softbody object.

Move in 1 frame steps forth and back in time by calling

object_softbody_step(Object *ob, float ctime)

original design drawings

things to write down nice

Concepts involved so far .. and it should be possible to blend them by tuning object props.

  1. goal - is kind of hooking the object to it's moving cage by more or less strong springs
  2. springs - using edges to model inner forces
  3. gravitation - as a generic prototype for other outer forces
  4. damping/friction in goal, springs and media

Unresolved so far ..

  1. self intersection, collision, other constraints (eg floor)

Further suggetions data structure for springs / force interaction

  1. vertex to vertex edges in most cases, but would be more flexible if they had no effect on catmull-clark etc. see stiff quads in here. think of diagonals in a cube avoiding volume to collapse and yes .. why not have springs to vertices in other objects/meshes animators will want to link soft objects, with the interface vertices moving
  2. vertex to object may be with nolinear spring behavior --> force fields
  3. object to object for building a multiple objects softbody

well let's collect some physical facts to get a feeling of what we are doing here

g  := gravitation_constant [m/sec^2]
el := distance(rotation point,center of mass) [m]
T  := period of motion [sec]
k  := spring constant [(kg * m /(sec^2))/m == kg/(sec^2)]
e  := damping constant e[kg/sec]
since we do -> d/dt(v)[m/(sec^2)] = -(e[kg/sec]/mass[kg])*v[m/sec]
called stokes friction --> applies to friction in liquids

Note: we could do d/dt(v)[m/(sec^2)] = -(e[kg/sec]/mass[kg])*v[m/sec]*|v[m/sec]| called newton friction -> applies to friction in gas then e[kg/m] a undamped one-dimensional mass spring system has T = 2*PI*SQRT(Mass/k);

Note: mass undamped mass spring period has NO lenght involved! a undamped single mass point pendulum has T = 2*PI*SQRT(lenght/el) a "distributed mass" pendudulum has T = 2*PI*SQRT( torque_of_inertia/(mass * el * g)) so we see: as soon as we start involving gravity we are loosing scale (== absolute vertex to vertex lenght ) invariance !


put your C&C here I think we should stick to Ton's converters philosophy My_Anything* Out=function(Anything* In) (if i can do return Anything.valid=true else Anything.valid=false ) unless you can convert Ton to OOP :-)

Integration in Blender, review

I'm still hesitating to make a choice for how to proceed with integrating it... with Blender's animation system in mind we can basically make three choices;

  1. Integrated in Object types (Mesh, Curve, etc) The simplest method is adding the necessary data for softbody (like 'spring' and 'goal' constants) to re-use existing structures in Mesh (like vertex groups). That way it can quickly work, including tools for vertex painting etc.
    Disadvantage; add softbody to Curve, Lattice etc. then is very cumbersome. It mixes up functionality, making maintenance & future development harder.
  2. Generic Object level Softbody data. Each Object can get the full data required for softbody, including all vertex information (with indices mapped to actual vertices for 3d coords) and springs. Routines (special editing mode?) are needed to convert Mesh->Softbody, edit springs and 'body points', and new tools have to be written for painting tools.
    This is how Maya does it, including the 'error' that arises when editing the Mesh itself; deleting vertices then screws up the indices in the Softbody structure. We can do better, of course. :)
    Disadvantage: This method is a bit 'un-blenderish', especially because the object itself is extended with a lot of data and editing methods... probably causing clumsy (modal) UI methods as well.
  3. New Object type We can also provide a new type of Object, which then offers a 'soft body construction kit' in editing mode, allowing its own editmode for physically behaving bodypoints to be added, springs, painting weights, etc. Main issue to solve then is establishing relationship(s) with another Object (or Objects). However, this can be done based on a deforming (parent) relationship (like a Lattice), or on a "map indices" method - where the vertex coordinates of a softbody are copied from/to another Object based on index numbers, like in the previous type. Plus it can support Hooks, vertex parents, etc.

Disadvantage: Making a Mesh Object to become "Softbody" then is a bit clumsy... but could be done with an option that automatically converts the Mesh data to a new Object, and inserting it as a Parent...

Writing down the three choices makes me tend to the third option, which basically is the mythical Emo Object, as being hyped a while during conferences. :) Best positive side of the third choice is that it becomes very 'Blenderish', fitting in the current architecture (and UI) nicely.

Integration in Blender, proposal

Let's go for option 2) now! I think it can be done without issues preventing it from going to a real Emo object. It would also mean to keep method 2) the simplest and fastest working softbody method. A couple of notes for how it would work;

  • Object will get a SoftBody struct, saved in file, with settings
  • For first release, only Object type Mesh will be supported.
  • Goal weights will be read from a fixed VertexGroup. VertexGroups are candidate for later restructure, should become generic object option
  • Per edge spring settings will not be supported for now, with as possible exception an edge with type flag "do not include for Subsurf", this to allow internal edges for stability
  • SoftBody effect will be in the end of the current 'Modifier" loop, so it works on top of all animation systems

In the F7 Object Buttons, a new Panel SoftBody will give options like:

  • Softbody, on/off
    • specific global softbody options, for general friction, math tweaks, etc
  • Goal, on/off
    • Specific goal options, for damping etc
  • Edge Springs, on/off
    • Specific edge spring options, for damping etc

To keep the Softbody a bit in control, we can adopt these conventions in the (3D window) UI:

  • On frame advance, lesser than 10 steps, softbody simulates time steps.
  • On frame advance, larger than 10 steps, softbody doesn't refresh.
  • On frame steps back, Softbody resets completely.
  • On exit editmode, reset completely.
  • While transform Softbody in object mode, do simulation steps, but reset at end or ESC.
  • And of course a button in the Panel causing a reset.

The immediate todo for after first release of Softbody:

  • An option to "bake", e.g. make the animation become not simulated and independent time steps
  • Option to define order of operations, in the current 'modifier' system (like wave effect, hook, etc.)

bjornmose / on collision detection, review /2005.05.31

Eagerly reading Baraff [BA] papers on cloth simulation, I focussed on doing best for that in current collision detection for SB.

Best: 1. As stated in the papers [BA] it is no good idea to detect the tansition of a particle through a surface to have a stable cloth simulation. The basic reason is : if a particle got inside, may be by initial conditions or by any other 'accident' it will be stuck there. So this (detect the tansition of a particle through a surface) is what the 'original' particle collision code does and is acceptable because one escaping particle won't spoil the over all illusion. OTH cloth particles trapped on the wrong side of the colliding face look very nasty.

2. The basic idea in Baraff [BA] papers to apply a force on particles to drive them to the outside and optionally drive it at a certain distance to it. So, what the hell is 'outside'. Simple: where the face nomal points to. But consider 2 paralell planes facing in opposite diretions: The particle is always 'inside' one plane. So we have to limit the inside condition of the first plane not to extend 'too much' into the forces generated by the second plane, otherways the particle gets pushed out by plane[1] then gets pushed out by plane[2] until it ends up in void space.

3. Current implementation decides: a: if particle is inside the prism defined by a potential collision tri face ( quads are always broken to tris ) and it's normal, distance to tri face is calculated; else this tri does not generate any forces (exit).

b: if (a:) if (particle is inside and distance to face is smaller than inner thickness) calculate exponetial repulsive force; else if (further inside) apply no force (exit); if (distance to face is smaller than outer thickness) calculate weaker force which is zero at outer thickness.

name / email / what about / date