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
[Crowds] H14 extract bone and joint transforms
3902 5 1- _milo_
- Member
- 763 posts
- Joined: Sept. 2011
- Offline
- edward
- 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.
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.
- _milo_
- 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);
}
}
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
- marcin
- 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.
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.
- edward
- 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.
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.
- _milo_
- 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);
}
}
.. 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