Hello,
I made a very simple pose editor which is not working yet: Playground
So with rotation around an axis it is not like expected:
bone.rotation[axis]=value
or
bone.rotate(rotationAxis, value, BABYLON.Space.LOCAL);
What I am doing wrong here?
Another question: does anybody made a better pose editor in Babylon?
The first question, if you set bone.rotation.x/y/z, you should update matrix after setting.If not, babylon will not update it. You can do like this https://playground.babylonjs.com/#CN4KJL#73 (note: because you use Eular Angle to control rotation, the range of X pitch is from -PI/2 to PI/2 , Y yaw/Z roll is from -PI to PI).
Pitch and yaw decide the forward of plane, horizon 360°, vertical 180°
The second question, bone.rotate( axis you want, delta value you want to rotate, rotate space ), you should set delta value into this arg, not the current value. https://playground.babylonjs.com/#CN4KJL#69, I think this is a bad way to set (we are not sure whether bone’s value is equal to current value)
thank you very much - this is very helpful.
The second question was about if somebody else made already such an editor?
I mean with sliders it is the easiest solution but dragging things around and having controls everywhere for rotation like in real 3D editing app is way more complicated so inventing everything from scratch if it already exists would be a huge amount of work here.
I try to improve the UI by selection of one body part. But this is only one mesh with bones.
How to get the correct bone by hover/click event here?
Thank you
I found something what I was looking for: https://playground.babylonjs.com/#2101ZD#5
It seems that on sceletonViewer it is not possible to attach a working actionManager. That is what I tried.
Workaround here: add a sphere for each bone. It would be nice having sceletonViewer clickable for each bone - this is not possible?
It would be really hard to do as the skeleton is on big merged mesh only and not a list of separated ones. Also it is defined in a utility layer which is by design not listening to events
ok that transformnode worked - thank you!
But I am still doing baby-steps here - so new questions
distance: it was a bit confusing because in documentation there is length property. I followed your advice:
if (bone.children && bone.children[0]) {
let child=bone.children[0]
length = BABYLON.Vector3.Distance(bone.position,child.position)
}
sometimes the length is correct but most times not.
UPDATE: I think I have solved this myself
bone.getAbsolutePositionToRef(mesh,point1)
child.getAbsolutePositionToRef(mesh,point2)
length = BABYLON.Vector3.Distance(point1,point2) https://playground.babylonjs.com//#CN4KJL#82
also I tried to follow the bone-mesh-clone to the original bone by setting the rotation:
so as setting a pointer to the same data structure I thought it should do it but it does not work:
tf.rotationQuaternion=bone.rotationQuaternion
also if I would have position set the same way there is no need for cylinder.attachToBone(bone, tf); in my opinion? but that all doesn’t work for me.
But I have another beginner question now
This is same code but instead of using standard Babylon-dummy file I am using a gdb file:
I can see the object and skeleton but my own objects for bones and joints are gone.
UPDATE: variation using translation nodes: https://playground.babylonjs.com//#CN4KJL#92
using .setParent - but also does not work
Here is a fixed version, you need the correct scale, and stop animations from interfering. You also need the gizmo displayed in the correct orientation: https://playground.babylonjs.com//#CN4KJL#103
Thank you! This looks good. About scale. In documentation it writes: "When you attach a mesh to a bone in a skeleton, the mesh will be scaled by the same scaling factor as the parent mesh of the skeleton. "
But as I understand your changes you apply a scale which fits to the skeleton. So this is a bug in Babylon or have I understand something wrong here?
mesh.scaling shows a 1,1,1 vector so I still do not understand why the huge balls are getting smaller here.
Anyway it works now and this is great
For another feature I need to change the bone length. So is it possible to change the length of a bone?
I tried
bone.scaling = new BABYLON.Vector3(…)
but it does not seem to do anything.
I have another similar question.
I want to store full pose and restore it.
So I made for each bone:
let lmat=bone.getLocalMatrix()
lmat.decompose(scale, rotationQ, position)
and stored scale,rotationQ and position for each bone. I think just storing lmat should do it as well.
for restoring the pose I made (load for each bone the data from an info object):
let lmat = bone.getLocalMatrix()
BABYLON.Matrix.ComposeToRef(info.scale, info.rotationQ, info.position, lmat)
bone.computeAbsoluteTransforms()
bone._markAsDirtyAndDecompose()
This does nothing which makes sense so far because as I understand I have to make it different because of gltf here and using transformNode but .getTransformNode().getLocalMatrix() does not exists. What is the best solution to do this here? Thank you!