Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

about DCM and joints order #13

Closed
hanhailangya opened this issue Jun 24, 2020 · 30 comments
Closed

about DCM and joints order #13

hanhailangya opened this issue Jun 24, 2020 · 30 comments

Comments

@hanhailangya
Copy link

作者您好:我有两个问题咨询
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
2.不同关节点定义的旋转顺序的原理是什么?
图形学小白,还望不吝赐教

@KevinLTT
Copy link
Owner

KevinLTT commented Jun 26, 2020

1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?

主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例

elif joint in ['RightUpLeg', 'RightLeg']:
child_idx = self.keypoint2index[node.children[0].name]
x_dir = pose[index['Hips']] - pose[index['RightUpLeg']]
y_dir = None
z_dir = pose[joint_idx] - pose[child_idx]
order = 'zyx'

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

2.不同关节点定义的旋转顺序的原理是什么?

其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样.

rotation_order='zxy' if not is_end_site else '',

zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.

@hanhailangya
Copy link
Author

hanhailangya commented Jun 26, 2020 via email

@miooooooooooo
Copy link

您好,请问如果是手势的话,那么应该如何建立手的模板以及计算每个关节点的向量

@KevinLTT
Copy link
Owner

您好,请问如果是手势的话,那么应该如何建立手的模板以及计算每个关节点的向量

可以看这个issues #26
我觉得主要是3步, 1) 根据掌指关节求掌平面 2) 根据求掌指关节和掌片面之间的夹角 3) 求其他关节的夹角
1)是四点求平面 2)是求向量和平面夹角 3)是求向量之间的夹角
注意掌指关节有两个自由度, 其他关节只有一个

@wtnan2003
Copy link

@hanhailangya @KevinLTT
前辈们,针对这句话:

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

  1. 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
  2. 我也对 About direction vector  #14 (comment)
    存在疑惑,在初始restpose中:

elif joint == 'LeftArm':
x_dir = pose[index['LeftForeArm']] - pose[joint_idx]
y_dir = pose[index['LeftForeArm']] - pose[index['LeftHand']]
z_dir = None
order = 'xzy'

此处的x_dir 和 y_dir 不是同一个方向的吗?
image

若能解惑,不胜感激

@Kismetzc
Copy link

@hanhailangya @KevinLTT
前辈们,针对这句话:

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

  1. 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
  2. 我也对 About direction vector  #14 (comment)
    存在疑惑,在初始restpose中:

elif joint == 'LeftArm':
x_dir = pose[index['LeftForeArm']] - pose[joint_idx]
y_dir = pose[index['LeftForeArm']] - pose[index['LeftHand']]
z_dir = None
order = 'xzy'

此处的x_dir 和 y_dir 不是同一个方向的吗?
image

若能解惑,不胜感激

朋友,你好
请问你这个图是怎么可视化出来的呀?是在blender打开还是用了什么插件

@wtnan2003
Copy link

@weidom
是的,blender打开的

@ZaVang
Copy link

ZaVang commented Jan 6, 2022

@hanhailangya @KevinLTT 前辈们,针对这句话:

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

  1. 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
  2. 我也对 About direction vector  #14 (comment)
    存在疑惑,在初始restpose中:

elif joint == 'LeftArm':
x_dir = pose[index['LeftForeArm']] - pose[joint_idx]
y_dir = pose[index['LeftForeArm']] - pose[index['LeftHand']]
z_dir = None
order = 'xzy'

此处的x_dir 和 y_dir 不是同一个方向的吗? image

若能解惑,不胜感激

1.每次输入都有一个为None,另两个不为None,但是另两个本身并不是正交的,这个代码做的其实是通过输入的第一个axis和由第一第三个axis确定的平面来生成一个新的坐标系。所以上面最后要再对z和y做叉乘得到新的x,这样的x才是正交的。
2.至于这个问题,同一个方向只是因为在tpose里是这样,后续每一帧这俩大部分时候都不是同一个方向。不过如果真的是同一个方向我也没想清楚会不会有问题。

@wtnan2003
Copy link

@ZaVang 转眼过了半年,已经弄懂,当年要是有您提点我会懂的更快 ,总之多谢回复

@ZaVang
Copy link

ZaVang commented Jan 10, 2022

