Game Development Community

Fun with BVH Files (the code)

by Chris Calef · in Torque Game Engine · 05/14/2008 (12:35 am) · 25 replies

Okay, I should know the right way to do this by now, but I have some code that goes along with the blog I just posted, and I need to put it somewhere that only Torque licensees can access. I'm going to post a link to a zip file here, since this forum is private, but it is still stored on my server at an accessible location. Hopefully that's okay.

For anyone who came here because of my blog, the files you want are here:
www.brokeassgames.com/blogs/chris/05-12-08/BVH_Resource.zip

If you want to see the blog, it is here:

http://www.garagegames.com/community/blogs/view/14732

The file called ShapeBaseCode.cpp contains new functions and console methods which can be appended to your ShapeBase.cpp, as well as a couple of function declarations at the top that need to go into ShapeBase.h.

I've also included some sample .bvh files to play with, and the default.cfg file I used for Kork. Outside of that, you're on your own, this should be enough to get you started. The bvh files have to go into a "bvh" directory right under the directory your dts model is in.

Once you load some motion capture files onto your model, you can use the "saveOut()" console method to write all sequences out to a file called "allSeq.dsq", and then change your player.cs to include that instead of all the individual dsqs.

I have yet to write the function that saves sequences out one at a time, though will probably get to that shortly.

Have fun!

Chris
Page «Previous 1 2
#1
05/14/2008 (5:48 am)
Chris, this is an amazing resource. I can't wait until I have some free time to play around with this. Now, I know I need to do some of my own research (ie go go Google), but do you know how readily available sample BVH files are? Is there a decent database containing an abundance of BVH?

Awesome, awesome work man.
#2
05/14/2008 (6:10 am)
They're pretty easy to find. We stumbled across a huge list of them that were done by some university a couple years ago. Lesko was able to get one of them working as an experiment, but that took him a while since he cleaned it up by hand and exported it in Maya.

This is an awesome bit of code, and is definitely going to come in handy. Great job Chris!
#3
05/14/2008 (6:38 am)
Would you like us to post errors with the ShapeBaseCode.cpp file? I have a stock version of TGE I keep around for integrating resources, just to provide feedback. I copied in the new methods, and got a ton of errors. I know the fixes for them, if you want.
#4
05/14/2008 (6:59 am)
Wow Chris this is an amazing resource, it may just be the one resource that could solve some problems for me once i get time to actually check it out.

Much like Micheal Perry i keep a clean TGE installed for initially intigrating resources to check them out and such.
#5
05/14/2008 (7:12 am)
//for (U32 i=0;i<kShape->nodes.size();i++)
//	Con::printf("nodes[%d] %s",i,kShape->getName(kShape->nodes[i].nameIndex));
} [b]// <---This needs to be commented out (MP)[/b]

Throughout the entire shapebase.cc, I received the following errors on multiple lines:
Quote:
ERROR 1 error C2248: 'ShapeBase::mShapeInstance' : cannot access protected member declared in class 'ShapeBase' c:\torque\tge\engine\game\shapebase.cc 4839

ERROR 2 error C2248: 'TSShapeInstance::mShape' : cannot access protected member declared in class 'TSShapeInstance' c:\torque\tge\engine\game\shapebase.cc 4116

ERROR 3 error C2666: 'dStrstr' : 2 overloads have similar conversions c:\torque\tge\engine\game\shapebase.cc 4157

ERROR 1 FIX:
Use getShapeInstance() to get access the member variable ShapeBase::mShapeInstance.
sprintf(filename,"%s/allSeq.dsq",object->[b]getShapeInstance()[/b]->mShape->mSourceResource->path);//,argv[2]);

ERROR 2 FIX:
Use getShape() to get access to the member variable TSShapeInstace::mShape.
sprintf(filename,"%s/bvh/%s.bvh",mShapeInstance->[b]getShape()[/b]->mSourceResource->path,bvhFile);

ERROR 3 FIX:
This error *usually* pops up when a resource is created using a codebase that is older than TGE 1.5. I

haven't found a fix yet, but I am looking at the function dStrstr(...) and see the issue.

dStrstr is an overloaded function:

extern char*       dStrstr(char *str1, char *str2);
extern char*       dStrstr(const char *str1, const char *str2);

So one takes 2 char*, whereas the second one takes 2 const char*.

In your functions, you are using a char* for one parameter, and a const char* for another:
if (!dStrstr(bufp,"JOINT"))
{
  ...
}

An immediate fix is to use casting:

if (!dStrstr([b](const char*)[/b]bufp,"JOINT"))
{
  ...
}

This removes the error, but I truly hate this approach. Casting a char* to a const char* just seems...wrong. I've never actually used dStrstr before, but if we are comparing 2 string can we just use dStrcmp(...) ?
When I implement dStrcmp(), the errors go away.

I'm going to try an actual test run with the new functions in the game now.
#6
05/14/2008 (7:14 am)
The above fixes were made on TGE 1.5.2
#7
05/14/2008 (8:06 am)
Found a few more bugs that were resulting in the importBVH() not loading FRAMES data. Just had to add in a few other delimiters such as "\n" and "\t".

After that, it worked beautifully. Nice work!
#8
05/14/2008 (8:32 am)
Worked beautifully as in: you were able to import a bvh? or compiled. I'm really excited to try this out :)
#9
05/14/2008 (8:33 am)
Dave - Yup. After I made the minor changes to fix the errors I was getting, I was able to import the "ballet.bvh" file and play it. Looked pretty good to me =)

I haven't posted all the problems/fixes I encountered, mainly because I'd like to hear from Chris and see if he had the same problems/fixes.
#10
05/14/2008 (8:43 am)
So, regarding the CFG, it's basically to get your rig in the same root pose as the bvh rig is.

This is the key part of the process, so is that something you do by eyeball to get the numbers which can be placed in the cfg?

Edit:

Looking at the blog again, it seems like the magic numbers in the 3rd column can be generated somehow (an included function?), and the other 3 columns are the manual tweaks necessary to get your rig into the same root pose as the bvh rig, which HOPEFULLY is in some kind of nice pose.
#11
05/14/2008 (11:03 am)
Hey y'all, sorry for those errors, submitted that stuff pretty late last night!

@Dave: the magic numbers were indeed generated somehow -- it's in the blog. If you do a search for "toEuler" you'll jump right down to it.

There are two sets of two eulers each. The first two eulers are for getting the rig into the same root pose, and the second two are for modifying the bvh rotations to deal with the bodypart local axis orientations, once you are in that pose.

I didn't have most of the problems re: getShape() etc., but using that instead of mShape is not doubt better form. I did this in a TGEA build from a couple months prior to 1.7 actually.

@Michael: thanks for the help! If you get the chance, please send your fixed version to me chris.calef at gmail and I'll update the resource as soon as I boot back into Windows.
#12
05/14/2008 (11:52 am)
@Chris - I'll go ahead and send you what I have so far.

I can now load all of the bvh files. Most of the dStrtok() calls Chris made were only checking for one delimiter:
" " (space).

I added in the following as delimiters for every dStrtok to handle spaces and common text file escape sequences: " \t\n".

Now all the bvh files will load.

Everything is looking pretty sweet...except a real monster of a bug has come out. After importing and playing an animation, console functionality dies. I can no longer type in the console...I get nothing but chode or blank characters.

If I keep going, the system eventually crashes. Back to the code :/
#13
05/14/2008 (12:02 pm)
Hm, THAT'S weird! Haven't seen that one. I do have a bug that others might notice, though, and I'd love to have help fixing. For some reason when I load a new animation, it very frequently will not play, it just sticks at the first frame. I crawled all through playThread and related code trying to figure it out and didn't get anywhere. However, if I saveOut and then load them up again, it works fine.
#14
05/14/2008 (12:04 pm)
I haven't used this as much as you probably have, but I haven't gotten that error yet :/
#15
05/14/2008 (12:15 pm)
Interesting. It's really erratic for me, but it happens a lot. I was sure I fixed it no less than THREE different times, each time it worked for a while, and then started again. (The best kind of bug!) :-\
#16
05/14/2008 (1:04 pm)
Eesh...you weren't kidding about the problem of the bvh file having more nodes/joints than the .dts object.

I just downloaded a tai chi ASF and AMC. I converted it to BVH. However, they are using one of the most anatomically correct bone structures I've ever seen. The lower back alone is made of about 9 nodes O.o
#17
05/14/2008 (1:56 pm)
Wow. That's kind of cool, would be nice to have a model that detailed. Anyway, it shouldn't be all that hard to modify my code, if you made the cfg file bvh numbers meaningful you could make something like a bvhMatters array (IntegerSet) and only load the rotations that "matter" into the nodeRotations array.
#18
05/14/2008 (3:57 pm)
Okay, I have now incorporated Michael's changes, with the exception of the dStrcmp instead of dStrstr.

On that issue, I'm actually searching inside the string for a word, not comparing the whole strings, so it doesn't seem like dStrcmp would work, unless it ignores whitespace by default. (Does it?)

However, I see your point on the const char *. I actually have no idea why I'm able to compile this, but it works fine for me. But, I went through and fixed it by creating a local char array that isn't const. Sigh. Gotta love working with strings in C++. Why did I ever leave perl? :-P

Anyway, anyone who downloaded this before should download it again, sorry for the inconvenience!
#19
05/14/2008 (4:40 pm)
Yeah, you have to explicitly tell dStrcmp to ignore spaces, tabs, and newlines. That's why I kept getting errors and crashes. That might also be why I'm getting chode in the console.

I'll download again tomorrow and integrate into a fresh build and let you know how it goes.
#20
05/14/2008 (5:02 pm)
I'm curious, Chris, I see the node listing in the bloq and I'm wondering if having your, say left and right node chains, swapped in the index list; would things still work with the code?

chriscalef.com/blogs/GarageGames/05-12-08/kork_nodes.360.jpg
Say, instead of my Bip01 L Clavicle securing the index position of [7], it were were nested at index position[11]. Essentially swapping their positions in the list. Are things still going to work as programed? No transporter accidents? heh-heh.

Reason I ask is that the makeHuman rig, is without naming conventions, the exact same rig, excepting the index positions of the major appendage chains.

Also, some rigs I see in bvh have the arm chains parented off the abdomen and not inline with the neck--head system. I have to run them thru POSER to rearrange the chains to my taste.


bye.

You want anatomical correct rig...I can build you one...heh-heh...won't run the bvh's though...too many nodes, not parented to achieve their proper local transforms. It was insane setting all the spine IK constraints...lol.
Page «Previous 1 2