Need help understanding "Replace Existing" transformation node

I’m trying to set some bone transformations for my hand, and override them on a particular finger. But I don’t understand how this works. This is what I did just for testing, so I can understand how these nodes work.

First I got my base hand pose.

Then, I did a translation transformation on the thumb (x=-10.0). So far so good.

Next, I added another transformation on the same bone right after. I set it to “Replace existing” and “Bone space”, and set the translation to zero. In my mind, this transformation should override the previous one and reset the thumb to its original place. But that doesn’t happen. In fact, this transformation does nothing at all.

If instead I set the translation on the latest node as 10.0, it adds this to the previous translation, and the thumb goes back to it’s original location.

I set the node as “Replace Existing”, but it seems to be adding instead. If I change the mode to “add”, nothing changes, it still behaves the same. Is this a bug? Or am I misunderstanding how this is supposed to work?

Usually the last node you have overrides whatever you previously plugged, but I think that in this case the values are added one after the other, since the previous node shift the thumb by -10, while the following node adds the value on top of the previous one.
I know that for other nodes ( like TwoBoneIK ) this doesn’t happen, so I’m not sure if this is a specific behaviour just for this node.

So is it impossible to do this? To reset any transformations done before?

Apperently no, but it would be better if you explain a bit more what you’re trying to achieve.
One way to remove the effect of the previous node would be to set the alpha of the first node based on the value of the second node, like if the float/vector connected to the location of the second node is >0, then the alpha of the first node is 0.

I don’t think I can do that. That first node in my example was just so I could test. In reality I have a node that comes from a plugin that converts raw tracking data into finger rotations behind the scenes. It comes from a single node and affects every bone in the skeleton. It looks like this:

image

And now I’m trying to override one finger after this node. In the same way as my test, the “Replace” setting doesn’t really replace the transformations performed by this node.

Ok got it, I did something similar in the past, but in the same BP I have the SK+AnimBP from the plugin ( let’s call it ShadowSK ) that I use just to grab the data ( SK is then hidden ), and another SK called TargetSK ( from the Mannequin/MH or your character ) where I’m using TransformBone nodes to remap the fingers data.
Then using BP logic I get the data from the ShadowSK ( rotation using GetSocketTransform in Component Space ) and I do a remap of the data on the TargetSK, so that I could tweak the min/max curling and spread.
By doing this you can drive pretty much whatever you want, because you get the data and apply the data to whatever hands/character you have.

I did this setup using Noitom Hi5, Manus Prime, Stretchsense Splay, Mollisen FTS and Senso Gloves, and it allows you to have total control over the data.

If you need help, feel free to get in touch.

Thanks for the help man. I’m sorry, this is a bit confusing to me, I’m still kinda new at this. Let me know if this is correct.

I’ll have my actor blueprint, and I’ll add two of the same skeletal mesh on it. I’ll have two animation blueprints, one applied to each mesh. Lets call them SK_TRACKING, SK_FINAL, ABP_TRACKING and ABP_FINAL.

So, ABP_TRACKING will be this, just as before:

image

This SK_TRACKING mesh will only store my tracking data, and it will be hidden. Do I have it right so far? And then I will copy bone transform info from this into the ABP_FINAL blueprint, and this one will be displayed, correct? Assuming this is what you mean, this is the part I’m lost at. How do I copy the bone data selectively (or entirely, for that matter) from one animation BP into the other one?

Yep, that’s right.
In order to get the data you need to use the SK_Tracking skeletal mesh, then GetSocketTransform, from there you get location/rotation/scale.
If your gloves only has one degree of freedom, check which one it is ( print the output of rotation ), and then create a float variable and store the data there.
Since you’ll need to do that for each finger, use an array.
Once you have store the data, you need to setup the TransformNodes inside the ABP_Final, so create as many nodes inside the AnimBP corresponding to each finger, split the rotation data and check which axis correspond to the fingers curling, and create a variable ( or make an array ) for that input.
Going back to the BP, you need to cast from the SK_Final to the ABP_Final, and set the array you previously saved, by using the data you gathered from the array of the SK_Tracking.
You most likely need to set clamps for the values from the SK_Tracking so that the rotation on each TransformBone will act accordingly, but once you figure one out, the others are easy to setup.

So by doing so you’re reading the realtime data from the gloves, apply a remap, and apply the data onto the other SK.

Out of curiosity, have you tried using the IK Retargeting function in UE5 to solve this?

Out of curiosity, have you tried using the IK Retargeting function in UE5 to solve this?

I have not. I’m learning as I go, I was unfamiliar with it.

I’m trying to apply your solution now. I think I’m doing something wrong. Here’s my “final” BP:

I added an input variable to get the first index joint rotation.

Here’s my actor BP, after I apply the tracking data:

“Left Hand” is the final one, “Holo Hand Skeletal Mesh Left” is the one getting the tracking data. The issue is that “Get Socket Transform” doesn’t seem to be changing.

On the GetSocketTransform use RTS Component as Transform Space.
Then before testing again do a bit of debug inside the ABP_Final by doing the following:
Disconnect the TestVar and try to manually put values on each of the axis, in order to understand which one is the curl value.
Since the rotation is set to Replace Existing, you need to manually find the values for the finger max opening/closing, so that you know which ones are your min/max, then reconnect the TestVar.
Go back to the BP and using the Print, try opening and closing your hand, and check which is the value that is changing ( the other two should not change that much ), and also here check the min/max of the finger opening/closing.
Now, for each axis of the rotator ( or just one if you have just curl ) use the Map Range Clamped, and set the min/max values you checked before, where the Input are the values you got from the Print, while the output are the values from the test you did using the TransformBone.
The clamp is the only thing missing in your setup, everything else looks fine ( except for the Transform Space mentioned above ).

Actually, I’m dumb. I was getting the transforms for the wrong hand. I fixed it, it’s working now.

Thank you so much for your help, I think I can get the rest done now.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.