@ZaVang 转眼过了半年,已经弄懂,当年要是有您提点我会懂的更快 ,总之多谢回复
没有没有,我也是刚刚入门的初学者,还有很多地方不懂。请问您现在知道这个eulermap里面每一个关节的x_dir,y_dir,z_dir的具体选择原理吗;比如下面这个
if joint == 'Hip':
x_dir = pose[index['LeftHip']] - pose[index['RightHip']]
y_dir = None
z_dir = pose[index['Spine']] - pose[joint_idx]
order = 'zyx'
为什么x_dir是lefthip-righthip而不能是lefthip-hip或者hip-righthip?
再比如这里
elif joint == 'Thorax':
x_dir = pose[index['LeftShoulder']] -
pose[index['RightShoulder']]
y_dir = None
z_dir = pose[joint_idx] - pose[index['Spine']]
order = 'zyx'
为什么z_dir不能是neck-thorax?
谢谢!

@wtnan2003
Copy link

@ZaVang
因为每一帧的旋转是相对初始T-pose计算,所以在每一帧3D点上建立坐标系的朝向应当与T-pose保持一致,这样比较两个frame的旋转计算出的旋转矩阵才是正确的,你可以看看捕获点,其实lefthip-righthip与lefthip-hip的向量方向并不一致
image

@ZaVang
Copy link

ZaVang commented Jan 10, 2022

@wtnan2003

感谢回复!我对您的回答还是有些疑问,在源代码中给出的initial direction来看,lefthip,hip和righthip都在平行于x轴的一条直线上,所以为了和T-pose保持一致,其实lefthip-righthip与lefthip-hip的向量方向都可以吧?当然后续每一帧的数据中这俩方向肯定是不一样的。假设一种情况,对于某一帧的坐标,我们去掉右半边的所有节点,那么毫无疑问应该选择lefthip-hip的方向吧,这时候再单独加上一个righthip的节点,让他和这一帧中righthip的坐标一致,这时候按理说只需要重新计算这一个节点的旋转矩阵即可吧。
所以我的意思是这样的选择方式应该不是唯一的?根据我的理解来看选择沿着坐标轴方向可能计算上确实方便很多。具体的您可以看看我最新提的issue

@hujb48
Copy link

hujb48 commented Jan 11, 2022

@hanhailangya @KevinLTT 前辈们,针对这句话:

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

  1. 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
  2. 我也对 About direction vector  #14 (comment)
    存在疑惑,在初始restpose中:

elif joint == 'LeftArm':
x_dir = pose[index['LeftForeArm']] - pose[joint_idx]
y_dir = pose[index['LeftForeArm']] - pose[index['LeftHand']]
z_dir = None
order = 'xzy'

此处的x_dir 和 y_dir 不是同一个方向的吗? image
若能解惑,不胜感激

1.每次输入都有一个为None,另两个不为None,但是另两个本身并不是正交的,这个代码做的其实是通过输入的第一个axis和由第一第三个axis确定的平面来生成一个新的坐标系。所以上面最后要再对z和y做叉乘得到新的x,这样的x才是正交的。 2.至于这个问题,同一个方向只是因为在tpose里是这样,后续每一帧这俩大部分时候都不是同一个方向。不过如果真的是同一个方向我也没想清楚会不会有问题。

@ZaVang 您好老兄,针对您的回复1.,我想向您请教一个问题。还是以右大腿RightUpLeg为例,即在不改变其他function函数的情况下,是否一定是‘zyx’的顺序呢,或者可以这么说:如果我用xz平面先叉乘得到新的y,再利用x和y做叉乘得到新的z,此时z是正交的,那么顺序是否可以换成‘xyz’而不用‘zyx’呢?假设换成xyz的话,后续代码会有何种影响呢?或者说在blender中的效果是否有区别呢?因为y确实是未知的,放在中间用xz的叉积求解可以理解,但是x、z的顺序会有影响吗?

@ZaVang
Copy link

ZaVang commented Jan 11, 2022

@hanhailangya @KevinLTT 前辈们,针对这句话:

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

  1. 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
  2. 我也对 About direction vector  #14 (comment)
    存在疑惑,在初始restpose中:

elif joint == 'LeftArm':
x_dir = pose[index['LeftForeArm']] - pose[joint_idx]
y_dir = pose[index['LeftForeArm']] - pose[index['LeftHand']]
z_dir = None
order = 'xzy'

