Dynamic deformation of mesh
I have a rather ambitious project I want to create. I use Lightwave and it has this Bullet engine that is used for collisions. It's very powerful. So I want to import my scene into Lightwave and apply some collision FX to a figure's hair and clothing for example. This part is fine. I now want to create a plugin in DAZ (not sure how to do this yet) that will connect to my own plugin in Lightwave (I know how to connect to and create a Lightwave plugin) and request the morph for the current frame and apply it. This would let me use the physics engine in Lightwave inside of DAZ Studio for the objects I tell it to.
I guess a simple version of this would be similar to the smoothing in DAZ Studio. It's not a morph, but it deforms the mesh. So two questions:
1. How do I get the current frame number? is it scene->getTime() / scene->getTimeStep() ?
2. What's the best way to have dynamic deformations?
For #2, I'd like to have local deformations if possible. A custom morph would be good if I can change the deltas at each frame. Or is a WS modifier the way to go? I would need to ensure that this morph is the very last one applied.
I'm not sure what's the best class to use. DzModifier? DzMorph? Is apply() called when you change frames? I don't think I can use DzMorph. One of the apply() methods supplied the deltas. Not sure how that even makes sense. I thought the DzMorph instance already knew what its deltas were.
Anyways, any help would be appreciated! Thanks!
edit: Just got an even better idea... if I manage this, I could write another plugin that sends the scene directly to Lightwave where I could then configure the physics settings. This is too good! lol
Comments
My thinking here is why not just work with someone to implement Bullet in DAZ Studio; I'm considering this instead of my previous Renderman plugin idea.
Bullet Physics only determines the deformations to make. It doesn't implement them on the objects.
Morphs aren't needed for rigid dynamics. That's just a matter of defining which objects to simulate, how they are limited, and what can collide with what. It's when you start working with soft-body dynamics that morphs become necessary....and simple linear morphs create a huge set of limitations.
I've actually been working on this (off and on, more off lately) since to do animated soft-body physics you need to dynamically modify the object vertices in non-linear ways. Regular DzMorphs won't do this (you CAN do it using one morph per frame, and having them turn on one frame at a time. It's messy!) So I came up with my own implementation (it's a subclass of DzMorph) which I call DzSplineMorph.
It's a morph that instead of simply being a single offset delta from base position for each vertex, is instead a DzSpline (actually working on it being a sequential list of DzSplines) which is curve-fit to the vertex positions that result from simulation (or can be adjusted manually, etc.) It's a 3D spline curve which tracks the offset position of a vertex. It isn't really that hard to implement. This allows for non-linear morphs, and morphs that effectively have 'multiple' values that are not collinear.
The physics simulation can use this to describe the changes in a surface due to physics and then use curve-fitting to find a least-splines set of curves to produce the same motion. One of these for each vertex. Of course, this makes a larger data structure, but for simple curves that are not TOO complex, it only requires a few points to define the spline. So you get a morph that takes up a lot more data storage, but is a LOT more flexible. Large meshes where most of the vertices move would get even larger spline morph data sets.
The DzSplineMorph I've created is mostly done, it's the curve-fitting algorithms that are giving me fits. (and of course, getting Bullet integrated into DS....that's its own little nightmare.)
(ed: Just to clarify.... A regular morph only stores ONE point (3 coords, x,y,z) per vertex in the original model (but only those that actually deform). It a linear offset from that vertexs un-morphed position. The vertex moves linearly (along a straight line) to the morph position as the morph is moved from 0% to 100%. Go beyond 100%, it just keeps moving along that same line at the same rate. The Spline Morph, in contrast....at its most basic (one spline per vertex) stores 3 points per vertex of the original model (again, only for those that actually deform), and those points define the inflection points of the spline curve. The vertex itself travels along the spline curve based on the morph percentage selected. Spline Morphs are limited to 0% to 100%, however, and cannot exceed either (no negative, nor above 100%))
To do a 'negative' it would basically double the amount of data...because there would have to be another spline going the 'negative' direction.
A morph to make a bulge to the right would be one set...going from 0 to 100. With a linear morph, going to the left would be simply going to -100. but with a spline, it would have to be 0 to 100 to the left, essentially the same data, but the opposite direction, right?
Yes and no; it would likely depend on the type of movement the joint is meant to have.
Morphs at joints would be a little different; the elbow joint itself would deform one way, but the sides of the elbow would have to deform at right angles to the bend.
A spline morph just allows the morph to deform non-linearly (i.e., not in a straight line).....so if the vertex in a 'bulge' needed to move along a curved path, then it would be useful for it. Mirroring a Spline around an endpoint (which the default vertex position is) is pretty simple, so doing one from -100% to 100% is doable. But going beyond +/- 100% would require some kind of predictive curve pathing based on the last part of the spline, and would be overly complicated (and would approach linear behavior rapidly) so it's probably not terribly useful to allow. Going negative doesn't really require additional data points, as they can simply be 'inverted' from the original spline path points (mirrored around the vertex origin). But except in a very few cases, it's probably not going to be terribly useful. Spline morphs are more an extension of morphs to allow for dynamics.
(an example of where a 'bulge' morph needs to be non-linear is when the two meeting surfaces would start to overlap. By using a spline morph, you could have it move so that bending beyond a certain point (and thus as the morph passed a certain %, if it is a JCM) the vertexes would start to shift outward, flattening the surface rather than moving toward the other part of the limb.)
I was trying to wrap my mind around the simplest case...
What about for something like a flag or cape? Would DzSplineMorph work for that?
Yes! That's precisely what it IS designed to handle. Though, it could be generated using a simple script, instead of having to do dynamic simulation for simple stuff (using basic trig functions and such to give it waves and such.
The DzSplineMorph design (it is basically just a DzMorph that stores a list of DzSplines instead of a list of vertices, and does spline calculations instead of linear interpolation) is what I finally came up with as a way to handle dynamics output for DS. It's not a perfect solution, but it's pretty flexible. The hardest part is curve-fitting the dynamics output to create each spline curve, and generating the inflection/control points. Different kinds of splines might work better than DzSpline, but those are already in place so they're a good starting point......
Bullet is the name of the physics engine in Lightwave. It does both rigid body and soft body physics. So on each frame, the deformations are different. One thing I've seen is the cape example that daywalker03 mentions. In Lightwave with the Bullet engine, the cape deformations are based on the speed of the cape (amongst other things) and the figure it is attached to. So I can't predict what the deformation will be. I need a way to grab the deformations at every frame, apply those, and render. The spline idea might work if I can dynamically grab the data from Lightwave. But now I'd need to find a way to set the slider value from 0 to 100% based on the frame index. I'm not even sure I need splines. But overlapping cubic splines would be good enough if I want to stretch or shrink the timeline of the deformations. What kind of splines are you using now if I may ask?
Hmm... Perhaps we should persue this, as Carrera is another application that uses Bullet, as is Poser. ;)
I'm quite familiar with the Bullet Physics library. I have it building in my environment (VS2015CommunityEdition) and as part of a plugin for DS. No connectivity between them yet (all the glue) but it's there. Lightwave 3D is also something I'm pretty familiar with (though I'm pretty behind on it, I can't afford to upgrade to a new version...I'm still on LW 9)
For any given scene, you may (or may not) require full physics. If you can 'fake' it using some equations and a script, it's often faster. But for animation, it's often insufficient.
Trying to run some kind of API between DS and LW would be pretty slow, but could be done. But to get Bullet Physics working within DS is what I'm looking toward.
As for what kind of spline I'm currently using, it's the standard DzNaturalSpline. I'm using 3 per vertex (one per coordinate axis) since the DzNaturalSpline is single-valued. I'll probably just make a new class, DzSpline3D, which will encapsulate this better. According to the DS 4.5+ SDK docs, DzNaturalSpline is "a special case of a cubic spline that has zero second derivative at its two end boundaries. A standard reference for natural splines are the Numerical Recipes books that can be found online."
I'm planning on re-writing the spline interpolation part to allow for multiple types of splines, as the DzNaturalSpline is a bit limiting. The equations aren't that hard. It's curve-fitting to the datapoints generated by the physics simulation for a given vertex to generate a very close approximation smooth curve with a minimal number of control points that's tricky and complicated.....
Sounds good; the Collision and IK parts could be useful as well, as could other things in there.
Oh!!! I feel a little silly. I didn't realize Bullet was actually open source. Now I see what you guys were saying. @hphoenix, if you're working on adding Bullet dynamics directly to DS, that would be absolutely incredible! Having said that, the features in Lightwave Layout for posing and animating are really nice (at least for me). I might still look into bridging animations, but this really opens up possibilities. Thanks for everyone's help. Looks like I have more research to do. :)
Collision is absolutely critical. IK isn't as much of a concern. But having Forward Kinematics (dynamics) is the whole point of physics simulation.
There are a lot of things that Bullet doesn't do yet. I'm hoping the get some stuff added that would really add to the potential of the engine. Fluid dynamics would be a godsend....being able to simulate air flow and fluid flow would be incredibly useful. Bouyancy would be useful as well. Gas/fluid pressure and elasticity would be cool too. But just rigid dynamics and soft-body deformation (which are already in there) will be enough to handle 98% of what is usually animated. A lot of the rest can be faked with a little work.
Don't feel silly. This stuff is incredibly complicated, nobody knows all of it.
Yes, I'm working on creating a Bullet Physics plugin for DS. The idea is to be able to assign nodes in the scene as either Non-Physical (default), Static, Kinematic, or Dynamic. The main plugin pops up a window that allows you to assign these characteristics (along with others) and basic world parameters. Then you hit 'simulate' and it runs the simulation, updating the objects in the scene according to that. Non-physical objects don't interact with the simulation at all. Static objects are collision only....like the floor or ground or a building....stuff that doesn't move, but stuff can run into it. Kinematic objects are like Static objects, but they have to update each simulation frame since they are animated (moving) according to DS animation (like a figure with an Aniblock attached) so the collision volume changes and can interact with other objects in the scene. Dynamic objects are fully simulated with the physics engine, and can be either Rigid or Soft-Body.
There's a lot of ground work to do ahead of actual implementation. The Spline morphs (for softbody deformations), the decision tree for automatic determination of bounding volume types for nodes, and more. Simple rigid simulation would be easy, but I want something more capable when I'm done. So a lot is going into the design and architecture of the plugin.
I'm also working on an isosurface plugin, which I'm hoping to implement in both CPU and CUDA (for those who have them). It's pretty complex too. Trying to allow iso-elements that are fairly complex (like superellipsoids and supertoroids) and the math is getting torturous. And I still can't find good information on SuperToroid implicit equations.....what I've found is contradictory, and poorly (i.e., doesn't) explains the parameters involved.
(My real work has been keeping me too busy to really focus on my DS plugin development.....I'm hoping after January, I'll be able to get back into it a bit. I think some of what I'm doing would really help out with animation and realism in DS, and give a lot of flexible tools to the users.)
Yes, fluid dynamics would be interesting to see in Bullet. One thing that will likely drive folks nuts trying to simulate wind is instanced elements of the trees and such in a scene.