赞
踩
由 SMPL 和 blender 对应关系引起的,发现理顺并不简单,这里总结下。
下面是我用于调试的代码
def f_2(): r1, r2, r3 = get_R2d(-45), get_R2d(45), get_R2d(90) fixp=np.array([1, 0]).reshape(2, 1) augp = np.array([1, 0, 1]).reshape(3, 1) a = augp # 下面这些 t 其实都是父骨骼的相对平移值 m1 = to3d(r1, None) # t = [0, 0] m2 = to3d(r2, fixp) m3 = to3d(r3, fixp) a = m1.dot(m2.dot(m3.dot(a))) print( a ) ’‘’[[1.70710678] [0.29289322] [1. ]]‘’‘ def to3d(x, y=None): A=np.eye(3) if x is None: return A if y is not None: A[:2, :2] = x A[:2, 2:] = y return A a, b = x.shape if a==2 and b ==1: A[:2, 2:] = x return A if a==2 and b==2: A[:2, :2] = x return A def get_R2d(theta): theta = np.deg2rad(theta) c, s = np.cos(theta), np.sin(theta) return np.array( [c, -s, s, c] ).reshape(2, 2) # 逆时针
解释一下f_2是主要部分,就是画了三个骨骼
然后第一个骨骼旋转-45度,第二个接着转 45,最后一个转90。
然后代码中使用的是相对旋转,可以看到用的是左乘变换矩阵,而且最后用的是相对位置。
就是先绕骨骼根部旋转,然后加上初始时相对父骨骼的距离。
(理解时也可以按照,尾节点是最终待求的点的位置,然后绕着头节点转,加的平移是头节点在父骨骼上相对于对父骨骼中头节点的距离)
(上述理解也就是为什么主要关注的是骨骼数目而不是关节点数,因为最终求的是变换矩阵,叶子节点是要被网格顶点代替的)
当然也可以用绝对位置理解,比如所有点绕着根节点旋转,然后接着往下,这样旋转矩阵乘的顺序就会相反,期间也要记录相关joint的位置。
下面两张图,说明在 blender 中其实 bone[n].head 与 显示的 joint[n] 是一致的,但是bone[n].tail 却因为建模的原因还有自己的一个点
首先要知道我们一般用的是 ob.pose.bones 这是个dict 通过 nm 索引。
bone=ob.pose.bones[bnm]
bone.location # 这个描述的是在edit模式下定义了骨骼后,从那个位置开始移动多少
bone.matrix #描述的是相对于父节点的变换(bone.parent)
bone.matrix.translation # 距离父节点的距离
# 推导
bone.location = bone.matrix.translation # 就说明要对齐到父节点的骨骼上
# 假如要让骨骼对齐到世界坐标的某个点 joint,而且这个骨骼只有一个父节点
bone.location = joint - bone.matrix.translation
# 但是上面这个的前提是
armature.matrix_world # 骨骼到世界坐标系的变换
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。