bvh Rotations to C4D HPB?

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

 
Thread Tools Search this Thread Display Modes
  1 Week Ago
bvh Rotations to C4D HPB?

Hi,
Does anyone know what the magic formula is for converting bvh rotation values to C4D HPB values?
AFAIK bvh rotations are Euler angles expressed in degrees. And HPB are also Euler angles expressed in degrees. But they are definitely not the same values.
Example:
bvh rotation = 0, 0, 0
C4D HPB rotation = 0, 90, 0 <----WTF?

I've tried the typical sdk functions for this: HPBToMatrix(), etc.. But so far I can't find the magic formula that will convert the bvh rotations to HPB properly.
Anyone know how to do this?

-ScottA
__________________
My Gallery
 
  1 Week Ago
You have to employ matrix multiplication in order to go from Euler angles to C4D HPB. First, you need to know the rotation order (which is given in BVH). I have *old* code that I used in InterPoser Pro for loading BVH onto the IPP joints. For HPB, it might be better to multiply rotation matrices (in rotation order). This is typically done in reverse: for instance, if the rotation order is XYZ, you multiply the rotation matrices (based on the rotation angle for each) like this: Matrix HPB = MatrixRotZ() * MatrixRotY() * MatrixRotX(). It may also be necessary to convert from right-handed to left-handed (not sure which BVH is in but C4D uses a left-handed coordinate system). If so, you have to use a similarity matrix to convert the handedness of the coordinate system. See what you get without consideration of handedness. If things look 'mirrored', I can provide code to convert from right->left.
__________________
Greebler | InterPoser

C4D-R16, VS2012, Xcode 4.6
 
  1 Week Ago
Robert! How are you?
You kind of vanished a while ago. It's good to see you back.

I'm working in Python. But I can switch over to C++ if needed.
In my bvh file I have this: CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
So I'm guessing that means the rotation order = ZXY

Here's what I have using your advice.
But I'm not sure how to get the hpb vector values from the hbpMtx?
import c4d,math
def main():
 
 rotMtxY = c4d.utils.MatrixRotY(0)
 rotMtxX = c4d.utils.MatrixRotX(0) #These zero values are just here as simple example values from my bvh file
 rotMtxZ = c4d.utils.MatrixRotZ(0)

 hpbMtx = rotMtxY * rotMtxX * rotMtxZ #<---How do I get the hpb vector values from this matrix?
 print hpbMtx

 #This returns vector(0,0,0) not vector(0,90,0) like the C4D importer does
 hpb = c4d.utils.MatrixToHPB(hpbMtx, c4d.ROTATIONORDER_HPB) #<---Not sure if this is correct?
 print hpb

if __name__=='__main__':
 main()


Also,
In my bvh file where the MOTION values are listed. I'm assuming that the values are always listed as XYZ. That never changes regardless of the order listed in the CHANNELS right?
I'm plugging in those values into my rotation matrices code accordingly. But I still can't get the correct rotation values from them.

-ScottA
__________________
My Gallery

Last edited by Scott Ayers : 1 Week Ago at 02:57 PM.
 
  1 Week Ago
The MOTION section values use the same position and rotation orders as those given in the CHANNELS section for the JOINT hierarchy.

MatrixToHPB() will give you a vector using the order (and type) as you specify in the second argument. So, you should be getting the actual HPB values if using 'c4d.ROTATIONORDER_HPB'.

As for why the Cinema 4D import yields (0,90,0) and you get (0,0,0) may have something to do with the axial system. The 90 degree rotation puts the Z as up instead of the Y. You may need to apply this 90 degree rotation to all rotation matrices (add a MatrixRotY(0.5*PI) as the first multiplication - last matrix multiplication, right to left).
__________________
Greebler | InterPoser

C4D-R16, VS2012, Xcode 4.6

Last edited by Kuroyume0161 : 1 Week Ago at 01:15 AM.
 
  1 Week Ago
Originally Posted by Kuroyume0161: You may need to apply this 90 degree rotation to all rotation matrices (add a MatrixRotY(0.5*PI) as the first multiplication - last matrix multiplication, right to left).
You lost me there.
I can't quite picture what you're saying.

Also:
I've successfully written my own fbx exporter. And the FBX sdk is also a right handed system like the bvh files are.
In order to convert my fbx rotation values to c4d I needed to swap the X&Y axis values.
In order to to convert the positions I needed to negate the Z axis value.
I'm not sure if I will need to do the same thing when working with bvh files?

-ScottA
__________________
My Gallery

Last edited by Scott Ayers : 1 Week Ago at 02:24 AM.
 
  1 Week Ago
I think I have it figured out. But I will need to test it some more before I'm 100% convinced.
This is what I came up with that seems to work:

#This is how to convert the rotation values in a .bvh file to HPB values in C4D
#This example uses a .bvh file that has the rotations listed as: ZXY
# EXAMPLE: CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
#Change the code if your .bvh file uses a different order

import c4d,math
def main():
 
 #First...we need to convert the bvh file's rotation values to radians
 #Why?..I have no frackin' clue!!
 vz = 1.45748 * math.pi / 180 #<---NOTE: This value needs to be negated from the Z value in the bvh file
 vx = -11.8543 * math.pi / 180
 vy = 1.15059 * math.pi / 180

 #Create three rotation matrices using the above values
 rotMtxZ = c4d.utils.MatrixRotZ(vz)
 rotMtxX = c4d.utils.MatrixRotX(vx) 
 rotMtxY = c4d.utils.MatrixRotY(vy)

 hpbMtx = rotMtxY * rotMtxX * rotMtxZ #The reverse rotation order in the bvh file

 #Apply the rotations to your own joint
 jnt = doc.SearchObject("myJoint")
 jnt.SetAbsRot(c4d.utils.MatrixToHPB(hpbMtx))

 """
 At this point your joint's rotations should match the rotation of the bvh file
 However...The axis might be pointing in different directions
 So we need to Align the joint's axis in the Z direction (as it is in the bvh file)
 """

 #Set the Axis option to "Z"
 jnt[c4d.ID_CA_JOINT_OBJECT_BONE_AXIS] = 2
 
 #Execute the Align button
 c4d.CallButton(jnt,c4d.ID_CA_JOINT_OBJECT_ALIGN_AX  IS)
 
 c4d.EventAdd()

if __name__=='__main__':
 main()


-ScottA
__________________
My Gallery
 
reply share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 09:45 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.