[Crowds] H14 extract bone and joint transforms

   3902   5   1
User Avatar
Member
763 posts
Joined: Sept. 2011
Offline
Is it possible to extract the joint information from crowd simulations?


Ideally I'm after joints with orient and position information, I can then use this data to copy contrain other data to the agents parts or possibly send the data to a third party procedural for render time skinning


Currently I can only seem to unpack the agents giving me a large poly mesh of the final skinned geo, I know the joint info is somewhere in the crowd data as the GL viewport does such a good job of viewing the joints when needed..

Please help
Miles Green, Supervising TD, Animal Logic
User Avatar
Member
7722 posts
Joined: July 2005
Offline
There's extensive list of VEX functions to manipulate the agents.
See for example:
- http://www.sidefx.com/docs/houdini14.0/vex/functions/agentlocaltransforms [sidefx.com]
- http://www.sidefx.com/docs/houdini14.0/vex/functions/agentworldtransforms [sidefx.com]

The current agent terrain adaptation for example, is done completely in VEX.
User Avatar
Member
763 posts
Joined: Sept. 2011
Offline
ah great.. that helps a lot thanks Edward.!

I now have this attrib wrangle snippet running over the packed crowd primitives that extracts the joints to points…for some reason the height of the returned points is a little offset in Y+

can I also ask can you see any quicker way code-wise, its not too bad with 2000 agents, but I'm open to suggestions

I'm assuming I can can just use another “cracktransform” call to extract the bone orients too



matrix agent_transforms = agentworldtransforms(0, @primnum);
if(len(agent_transforms)>1)
{

foreach (int index; matrix bone;agent_transforms)
{
vector pos = cracktransform( 0, 0, 0, {0,0,0}, bone);
int virtual_pointnum = addpoint(0 , pos + @P);
}

}
Miles Green, Supervising TD, Animal Logic
User Avatar
Member
1 posts
Joined:
Offline
If you need to constrain something to specific part of agent rig you can use agentrigfind.


int idx = agentrigfind(0, @ptnum, “rightHand”);

if (idx>=0) {
matrix bone_matrix = agentworldtransform(0,@ptnum,idx);
v@bone_pos = cracktransform(0, 0, 0, {0,0,0}, bone_matrix);
v@bone_rot = cracktransform(0, 0, 1, {0,0,0}, bone_matrix);
}


You can also get agent transform matrix using:


matrix agent_xform = primintrinsic(0, “packedfulltransform”, 0);


Hope this helps.
User Avatar
Member
7722 posts
Joined: July 2005
Offline
I think marcln has a good point, the +@P you're doing might be off if the primitive transform has a rotation. So the proper thing to do is to do “pos *= agent_xform” even though it's more expensive where there are no rotations.

As for cracktransform(), it's a pretty old function so I'm not sure if it's the fastest thing these days. It might be faster to pull out the translates out of the bone_matrix yourself and then use polardecomp() for the rotation.
User Avatar
Member
763 posts
Joined: Sept. 2011
Offline
thanks guys.. I finally got round to finishing it no idea what polardecomp actually does in the guts but it seems to work..

.. for anyone thats interested in doing the same this is the final code block, I also strip out rig transforms that are not named bones:



p@orient = 0;
i@agentId = @ptnum;
s@boneName = “None”;

//get agents rig transforms and names
matrix agent_transforms = agentworldtransforms(0, @ptnum);
string agent_transform_names = agenttransformnames(0, @ptnum);

//get agent transform
matrix agent_xform = primintrinsic(0, “packedfulltransform”, @ptnum);


foreach (int index; matrix bone;agent_transforms)
{
//strip out nulls and only use named “bone” joints
if(endswith(agent_transform_names,“_bone”))
{
//get pos
vector pos = {0,0,0} * bone;

//add point at joint position + add agent xform
int virtual_pointnum = addpoint(0 , pos *=agent_xform);

//get orient + add agent xform
matrix3 rotmat = polardecomp(matrix3(bone*agent_xform));
vector4 qrot = quaternion(rotmat);

int set_bonename = setpointattrib(0,“boneName”, virtual_pointnum , agent_transform_names);
int set_orient = setpointattrib(0,“orient”, virtual_pointnum , qrot);
int set_charId = setpointattrib(0,“agentId”, virtual_pointnum , @ptnum);

}
}

Miles Green, Supervising TD, Animal Logic
  • Quick Links