【问题标题】:Retrieving bone rotations from 3D Skeleton in ARKit 3从 ARKit 3 中的 3D 骨架中检索骨骼旋转
【发布时间】:2020-01-23 04:03:31
【问题描述】:

我正在尝试获取与其父母相关的骨骼旋转,但我最终得到了非常奇怪的角度。

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

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 以使其易于阅读并尝试了解正在发生的事情。 p>

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

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

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

LocalMatrix = Inverse(JointModelMatrix) * (ParentJointModelMatrix)

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

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

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

这是我自己的装备:

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

【问题讨论】:

    标签: swift arkit ios13 realitykit


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

    【讨论】:

    • 要去试试这个 :-) 会让你知道的
    • 试过了,但角度似乎没有改变。我总是在 orientation 变量中得到一个 T-Pose,无论人是否在移动。我做错了吗?我只是为每个骨骼获取了orientation 变量并将其应用于我的装配角色。在将它应用到我的角色之前,我应该对这个方向做些什么吗?
    • 好的,TBH 我在自己的项目中实际使用的是jointModelTransforms,然后是关节位置和父关节位置之间的差异以获得“骨骼矢量”。这绝对适合我。
    • 你能用代码详细说明你的答案吗?所以我明白你在做什么。例如,我在您发布的答案中看不到jointModelTransform。
    【解决方案2】:

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

      let skeleton = bodyAnchor.skeleton
      let jointTransforms = skeleton.jointLocalTransforms
    
      for (i, jointTransform) in jointTransforms.enumerated() {
        print(Transform(matrix: jointTransform).rotation)
      }
    

    【讨论】:

    • 这是我已经尝试过的,我可以说 ArKit 3 目前对于 MoCap 来说是可怕的。 T-Pose 甚至没有归零。 :(如果有人取得了任何成就,请发表评论
    猜你喜欢
    • 2021-01-20
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多