Difference between revisions of "HoudiniKinefx"

From cgwiki
 
(39 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
== Kinefx ==
 
== Kinefx ==
  
Kinefx covers a lot of ground, but there's a pleasing DNA share with a lot of established houdini workflows. Basically if you've used packed prims before and wrangles, you get the core of kinefx.
+
=== Overview ===
 +
Kinefx covers a lot of ground, but there's a pleasing DNA share with a lot of established houdini workflows. It also makes a point to seperate a few rigging and animation concepts which other packages tend to merge together. More explainations below, but at a high level:
 +
 
 +
==== Joints ====
 +
As you think they are, joints or bones like in other packages. They're represented as points and lines in sops (unlike Houdini's old bone system which was up at the /obj level), so that allows for some interesting joints vs sops vs geometry interplay.
 +
 
 +
==== Skinning ====
 +
The act of binding a mesh to joints. This is all assumed to be done on a static skin mesh and a static skeleton, and note that it doesn't actually move the skin, it just sets up weighting attributes. The actual moving is done via...
 +
 
 +
==== Deformation ====
 +
Given a skin with weights, and a bind pose (called a rest pose in Houdini) and a moving set of joints, move the skin. But how do you move those joints?
 +
 
 +
==== Rig ====
 +
 
 +
''I said 'high level', but this is one of the biggest conceptual changes of kinefx rigging vs other systems, it needs more words...
 +
''
 +
 
 +
A rig is way to move joints around. Self evident, sure, but spend some time thinking about this.
 +
 
 +
If joints are just points like everything else in sops, you could use a transform sop to move them around. And just like everywhere else in sops, if you do this, its totally freeform; it won't care about the lines between the points, or the connectivity, do what you want, use an edit sop, soft transforms, fine. That's a rig.
 +
 
 +
It's likely that you'll want to maintain the relationships between your joints though. So if you rotate a shoulder, the elbow and wrist and hand joints should rotate too. A Rig Pose sop gives you this, its a transform sop that is aware of joints, and gives you FK abilities. So a rig pose sop is a rig.
 +
 
 +
But you probably want IK too right? Well what do you need at the minimum for IK, a skeleton and a IK target? Well lucky for you there's an IK chains sop, give it those inputs, you get your IK. So the IK chains sop is a rig.
 +
 
 +
'Wait a sec, if this is houdini, and sops has great vex and vops support, and kinefx is in sops... can I use vex and vops in rigs?' Why yes you can! A Rig Wrangle and a Rig Vop are designed for this, giving you manipulation of points which is skeleton hierarchy aware. So vex and vops are also rigs.
 +
 
 +
And there's more, like foot roll vops, and FBIK sops, and skeleton blend sops etc. Rigs are sops.
 +
 
 +
===== Sop modelling vs sop rigging =====
 +
 
 +
Quick aside to talk about sops for modelling.
 +
 
 +
In sops for modelling, you chain nodes together, and geo flows and gets modified from one node to the next.
 +
 
 +
If you have a 'live' modelling chain of box, polyextrude, bevel, smooth, copytopoints, you generally don't expect to see all those controls on screen at once. You select each node, do a thing, go to the next node. If you DO want a master control, you have to wire them up to a controller null, or make an HDA and expose all the controls at the top.
 +
 
 +
Now lets do a search and replace on the above statement, for how kinefx operates:
 +
 
 +
In sops for '''rigging''', you chain nodes together, and '''animation+joints''' flow and get modified from one node to the next.
 +
 
 +
If you have a 'live' rigging chain of skeleton, rig pose, FBIK, foot-roll, you generally don't expect to see all those controls on screen at once. You select each node, do a thing, go to the next node. If you DO want a master control, you have to wire them up to a controller null, or make an HDA and expose all the controls at the top.
 +
 
 +
Breaking that down, each node does its one particular operation, and passes its modified animation to the next node. This is exciting in that the rigging process itself can now be procedural, freeform, as exploratory as sops allows you to be.
 +
 
 +
It's also a quite a paradigm shift, as animators generally DON'T want this, they want their uberrig with fk/ik/fbik/spaceswitch/bendybone/layering crazyspace, and then complain the rig is too slow.
 +
 
 +
This ability to do true modular rigs, approach animation as a node based layering of motion from one node to the next, is gonna take some time for people to get their heads around.
 +
 
 +
==== Motion clips ====
 +
 
 +
Take some motion, like a skeleton walk cycle, and 'freeze' it so you see all the frames in one hit. This is a motion clip. Now that it doesn't have any animation, but is just a collection of shapes, you can apply modelling operations to it, delete shapes, duplicate it to make it run longer etc. You then run it through a 'motion clip evaluate' to convert it back to animation.
 +
 
 +