此处的x_dir 和 y_dir 不是同一个方向的吗? image
若能解惑,不胜感激

1.每次输入都有一个为None,另两个不为None,但是另两个本身并不是正交的,这个代码做的其实是通过输入的第一个axis和由第一第三个axis确定的平面来生成一个新的坐标系。所以上面最后要再对z和y做叉乘得到新的x,这样的x才是正交的。 2.至于这个问题,同一个方向只是因为在tpose里是这样,后续每一帧这俩大部分时候都不是同一个方向。不过如果真的是同一个方向我也没想清楚会不会有问题。

@ZaVang 您好老兄,针对您的回复1.,我想向您请教一个问题。还是以右大腿RightUpLeg为例,即在不改变其他function函数的情况下,是否一定是‘zyx’的顺序呢,或者可以这么说:如果我用xz平面先叉乘得到新的y,再利用x和y做叉乘得到新的z,此时z是正交的,那么顺序是否可以换成‘xyz’而不用‘zyx’呢?假设换成xyz的话,后续代码会有何种影响呢?或者说在blender中的效果是否有区别呢?因为y确实是未知的,放在中间用xz的叉积求解可以理解,但是x、z的顺序会有影响吗?

xyz和zyx的差别就是看哪一个轴是基准,这里的基准意思就是你选了哪个方向作为其中一个坐标轴。你可以试试看只改变顺序得到的结果。我其实也没有完全理解每一个joint他这些x、y、z轴是怎么选的,就你举例的点来说,按我的理解应该是xyz,因为初始的direction是[-1,0,0],但是作者给出的代码实际上确实是没问题。这一块我也不知道怎么解释了。你可以先试试就改变这一个点的xyz顺序,结果如何变化。

@hujb48
Copy link

hujb48 commented Jan 12, 2022

@hanhailangya @KevinLTT 前辈们,针对这句话:

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

  1. 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
  2. 我也对 About direction vector  #14 (comment)
    存在疑惑,在初始restpose中:

elif joint == 'LeftArm':
x_dir = pose[index['LeftForeArm']] - pose[joint_idx]
y_dir = pose[index['LeftForeArm']] - pose[index['LeftHand']]
z_dir = None
order = 'xzy'

此处的x_dir 和 y_dir 不是同一个方向的吗? image
若能解惑,不胜感激

1.每次输入都有一个为None,另两个不为None,但是另两个本身并不是正交的,这个代码做的其实是通过输入的第一个axis和由第一第三个axis确定的平面来生成一个新的坐标系。所以上面最后要再对z和y做叉乘得到新的x,这样的x才是正交的。 2.至于这个问题,同一个方向只是因为在tpose里是这样,后续每一帧这俩大部分时候都不是同一个方向。不过如果真的是同一个方向我也没想清楚会不会有问题。

@ZaVang 您好老兄,针对您的回复1.,我想向您请教一个问题。还是以右大腿RightUpLeg为例,即在不改变其他function函数的情况下,是否一定是‘zyx’的顺序呢,或者可以这么说:如果我用xz平面先叉乘得到新的y,再利用x和y做叉乘得到新的z,此时z是正交的,那么顺序是否可以换成‘xyz’而不用‘zyx’呢?假设换成xyz的话,后续代码会有何种影响呢?或者说在blender中的效果是否有区别呢?因为y确实是未知的,放在中间用xz的叉积求解可以理解,但是x、z的顺序会有影响吗?

xyz和zyx的差别就是看哪一个轴是基准,这里的基准意思就是你选了哪个方向作为其中一个坐标轴。你可以试试看只改变顺序得到的结果。我其实也没有完全理解每一个joint他这些x、y、z轴是怎么选的,就你举例的点来说,按我的理解应该是xyz,因为初始的direction是[-1,0,0],但是作者给出的代码实际上确实是没问题。这一块我也不知道怎么解释了。你可以先试试就改变这一个点的xyz顺序,结果如何变化。

好的老兄,我再尝试一下,感谢!

@ZaVang
Copy link

ZaVang commented Jan 12, 2022

