Crowds - more detailed info re. agents/clips?

   2071   2   1
User Avatar
Member
263 posts
Joined: Oct. 2010
Offline
Hi,

We've been trying to figure out the nitty gritty of what's actually going on behind the scenes in the new H14 crowd tools, in order to do some customisations for our pipeline here. It's great that a lot of data is accessible easily via attributes, but there are still some things that are a bit opaque and hard to fully understand.

We already have animations baked out into our own format that we have been previously been reading in and applying to our characters in houdini. These animations are already available and checked in to our own asset library, and it would be a bit annoying to have to then re-generate additional files on disk, so we'd like to be able to have a setup that's ‘live’, reading in animation with our own tools, and without having to bake out additional clip files.

So a few questions:

* I notice that when using the Input: Scene mode on the Agent SOP and pressing ‘Reload’ it seems to take the bone transformations from the rig object subnet, and ‘bake’ them to clip internally. I don't see any output files, so is this doing the same thing as an agent bake, but storing it in memory? What actually happens when you press Reload?
* If this is the case, is it possible to somehow bake multiple animation clips in memory in advance, from the one agent rig subnet, so that we can switch between clips without having to have multiple rig subnets - one for each animation?
User Avatar
Member
7734 posts
Joined: July 2005
Online
mattebb
* I notice that when using the Input: Scene mode on the Agent SOP and pressing ‘Reload’ it seems to take the bone transformations from the rig object subnet, and ‘bake’ them to clip internally. I don't see any output files, so is this doing the same thing as an agent bake, but storing it in memory? What actually happens when you press Reload?

It's as you say. In “Scene” mode, the Agent SOP does exactly as what the Agent ROP does except it doesn't save out the generated data out to disk. It just directly uses the data. When you press “Reload”, then it just does the bake again and uses the result (without saving to disk).

* If this is the case, is it possible to somehow bake multiple animation clips in memory in advance, from the one agent rig subnet, so that we can switch between clips without having to have multiple rig subnets - one for each animation?

Not without changes to the Agent SOP. This was a discussed feature but we didn't have time for it in H14.0. It wasn't clear what the best way interface for that would be. I think using “Takes” is one option to expose this functionality. I'd be happy to hear what you think would make sense.

The problem with scene mode is that it needs to cook the character for the entire length of the clip and I'm not sure one really wants to do that every time you load the .hip file. It almost sounds like it would be better to create a custom SOP via the HDK that directly sets the clip animation from your custom format into the agent primitive. A rough sketch of the code would look something like this:
void
addClip(
GU_AgentDefinition& defn,
const char* clip_name,
const CL_Clip& cl_clip)
{
// create an empty clip bound to the definition's rig
GU_AgentClipPtr clip = GU_AgentClip::addClip(clip_name, defn.rig());
// load the CL_Clip into the agent clip
clip.load(cl_clip);
// add it to the definition
defn.addClip(clip);
}
GU_Agent*
getAgent(GEO_Primitive* prim)
{
if (prim->getTypeId() != GU_Agent::typeId())
return NULL;
return UTverify_cast<GU_Agent*>(((GU_PrimPacked*)prim)->implementation());
}
void
agentSetupClips()
{
// Multiple agent primitives share the same definition. So we need to get
// definition for each different rig. In practice, you'll probably need to
// loop though all the primitives and find all the unique definitions that
// have the rigs that you want to load the clips for.
GU_AgentDefinition& defn = getAgent(an_agent_prim)->definition();
// Multiple calls to addClip for each one
addClip(defn, clip_name1, cl_clip1);
addClip(defn, clip_name2, cl_clip2);
addClip(defn, clip_name3, cl_clip3);
… etc …
}


The current problem with this approach is that you first need to marshal your animation into a CL_Clip object and then convert it into a GU_AgentClip. If we want this route to be efficient, I'll need to an API to more directly set the transforms into a GU_AgentClip.
User Avatar
Member
7734 posts
Joined: July 2005
Online
PS. I've now added a GU_AgentClip::setLocalTransforms() method for tomorrow's daily H14.0.284 build.
  • Quick Links