University of Southern CaliforniaUSC
USC ICT TwitterUSC ICT FacebookUSC ICT YouTube

Animating model using bvh file | General SmartBody Discussion | Forum

Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
Animating model using bvh file
July 9, 2014
4:16 am
Avatar
Member
Members
Forum Posts: 8
Member Since:
July 8, 2014
sp_UserOfflineSmall Offline

Hi, 

The bvh file works fine if I don't do the joint mapping. 

I follow the steps as you said in here https://www.mail-archive.com/smartbody-developer@lists.sourceforge.net/msg00163.html

But if I try to apply joint mapping to bvh, all the motions won't work. 

It seems the SmartBody can't apply joint mapping for my bvh files. 

How should I sovlve this problem?

 

Thank you. 

July 10, 2014
1:27 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

When you apply a joint map to a skeleton, you are essentially renaming the joints so that the controllers can easily identify the legs, arms, head, spine, etc. Once you do that to a skeleton, only motions that have a similar mapping will work on it.

 

So if you are trying to use a motion on a SmartBody skeleton, you should do a joint mapping onto that motion. If you want to use that motion on its own skeleton, you should map both the skeleton and the motion.

 

You can also send me the bvh for testing if you like.

 

Ari

July 10, 2014
2:57 am
Avatar
Member
Members
Forum Posts: 8
Member Since:
July 8, 2014
sp_UserOfflineSmall Offline

Thanks for the reply.

I figure out what the problem is. 

When this function is called, it can't get the motion's file name

void SBJointMap::applyMotionRecurse(const std::stringdirectory) (SBJointMap.cpp)

 

So in this function, I set the motion's file name when parsing bvh file.

bool ParserBVH::parse(SkSkeletonskeletonSkMotionmotionstd::string namestd::ifstream &filefloat scaleint N1int N2) (ParserBVH.cxx)

This actually makes it do the joint mapping for my animations. 

But when I play the animation, bone rotations are totally wrong. 


July 10, 2014
3:00 am
Avatar
Member
Members
Forum Posts: 8
Member Since:
July 8, 2014
sp_UserOfflineSmall Offline
July 10, 2014
4:07 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

It looks like the skeleton is oriented with z-up, instead of y-up which SmartBody expects. It looks like the .bvh file already contains the SmartBody joint names, so you don't need to do a joint mapping on the file.

If you can reexport the bvh file with y-up instead of z-up, it should work without any special handling.

However, the bad orientation causes some problems. You can reorient the skeleton by loading the .bvh then doing the following:

 

myskel = scene.getSkeleton("Test.bvh")

joint = myskel.getJoint("base")

joint.setPrerotation(SrVec(1, 0, 0), -3.14159  / 2.0) # prerotate the base joint by 90 degree

 

(When you load a .bvh file, both a skeleton and a motion get created).

Unfortunately, the motion data will still be applicable only to its own skeleton. However, you can fix this by creating a retargeting instance between the Test.bvh skeleton and motion, and your current character (SmartBody manual, page 76).  The retargeting instance will automatically fix this problem.

 

But by far the simplest solution is to export the bvh with y-up. Keep in mind that your skeleton is sized for meters, so if you use that data on characters that use centimeters, then the translation values will be incorrectly scaled.

 

Ari

July 10, 2014
6:16 am
Avatar
Member
Members
Forum Posts: 8
Member Since:
July 8, 2014
sp_UserOfflineSmall Offline

Thanks Ari for your help. 

I actually solve this problem by changing Rotation Mode from Quat to Euler for each bones in Blender. 

I'm not quite sure why, but this did the job. Now all animations are correct in SmartBody. 

July 10, 2014
5:00 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

Ok, great. Are there any other steps that were needed to export from Blender?

July 15, 2014
3:51 am
Avatar
Member
Members
Forum Posts: 8
Member Since:
July 8, 2014
sp_UserOfflineSmall Offline

Seems like there's some problem if I create the skeleton from my xml file. 

The bone orientation is different if I'm using bvh file to create skeleton. 

The animation works fine if I'm using the bvh file, but it crashes everytime I try to select any joint in Retarget Viewer.

.bvh file

https://drive.google.com/file/d/0B-MN1PKPgpDAemkteXZKQUNuNE0/edit?usp=sharing

.xml

https://drive.google.com/file/d/0B-MN1PKPgpDAMUM2SnRrRVdQYU0/edit?usp=sharing

July 15, 2014
4:26 am
Avatar
Member
Members
Forum Posts: 8
Member Since:
July 8, 2014
sp_UserOfflineSmall Offline
July 16, 2014
7:36 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

hmm..I'm not getting the crash. Can you send me the repro steps?

There is already a zebra2-map.py script that could do the mapping for you:

 

scene.addAssetPath("script", "scripts")

scene.run("zebra2-map.py")

z = scene.getJointMapManager().getJointMap("zebra2")

sk = scene.getSkeleton("merge_Fireman.skeleton.xml")

m = scene.getMotion("my_animation")

z.applySkeleton(sk)

z.applyMotion(m)

July 17, 2014
7:08 am
Avatar
Member
Members
Forum Posts: 8
Member Since:
July 8, 2014
sp_UserOfflineSmall Offline

If you use the bvh file to create the skeleton, and select any bone in retarget viewer, SmartBody will crash. 

sk = scene.getSkeleton("fireman_arm.bvh")

 

It turns out that I need to create the skeleton without pre-rotation from xml file. 

Is there any demo of how to create skeleton by calling 'createSkelWithoutPreRot' ?

Thank you. 

July 18, 2014
3:50 pm
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline

Hi,

I have a problem with animating .bvh files. I followed the steps as you said here https://www.mail-archive.com/smartbody-developer@lists.sourceforge.net/msg00163.html, and I can load the skeleton but not the motion. This is the error I get:

Character AVATAR does not have a motion scheduler, so cannot schedule motion.

I appreciate your help. Thank you.

July 18, 2014
6:51 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

The smartbody-developer mailist list is now out of data. Please refer to the SmartBody manual instead (in the top level directory of the SmartBody distribution, or at http://smartbody.ict.usc.edu/d.....umentation)

 

You'll need to add:

 

mycharacter.createStandardControllers()

 

which sets up the controllers for the character.

 

Ari

July 19, 2014
12:20 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

neroxiao said
If you use the bvh file to create the skeleton, and select any bone in retarget viewer, SmartBody will crash. 

sk = scene.getSkeleton("fireman_arm.bvh")

 

It turns out that I need to create the skeleton without pre-rotation from xml file. 

Is there any demo of how to create skeleton by calling 'createSkelWithoutPreRot' ?

Thank you. 

I'm not able to reproduce your crashing using the SVN trunk (which version are you using?)

However, you can do this:

 

sk = scene.getSkeleton("fireman_arm.bvh")

sk2 = sk.createSkelWithoutPreRot("mynewskeleton")

 

and then you should be able to access it:

 

myskel  = scene.createSkeleton("mynewskeleton")

 

Note that 'scene.getSkeleton()' returns the master instance for the skeleton, while 'scene.createSkeleton()' creates an instance (copy) that can be used on a character.

 

Ari

July 19, 2014
12:21 am
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline

Thanks a lot. It worked. But then I bumped into another problem. So far, I have successfully done joint mapping on my skeleton and motion file (which are both xxx.bvh), i.e. after joint mapping I could animate my skeleton with the motion. Now I am trying to do a retargetting to animate ChrBrad model with my bvh file. I have written the code for retargetting as stated in the manual p.76. After retargetting, although  don't get any errors, when I run the command bml.execBML('ChrBrad', '<animation name="xxx.bvh"/>'), nothing happens! 

Thanks for your time and help.

July 19, 2014
12:27 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

Your motion should be associated with your skeleton:

 

motion = scene.getMotion("mymotion")

motion.setMotionSkeletonName("myskeleton")

 

then create your retargeting instance between your skeleton and the ChrBrad.sk skeleton.

 

Was that all done?

 

Ari

July 19, 2014
12:58 am
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline

Yes, I have done that. Could you please take a look at my code here:

https://drive.google.com/folderview?id=0B-XjyM5L5YwFb3dDOVRuRGdhMHM&usp=sharing

It is the avatarDemo.py. Thank you.

July 19, 2014
1:13 am
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline

I have also uploaded the the joint mapping which is in scripts and the .bvh file which is in sbm-common. I appreciate your help.

Thanks

July 20, 2014
9:18 pm
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline

I still have a problem with retargtting. Is the problem maybe because I am using a bvh file to create the skeleton of the source motion? 

Thanks

July 20, 2014
10:37 pm
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline

I am stuck in this problem for some days now, I truly appreciate your help. Thanks.

July 21, 2014
12:03 am
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline

I realized that my mapping was incorrect. Now, that I mapped all the DOFs, it does not apply the motion on the its mapped skeleton! So, I am back at step 1 again!

July 21, 2014
12:04 am
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline

The mapping is correct now, since I can apply the motions from SB to myskeleton but not the other way around.

July 21, 2014
12:11 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

Can you give me access to your script on Google Drive or post it here? I can't get it without permissions.

 

Ari

July 21, 2014
12:16 am
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline
July 21, 2014
2:18 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

Ok, I suggest that you change the avatar mapping like this:

 

...

avatarMap.setMapping("RightShoulder", "r_acromioclavicular")
avatarMap.setMapping("RightArm", "r_shoulder")
avatarMap.setMapping("RightForeArm", "r_elbow")

 

Since the shoulder joints start at the center spine, which is most similar to the acromioclavicular joint.

Also, I would map:

avatarMap.setMapping("Hips", "spine3")

since you are only tracking the upper body.

 

You can try running the AddCharacterDemo.py, then run the following code which will load the motion files, run the joint mapping, then set up a retarget instance to the Maarten/Brad character:

 

------------------------

 

# replace this with your directory

path = "c:/users/shapiro/sbsupport/najmeh/"

scene.loadAssetsFromPath(path + "sbm-common/common-sk")

scene.addAssetPath("script", path + "scripts")
scene.run("avatar-map.py")

amap = scene.getJointMapManager().getJointMap("avatar2")
print "Applying joint map to skeleton "
sk = scene.getSkeleton("Contrast001.bvh")
amap.applySkeleton(sk)

motion = scene.getMotion("skl.bvh")
motion.setMotionSkeletonName("Contrast001.bvh")
amap.applyMotion(motion)
motion = scene.getMotion("Contrast001.bvh")
motion.setMotionSkeletonName("Contrast001.bvh")
amap.applyMotion(motion)
    
# create a retargeting instance between this and the ChrBrad.sk skeleton

endJoints = StringVec()
endJoints.append('l_forefoot')
endJoints.append('l_toe')
endJoints.append('l_wrist')
endJoints.append('r_forefoot')
endJoints.append('r_toe')
endJoints.append('r_wrist')

relJoints = StringVec()
relJoints.append('spine1')
relJoints.append('spine2')
relJoints.append('spine3')
relJoints.append('spine4')
relJoints.append('spine5')
#relJoints.append('r_sternoclavicular')
#relJoints.append('l_sternoclavicular')
#relJoints.append('r_acromioclavicular')
#relJoints.append('l_acromioclavicular')
retarget = scene.getRetargetManager().createRetarget("Contrast001.bvh", "ChrBrad.sk")
retarget.initRetarget(endJoints, relJoints)

----------------------------

 

Now, keep in mind that your animation is very dirty (many pops and flips). I'd recommend sending it through a low-pass filter first. The problems are much more obvious on a skinned character, than on the character that only shows bones. It's hard to get a successfull retargeting with such data.

 

Ari

July 21, 2014
4:39 pm
Avatar
Member
Members
Forum Posts: 21
Member Since:
July 16, 2014
sp_UserOfflineSmall Offline

It worked! Thanks very much Ari, for all your help. You are right, I have to clean the data first. Well I can apply a filter before hand, or clean the data more carefully with Blade. You helped me a lot, thank you.

Forum Timezone: America/Los_Angeles

Top Posters:

jwwalker: 80

jyambao: 52

rbaral: 47

adiaz: 30

WargnierP: 29

lucky7456969: 28

mbarros: 28

avida.matt: 26

JonathanW: 24

laguerre: 23

Member Stats:

Guest Posters: 69

Members: 122211

Moderators: 3

Admins: 4

Forum Stats:

Groups: 1

Forums: 5

Topics: 531

Posts: 2495