Jump to content

Importing bvh mocap losing bones


rangi

Recommended Posts

Hi all,

I'm playing around with some .bhv biovision motion capture files and bringing them into houdini. I may be missing something obvious but it seems to be losing the last bone at the end of each heirachy branch...

In the .bvh file it describes a tree of joints listed as:

LeftHip -> LeftKnee -> LeftAnkle -> End site

Each of those joints has an offset which is essentially the bone length.

I run the mcbiovision program over this .bvh and cmdread the generated .cmd file. The script creates the bones that connect the joints as:

Hips_To_LeftHip -> LeftHip_To_LeftKnee -> LeftKnee_To_LeftAnkle

And the correct animation (rotation) channels are read in through the .bclip and exported from chops to these bones. All good. Except, I'd expect another bone called something like LeftAnkle_To_EndSite, which would be the foot. It would have the rotations of LeftAnkle from the .bvh file.

I think I could write a perl script to add an extra bone at the end of each chain in the .bvh file, as well as buffering the channel data lines. But I don't want to go to that hassle if it's a simple bug or I'm using the script incorrectly.

The heirachy the cmdread creates is the same if I use noK, FK or IK.

Anyone else been here?

Beers,

Rangi.

Link to comment
Share on other sites

hey rangi,

unfortunately, i can't help you out a ton but from my own impression, i don't think you're losing a bone.. i've been messing around with some bio vision mocap files in houdini and not a single one i've tested out has an end foot controller.. nor do they have hand controllers either.. legs end at the ankle.. arms end at the wrist..

