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
Refactor flexible skinning #4812
Conversation
…ing any Object3D instace to be used for skinning--not just Bone instances. Furthermore, this commit removes the restriction that a SkinnedMesh can only be skinned by child objects/bones. Now, a SkinnedMesh can reference arbitrary objects for the purpose of skinning. One implication of this is that Bone.skinMatrix has been removed as it is no longer necessary. Here is a breakdown of the notable changes: src/extras/animation/Animation.js * Fixed animation of non-bones * Removed references to skinMatrix src/extras/animation/AnimationHandler.js * Removed special handling of SkinnedMatrix instances src/extras/animation/KeyFrameAnimation.js * Removed special handling of Bone instances * Removed references to skinMatrix src/extras/helpers/SkeletonHelper.js * Removed references to skinMatrix and Skeleton src/objects/Bone.js * Removed references to skinMatrix src/objects/Skeleton.js * Removed entirely, refactoring functionality back into SkinnedMesh src/objects/SkinnedMesh.js * Re-added code to construct the skeleton hierarchy when it is present in the geometry object that is passed to the constructor. This is here for backwards compatibility and could be refactored at a later time. * Added bind() function that takes an array of bones (Object3D instances) that are used to skin the mesh. This function establishes the initial bind transforms of the mesh and bones. * Added initBoneInverses() function that is used internally by bind() to calculate the bind matrices. * Added initBoneMatrices(), which contains refactored code that previously existed in the constructor (prior to the THREE.Skeleton refactor). This code sets up storage for the bone matrices and/or texture. It is used internally by bind(). * Added updateBoneMatrices(), which is called by the renderer after the scene's world matrices have been updated. This is done in a separate pass because SkinnedMesh can depend on objects that are stored anywhere in the scene hierarchy, not necessarily child objects. src/renderers/WebGLRenderer.js * Call updateBoneMatrices() on SkinnedMesh instances after world matrices have been updated * Removed references to Skeleton
Conflicts: build/three.js build/three.min.js
Why was I mean, I did read your reasoning in the other thread but I agree with @crobi on thinking that is good to have an object that tracks all the bone hierarchy and that can be reused in different |
Also, try not to include builds in PRs. |
Hi Mr. Doob, First, sorry for committing the builds—I’ll be sure not to do that next time. I like the idea of being able to animate multiple meshes with a single Firstly, with my changes, Why do For example, previously
where
where In either case, the end result is the same: How can we solve this? How can we decouple
Instead, if the shader expects
In this case, we have decoupled the
where With this approach, we could then have multiple This post ended up being longer than I planned, but hopefully it makes sense. Please let me know if you have questions or suggestions. |
Your suggestion with doing skinning in world space costs one more matrix multiplication per vertex and gives you the flexibility to reuse the bone matrices for different meshes, I like that.
I assume you can also set your Another thing, apart from storing the bone matrices, a |
…sformations from the transforms that bind a THREE.Skeleton to a THREE.SkinnedMesh. This allows us to animate multiple THREE.SkinnedMesh instances with a single THREE.Skeleton. Here is a summary of the major changes: extras/helpers/SkeletonHelper.js * Fixed code mistakes (missing 'THREE'). objects/Bone.js * Removed duplicate code that is already in THREE.Object3D. objects/Skeleton.js * Not a descendant of THREE.Object3D (previous version was). * Stores boneMatrices and boneTexture. * Independent of THREE.SkinnedMesh. objects/SkinnedMesh.js * Refactored boneMatrices and boneTexture related code into THREE.Skeleton. * Added two bind matrix modes: "attached" and "detached". renderers/WebGLRenderer.js renderers/webgl/WebGLProgram.js * Attach bindMatrix and bindMatrixInverse to shaders. renderers/shaders/ShaderChunk.js renderers/shaders/ShaderLib.js * Use bind matrices during skinning.
Please see the most recent code. I have re-introduced THREE.Skeleton and decoupled it from THREE.SkinnedMesh. This will allow us to animate multiple meshes with a single skeleton. The mesh-specific bind matrices are stored in THREE.SkinnedMesh and used by the vertex shader to transform to/from "bind space" (world space in the current implementation). The previous version of THREE.Skeleton created the skeleton hierarchy, which I have moved back to THREE.SkinnedMesh. I see this as application-specific (or at least high-level functionality) and would rather not have it in THREE.Skeleton. For example, the hierarchies that I deal with are often mixes of THREE.Bone, THREE.Mesh, THREE.Light, etc. I would like to remove this behaviour from THREE.SkinnedMesh as well, but I have left it there for backwards compatibility. In the future, it might be nice to have a THREE.Model class that would provide convenience functions for loading files (FBX, Collada), attaching skeletons and animations as well as providing a logical container for node hierarchies. I think this was partly the intent of THREE.SkinnedMesh; however, the THREE.SkinnedMesh approach imposed the limitations that led to this pull request. Anyways, let me know what you think and if you have any suggestions, questions or comments. |
Thoughts? |
Conflicts: build/three.js src/extras/animation/Animation.js src/objects/Skeleton.js
I just updated the branch, merging it with the current version of "dev" and removing the built files (three.js and three.min.js). I'd love to get this pulled into dev, if possible. Please let me know if there's anything I can do to help, if any changes are required, or if you have any questions. Thanks. |
I'll have a proper read on this one later this week. Sorry for the delay! |
Sorry for this, but could you try merging with the latest |
Conflicts: src/objects/Skeleton.js src/renderers/shaders/ShaderChunk.js
Yup, should be merged now. |
Thanks for your patience! ^^ |
Just for clarification, is this a potentially breaking change? Or will the current skinned meshes work the same with current parameters? |
@mrdoob - Great, thanks! @EskelCz - I did my best to maintain backwards compatibility with the previous usage of SkinnedMesh. All of the example applications ran as-is, for example. It's possible that missed something though, so please let me know if you run into any differences and I'll let you know how to update your code. |
@ikerr I think this change broke Do you mind taking a look? |
@mrdoob Thanks, taking a look now. I'll let you know when I have a fix. |
Fixes glTF skeleton loading, which was broken by pull request #4812.
This commit improves the flexibility of the animation system by allowing any Object3D instance to be used for skinning--not just Bone instances. Furthermore, this commit removes the restriction that a SkinnedMesh can only be skinned by child objects/bones. Now, a SkinnedMesh can reference arbitrary objects for the
purpose of skinning. One implication of this is that Bone.skinMatrix has been removed as it is no longer necessary.
For prior discussion, see issue #4782:
#4782