-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for other solvers? #2
Comments
The major issue with FABRIK is that it can not implicitly support hinge joints (since the positions of the joints cannot encode twist by themselves). Generally, I find CCDIK to be more flexible than FABRIK when it comes to hinge joints, limits, and constraints (while being roughly the same implementation complexity). The key to doing it elegantly (in 3D) is to formulate the CCDIK "rotate toward" step, the hinge constraint, and the rotation limits all as sequential rotations (which minimally rotate one vector to point along another vector). The Unity C# code I used to accomplish this in a hierarchy looks like this. (note that all these calculations are being done in world-space). The live demo here is also a part of that git repo (if you want to take it apart in context). While this rotation operation is typically done with Quaternions, the direct-matrix version of it is the subject of this excellent article by Inigo Quilez. Generally FABRIK has nicer long-distance convergence properties, so what I typically do in production is run one iteration of FABRIK (without hinge/joint constraints) to get the nice convergence, and then clean up that result with CCDIK (with hinge+joint constraints). The two solvers should be able to run side-by-side, reusing all of the same data structures and math (for instance, a rotation-limit is really just a hinge joint plus the ball-socket limit applied in sequence). |
Thanks for the resources! CCD was the first implemented version, but had difficulties constraining rotations (after having done the FABRIK version, I no longer think I'd have the CCD issues). How do you imagine the configuration of these solvers? One solver per IK system, where a solver could be FABRIK, CCD, or a solver that uses both (like the FABRIK+CCD method you describe), or just only use a specific method, like FABRIK+CCD? Would joint implementations have to be solver-specific? If so, the FABRIK+CCD approach seems even more appealing. |
Similarly, I imagine each IK system should consistently use the same solver (or hybrid solver), such that an IK chain's children chains must use the same solver. Is there an advantage to allow individual chains to have their own solvers, or is this a system-wide configuration? Separately, but related, I've been mulling over the need for the IK root class altogether, and just move 'system wide' configuration to a root chain. More here: #7 |
While I can't comment on the data-structure-side of the architecture, I'd vote for the "solve" method to just have arguments for which technique, how many iterations, and perhaps a bitmask/enum for which types of constraints to consider... This way, the "hybrid" technique is just calling |
This is great insight, @zalo, thank you! I'll sketch up a solution when I have some time. |
Currently, THREE.IK uses a FABRIK solver. Is it worthwhile to adopt the ability to swap out solvers for different scenarios, like using CCD? Would constraints be able to be generalized across solvers?
The text was updated successfully, but these errors were encountered: