【问题标题】:Aligning ARFaceAnchor with SpriteKit overlay将 ARFaceAnchor 与 SpriteKit 叠加层对齐
【发布时间】:2019-04-10 01:50:49
【问题描述】:

我正在尝试在特定几何点ARFaceGeometry/ARFaceAnchor 上计算 SpriteKit 覆盖内容位置(不仅仅是覆盖视觉内容)。

我正在使用计算出的世界坐标中的SCNSceneRenderer.projectPoint,但结果是 y 反转并且未与相机图像对齐:

let vertex4 = vector_float4(0, 0, 0, 1)
let modelMatrix = faceAnchor.transform
let world_vertex4 = simd_mul(modelMatrix, vertex4)
let pt3 = SCNVector3(x: Float(world_vertex4.x),
                     y: Float(world_vertex4.y),
                     z: Float(world_vertex4.z))
let sprite_pt = renderer.projectPoint(pt3)

// To visualize sprite_pt
let dot = SKSpriteNode(imageNamed: "dot")
dot.size = CGSize(width: 7, height: 7)
dot.position = CGPoint(x: CGFloat(sprite_pt.x), 
                       y: CGFloat(sprite_pt.y))
overlayScene.addChild(dot)

【问题讨论】:

    标签: swift sprite-kit scenekit arkit face


    【解决方案1】:

    根据我的经验,ARKit 的projectPoint 函数给出的屏幕坐标在绘制到例如CALayer 时可以直接使用。这意味着它们遵循here 中描述的 iOS 坐标,其中原点在左上角,y 是倒置的。

    SpriteKit 有its own coordinate system:

    单位坐标系将原点放置在框架的左下角,将(1,1)放置在框架的右上角。 sprite 的锚点默认为 (0.5,0.5),对应于帧的中心。

    最后,SKNodes 被放置在一个 SKScene 中,它的原点位于左下角。您应该确保您的 SKScene 与您的实际视图大小相同,否则原点可能不在视图的左下角,因此您从视图坐标中定位节点的位置可能不正确。 this question 的答案可能会有所帮助,特别是检查视图的 AspectFit 或 AspectFill 以确保您的场景被缩小。

    场景的原点位于左下角,根据您的场景大小和缩放比例,它可能会在屏幕外。这是 0,0 所在的位置。因此,您添加的每个孩子都将从那里开始,并根据位置向上和向上工作。 SKSpriteNode 的原点位于中心。

    因此,从视图坐标和 SpriteKit 坐标转换的两个基本步骤是 1) 反转 y 轴,使原点位于左下方,以及 2) 确保 SKScene 框架与视图框架匹配。

    我可以稍后更全面地测试一下,如果有任何问题,我会进行编辑

    【讨论】:

    • 我发布了一个简单的测试用例来演示这个问题:github.com/AnsonT/ARFaceSpriteKitMapping。使用 ProjectPoint 映射到 spritekit 坐标的顶点只是不与图像或场景套件几何图形对齐。非常感谢您查看我的问题。
    • 注意,目标是做正确的变换计算以映射到相机图像,我只是使用 spritekit 进行可视化。
    • 您想要映射到的“相机图像”是什么意思?喜欢实际的ARFrame?如果您只是使用 SpriteKit 来可视化 projectPoint 的输出,那么您的可视化器的坐标系将与您最终尝试映射到的坐标系不同。
    • 是的,ARFrame,capturedImage。
    • 那么最终你会想要从屏幕坐标转换为 ARFrame 坐标。尝试使用ARFrame's displayTransform function 给出的变换矩阵的逆矩阵。您可能必须首先对 projectPoint 调用返回的坐标进行归一化。
    【解决方案2】:

    找到了使用 camera.projectPoint 而不是 renderer.projectPoint 的转换。

    要在 spritekit 上正确缩放点:设置 scaleMode=.aspectFill

    我更新了https://github.com/AnsonT/ARFaceSpriteKitMapping 来演示这个。

        guard let faceAnchor = anchor as? ARFaceAnchor,
            let camera = sceneView.session.currentFrame?.camera,
            let sie = overlayScene?.size
        else { return }
    
        let modelMatrix = faceAnchor.transform
    
        let vertices = faceAnchor.geometry.vertices
    
        for vertex in vertices {
            let vertex4 = vector_float4(vertex.x, vertex.y, vertex.z, 1)
            let world_vertex4 = simd_mul(modelMatrix, vertex4)
            let world_vector3 = simd_float3(x: world_vertex4.x, y: world_vertex4.y, z: world_vertex4.z)
    
            let pt = camera.projectPoint(world_vector3, orientation: .portrait, viewportSize: size)
    
            let dot = SKSpriteNode(imageNamed: "dot")
            dot.size = CGSize(width: 7, height: 7)
            dot.position = CGPoint(x: CGFloat(pt.x), y: size.height - CGFloat(pt.y))
            overlayScene?.addChild(dot)
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-30
      • 2017-03-12
      • 1970-01-01
      • 2020-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-25
      相关资源
      最近更新 更多