@hujb48 我今天看机器人学的时候发现了我之前一直理解错了。上面的例子rightupleg确实应该是zyx的顺序。在计算rightupleg的子节点rightknee的坐标的时候,需要的是rightupleg处的旋转矩阵,由于rightknee的初始向量是(0,0,-1),因此rightupleg处的旋转矩阵的第三行应该要平行于rightupleg-rightknee。所以应该以此为基准选择zyx的顺序。
而我之前不能理解的Hip处的旋转矩阵其实是近似的旋转。因为实际上lefthip、righthip和spine的位置应该只取决于offset和hip处的旋转矩阵,因此这三个点和hip,他们四个的相对位置应该是固定的,我看了blender里的结果发现好像确实是这样。因此按照上面的逻辑z轴要和spine-hip平行,x的正向轴要和lefthip-hip平行,x的负向轴和hip-righthip平行,这样有三个方程,但是因为这几个点相对位置是固定的,必然不能全部满足,所以作者的代码里选择了z轴与spine-hip平行,然后把另两个方程合在了一起,满足了righthip-lefthip和x轴平行。
我也是刚入门,自己摸索出来的上面结论,可能也还有不正确不到位的地方,兄弟你可以自己也实验看下我说的对不对。

@hujb48
Copy link

hujb48 commented Jan 12, 2022

@hujb48 我今天看机器人学的时候发现了我之前一直理解错了。上面的例子rightupleg确实应该是zyx的顺序。在计算rightupleg的子节点rightknee的坐标的时候,需要的是rightupleg处的旋转矩阵,由于rightknee的初始向量是(0,0,-1),因此rightupleg处的旋转矩阵的第三行应该要平行于rightupleg-rightknee。所以应该以此为基准选择zyx的顺序。 而我之前不能理解的Hip处的旋转矩阵其实是近似的旋转。因为实际上lefthip、righthip和spine的位置应该只取决于offset和hip处的旋转矩阵,因此这三个点和hip,他们四个的相对位置应该是固定的,我看了blender里的结果发现好像确实是这样。因此按照上面的逻辑z轴要和spine-hip平行,x的正向轴要和lefthip-hip平行,x的负向轴和hip-righthip平行,这样有三个方程,但是因为这几个点相对位置是固定的,必然不能全部满足,所以作者的代码里选择了z轴与spine-hip平行,然后把另两个方程合在了一起,满足了righthip-lefthip和x轴平行。 我也是刚入门,自己摸索出来的上面结论,可能也还有不正确不到位的地方,兄弟你可以自己也实验看下我说的对不对。

@ZaVang 感谢老哥您的回复以及非常详细讲解,受益匪浅,但我仍弄不懂的两个个问题:

  1. 就是针对每个joint,其旋转顺序的第一个轴dir的设置都是父节点-子节点的相应设置,这个好理解,那么旋转顺序的第三个轴是如何进行设置的?例如cmu中的“joint==‘LeftForeArm’这个点,顺序是xzy,那么x_dir就是‘LeftHand’->'LeftForeArm', 但是为何y_dir设置成'LeftForeArm'->'LeftArm',而不选择z_dir设置成'LeftForeArm'->'LeftArm',y_dir=None,此时顺序为xyz呢?这个设置应该如何判断?还是说按我说的设置其实本质上没有区别,只是轴的叫法不一样?
  2. 另外第三个轴到底应该如何进行选择哪些点间向量设置较为合适?因为我看joint==‘LeftForeArm’的y_dir为'节点本身LeftForeArm'->'父节点LeftArm',而“joint==‘LeftArm’的y_dir为'节点本身的子节点LeftForeArm'->'节点本身的子节点的字节点LeftHand',而对于joint=='LeftUpLeg'和'LeftLeg'的话,其第三轴x_dir又是固定的'LeftUpLeg'->'Hips',这里我始终无法理解
    以上两点,还望赐教!

@ZaVang
Copy link

ZaVang commented Jan 12, 2022

