I have a a skinned mesh. At some point I would like to manually move a mesh instance, that is part of the rig. What would be the right way to stop skin updates so that it won’t affect the vertex positions. For example, mesh instances have a visible property that control whether it is rendering or not. Would there be some analogy for skin instances to enable/disable them?
Are you using the Anim component? If so, I guess the ‘correct’ method would be to use a layer mask or updating the mask.
Wondering it makes sense that the mesh instance also has some level of control on whether it should be updated as part of the skinned update
Thinking in the short term, setting and nulling the skinInstance on the meshInstance might be the easiest thing to do here? (Just have to remember to destroy it when it’s no longer needed when destroying the Entity)
Thanks, I should have mentioned that I need the skin instance to be preserved, so I can later return the mesh instance to its skin transform and it would continue to animate.
You could store it somewhere and reassign it afterwards.
this.skinInstance = meshInstance.skinInstance; meshInstance.skinInstance = null; // later meshInstance.skinInstance = this.skinInstance; this.skinInstance = null;
Not great but should get you there?
Hmm, I could try that. Will the instance have correct transform once it is “re-atatched”?
What do you mean by correct transform?
I expect when you re-attach it, it will be updated by the bone transform as the internals of the skinInstance have not been changed or updated when removing it from the mesh instance.
I suppose that would be the way to go then. I just need to figure out the transform the instance should return to, since the skin was not updating. I meant that the skin’s node won’t have an updated transform, so I will have to find some other way to find where I need to return to. I will also look into anim masks - haven’t used those yet. They seem to be promising too. Seems like I can just enable/disable the mask to stop the skin update? Will try that first.
The skin instance is driven by the bones which is why you see the Root Bone property on the Render Component.
The Anim layer mask will allow you to filter out which bones will used to the update the skinned instance which is a finer control then doing it on a per meshinstance basis.
Edit: That said, there doesn’t seem to be an easy way to update the mask unfortunately
Edit2: No, wait. I found it AnimComponentLayer | PlayCanvas API Reference
If you would stop the skin to update, your mesh would render in the default position, which is usually a T-pose. Is that what you’re after?
If you want it to stop at the last position, you should just pause the animations?
@mvaligursky hmm, right, so I want something in between. I’d like the rest of the mesh instances to continue their merry way. At some point of the animation, I’d like to grab a part of the mesh. At that time, I need it to stop animating, but the rest of the instances should continue the animation. Some time later, I want to return that piece back to where it belongs, so it can continue its animation in line with the other pieces.
I was thinking I’d have an opportunity to stop the skin instance updating the mesh instance transform. Ideally, just cancel the update, but continue updating internal node, so when the time comes, I could get that transform and return the piece to its (future) place. However, this doesn’t seem to be the case, or maybe it is with the masks? Not sure, as I haven’t tried yet. Maybe spawning a clone instance and hiding the original would work? I’d prefer not to dirty the scene graph, though.
To be honest, I’m not sure what you’re trying to do. Could you provide more context here?
With skinning, a single mesh instance gets updated / skinned by a whole hierarchy of nodes (a skeleton). Do you want to stop the whole skeleton from updates, or just a node? Perhaps you can override skinning matrices after the skinning … I think one of the engine anim examples does it … it modifies a single node / bone after the animation to make the head look at some point.
Well, I probably don’t want to stop the node to be updated (I could use it later). I want only the mesh instance to stop getting updates from the skin instance temporarily. Yes, a good example would be Assassin’s Creed - if you get close to an item of interest, the character’s head would turn to look at it, if you get far enough, it will resume its idle/walk animation. I will check the engine examples as well, thank you for the pointer!
Another way to do this is to set the bone position (of the head in the case of looking at something) in the postUpdate as that is called after the anim system is updated.
That is a good idea, actually. I usually try not to do any transform updates in post update, since that is when we update the camera, which may introduce jitter. Will give it a go as well, maybe I can get away with it.
I think if you listen for the anim system ‘animationUpdate’ event, it will callback after the anim update and before the postupdate Application Lifecycle | Learn PlayCanvas
Spent some more time on this one. So, the current approach I have is this:
Pre: the entity position was changed manually in post update, overriding whatever skin was trying to set.
I now want to move that entity back to its animation position.
- On mouse event, I grab the current position.
- I then immediately call
.anim.update(0)(if no animation was running) and read entity position again. If I understand correctly, this should update the entity transform via the skin matrices and reading the position would now return the position of the entity that the skin is enforcing.
- I grab the skin position and move on to post update.
- In post update, having start and finish, I interpolate the entity position to return it back to the animation.
I works for the most part, except one issue - once the interpolation starts, for the first 1 or 2 frames I see the mesh at its destination position, before it starts to interpolate properly. It also doesn’t happen always, sometimes interpolating without popping at the last position. I’d say once every 4-5 tries, I get that flicker for some reason.
So the loop is mouse event > post event interpolation. I somewhere get that single frame being rendered in between (or maybe right before the mous event…).
Alright, the flickering issue was due to the timing of mouse event. The solution that worked for me is not to process the interpolation targets immediately on mouse event. Instead, record the event and process it in the post update. This eliminated the flicker on the interpolation start:
Nice work on going from animation to ragdoll and back again! That is very smooth