This covers similar ground to what chops does (the idea of swapping time for modelling and back again), but much simplified, and staying in comfortable sops land.
 +
 
 +
Right, enough overview. Lets move onto details!
  
 
=== Rig vs deformation ===
 
=== Rig vs deformation ===
Line 95: Line 150:
  
 
Download hip: [[:File:kinefx_starfish.hip]]
 
Download hip: [[:File:kinefx_starfish.hip]]
 +
 +
=== Proper rotation in a rig wrangle with prerotate ===
 +
 +
Much thanks to Stephan Walsch and Henry Dean for this one.
 +
 +
Short version: When rotating @localtransform attributes in a rig wrangle, use '''pre'''rotate() instead of rotate().
 +
 +
Long version:
 +
 +
The previous wrangle trick works fine for lots of joints, but if you use want to rotate a specific joint in a wrangle like a rig pose does, it behaves unexpectedly. Here's a simple root/middle/tip 3 joint chain to represent a shoulder/elbow/wrist. If I use a rig pose to select and rotate the elbow, it behaves as expected; the joint itself rotates, the wrist comes along for the ride:
 +
 +
[[File:rigpose_rotate.gif]]
 +
 +
To replicate that in a rig wrangle, I'll use the '''rotate()''' vex function:
 +
 +
vector axis = {1,0,0};
 +
float angle = radians(ch('angle'));
 +
rotate(4@localtransform,angle, axis);
 +
 +
If I run this in points mode so it applies to all the joints, the arm curls up as expected:
 +
 +
[[File:kinefx_wrangle_rotate.gif]]
 +
 +
But if I limit it to just the elbow (ie point 1), it doesn't behave as expected; it rotating everything from the shoulder!
 +
 +
[[File:kinefx_rotate_joint1.gif]]
 +
 +
If I make it just animate the wrist (joint 2), it looks correct at first glance:
 +
 +
[[File:kinefx_rotate_tip2.gif]]
 +
 +
But look closely, the elbow is wrong. Yes it's staying in the right location, but it's also not rotating (the axis handles aren't moving). More importantly, we shouldn't have to employ tricks like "if you want to rotate the elbow in a wrangle, remember to select the wrist", that's crazy.
 +
 +
Luckily the fix is simple. Go back to rotating the elbow and instead of rotate(), use '''pre'''rotate():
 +
 +
[[File:kinefx_prerotate.gif]]
 +
 +
Why? It's easier to play with than to explain in words, but its a combination of how matricies combine, and how they're defined, and how kinefx applies joint transformations.
 +
 +
First, when combining matricies, order is important. If matrix A represented 'move forward 1 unit' and matrix B represented 'rotate 45 degrees right', multiplying those matricies will combine them, but AxB will look different to BxA:
 +
 +
[[File:kinefx_matrix_order.gif]]
 +
 +
Secondly, a matrix could be defined in worldspace, or defined in relation to other matricies. The kinefx @localtransform matrix is the latter, it's describes each joint rotation relative to its parent. That means if you use rotate() on localtransform, it too rotates relative to the parent. Hence rotate() on the elbow ended up rotating from the shoulder.
 +
 +
The prerotate() vex function does as the name implies, it applies the rotation to the matrix first. Ok, but first compared to... what?
 +
 +
Well, a key job of a rig wrangle, a rig pose, a rig vop etc is to update the positions of the joints, ensuring transforms of parents are passed to children. By pre-rotating, the matrix of the joint you specify is rotated first, then when the rig pose updates transforms, it then gets moved to the right position relative to the parent.
 +
 +
Interestingly as a bonus aside, I happened to look at the help for the rig pose node, and it explains how you have a choice per animation to work in premult or postmult modes, and check it out, the default mode is premult, so this actually aligns with what I've just learned about rotate vs prerotate in vex. Go figure.
 +
 +
https://www.sidefx.com/docs/houdini/nodes/sop/kinefx--rigpose.html
 +
 +
[[File:rigpos_premult.png]]
 +
 +
In other words, if things are behaving strangely, use prerotate. :)
  
 
=== FBIK ===
 
=== FBIK ===
Line 106: Line 217:
 
Bring in a rig, here I've loaded mocapbiped3, chose a walk, and imported it with the '''scenecharacterimport''' node. Split off the feet and hips, move the hips, feed those to the second input of the fbik sop, and the original rig to the first input.
 
Bring in a rig, here I've loaded mocapbiped3, chose a walk, and imported it with the '''scenecharacterimport''' node. Split off the feet and hips, move the hips, feed those to the second input of the fbik sop, and the original rig to the first input.
  
FBIK will do its best to push the rig to match the positions of the bones you specify. Tweaking some weighting options on the FBIK node can help get rid of glitches.
+
FBIK will do its best to push the rig to match the positions of the bones you specify.  
  
 
It's not perfect, things like knees will wobble everywhere, but like I said, its fun.
 
It's not perfect, things like knees will wobble everywhere, but like I said, its fun.
 +
 +
The two things everyone notices when you first do full body ik is that the ankles don't lock, and the hips often don't track well with the target hips. To fix:
 +
 +
* Add a configure multiparm, select the ankles, give them a higher weighting, say 10.
 +
* The default damping of 0.5 is often too high for the hips, so the system is trying to blur/soften the overall solve, which means the hips don't hit the pose you want. Try lowering damping until the hips track better.
 +
 +
Also for you young folk, Shynola did a fantastic take on this vector skeleton style for Beck 17 years ago! SEVENTEN YEARS, OH GOD I'M OLD: https://www.youtube.com/watch?v=RIrG6xBW5Wk
  
 
=== Proximity skinning ===
 
=== Proximity skinning ===
Line 225: Line 343:
  
 
=== Rig vop ===
 
=== Rig vop ===
 +
 +
So this is a new way of working, only just got my head around it after watching a few videos.
 +
 +
Where kinefx is concerned, forget what you know about vops. Paralellism, magic of all-things-at-once, stop it. The default mode of rig vops is closer to maya rigging with the network editor, or hypershade if you're old like me... remember hypershade?
 +
 +
The biggest clue here is that it's set to detail mode by default. Why? Well in a 'proper' character rig context, you're doing specific things to specific parts of a character. Eg:
 +
 +
*Make a [https://www.sidefx.com/docs/houdini18.5/nodes/vop/kinefx--solveik.html 2 bone ik solver].
 +
*Make a [https://www.sidefx.com/docs/houdini18.5/nodes/vop/kinefx--reversefoot.html reverse foot setup].
 +
*Make a [https://www.sidefx.com/docs/houdini18.5/nodes/vop/kinefx--realisticshoulder.html clavicle/shoulder correction rig].
 +
 +
Rig Vops are designed for these kind of operations; joint specific stuff that's more finnicky than sops, but doesn't involve running on every joint in parallel.
 +
 +
Easier to explain with an example.
 +
 +
==== Floating parent constraint ====
 +
 +
[[File:rig_vop_parent_paul_small.gif]]
 +
 +
Download hip: [[File:kinefx_rig_vop_parent.hip]]
 +
 +
Fancier rigs in Maya or Houdini might have bones parented to other bones, but not via a straight parent/child bone link. Maybe its a null in between, or a group, or a parent constraint. All fine if you're dealing with obj style transforms, but how can you replicate this in kinefx if ultimately its all about points and lines and how they're connected?
 +
 +
In this example I've parent constrained some bunny ears to Paul. Animating Paul is not interesting, nor are modelling the ear or their lag animation (though I quite like it), whats interesting is the workflow to setup the constraint animation.
 +
 +
First, lets get the rig vop and viewport ready:
 +
 +
# Make a rig vop
 +
# Connect the ears to the first input, Paul's skeleton to the second
 +
# Set the display flag to the vop, hit enter in the viewport to active its state (the joints should get dots), dive inside.
 +
 +
Now imagine you're back in Maya, about to make a ribbon ik or something. You'd drag joints from the viewport or outliner into the network, add some other nodes, wire it all up right? ''It's the same here!''
 +
 +
# Drag the head joint into the vop network. Yes really. It will make you a 'get_transform' vop for the head.
 +
# Click the root of one bunny year. It splits in 2. Drag the upper one to the viewport, above the head transform vop. This will make a 'get transform' for the ear.
 +
# Click the root of the ear again, it splits, this time choose the lower dot. Drag it in and put it over on the right, this will create a 'set transform' for the ear.
 +
# Make a 'parent constraint' vop, put it in the middle.
 +
# Setup the inputs; Connect ear xform to xform, head xform to newparent
 +
# Setup the outputs; outxform to the xform of the setTransform on the right, ptnum from the ear gettransform to pt of the settransform.
 +
# click 'update offset' to set the offset of the ear to the head
 +
 +
Done! See? Feels very 'I'm rigging in Maya'. Repeat for the other ear, hey presto, parent constraints.
 +
 +
Why did selecting and dragging the head just work, while the ear gave an option? Well, the head is from the second input. If you know vex and vops, that means its read only, so you it'll just give the option to read its transform. The ear is connected to the first input, meaning you could set or get attributes, hence you get the choice.
 +
 +
Quick gif summary:
 +
 +
[[File:rigvop_parent_process.gif]]
 +
 +
==== Misuse of a rig vop in point mode ====
  
 
[[File:rig_vop.png]]
 
[[File:rig_vop.png]]
  
If you're using the rig vop to do the kind of tricks I do in wrangles, make sure you set the mode to 'point' on the top of the vop network, it's set to detail by default.
+
The above tip shows how rig vops are meant to be used, but say you wanted to pooh-pooh all that work, and do the crazy 'work on all the things the same way', like the silly bendy tentacle trick I'm so fond of. You can do that, just change the mode from 'detail' to 'point' on the top of the vop network.
 +
 
 +
Note that because you'd likely require several bind and bind export vops to get transforms, parents, whatever else, you can use the  '''getpointtransform''' and '''setpointtransform''' vop nodes instead. They're convenience vops to help you get and set what you need, while also having a handy passthrough for the point number, to help make the networks a little tidier. Nice.
  
Also when you're inside use the '''getpointtransform''' and '''setpointtransform''' vop nodes. They're convenience vops to help you get and set what you need quickly instead of needing a lot of bind and bind export vops. Also note it has passthrough for the point number, to help make the networks a little tidier. Nice one kinefx team.
+
Also note that rig vops have a lot of python under the hood for the view state stuff (so you can see joints from all the inputs, the drag-n-drop stuff). This can get confused if you happen to wire inputs that aren't joints, and the node will complain and error annoyingly. If this happens, you can go to the rig tab at the top of the rig vop and turn off 'compute transforms for input #N', for that particular input.

Latest revision as of 23:59, 11 April 2021

Kinefx

Overview

Kinefx covers a lot of ground, but there's a pleasing DNA share with a lot of established houdini workflows. It also makes a point to seperate a few rigging and animation concepts which other packages tend to merge together. More explainations below, but at a high level:

Joints

As you think they are, joints or bones like in other packages. They're represented as points and lines in sops (unlike Houdini's old bone system which was up at the /obj level), so that allows for some interesting joints vs sops vs geometry interplay.

Skinning

The act of binding a mesh to joints. This is all assumed to be done on a static skin mesh and a static skeleton, and note that it doesn't actually move the skin, it just sets up weighting attributes. The actual moving is done via...

Deformation

Given a skin with weights, and a bind pose (called a rest pose in Houdini) and a moving set of joints, move the skin. But how do you move those joints?

Rig

I said 'high level', but this is one of the biggest conceptual changes of kinefx rigging vs other systems, it needs more words...

A rig is way to move joints around. Self evident, sure, but spend some time thinking about this.

If joints are just points like everything else in sops, you could use a transform sop to move them around. And just like everywhere else in sops, if you do this, its totally freeform; it won't care about the lines between the points, or the connectivity, do what you want, use an edit sop, soft transforms, fine. That's a rig.

It's likely that you'll want to maintain the relationships between your joints though. So if you rotate a shoulder, the elbow and wrist and hand joints should rotate too. A Rig Pose sop gives you this, its a transform sop that is aware of joints, and gives you FK abilities. So a rig pose sop is a rig.

But you probably want IK too right? Well what do you need at the minimum for IK, a skeleton and a IK target? Well lucky for you there's an IK chains sop, give it those inputs, you get your IK. So the IK chains sop is a rig.

'Wait a sec, if this is houdini, and sops has great vex and vops support, and kinefx is in sops... can I use vex and vops in rigs?' Why yes you can! A Rig Wrangle and a Rig Vop are designed for this, giving you manipulation of points which is skeleton hierarchy aware. So vex and vops are also rigs.

And there's more, like foot roll vops, and FBIK sops, and skeleton blend sops etc. Rigs are sops.

Sop modelling vs sop rigging

Quick aside to talk about sops for modelling.

In sops for modelling, you chain nodes together, and geo flows and gets modified from one node to the next.

If you have a 'live' modelling chain of box, polyextrude, bevel, smooth, copytopoints, you generally don't expect to see all those controls on screen at once. You select each node, do a thing, go to the next node. If you DO want a master control, you have to wire them up to a controller null, or make an HDA and expose all the controls at the top.

Now lets do a search and replace on the above statement, for how kinefx operates:

In sops for rigging, you chain nodes together, and animation+joints flow and get modified from one node to the next.

If you have a 'live' rigging chain of skeleton, rig pose, FBIK, foot-roll, you generally don't expect to see all those controls on screen at once. You select each node, do a thing, go to the next node. If you DO want a master control, you have to wire them up to a controller null, or make an HDA and expose all the controls at the top.

Breaking that down, each node does its one particular operation, and passes its modified animation to the next node. This is exciting in that the rigging process itself can now be procedural, freeform, as exploratory as sops allows you to be.

It's also a quite a paradigm shift, as animators generally DON'T want this, they want their uberrig with fk/ik/fbik/spaceswitch/bendybone/layering crazyspace, and then complain the rig is too slow.

This ability to do true modular rigs, approach animation as a node based layering of motion from one node to the next, is gonna take some time for people to get their heads around.

Motion clips

Take some motion, like a skeleton walk cycle, and 'freeze' it so you see all the frames in one hit. This is a motion clip. Now that it doesn't have any animation, but is just a collection of shapes, you can apply modelling operations to it, delete shapes, duplicate it to make it run longer etc. You then run it through a 'motion clip evaluate' to convert it back to animation.

This covers similar ground to what chops does (the idea of swapping time for modelling and back again), but much simplified, and staying in comfortable sops land.

Right, enough overview. Lets move onto details!

Rig vs deformation

Or the alt title "Why doesn't my character move when I load it?"

Unlike most other 3d apps, kinefx defines a clear split between rigging and deformation. What does that mean? If you grab an fbx from Mixamo and load it into any other app, you'll see the character moving.

In Houdini, you'll see this:

Paul rig.png
60fps gif of complex dance. Damnit Paul, move!

If you connect a null to the last output you'll see the bones dancing away, but to actually see Paul shake his booty, you need to connect a bone deformer sop, which as implied, deforms the skin, using the skinweight attributes on the points, with the bone animation.

Paul rig2.png
Shake it Paul!

Oh wait a sec, there's no anim defined in this. Silly me. If I animate the bones with say a rig pose (similar to a transform sop, but designed to work with kinefx joints and respects parent/child relationships), he'll move:

Paul flail.gif

Or better, swap for some mocap I saved in another fbx:

Paul twerk.gif
No words for such beauty.

'Yes yes, but why all this hassle?' Well quite often you don't need to see the skin deformation. Eg if exporting to a game engine, you save the skin weights and the joint animation to fbx, but you don't need to pay the cost of the expensive skin deformation. The updated fbx export rop has you covered:

Paul fbx export.gif

Or if you're gonna do a crowd, then you export the skin+rig+animation through a different agent process. The separation of deformation from rig seems needless at first, but it's actually quite powerful, and opens the door to whole new ways of processing and applying animation procedurally.

Motion clips

Use Houdini for long enough and you get very attuned to time dependency; do your nodes need to recalculate every frame, or can they just cook once? Knowing how to control this becomes an important trick for efficient setups.

But here we are on the Kinefx wiki page, surely 'kine' implies motion, there's nothing to be done right?

WRONG!

Kinefx steals a trick from chops, and lets you freeze all the frames of an animation into a static moment, called a motion clip.

Motionclip01.gif

Now that this is done, we can do whatever silly modelling operations we want, treating it like a big bunch of curves (cos its a big bunch of curves). When done, we can convert it back to animation with a motion clip evaluate.

Motionclip02.gif

What's cool is that you can do quite drastic modelling operations to the motionclip. Delete frames. Delete entire limbs. Apply smooth operations. Swap from each-frame-as-a-skeleton to each-bone-as-a-motion-path, do stuff, swap back. Super powerful stuff. Chops always had the promise of 'treat time as a modelling operation', but never really delivered, this delivered. It's also worth pointing out it's not limited to kinefx rigs, lots of potential here!

Some ideas to think about:

  • Transporting hips with animation has always been tricky unless you can take bgeo sequences or alembics with the hip. Now you can convert to a motionclip, and stash it in the hip.
  • Fix ground intersections with a modelling operation; convert stuff to a motion clip, ray stuff to the ground, convert back

Localtransform and kinefx wrangle

For me one of the most exciting things is the core ability to treat curves as joint chains. I've experimented with doing this in the past (see CurveUnrollTutorial ), but it's quite a lot of work. Now all that stuff comes for free!

When you get into kinefx, the sections of a line are treated as joint chains. Each point gets a @localtransform matrix4 attribute. If you rotate it, it is treated as a FK rotation in a joint chain, ie, rotate the elbow, and you'll have the wrist, hand, fingers all come along too in a FK style.

This means if you animate all the rotations of all the joints, you get easy wiggly waggly setups. So:

  1. Make a line with 10 segments
  2. Append a skeleton sop which will create @localtransform for you
  3. Append a rig wrangle
  4. Try something like this:
rotate(4@localtransform, @Time, {1,0,0});

When you scrub the timeline, you'll see the line curl up as each 'joint' is rotated over time. What if you increase the amount of rotation from the start to the end of the curve?

rotate(4@localtransform, @Time*@ptnum*0.1, {1,0,0});

or drive with a sine wave and tweak the values a bit?

rotate(4@localtransform, .2*sin(-@Time*3+@ptnum*0.2), {1,0,0});

or just be really silly, do this, and copy some lines to a sphere:

rotate(4@localtransform, .4*sin(rand(@primnum)-@Time*2+@ptnum*.05), vector(curlnoise(@P+rand(@prinum)+@Time*0.2)));

Kinefx starfish.gif

Download hip: File:kinefx_starfish.hip

Proper rotation in a rig wrangle with prerotate

Much thanks to Stephan Walsch and Henry Dean for this one.

Short version: When rotating @localtransform attributes in a rig wrangle, use prerotate() instead of rotate().

Long version:

The previous wrangle trick works fine for lots of joints, but if you use want to rotate a specific joint in a wrangle like a rig pose does, it behaves unexpectedly. Here's a simple root/middle/tip 3 joint chain to represent a shoulder/elbow/wrist. If I use a rig pose to select and rotate the elbow, it behaves as expected; the joint itself rotates, the wrist comes along for the ride:

Rigpose rotate.gif

To replicate that in a rig wrangle, I'll use the rotate() vex function:

vector axis = {1,0,0};
float angle = radians(ch('angle'));
rotate(4@localtransform,angle, axis);

If I run this in points mode so it applies to all the joints, the arm curls up as expected:

Kinefx wrangle rotate.gif

But if I limit it to just the elbow (ie point 1), it doesn't behave as expected; it rotating everything from the shoulder!

Kinefx rotate joint1.gif

If I make it just animate the wrist (joint 2), it looks correct at first glance:

Kinefx rotate tip2.gif

But look closely, the elbow is wrong. Yes it's staying in the right location, but it's also not rotating (the axis handles aren't moving). More importantly, we shouldn't have to employ tricks like "if you want to rotate the elbow in a wrangle, remember to select the wrist", that's crazy.

Luckily the fix is simple. Go back to rotating the elbow and instead of rotate(), use prerotate():

Kinefx prerotate.gif

Why? It's easier to play with than to explain in words, but its a combination of how matricies combine, and how they're defined, and how kinefx applies joint transformations.

First, when combining matricies, order is important. If matrix A represented 'move forward 1 unit' and matrix B represented 'rotate 45 degrees right', multiplying those matricies will combine them, but AxB will look different to BxA:

Kinefx matrix order.gif

Secondly, a matrix could be defined in worldspace, or defined in relation to other matricies. The kinefx @localtransform matrix is the latter, it's describes each joint rotation relative to its parent. That means if you use rotate() on localtransform, it too rotates relative to the parent. Hence rotate() on the elbow ended up rotating from the shoulder.

The prerotate() vex function does as the name implies, it applies the rotation to the matrix first. Ok, but first compared to... what?

Well, a key job of a rig wrangle, a rig pose, a rig vop etc is to update the positions of the joints, ensuring transforms of parents are passed to children. By pre-rotating, the matrix of the joint you specify is rotated first, then when the rig pose updates transforms, it then gets moved to the right position relative to the parent.

Interestingly as a bonus aside, I happened to look at the help for the rig pose node, and it explains how you have a choice per animation to work in premult or postmult modes, and check it out, the default mode is premult, so this actually aligns with what I've just learned about rotate vs prerotate in vex. Go figure.

https://www.sidefx.com/docs/houdini/nodes/sop/kinefx--rigpose.html

Rigpos premult.png

In other words, if things are behaving strangely, use prerotate. :)

FBIK

Kinefx fbik.gif

Download hip: File:kinefx_fbik_hips.hip

Not sure if this is the right way to use it, but its fun.

Bring in a rig, here I've loaded mocapbiped3, chose a walk, and imported it with the scenecharacterimport node. Split off the feet and hips, move the hips, feed those to the second input of the fbik sop, and the original rig to the first input.

FBIK will do its best to push the rig to match the positions of the bones you specify.

It's not perfect, things like knees will wobble everywhere, but like I said, its fun.

The two things everyone notices when you first do full body ik is that the ankles don't lock, and the hips often don't track well with the target hips. To fix:

  • Add a configure multiparm, select the ankles, give them a higher weighting, say 10.
  • The default damping of 0.5 is often too high for the hips, so the system is trying to blur/soften the overall solve, which means the hips don't hit the pose you want. Try lowering damping until the hips track better.

Also for you young folk, Shynola did a fantastic take on this vector skeleton style for Beck 17 years ago! SEVENTEN YEARS, OH GOD I'M OLD: https://www.youtube.com/watch?v=RIrG6xBW5Wk

Proximity skinning

Kinefx skin.png

Download hip: File:kinefx_skin_simple.hip

The launch docs gloss over this a little bit, you can work it out by reverse engineering some of the later examples.

Captureproximity sop is what you want. Geo to the left, rig to the right, feed that and your animated skeleton to a bone deform.

Play with the weights tab on the capture proximity to boost the number of influences, smooth out the reuslts.

If you want to refine the weights, use a capturelayerpaint.

Kinefxcapturepaint2.gif

Biharmonic skinning

Kinefx biharm screenshot.png

Download hip: File:kinefx_biharmonic_skin.hip

Several people asked 'Why did you do proximity skinning? Why not biharmonic?' The answer was 'I didn't know how'.

Luckily several nice people shared their setups, so here it is, and the results are impressive. No wonder everyone thought I was silly.

I'm trying to commit these steps to memory:

  • Make your skeleton and a reasonably high res skin
  • BoneCaptureLine to define capture regions for the joints
  • Tetembed, skin to first input, capturelines to second; this creates the tet mesh and weightings
  • BoneCaptureBiharmonic, skin to first input, tetembed to second, this transfers the weight to the skin geo
  • BoneDeform, previous node to first, skeleton to second, skeleton via rigpose to third

Manually drawing a skeleton

The skeleton above was drawn directly in the skeleton sop, it has lots of options to help you draw joints, mirror them, constrain to planes or inside geo etc, detail are in the sidefx docs.

Skeleton sop hotkeys.png

Take 2 mins to go over the shortcuts and various modes, its pretty good fun. In the mp4 I'm doing the following:

  • Mostly in 'freehand' mode to click-click-click the core hips-to-head joint chain
  • Hit enter to swap to edit mode, tweak on, child compensate on, drag on joints to fix placement
  • Select a joint, hit enter again to draw arm, leg, tail
  • r.click, split to create elbow
  • select shoulder/elbow/wrist, r.click, mirror and duplicate to create opposite side.

Rig from labs straight skeleton

Kinefx straight skel.png

Download hip: File:kinefx_straight_skeleton.hip

Takes a bit of cleanup, but it works. The key thing is for the curves to have their orientation correct, ie if you were to follow the vertex ordering, the joints must flow like joints. No child joints pointing back up to the root or backwards joints, most of the errors I had were due to this.

A fix here after chatting with Henry Dean is to select the 'hips', use edge transport to calculate distance to the hips, sort by that distance attribute, and polypath to force a rebuild of the vertex order based on point/prim order.

Rig doctor to help debug curve direction

Kinefx rigdoctor parent to child.gif

When you get warnings of cycle errors, that implies some of your curves are backwards. Append a rig doctor, turn on 'show parent to child', and you'll see a little arrowhead to show how the curves are flowing. Red is bad. In the gif the red arrows appear if I take the resampled straight skeleton. The good one is using the edge transport, sort, polypath trick outlined above.

Procedural weights

Kinefx procedural weights loop.gif

Download hip: File:kinefx_procedural_weights.hip

Skinning sounds like an artist thing yeah? All that falloff stuff and painting weights? Ew. You left all that behind when you joined the houdini party.

If you know ahead of time exactly what your weights are, you can 'fake' what the capture proximity sop does through vex. It's a little tricky, Edward Lam from SideFx gave some great pointers here.

The weight attributes made by capture proximity are awkward to manipulate with vex, so there's 2 helper sops, capture pack and capture unpack to convert stuff into vex friendly attributes and back again.

This setup fakes what the capture unpack node does, creating arrays of the joints and their weights per point. It also creates a tricksy detail attribute used by some skinning related nodes.

There's 2 setups in here, the first takes some circles, makes the same number of joints, and procedurally weights the skinned circles to the joints and wiggles them.

The second setup could potentially be more interesting (but ultimately does what the labs rigid bodies converter does if you need a full solution). It takes packed animation, creates a joint for each, transfers the packed animation to joint animation, and skins the unpacked shapes back to the joints. It's slightly off, you can see the cubes are rotated 45 degress compared to the packed source, something I'll need to work on.

Noël Froger noticed the misalignment that happens in the conversion, and kindly offered a fix. He adds:

In the RigDoctor sop enable 'Convert Instance Attribute' as well as 'Initialise Transform'. And before that you have to use the packed intrinsic transform to generate orient.

Fix orient.png

Thanks Noel!

Kinefx to agents to lops to arkit

Kinefx arkit.gif

Download hip: File:kinefx_to_agents.hip

First, a series of yay/boo points to build tension:

  • ARKit on iOS uses USDZ.
  • Houdini can export USDZ!
  • ARKit doesn't support arbitrary shape animation.
  • ARKit does support skeletal animation!
  • USDZ doesn't support arbitrary standalone skeletal animation.
  • USDZ does support USDSkel, which was originally designed to handle crowds!
  • Houdini can export crowd agents to USDSkel via Lops!!

Exciting right?

This hip takes the previous animation, defines an agent from the static rig joints, imports the skinned geo to the agent, creates a motion clip from the rig animation, attaches that to the agent, and exports that to lops.

Like the previous example there's a few rough edges I want to sort out, but it's almost there. Again thanks to Edward Lam at SideFx for helping with some of the tricky details. In particular the line earlier about 'tricksy detail attributes'? This is where it's used; the agent sop requires that attribute.

Rig vop

So this is a new way of working, only just got my head around it after watching a few videos.

Where kinefx is concerned, forget what you know about vops. Paralellism, magic of all-things-at-once, stop it. The default mode of rig vops is closer to maya rigging with the network editor, or hypershade if you're old like me... remember hypershade?

The biggest clue here is that it's set to detail mode by default. Why? Well in a 'proper' character rig context, you're doing specific things to specific parts of a character. Eg:

Rig Vops are designed for these kind of operations; joint specific stuff that's more finnicky than sops, but doesn't involve running on every joint in parallel.

Easier to explain with an example.

Floating parent constraint

Rig vop parent paul small.gif

Download hip: File:Kinefx rig vop parent.hip

Fancier rigs in Maya or Houdini might have bones parented to other bones, but not via a straight parent/child bone link. Maybe its a null in between, or a group, or a parent constraint. All fine if you're dealing with obj style transforms, but how can you replicate this in kinefx if ultimately its all about points and lines and how they're connected?

In this example I've parent constrained some bunny ears to Paul. Animating Paul is not interesting, nor are modelling the ear or their lag animation (though I quite like it), whats interesting is the workflow to setup the constraint animation.

First, lets get the rig vop and viewport ready:

  1. Make a rig vop
  2. Connect the ears to the first input, Paul's skeleton to the second
  3. Set the display flag to the vop, hit enter in the viewport to active its state (the joints should get dots), dive inside.

Now imagine you're back in Maya, about to make a ribbon ik or something. You'd drag joints from the viewport or outliner into the network, add some other nodes, wire it all up right? It's the same here!

  1. Drag the head joint into the vop network. Yes really. It will make you a 'get_transform' vop for the head.
  2. Click the root of one bunny year. It splits in 2. Drag the upper one to the viewport, above the head transform vop. This will make a 'get transform' for the ear.
  3. Click the root of the ear again, it splits, this time choose the lower dot. Drag it in and put it over on the right, this will create a 'set transform' for the ear.
  4. Make a 'parent constraint' vop, put it in the middle.
  5. Setup the inputs; Connect ear xform to xform, head xform to newparent
  6. Setup the outputs; outxform to the xform of the setTransform on the right, ptnum from the ear gettransform to pt of the settransform.
  7. click 'update offset' to set the offset of the ear to the head

Done! See? Feels very 'I'm rigging in Maya'. Repeat for the other ear, hey presto, parent constraints.

Why did selecting and dragging the head just work, while the ear gave an option? Well, the head is from the second input. If you know vex and vops, that means its read only, so you it'll just give the option to read its transform. The ear is connected to the first input, meaning you could set or get attributes, hence you get the choice.

Quick gif summary:

Rigvop parent process.gif

Misuse of a rig vop in point mode

Rig vop.png

The above tip shows how rig vops are meant to be used, but say you wanted to pooh-pooh all that work, and do the crazy 'work on all the things the same way', like the silly bendy tentacle trick I'm so fond of. You can do that, just change the mode from 'detail' to 'point' on the top of the vop network.

Note that because you'd likely require several bind and bind export vops to get transforms, parents, whatever else, you can use the getpointtransform and setpointtransform vop nodes instead. They're convenience vops to help you get and set what you need, while also having a handy passthrough for the point number, to help make the networks a little tidier. Nice.

Also note that rig vops have a lot of python under the hood for the view state stuff (so you can see joints from all the inputs, the drag-n-drop stuff). This can get confused if you happen to wire inputs that aren't joints, and the node will complain and error annoyingly. If this happens, you can go to the rig tab at the top of the rig vop and turn off 'compute transforms for input #N', for that particular input.