@hujb48 我今天看机器人学的时候发现了我之前一直理解错了。上面的例子rightupleg确实应该是zyx的顺序。在计算rightupleg的子节点rightknee的坐标的时候,需要的是rightupleg处的旋转矩阵,由于rightknee的初始向量是(0,0,-1),因此rightupleg处的旋转矩阵的第三行应该要平行于rightupleg-rightknee。所以应该以此为基准选择zyx的顺序。 而我之前不能理解的Hip处的旋转矩阵其实是近似的旋转。因为实际上lefthip、righthip和spine的位置应该只取决于offset和hip处的旋转矩阵,因此这三个点和hip,他们四个的相对位置应该是固定的,我看了blender里的结果发现好像确实是这样。因此按照上面的逻辑z轴要和spine-hip平行,x的正向轴要和lefthip-hip平行,x的负向轴和hip-righthip平行,这样有三个方程,但是因为这几个点相对位置是固定的,必然不能全部满足,所以作者的代码里选择了z轴与spine-hip平行,然后把另两个方程合在了一起,满足了righthip-lefthip和x轴平行。 我也是刚入门,自己摸索出来的上面结论,可能也还有不正确不到位的地方,兄弟你可以自己也实验看下我说的对不对。

@ZaVang 感谢老哥您的回复以及非常详细讲解,受益匪浅,但我仍弄不懂的两个个问题:

  1. 就是针对每个joint,其旋转顺序的第一个轴dir的设置都是父节点-子节点的相应设置,这个好理解,那么旋转顺序的第三个轴是如何进行设置的?例如cmu中的“joint==‘LeftForeArm’这个点,顺序是xzy,那么x_dir就是‘LeftHand’->'LeftForeArm', 但是为何y_dir设置成'LeftForeArm'->'LeftArm',而不选择z_dir设置成'LeftForeArm'->'LeftArm',y_dir=None,此时顺序为xyz呢?这个设置应该如何判断?还是说按我说的设置其实本质上没有区别,只是轴的叫法不一样?
  2. 另外第三个轴到底应该如何进行选择哪些点间向量设置较为合适?因为我看joint==‘LeftForeArm’的y_dir为'节点本身LeftForeArm'->'父节点LeftArm',而“joint==‘LeftArm’的y_dir为'节点本身的子节点LeftForeArm'->'节点本身的子节点的字节点LeftHand',而对于joint=='LeftUpLeg'和'LeftLeg'的话,其第三轴x_dir又是固定的'LeftUpLeg'->'Hips',这里我始终无法理解
    以上两点,还望赐教!

第一个问题,因为在初始的direction中z轴是垂直leftarm、leftforearm、lefthand平面的,所以设置y_dir就是这个目的,这样插乘出来的z_dir同样垂直这三个节点。至于为什么这样做,我的理解是这样转动少一点吧。我自己试着列了一下方程我发现旋转矩阵都不是唯一的,所以我认为在这个地方按照你说的那样应该也没问题,你可以就把这一部分代码改了试验一下结果看看。

第二个问题,也是一样的,我是觉得矩阵不唯一,但是有一点是要保证的,就是比如我某个节点(假设这个节点只有一个子节点)初始directiron是(1,0,0),那么我后面一定是xyz或者xzy的order,而且x一定是子节点减自己。其他的选取就随便吧。我是这么理解的。当然也有可能不对。

@hujb48
Copy link

hujb48 commented Jan 13, 2022

@hujb48 我今天看机器人学的时候发现了我之前一直理解错了。上面的例子rightupleg确实应该是zyx的顺序。在计算rightupleg的子节点rightknee的坐标的时候,需要的是rightupleg处的旋转矩阵,由于rightknee的初始向量是(0,0,-1),因此rightupleg处的旋转矩阵的第三行应该要平行于rightupleg-rightknee。所以应该以此为基准选择zyx的顺序。 而我之前不能理解的Hip处的旋转矩阵其实是近似的旋转。因为实际上lefthip、righthip和spine的位置应该只取决于offset和hip处的旋转矩阵,因此这三个点和hip,他们四个的相对位置应该是固定的,我看了blender里的结果发现好像确实是这样。因此按照上面的逻辑z轴要和spine-hip平行,x的正向轴要和lefthip-hip平行,x的负向轴和hip-righthip平行,这样有三个方程,但是因为这几个点相对位置是固定的,必然不能全部满足,所以作者的代码里选择了z轴与spine-hip平行,然后把另两个方程合在了一起,满足了righthip-lefthip和x轴平行。 我也是刚入门,自己摸索出来的上面结论,可能也还有不正确不到位的地方,兄弟你可以自己也实验看下我说的对不对。

