Physics simulation for character hair

Ah, that simple? Thanks!

Fair enough. Afterall the hair simulator was my idea :stuck_out_tongue:

FWIW, some technical details (concerning the interaction with controlJoint) are described in one of my earlier posts, [url]global coordinates of a joint - #7 by Technologicat].

It would be nice to post the code in order to explain this whole thing more clearly, but I’m not yet satisfied with its quality - the current implementation is missing some important features. Furthermore, the code resides inside an unmaintainable mess of miscellaneous experiments, so I would first need to spend some time to make a minimal working example containing just the hair simulation before it’s readable to anyone but me.

(As for the missing features: currently, the external force is a global constant vector; this must change to support fictitious forces. Also, upon closer thought I have noticed that there is currently no mechanism for specifying a custom rest position for any except the first element in the chain - the neutral position of the chain is always a straight line in the direction pointed by the first segment. This needs to change to make it possible to simulate trees, too. Finally, the chain abstraction must go; the simulation needs to be able to support an arbitrary tree topology.)

Thanks for the interesting and detailed technical overview. This should help a lot.

With that information, I think that there are two options: either the PandaNode subclass approach, utilizing the existing controlJoint mechanism, or the AnimChannel approach. It seems an AnimChannel might be marginally faster, and at least in any case cleaner, as it would avoid one extra layer of logic (namely controlJoint and its dummy nodes).

I imagine that in this approach, I would modify Actor to add a method controlJointTreeByPhysics (or something more compactly/sensibly named) that would take over the control of the specified joint and all its children, and make their animation follow the physics simulation. This would be implemented in a PhysicsAnimChannel (or something), which would set the joint transformations based on the simulation state (in a forced mode, overwriting animation).

But where would the simulation code go? It is something that needs to be run once per frame per controlled joint tree, since the joints in the tree interact.

There must also be some way to set simulation parameters - some of these are per-simulation (gravity vector, timestep length), but others are per-joint (stiffness, damping). In the PandaNode approach, the node provides a natural container for all such data, but at the moment I don’t see a logical place for this data in the AnimChannel approach.

(Background: the simulation needs the global positions of all the mass points representing the joint origins to compute the next timestep; though “global” may here be a misnomer since it is easier to work in the coordinate system of the character, or even that of the hair parent joint. I haven’t considered whether a purely local approach is possible.

An important property of hair simulation is that the “bone lengths” (in the Blender sense) stay constant. Working in rotation space (using quaternions to represent orientations) would be one possibility (very elegant since the choice of space automatically enforces the constraint), but I think the forces affecting the mass points are easier to model in a Cartesian xyz frame. This is the approach I have used. The Cartesian approach needs the positions of the neighboring nodes (joints) to enforce the length constraints. Then there is also a second constraint, requiring that the correction to the position, applied by the length constraint, does not change the kinetic energy.)

Something to keep in mind for future development is how to handle collisions. Not many games do hair collisions well or at all, so here is a chance to shine. (Hair? Shine? Get it? :stuck_out_tongue: ) One possibility - probably enough for a first version - is to code some very limited collision support into the simulation itself (to handle the most egregious cases such as hair intersecting the character’s head). This is however not an ideal solution.

It would be better to interface with Panda’s existing collision system, but then the simulation needs to be able to talk with that. Currently, I have no idea where to even start looking - and maybe it is best left for later anyway to keep the project from ballooning out of hand. But, it would be ideal to take into account the possibility to add this later, in order not to do any critical design mistakes.

It occurs to me now that the same mechanism could also be used for ragdolls (running the simulation on the model root joint), but doing ragdolls properly would require support for constraints on allowed rotations.

Setting up such constraints manually is painful to say the least - for this to be usable, the constraints would need to be exported from the modeling package. At least Blender supports bone constraints. Right now I have no idea whether YABEE can export them, or if indeed the egg file format supports that or not (I suspect not?).

(I don’t really need ragdolls right now, but it would be a natural extension of the hair simulation system.)

Based on your description, it actually sounds like a pretty good fit, provided that we can find a logical place for the simulation code, which needs to work, not per-joint, but per-controlled-joint-tree. This seems to me the cleanest of the ideas so far.