Thursday 16 July 2020

Show all clips in an Agent's Clip Catalog

Here is a way of displaying all the clips in an Agent's clip catalog.



Let's say you have an agent with a number of clips already defined.
It's very useful to playblast the agent, as it plays the animation in each clip.
It's possible to manually place agents and change the clip of each agent, but that can be laborious and we want to do things procedurally, do we not?

  1. In a fresh scene, lay down a Geometry object, rename it 'Agents'. Inside it, lay down an Agent SOP node. Point Agent Definition Cache to where the Agent definition is located, so that the agent is loaded into your scene.


    All the Agent's clips will be available in the Current Clip dropdown menu.
     
  2. Drop down an Attribute Wrangle node.
    The Wrangle will create an array from the Clip Catalog.
    Then, it will create a point for each clip.
    Each point will have a string attribute, containing the name of one clip from the catolog.


    The 'addpoint' VEX function is also reading a parameter added to the Wrangle node.
    The 'seperation' parameter changes the distance between each point.
    I have decided to arrange all the points along the x-axis. This made sense for me as all my clips are aligned along the z-xais.


    The Geometry Spreadsheet shows all the points created and the string attribute 'catalogClip'.
    This attribute will be used later.

  3. Next, use a Foreach loop to place an agent on each of the points.


    The Foreach node is using 'Fetch Piece or Point' as the Method


    The Crowd Source node is reading the 'catalogClip' attribute from each point and using that string value to set the Initial State.
    Gotcha! The VEX function to do this is 'points()' and NOT 'point()'. Note well the extra 's' in the function name. This is a variation of the point() function that handles string attributes.

    To label the clips, use the Font node to generate text.




    The Font node can read data, not just text. It requires the data to be evaluated, using the back-ticks (`)
    The Font node does not take an input, so to get data into it, use a Spare Input.
    Using the cog menu at the top of the parameter pane, choose Add Spare Input.
    Drag the Block Begin node from the Foreach loop into the newly created Spare Input field.
    That allows the Font node to read data from the geometry going into the Foreach loop.
    The data we need is 'catalogClip', so the syntax to read that into the Font node is:
    `points(-1, 0, "catalogClip")`
    Here, the first parameter is -1, which tells the node to read the first Spare Input.
    The text generated by the Font node needs to be translated to the location of each point.
    The expressions in the 'origin' parameter reads the "P" attribute of each point.
    The y component of the origin is using the modulus operator (%) to stagger the position of the text to avoid overlapping text.

    If required, a line can be drawn between the text and the point, to clearly show which text comment references each Agent.



    The line node will draw a poly line from a point, in a specified direction.
    I used the same location as the Font node for the 'origin' parameter, only I raised the y-position by a small amount.
    The direction is simply (0,1,0)
    The length of the line is just the y-origin, multiplied by -1.

  4. Merge the three elements and connect the merge to the first input of the Block End of the Foreach loop.

  5. Add and Agent Terrain Adaptation node to apply foot locking.



    For this to work, an Agent Prep node needs to specify the IK chains for the legs.
    I copied the one from the Agent Definition HIP file (along with the associated CHOP Network)


Wednesday 8 July 2020

Re-Time Agent Clips using CHOPS

Here is a quick method for re-timing clips for use in a Crowd system.

If you have a clip, loaded from a FBX file directly into the Agent Clip node, that is too slow or too fast you can re-time the clip.

In my example, I have loaded a number of clips, categorised by type - I love to be organised that way and it speeds things up if you have many clips.

I have a little transition clip where the agent moves hands from the knee to the lap. The original clip os very slow, taking 65 frames to complete the actions. I need it to be done much quicker than that.
I don't want to open the clip and re-animate it, export the clip and re-import it. I would much rather re-time the clip as I am working in the Agent Definition workflow.

Here is the original clip alongside the re-timed clip for comparison

 
 

To re-time a clip:

  1. Create a new Agent Clip node, after the original clip has been loaded.
  2. Create a CHOP network node

  3. Inside the CHOP network, create an Agent node. Set the Agent node to read the node upstream of the new Agent Clip node that was just created. In my example, I created a Null just after all the Agent Clip nodes. I point the Agent CHOP to that Null.


  4. Still in the CHOP network, create a Channel CHOP, a Warp CHOP and a Trim CHOP. Connect the nodes as shown in the network above.
  5. The Warp node reads a 'curve' from it's second input and will re-time the clip depending on the value of that curve. In my case I want to speed up the clip by 3x. To do that, I set the value of the channel curve to 3. To halve the speed, set the value to 0.5 and to reverse the clip, set the value to -1. etc.

  6. Next, the clip's channels will need to be trimmed to the correct length. Using the Trim node, set the start and end points as you need them. For my case, the original clip length was 67 frames, so I set the new end point to 22.

  7. Drop down an Output node and set it's output flag.
  8. Back out of the CHOP network and set the Agent Clip node to read the re-timed clip.
    The input source will be 'CHOP' and select the CHOP network that contains the re-timed clip.

This new clip can be used just like any other clip in the Crowd setup. You can use this method to reverse clips and even ramp clip speed if you need to.