@ZaVang 感谢老哥您的回复以及非常详细讲解,受益匪浅,但我仍弄不懂的两个个问题:

  1. 就是针对每个joint,其旋转顺序的第一个轴dir的设置都是父节点-子节点的相应设置,这个好理解,那么旋转顺序的第三个轴是如何进行设置的?例如cmu中的“joint==‘LeftForeArm’这个点,顺序是xzy,那么x_dir就是‘LeftHand’->'LeftForeArm', 但是为何y_dir设置成'LeftForeArm'->'LeftArm',而不选择z_dir设置成'LeftForeArm'->'LeftArm',y_dir=None,此时顺序为xyz呢?这个设置应该如何判断?还是说按我说的设置其实本质上没有区别,只是轴的叫法不一样?
  2. 另外第三个轴到底应该如何进行选择哪些点间向量设置较为合适?因为我看joint==‘LeftForeArm’的y_dir为'节点本身LeftForeArm'->'父节点LeftArm',而“joint==‘LeftArm’的y_dir为'节点本身的子节点LeftForeArm'->'节点本身的子节点的字节点LeftHand',而对于joint=='LeftUpLeg'和'LeftLeg'的话,其第三轴x_dir又是固定的'LeftUpLeg'->'Hips',这里我始终无法理解
    以上两点,还望赐教!

第一个问题,因为在初始的direction中z轴是垂直leftarm、leftforearm、lefthand平面的,所以设置y_dir就是这个目的,这样插乘出来的z_dir同样垂直这三个节点。至于为什么这样做,我的理解是这样转动少一点吧。我自己试着列了一下方程我发现旋转矩阵都不是唯一的,所以我认为在这个地方按照你说的那样应该也没问题,你可以就把这一部分代码改了试验一下结果看看。

第二个问题,也是一样的,我是觉得矩阵不唯一,但是有一点是要保证的,就是比如我某个节点(假设这个节点只有一个子节点)初始directiron是(1,0,0),那么我后面一定是xyz或者xzy的order,而且x一定是子节点减自己。其他的选取就随便吧。我是这么理解的。当然也有可能不对。

感谢老哥,您的回复十分有用且帮助很大,我再去进行一些尝试和理解后应该也有更好的体会,
再次感谢!

@ZaVang
Copy link

ZaVang commented Jan 13, 2022

@hujb48 我重新想了下,关于你上面那个问题应该可以这样解释。我之前想当然觉得都可以随意转动,实际上并不是,就拿LeftArm来说,想象一下真人的情景,我们假设T-pose下手窝朝前,也就是-y方向。那么在实际转动中,可以发现leftarm只能绕z轴和x轴转动。在这里绕着x轴转动其实没啥意义,因为不影响后续的点的位置,如果后续还有手指等节点,我们也可以把旋转归到lefthandt节点上去,所以我们在这里就假设leftarm这块只沿z轴转动。也就是说在任意的情况下,leftarm、leftforearm、lefthand应该都在xy平面上,所以这也解释了为什么要设置leftforearm-leftarm为y轴然后叉乘出z轴了。主要是一直忽略了每个点并不能随意旋转,要从实际人体结构考虑。这样想其他节点的各个轴向的选取就没什么问题了,除了thorax节点那个地方,z轴我认为应该是neck-throax而不是thorax-spine。也可能是我哪里没搞楚。

我之所以想到了这一点,是受到下面这篇文章里的启发。
Tracking and Modelling Motion for Biomechanical Analysis

文章里的3.1介绍了人体的关节大概可以分为几种类型,每种类型有不同的自由度。在文章举的例子里提到了手肘这样的节点自由度是1。具体的你可以看这篇文章了解一下。

@hujb48
Copy link

hujb48 commented Jan 13, 2022

@ZaVang 非常感谢,这样的解释非常通透,也进一步帮我理解了轴向选取的问题,再次十分感谢您!文章我会进一步阅读!对我进一步学习人体运动学十分有帮助!

@ZaVang
Copy link

ZaVang commented Jan 14, 2022

@ZaVang 非常感谢,这样的解释非常通透,也进一步帮我理解了轴向选取的问题,再次十分感谢您!文章我会进一步阅读!对我进一步学习人体运动学十分有帮助!

老哥过奖了,我也是刚入门自学,一起交流进步!

@gaowei724
Copy link

gaowei724 commented Jan 19, 2022

1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?

主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例

