7

我试图获得与他们父母相关的骨骼旋转,但我最终得到了非常奇怪的角度。

我已经尝试了一切,矩阵乘法,偏移量,轴交换,但没有运气。

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设置为a SCNNode.transform,这样我就可以检索eulerAngles以使其易于阅读并尝试了解正在发生的事情。

我开始锻炼一些关节,但我认为这纯属巧合或运气,因为其余的骨头旋转得很奇怪。

在其他尝试中,我使用jointModelTransforms(模型,而不是本地)来获取它们,因此所有变换都相对于骨架的根骨骼。

使用这种方法,我可以像这样进行矩阵乘法:

LocalMatrix = Inverse(JointModelMatrix) * (ParentJointModelMatrix)

为了获得相对于其父项的旋转,但在相同的情况下,一些骨骼旋转正常,而另一些旋转奇怪。我敢打赌纯属巧合。

为什么我要获得骨骼旋转?

我正在尝试用我的手机构建一个 MoCap 应用程序,将旋转传递给 Blender,尝试从中构建 .BVH 文件,这样我就可以在 Blender 上使用它们。

这是我自己的装备:

我以前用 Kinect 做过这个,但是我已经尝试了好几天在 ARKit 3 上做这个,但没有运气:(

4

2 回答 2

1

使用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)。其他关节是从使用标准化骨架的关节推断出来的。这意味着,例如,您获得的肘部角度不会是被跟踪人员肘部在那里的确切角度。

于 2019-11-10T16:43:04.147 回答
0

只是一个猜测......这可以完成工作吗?

  let skeleton = bodyAnchor.skeleton
  let jointTransforms = skeleton.jointLocalTransforms

  for (i, jointTransform) in jointTransforms.enumerated() {
    print(Transform(matrix: jointTransform).rotation)
  }
于 2019-10-20T18:57:40.387 回答