我试图让骨骼旋转与他们的父母有关,但最终我得到了怪异的角度。
我已经尝试了一切,矩阵乘法,偏移量,轴交换,没有运气。
guard let bodyAnchor = anchor as? ARBodyAnchor else { continue }
let skeleton = bodyAnchor.skeleton
let jointTransforms = skeleton.jointLocalTransforms
for (i, jointTransform) in jointTransforms.enumerated() {
//RETRIEVE ANGLES HERE
}
在//RETRIEVE ANGLES HERE
中,我尝试了不同的方法:
let n = SCNNode()
n.transform = SCNMatrix4(jointTransform)
print(n.eulerAngles)
在这次尝试中,我将 jointTransformation 设置为SCNNode.transform
,以便可以检索 eulerAngles 以使其易于阅读,并尝试了解正在发生的事情。
我开始工作一些关节,但是我认为这纯粹是巧合或运气,因为其余的骨头旋转得很奇怪。
在其他尝试中,我使用 jointModelTransforms (模型,而不是Local)来获取它们,因此所有变换都相对于骨架的根骨骼。
使用这种方法,我可以像这样进行矩阵乘法:
LocalMatrix = Inverse(JointModelMatrix) * (ParentJointModelMatrix)
要获得相对于其父对象的旋转,但在相同情况下,一些骨骼可以旋转,而其他骨骼则怪异地旋转。我敢打赌,纯属巧合。
为什么要使骨骼旋转?
我正在尝试使用手机构建MoCap应用程序,并将旋转传递给Blender,并尝试从中构建.BVH文件,以便可以在Blender上使用它们。
这是我自己的装备:
我以前使用Kinect做到了这一点,但我已经尝试了好几天在ARKit 3上做到这一点,但没有运气:(
答案 0 :(得分:0)
只是一个猜测……这能起到作用吗?
let skeleton = bodyAnchor.skeleton
let jointTransforms = skeleton.jointLocalTransforms
for (i, jointTransform) in jointTransforms.enumerated() {
print(Transform(matrix: jointTransform).rotation)
}
答案 1 :(得分:0)
使用simd_quatf(from:to:)
和正确的输入即可。在开始对向量进行归一化之前,我一直在处理怪异的角度:
guard let bodyAnchor = anchor as? ARBodyAnchor else { continue }
let skeleton = bodyAnchor.skeleton
let jointTransforms = skeleton.jointLocalTransforms
for (i, jointTransform) in jointTransforms.enumerated() {
// First i filter out the root (Hip) joint because it doesn't have a parent
let parentIndex = skeleton.definition.parentIndices[i]
guard parentIndex >= 0 else { continue } // root joint has parent index of -1
//RETRIEVE ANGLES HERE
let jointVectorFromParent = simd_make_float3(jointTransform.columns.3)
let referenceVector: SIMD3<Float>
if skeleton.definition.parentIndices[parentIndex] >= 0 {
referenceVector = simd_make_float3(jointTransforms[parentIndex].columns.3)
} else {
// The parent joint is the Hip joint which should have
// a vector of 0 going to itself
// It's impossible to calculate an angle from a vector of length 0,
// So we're using a vector that's just pointing up
referenceVector = SIMD3<Float>(x: 0, y: 1, z: 0)
}
// Normalizing is important because simd_quatf gives weird results otherwise
let jointNormalized = normalize(jointVectorFromParent)
let referenceNormalized = normalize(referenceVector)
let orientation = simd_quatf(from: referenceNormalized, to: jointNormalized)
print("angle of joint \(i) = \(orientation.angle)")
}
但要记住的一件事:
ARKit3仅跟踪某些关节(AFAIK在ARSkeleton.JointName
中命名为关节)。其他关节是从使用标准骨架的关节中推断出来的。这意味着,例如,您为肘部获得的角度将不是被跟踪的人肘部在那里的确切角度。