elif joint in ['RightUpLeg', 'RightLeg']:
child_idx = self.keypoint2index[node.children[0].name]
x_dir = pose[index['Hips']] - pose[index['RightUpLeg']]
y_dir = None
z_dir = pose[joint_idx] - pose[child_idx]
order = 'zyx'

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

2.不同关节点定义的旋转顺序的原理是什么?

其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样.

rotation_order='zxy' if not is_end_site else '',

zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.

您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。
我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。

github

感谢!

@hujb48
Copy link

hujb48 commented Mar 1, 2022

1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?

主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例

elif joint in ['RightUpLeg', 'RightLeg']:
child_idx = self.keypoint2index[node.children[0].name]
x_dir = pose[index['Hips']] - pose[index['RightUpLeg']]
y_dir = None
z_dir = pose[joint_idx] - pose[child_idx]
order = 'zyx'

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

2.不同关节点定义的旋转顺序的原理是什么?

其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样.

rotation_order='zxy' if not is_end_site else '',

zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.

您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。

github

感谢!

您好,请问您这个问题解决了吗

@gaowei724
Copy link

1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?

主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例

elif joint in ['RightUpLeg', 'RightLeg']:
child_idx = self.keypoint2index[node.children[0].name]
x_dir = pose[index['Hips']] - pose[index['RightUpLeg']]
y_dir = None
z_dir = pose[joint_idx] - pose[child_idx]
order = 'zyx'

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

2.不同关节点定义的旋转顺序的原理是什么?

其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样.

rotation_order='zxy' if not is_end_site else '',

zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.

您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。
github
感谢!

您好,请问您这个问题解决了吗

嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py
应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。

@Kismetzc
Copy link

Kismetzc commented Mar 2, 2022

@gaowei724 @wtnan2003 @hanhailangya @ZaVang 请问大家还有找到精度比较高的 可以转化为.bvh文件保存的方法吗?

@hujb48
Copy link

hujb48 commented Mar 3, 2022

1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?

主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例

elif joint in ['RightUpLeg', 'RightLeg']:
child_idx = self.keypoint2index[node.children[0].name]
x_dir = pose[index['Hips']] - pose[index['RightUpLeg']]
y_dir = None
z_dir = pose[joint_idx] - pose[child_idx]
order = 'zyx'

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

2.不同关节点定义的旋转顺序的原理是什么?

其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样.

rotation_order='zxy' if not is_end_site else '',

zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.

您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。
github
感谢!

您好,请问您这个问题解决了吗

嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py 应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。

感谢老哥,研究了一下发现还是相对不好理解,您这边是否可以提供一个使用demo,这个算法如何配合骨骼.bvh头以及3D点进行使用

@gaowei724
Copy link

1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?

主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例

elif joint in ['RightUpLeg', 'RightLeg']:
child_idx = self.keypoint2index[node.children[0].name]
x_dir = pose[index['Hips']] - pose[index['RightUpLeg']]
y_dir = None
z_dir = pose[joint_idx] - pose[child_idx]
order = 'zyx'

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

2.不同关节点定义的旋转顺序的原理是什么?

其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样.

rotation_order='zxy' if not is_end_site else '',

zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.

您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。
github
感谢!

您好,请问您这个问题解决了吗

嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py 应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。

感谢老哥,研究了一下发现还是相对不好理解,您这边是否可以提供一个使用demo,这个算法如何配合骨骼.bvh头以及3D点进行使用

抱歉我现在在写毕业论文,没时间写详细的demo,只能提供个解决思路,希望能够帮助到您:配置这整个项目的环境是很费事的,但是如果只想运行处理BVH的部分并不困难。
https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/BVH.py
这个里面有个load 方法,你可以用它加载一下它的样例bvh文件:
比如这个 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ybot.bvh
载入之后是一个Animation类,你可以用里面的postion_global得到3D 关键点,即Forward kinematics功能,之后你可以使用得到的这个关键点测试上面提到的IK算法,譬如使用类BasicJacobianIK的IK算法,他的API是这样:
def init(self, animation, positions, iterations=10, silent=True, **kw):
animation就是用BVH.load载入的Animation类,positions是你之前得到的3D关键点。

