Noobie - parenting and transforms

Hi to the forum, I am a noobie, project is an articulated human skeleton with a few restrictions to the types of movement.

I started off with the spine, the vertebra have gaps (spinal disks are not included in this model) - instead of a disk - I create a small sphere mesh on the “top” of each vertebra - which is the “joint” about which the next vertebra rotates.

I specify the position of each “sphere joint” relative to the previous sphere joint, this is convenient as I am creating the ‘sphere joints’ in Babylon and I have to position the sphere joints by eye so actually relative positioning is very convenient.

However the vertebra are imported from file so I have to process them, they are all in the correct position relative to each other and all have the same global origin ( 0, 0, 0 ) - if you simply import the lot into say blender you will see a complete skeleton.

The behaviour I observe when a vertebra mesh vertex at say ( 1, 2, 3 ) is made a child of a ‘sphere joint’ at ( 10, 50, 100 ) then the mesh vertex appears to be now at position ( 11, 52, 103 ) - the vertices have not been automatically adjusted to reflect the parenting - becoming a child of a mesh at ( 40, 50, 60 ) effectively moves the visual position of the child by 40 in the X direction, 50 in the Y and so on.

I have dealt with this by keeping an ‘accumulated offset’ associated with each vertebra which is the transform required to ensure that the mesh appears to not to move when it is made a child of the previous ‘sphere joint’.

I wanted to ask whether this ‘manual’ process is necessary or have I missed an elegant way of getting this to work automatically? Is there a way to make sure that a mesh does not move visually when it is made a child of another mesh?

Thanks Jon.

Hi and welcome!

I hope I understood correctly but what you are trying to do is not a perfect fit for babylon’s parent-child.

A child’s transformation (LOCAL transformation) is relative to its parent. if no parent is found, the “parent” is the world itself (so in this case - global position is the local position).

In any way, the vertex data loaded by babylon is not changed when you transform the object. so setting an object at (1,2,3) will “transform” the vertex data during rendering, but this will still be at (0,0,0). Same thing goes with parenting - as you noticed, if the parent is at 10,50,100 and the child is at 1,2,3, the vertex data will render at 11,52,103 , but will still stay at 0,0,0.

We don’t recommend changing vertex data on each frame. this is relatively expensive and will reduce your FPS (of course, depends on the complexity of the object). However, if that’s what you actually need, you can always bake the current object’s transformation to the vertex data and have its location “reset” to (LOCAL) 0,0,0 . That means that for babylon the object is at 0,0,0, but its vertices’s origin is no longer 0,0,0, but the previous transformation of the object before baking the transformation into the vertices data. The function to bake is (surprisingly) called mesh.bakeCurrentTransformIntoVertices(), in case you want to use it.

1 Like

Hi Raanan,

Thanks for replying and the welcome.

The reason I am using parent-child may be illustrated by considering the spine. If vertebra N bends forward by 1 degree then verebra N+1 moves with vertebra N and is now in a different orientation with respect the the world, in addition it is very likely that vertebra N+1 is also bending forward itself by something like 1 degree since human beings tend to bend a region of spine rather than one vertebra. The parent child relationship is ideal for this because it takes care of this automatically, I can ask all vertebra to bend forward by 1 degree and what I get is a curve just like you would get with one of those wooden articulated toy snakes.

Regards performance overheads, that is fine, the way this will eventually work is that I will be able to pose the skeleton in various ways with my own keyframe system, all angles of all articulated joints will be recorded for each keyframe and then I will spline through those angles to get the “tweening” - performance does not matter, its not for real time (game) animation - video frame by frame and so on.

I am not actually ‘changing’ vertex data on each frame since I am applying transformations - there is no baking during movement, the complex mesh vertex data is not being written to, only the transform matrices that are associated with each mesh are being changed.

I do use the baking process once at the very start, this is because for some bizzare reason to do with the original skeleton data - the bone OBJ files are all centered around something like ( 0, 0,7, -1113 ) so to make life easier I first transform and bake the skeleton centred on ( 0 0 0 ) but after that there are no more bakes - it just means a reduction in coding complexity for me - do it once and then forget about it.

Thanks for answering the question ie that when a mesh moves into a local frame it is not automatically adjusted (either by means of slow and direct vertex modification or by means of a transform which is fast ) with the consequence that the mesh will appear to move as it becomes a child because its data is still relative to ( 0 0 0 ).

As I mentioned I am dealing with this issue by storing an accumulated offset vector for each successive vertebra in the spine, this is used to transform ( but not bake ) the vertebra so that it does not appear to move when it becomes a child of another and so stays in the same place relative to the rest of the skeleton. What is achieved is that although the vertebra does not appear to move, its centre of rotation is now relative to the previous vertebra and in addition it now gets “automatic updates” in the sense that a rotation on vertebra N results in all vertebra after it ( N+1, N+2, … ) changing position as you would expect. I just wanted to check that I was not doing this “the hard way” and that there was not some feature in Babylon which would say "change to this local co-ordinate system but alter the meshes transform so that the action of parenting does not move it relative to the global co-ordinate system.

At the moment I have all cervical and thoracic vertebrae “rigged*” - and that entire section of spine is moving in real time without any noticeable delays - so far Bablyon seems to be handling it with ease.

*by rigged I mean by means of my own bespoke code.

I am very impressed with Babylon - my project demands a lot of it and so far it is handling everything with ease, the only complexity I envisage so far is writing a constraints manager to deal with some of the more complex bone relationships which will not be fully handled by the parent-child relationship.

1 Like

That’s sounds complex :slight_smile:
You can always use the absolutePosition setter (rotation is included as well) to alter a child’s transformation in world coordinates, but i doubt this will really help (you will need to calculate the relative transformation for each bone).
I personally dont have a better solution, but maybe someone else here has a better solution.

We love hearing that :slight_smile:

Yup, every time I think of a new feature either for intended use or debug I usually find ten lines of code and I have it in place - for instance being able to video animations of the skeleton, that really was around ten lines of code.

I already have used “pick” to centre on a particular bone, colour it, centre view on it, and tell me its name so that I can work out what is going on when I am debugging - again a few lines of code and bang I have an invaluable debug tool.

The manual and rather awkward task is positioning a couple of hundred small spheres to represent joints and setting their parent child relationships, so far I have found no better method than to guess the XYZ for each sphere and position it by eye - it is tricky of course because my joints are all positioned in a long chain of local co-ordinate systems and so you have to always work down the chain in the direction of parent to child ( which is then a parent to the next and so on ).

It really is a powerful tool because it delivers powerful results with few lines of code.

1 Like

I think it is a reasonable approach to achieve a particular goal. Plus iteration can only improve. I hope you find your way to all the phalanges.

@withADoveInOneHand

:grinning: You know your anatomy !

Not quite at the phalanges yet. He can now do squats although his feet and hands are not complete, only his first rib follows in the squat but the rib cage is one of the zones that needs a special constraints manager - individual rib movement a function of sternum and spine so not a straightforward single parent => single child relationship.

1 Like

I really appreciate the thorough investigation you are giving to the problem. If you can keep the solution extensible to some degree, all the better.