(using houdini's mcbiovision as well to convert and then sourcing in the cmd file.. )

but yea.. apart from that i can't help much, but i'm begining to think that this might be standard for a biovision mocap setup...? i mean, i've gone through a handful of them to play around with and they are all the same general rig setup.

hth,

dave

Link to comment
Share on other sites

as a side note, a couple of these .bvh's i've been testing seem to have glitches in the animation.. by glitches i mean a bone here and there might flip out for a frame or two. So basically you see flashes of sporadic movement within the general "correct" movement of the figure. if i go and check out the channels of each bone in chops (sourced from the .bclip), i can see the specific channels jump over the course of a frame.

i'm not completely shocked as i'm sure most mocap data is not perfect and some editing must be done, but i was hoping to be able to maybe smooth it out easily within chops. so far i've tried a mixture of things from resampling the channels in chops to filtering them with all different kinds smoothing types and settings.. but alas, nothing has done much without affecting the "correct" movements too much.

So after all this, my question is: is there any methods/operators i may be overlooking that could help with this spiking issue or should i get my hands ready for some manual editing?

thanks everyone,

dave

Update:

Ok, i've been messing around with it a little more and thought of a possible way to do this. What I came up with was to take the slope (derivative) of the glitchy mocap channels. This easily pointed out the places where spikes occured (obviously because things that spike have a massive slope). Then with some use of the limit chop and and filtering chop, i was able to bring those guys down and ease them in and out a little better.. so then i figured to get back to the original position data, i should just take the area (integral). so i go ahead and do that and don't have much luck. it's just not working.

so i go ahead and bypass the limiting and filtering and just have the original mocap channels go through the slope and then the area. according to my understanding of good old high school math, the channels viewed at the area chop should be exactly the same as the original mocap channels.. but for some odd reason they are offset from eachother.. and it seems to be offset by different amounts per channel.. i would have thought just taking the derivative of something and then the integral of it would just put me back to the begining.. i'm thinking it might have to do with "reseting the area back to zero" through the second input.. but i can't seem to wrap my head around that just yet.

anythoughts would be appreciated..

also, if any admins want to move my thing to a whole new thread, then go right ahead.. i had no intentions to steal the attention away from rangi's original problem..

thanks..

Link to comment
Share on other sites

Hmm ... to solve the rotation popping problem, try just inserting a Transform CHOP before the null chop named data. Change the default Rotation Order in the first tab from RX,RY,RZ to RZ,RY,RX to match the bones.

16999[/snapback]

while changing the rotation order didn't work, just appending a default transform chop did the trick. must of been out of whack and just needed rotation orders to be set in the first place..

nice one ed.. thanks a bunch..

Link to comment
Share on other sites

Hi Dave,

I'm sure I'm losing a bone. I've pulled the same .bvh file into Motionbuilder and it has hands and feet. Currently I'm trying to add an extra sacraficial bone at the end of each branch while inside motionbuilder and then export it again to pull into houdini. Some mixed success, I now have the feet, hands and head animation appearing in houdini but I'm losing the translation of the root.

This is a problem of my lack of motionbuilder expertise and the way .bvh files only really do one transform and that has to be the root node. MB seems to be adding a new root with no translation, and that's the channels it's exporting.

WRT your bone popping.. make sure that your file chop fps are the same as what you are playing. A lot of mocap data I've been looking at is fine on integer frame values. ie. the same end rotation can be found using different eular rotations, but they can't be blended.

This problem goes away when you use the -i flag when calling mcbiovision. The rotation data is all converted to translation applied to nulls, each bone is controlled through FK (single link IK). Sub-frame blending is now performed on a translated object rather than eular rotations. This isn't the end of the story, however, because we need to twist the bone as well. There is some functionality for this in the mcbioconvert script but it seems intended for multiple bone IK.

Of course if the mocap data is just plain dirty then it's gotta be cleaned up. The Chops techniques you're looking at I'm just beginning to investigate, so maybe more on that later.

Cheers,

r.

Link to comment
Share on other sites

while changing the rotation order didn't work, just appending a default transform chop did the trick. must of been out of whack and just needed rotation orders to be set in the first place..

nice one ed.. thanks a bunch..

17001[/snapback]

Oh oops ... hmm ... Maybe you also need to change the transform order in the second tab to be RZ,RY,RX as well. I guess a default Transform CHOP works because we're not doing any real transforming so it works as long as the two of them match.

Just in case anyone is interested, using a Transform CHOP will sometimes magically fix euler rotation problems because it always does this "smoothing" post-pass on the rotation channels. For the mathematically inclined, multiple euler angle combinations can represent the same orientation (or rotation matrix). So when one converts a rotation matrix into euler angles, there are multiple solutions to choose from. The best solution is usually the one that is closest to the orientation from the last frame. So what the Transform CHOP does is create a rotation matrix from the euler angles at each frame, and then convert it back to euler angles, but choosing the one that is closest to the orientation in the previous frame.

Link to comment
Share on other sites

I'm sure I'm losing a bone. I've pulled the same .bvh file into Motionbuilder and it has hands and feet.

ahh, i see.. hmm.. will look and see if i can dig in to anything.. i would be curious to bring the bvh's i have in to something else and see if they were actually supposed to have hands and feet as well.. if you could post the mocap file, maybe one of us around here will be able to discover something.. but i highly doubt that you would be able to post something like that.. :rolleyes:

WRT your bone popping.. make sure that your file chop fps are the same as what you are playing.

yup, that's exactly what was going on.. very odd because i could of sworn that was the first thing i checked/tried.. but hey, it's late, i could of thought i did a lot of things i really didn't do...

edward: good to know.. thanks for that bit of info..

thanks guys for the help. hopefully something can be figured out for your situation rangi..

Link to comment
Share on other sites

The best solution is usually the one that is closest to the orientation from the last frame. So what the Transform CHOP does is create a rotation matrix from the euler angles at each frame, and then convert it back to euler angles, but choosing the one that is closest to the orientation in the previous frame.

Cool... That's a great tip. I'd been thinking to turn it into IK chains then bake out the eular rotations again, but this does it. It's easy to underestimate CHOPs.

if you could post the mocap file, maybe one of us around here will be able to discover something..

Well, let's take this as an example since it's lean and clean: Biovision BVH Parsing. Download the Example1.bvh from there. It's only got two keyframes and a reasonably simple heirachy so useful for this. The page is a good description of .bvh as well.

There's some confusing stuff houdini does inside of mcbiovision. Just looking at channel counts, there's 57 channels described in the .bvh, we end up with 54 channels in the .bclip. At first glance the Hip seems to be losing it's rotates, but I think there's something going on where it's pushing those rotates down the heirachy one step. There is probably some good sense there but it does confuse the issue.

I was expecting to have something like 57 channels in the .bvh and only 42 in the .bclip, losing 3 channels from the end of each branch. Maybe this discrepancy is different because mcbiovision is splitting channels up? Adding 3 to the beginning of each branch, but losing one at the end....

Anyway, parsing the .bvh file by eye we can see that we have:

ROOT Hips
{
	OFFSET	0.00	0.00	0.00
	CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
	JOINT Chest
	{
  OFFSET  0.00  5.21  0.00
  CHANNELS 3 Zrotation Xrotation Yrotation
  JOINT Neck
  {
 	 OFFSET  0.00  18.65  0.00
 	 CHANNELS 3 Zrotation Xrotation Yrotation
 	 JOINT Head
 	 {
    OFFSET  0.00  5.45  0.00
    CHANNELS 3 Zrotation Xrotation Yrotation
    End Site 
    {
   	 OFFSET  0.00  3.87  0.00
    }
 	 }
  }

If we consider the OFFSET keyword to essentially be describing a bone and it's length then we would expect a bone chain of four, with these names and bone lengths

Hip_to_Chest : 5.21

Chest_to_Neck : 18.65

Neck_to_Head : 5.45

Head_to_End : 3.87

They should each have a rotation.

mcbiovision stops at Neck_to_Head, Head_to_End is simply never created.

I haven't had time to play more with Motionbuilder and adding sacraficial limbs, still at the stage of having difficulty exporting a sane .bvh file.

I think it might be simplest to write a whole new parser. To save on re-inventing the wheel does anyone have any code kicking around? I think these little standalone apps are very low down on the sidefx developers priority.

Beers,

Rangi.

Link to comment
Share on other sites

hey rangi,

i'll check out those things maybe a little later.. kinda pressed right now..

until then, i came across this perl script to get bvh in to a mel script.. maybe you can get it out of maya better then MotionBuilder.. i don't have maya in front of me right now, so i can't test.. but who knows..

http://accad.osu.edu/~mlewis/Mocap/

hth,

dave

Link to comment
Share on other sites

hey,

just compared that example1.bvh to it's bclip generated from mcbiovision.. and you're absolutely right.. it's definitely dropping out that last bone from the use of the 5 end site's...

very wierd.. maybe edward might be able to comment on what's going on...?

another thought.. you mentioned earlier that MB was seeing these bones correctly, it was just recreating a new root and thus you were losing the transformation of the original root.. could you get the MB data out to houdini for all the rotations.. then use mcbiovision to get the data into houdini through the bclip.. then maybe could you utilize the MB rotations in collaboration with the correct root translation in the bclip, all within houdini?

Link to comment
Share on other sites

I asked and apparently the initial files Biovision gave to SESI had redundant bones on the ends of each bone chains and so that's why mcbiovision is dropping the ends intentionally. RFEs should be sent to support (erm, I mean ... "not me" :) ).

Link to comment
Share on other sites

Hey,

I pulled apart a perl .bvh parser with the intention of building a houdini one from scratch... too big a project to include all the funcitonality of mcbiovision. Instead here's a hack to add a redundent bone using the offset described for the End Site.

Sidefx Exchange: bvhpad.pl

Not the most stable script in the world. Falls over if there's a leading space, such as in the Example1.bvh we've been looking at.

Line 50 has a shift(@p) which should be run if @p == " ". How do I do that in perl? Must be simple...

Anyway, my ballerina is now up on her toes and my fencer has something to hold his sword with.

Ta for the help,

r.

Link to comment
Share on other sites

Me again, just chatting with myself ;p I'll stick this in the wiki when we're done.

I've been playing some more with issues of data quality. What I've been seeing on the same .bvh files in Motionbuilder have been far superior to what I've been getting in Houdini. What's happening eh?

As far as I can tell bringing it in as bones has the effect of the OFFSET parameters being baked into the rotations. So instead of having OFFSET 0 3 4 it sets a bone length of 5 and offsets the rotation in the motion channels. It is at this stage where otherwise clean mo-cap data is getting dirty with gimbol lock and multiple eulor solutions causing havok. A transform CHOP helps, but I still get joints spinning around on their axis.

Using the IK flag in mcbiovision disgards the capture's twist information! As far as I can make out at least. Useless.Could be some interest in defining twist effectors on dual chains but I think that level of setup is better to be manual created inside of houdini. It's all overhead anyways.

Bringing the data in as object joints provides much better results. This way the heirachy inside houdini much better represents the .bvh description. A joint (ie. an object, not a bone) is translated by 0 3 4 and then rotated. Much less fuss and far more stable solution. You don't need to run the pad script on this one either, because the rotation data is fed into the last joints on the chains. It's still useful to run the script if you want the sizes of the original skeleton to be represented. Delete the extra channels though (*_end:r*) as in this case they are just overhead.

At this stage I expected the results to match exactly. No... there's still sub-frame flipping.. What's happening? The (kinda) standard rotation order in .bvh is rz, ry, rx. Same as bones in houdini. For whatever reason mcbiovision converts this to ry, rx, yz. So we get flipping because fancy arse transform matrixes are being applied. Here we can get rid of the sub-frame flipping with a Transform CHOP setting the rot order to ry, rx, rz in both the Transform and the Input tabs.

Ah, I've got lovely clean mocap in houdini. But what a fuss. mcbiovision should have a tag to leave the rot order how it is. Perhaps that's what the -v "Reverse joint rotation order" is for. It seems to have no effect.

I just need to setup these geometry "joints" so that they start controlling actual bones and I'll be done.

Cheers,

r.

Link to comment
Share on other sites

Ah, I've got lovely clean mocap in houdini. But what a fuss.

hey rangi,

i completely agree.. mcbiovision should be there to take all this in to account (right bone count, correct rotation order, etc).. you should definitely RFE this to SESI so this whole process can be much more efficient and logical..the reason why i suggest you to RFE it is because you seem to have the most in depth knowledge of what is going on here.. while I'm able to follow what's going on and what you've done, i'm sure you grasp the whole thing much much better than i.

nice work on that script by the way..

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...