同理,你可以用它来处理你自己的BVH(如果你只有关键点,那么这个BVH的骨骼结构需要自己设计一下,设计好之后我是参考了https://github.com/KevinLTT/video2bvh/blob/master/bvh_skeleton/bvh_helper.py中write_bvh的写法生成的BVH)

@hujb48
Copy link

hujb48 commented Mar 5, 2022

1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?

主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例

elif joint in ['RightUpLeg', 'RightLeg']:
child_idx = self.keypoint2index[node.children[0].name]
x_dir = pose[index['Hips']] - pose[index['RightUpLeg']]
y_dir = None
z_dir = pose[joint_idx] - pose[child_idx]
order = 'zyx'

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

2.不同关节点定义的旋转顺序的原理是什么?

其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样.

rotation_order='zxy' if not is_end_site else '',

zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.

您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。
github
感谢!

您好,请问您这个问题解决了吗

嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py 应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。

感谢老哥,研究了一下发现还是相对不好理解,您这边是否可以提供一个使用demo,这个算法如何配合骨骼.bvh头以及3D点进行使用

抱歉我现在在写毕业论文,没时间写详细的demo,只能提供个解决思路,希望能够帮助到您:配置这整个项目的环境是很费事的,但是如果只想运行处理BVH的部分并不困难。 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/BVH.py 这个里面有个load 方法,你可以用它加载一下它的样例bvh文件: 比如这个 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ybot.bvh 载入之后是一个Animation类,你可以用里面的postion_global得到3D 关键点,即Forward kinematics功能,之后你可以使用得到的这个关键点测试上面提到的IK算法,譬如使用类BasicJacobianIK的IK算法,他的API是这样: def init(self, animation, positions, iterations=10, silent=True, **kw): animation就是用BVH.load载入的Animation类,positions是你之前得到的3D关键点。

同理,你可以用它来处理你自己的BVH(如果你只有关键点,那么这个BVH的骨骼结构需要自己设计一下,设计好之后我是参考了https://github.com/KevinLTT/video2bvh/blob/master/bvh_skeleton/bvh_helper.py中write_bvh的写法生成的BVH)

再次非常感谢老哥您的回复,十分感谢!- -我仔细研究一下,您的回复非常有帮助!

@leishengsheng
Copy link

leishengsheng commented May 14, 2024

1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?

主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例

elif joint in ['RightUpLeg', 'RightLeg']:
child_idx = self.keypoint2index[node.children[0].name]
x_dir = pose[index['Hips']] - pose[index['RightUpLeg']]
y_dir = None
z_dir = pose[joint_idx] - pose[child_idx]
order = 'zyx'

在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.

2.不同关节点定义的旋转顺序的原理是什么?

其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样.

rotation_order='zxy' if not is_end_site else '',

zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.

您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。
github
感谢!

您好,请问您这个问题解决了吗

嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py 应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。

感谢老哥,研究了一下发现还是相对不好理解,您这边是否可以提供一个使用demo,这个算法如何配合骨骼.bvh头以及3D点进行使用

抱歉我现在在写毕业论文,没时间写详细的demo,只能提供个解决思路,希望能够帮助到您:配置这整个项目的环境是很费事的,但是如果只想运行处理BVH的部分并不困难。 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/BVH.py 这个里面有个load 方法,你可以用它加载一下它的样例bvh文件: 比如这个 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ybot.bvh 载入之后是一个Animation类,你可以用里面的postion_global得到3D 关键点,即Forward kinematics功能,之后你可以使用得到的这个关键点测试上面提到的IK算法,譬如使用类BasicJacobianIK的IK算法,他的API是这样: def init(self, animation, positions, iterations=10, silent=True, **kw): animation就是用BVH.load载入的Animation类,positions是你之前得到的3D关键点。

同理,你可以用它来处理你自己的BVH(如果你只有关键点,那么这个BVH的骨骼结构需要自己设计一下,设计好之后我是参考了https://github.com/KevinLTT/video2bvh/blob/master/bvh_skeleton/bvh_helper.py中write_bvh的写法生成的BVH)

大哥我在试你说的方法,我先设计了我的bvh头,然后用bvh.load加载我设计的bvh为anmi,使用BasicJacobianIK(anmi,position),这里的position是我用自己模型跑出来的3d坐标位置,然后进行ik(),得到的结果是很复杂的乱动。你看我的思路有没有问题吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants