利用者:Aligorith/GSoC2010 Bullet Design Overview
Overview
We assume that multiple simulations can take place in a scene. So,
- Each scene has a list of Bullet simulation “worlds” that take place in it.
- Each of these simulation worlds stores:
- A reference to the Bullet physics world for that sim. This is not stored to file, but will need to be created after reading the file.
- Also, we store settings such as timesteps/substeps (i.e. global quality control) per sim.
- Other general settings, such as ‘gravity’ vector, might be best taken directly from Blender Scene instead of customising per sim. While we lose ability to have really funky effects, having different settings needing syncing is probably too confusing.
- Then again, this could be a default to Scene but still allow local overrides situation. For now, we’ll stick with the simpler version proposed, and can probably easily extend the system later when needed.
- A reference to the Blender group…
- Each Blender group determines the set of objects that participate in a particular simulation
- The key benefit of this is that it’s easier to identify the set of objects that participate per sim (both on user and also on eval side)
- It might be possible to store the Bullet world on groups, or have the object list stored in the Bullet world directly. However, doing either way looses some advantages – groups are not directly linked to scenes, so no way to tell which groups to eval when evaluating a particular scene; and storing the object list directly would mean that we can’t reuse existing Outliner + selection tools to quickly get hold of all relevant objects…
- Bullet settings are stored on each Object participating in a sim. These would be shown under the ‘Physics’ context, to keep in line with the rest of the physics sims?
- These settings include the role that the object plays in the sim. This is partially determined automatically (whether the object has animation data or not decides between ‘static’ and ‘kinetic’ in Bullet terms). Additional settings determine whether loc/rot/locrot are controlled by Bullet or by Animato, and the strength of this control. Both of these settings are driveable+animateable like any other setting.
- Objects acting as duplicators (using dupliverts, etc.) will be like “cloners” elsewhere…
- Collision data for an object is also included here, including collision shape and parameters regarding collision response?
- Perhaps we could reuse the existing Collisions panel, though perhaps it’d be nice to have our own since that one is getting a bit cluttered (particles on one side, cloth/softbodies on the other… rigidbodies doesn’t really fit on either side)
- Some objects included in the group may just be effectors (i.e. wind). Probably these cannot be controlled by Bullet for lack of any suitable geometry (though collision shapes would alleviate this), but would either be static or animated but not dynamic.
- These settings include the role that the object plays in the sim. This is partially determined automatically (whether the object has animation data or not decides between ‘static’ and ‘kinetic’ in Bullet terms). Additional settings determine whether loc/rot/locrot are controlled by Bullet or by Animato, and the strength of this control. Both of these settings are driveable+animateable like any other setting.
- Triggering an object’s involvement in a sim (i.e. when does it start, what special actions need to be taken then) is a complicated biz…
- For initial phase of SoC, will just implement simple start sim immediately/on-collision type system as seen elsewhere
- Later when there’s time (possibly after SoC), a more complicated system that can have scripted control while still maintaining basic setup simplicity could be added. This would allow for much more complex setups, such as introducing variability into the response by altering settings of the objects?
- Constraints between Objects in sim (Bullet constraints) could be part of standard Constraints UI. There is already the ‘Rigid Body Joint’ constraint implemented like this, though further integration would need more careful thought.
- Depending on how we evaluate Bullet sims relative normal constraints, we probably need to enforce that these constraints are at the ends of the stacks, so that we can see that they are executed later, instead of as part of normal constraint eval.
- Alternatively, could have as separate constraint stacks to communicate this separation clearly.
- Caches for improved performance are perhaps best stored attached to each sim. That way, some sims can be cached, and others can be left as is. Also, this allow possibility of relying on PointCache formats instead, and also facilitates easier management of sims.
Major limitations/problems of this approach
- Storing the sim settings on the Objects directly is problematic if we have an Object involved in more than one sim.
- This is probably a non-issue if the only objects that will be used in such a way would only be acting as triggers/colliders affecting the dynamics of simulated objects across sims. For example, “rocky terrain mesh” belongs to multiple groups since many sets of sims need to use it as collider…
- Dynamically simulated objects pose more of an issue, since their behaviour could vary in quite a few ways depending on which action we use.
- 1) Only simulate for the first sim where it appears, and then for the later ones, treat it as kinetic. This is quite a reliable way that means that we won’t have any weird results from conflicting Bullet sims that aren’t aware of each other.
- One downside is that we will therefore need to tag whether object has been affect by a sim for current update yet.
- Secondly, it will not be easy to predict if an Object’s stated role will be carried out or not for any given sim. You’d need to check the ordering and which sims the object belonged to in order to get a full picture of the interactions…
- 2) Simulate the object each time, feeding its current state to the Bullet, and letting it make a decision on this. This way ensures that result is correct for each stage, but not more than that.
- 3) Prevent dynamic objects from being part of more than one group used for Bullet sims. This would have to be done on UI level to disable/flag any objects that don’t obey, and warn user that the object won’t be evaluated dynamically, but will just be treated as static/kinetic.
- Perhaps this is the simplest option we have if we want to prevent dealing with any tricky cases in the bugtracker/forums in years to come
- This is limiting, especially when you want object in sim 1 to be dynamically controlled, but then to affect object in sim 2 as result of its movements. We could argue that these should be in the same sim anyway, but perhaps there are benefits to either way?
- 1) Only simulate for the first sim where it appears, and then for the later ones, treat it as kinetic. This is quite a reliable way that means that we won’t have any weird results from conflicting Bullet sims that aren’t aware of each other.
Evaluation
Probably Bullet will need to be evaluated AFTER all Objects are evaluated due to the way this is setup. This is because Bullet eval needs to get transforms of objects involved, and also we need to make sure that all Bullet settings on these have been animated+driven accordingly already. We could try to make the Depsgraph find an ideal order for this, BUT how do we insert a call to Bullet sim in scene_update_tagged() and friends in the right place in the loops over the objects?! Therefore, we do a “Bullet pass” after evaluating all Objects + their drivers.
So, eval pipeline/loop looks a bit like:
- 1) Eval all animation for all datablocks (on frame change only)
- 2) For each scene (do current scene only if not changing frames)
- a. Update each object (if tagged by desgraph)
- i. Eval drivers + constraints
- ii. Calc modifiers/data/etc.
- b. Recalc each Bullet sim for the scene* (frame change only???). For each sim:
- i. Pass in all relevant object transforms (current states)
- ii. Make sure scene settings are up to date
- iii.Perform simulation
- iv. Read off transforms
- a. Update each object (if tagged by desgraph)
(* - only new part in this pipeline)
There are two problems with this approach:
- 1) Interacting with other sims will be difficult. They will not know what Bullet will do at all…
- 2) Not taking advantage of the Depsgraph may disadvantage us somewhat in the long run, especially in terms of speed-hits, and/or sims not updating properly in response to changes
User-Side Notes
To setup a Bullet sim:
- 1) Create objects normally
- a. Model/rig/duplivert/parent
- 2) Select them
- 3) Run operator(s) to setup Bullet sim from these settings
- a. Group is created, and all objects are added to group
- b. Bullet sim is created
- 4) Tweak settings…
- a. for Objects in the sim – role/mass/friction/collision-shape
- b. for sim – timestep/gravity?
- 5) Optionally, set up specific triggering conditions… (advanced users only)
- 6) Preview results and/or tweak again…
Operators for 3) could include:
- Add objects to sim as passive participants (animato control)
- Add objects to sim as active participants (bullet control)
- Add Bullet constraints between sims
Visual manipulation/tools could include:
- Handles for setting initial velocity, orientation, and direction
- Visualisation and tweaking of constraint settings, and/or setup these constraints
Alternatively (or in addition), another workflow could be:
- 1) Shift-A (Add Menu) -> Bullet Setup -> {…Preset commonly used setup…}
- 2) Tweak settings added to scene from template builtin
- 3) Preview and tweak