【问题标题】:Get the index of the face pointing up of SCNNode获取 SCNNode 向上的人脸索引
【发布时间】:2020-09-21 02:59:07
【问题描述】:

我陷入了一个困难的场景,因为我之前从未使用过 scenekit。我必须创建一个骰子,滚动时应打印所选数字。我使用 scenekit 实现了骰子,然后使用以下函数滚动它:

func roll(dice: SCNNode) {
    let randomX = Float(arc4random_uniform(4) + 1) * (Float.pi / 2)
    let randomZ = Float(arc4random_uniform(4) + 1) * (Float.pi / 2)

    dice.runAction(
        SCNAction.rotateBy(x: CGFloat(randomX * 5), y: 0, z: CGFloat(randomZ * 5), duration: 0.5)
    )

    DispatchQueue.main.asyncAfter(deadline: .now()+1) {
        print("Up side: \(self.boxUpIndex(self.dice)+1)")
    }
 }

然后我尝试使用以下代码获取所选号码,但是它不会打印正确的所选面。

func boxUpIndex(_ boxNode: SCNNode?) -> Int {
    let rotation = boxNode?.orientation

    var invRotation = rotation
    invRotation?.w = -(rotation?.w ?? 0.0)

    let up = SCNVector3Make(0, 1, 0)

    //rotate up by invRotation
    let transform = SCNMatrix4MakeRotation(invRotation?.w ?? 0.0, invRotation?.x ?? 0.0, invRotation?.y ?? 0.0, invRotation?.z ?? 0.0)
    let glkTransform = SCNMatrix4ToGLKMatrix4(transform)
    let glkUp = SCNVector3ToGLKVector3(up)
    let rotatedUp = GLKMatrix4MultiplyVector3(glkTransform, glkUp)

    let boxNormals = [
        GLKVector3(
            v: (0, 1, 0)
            ),
        GLKVector3(
            v: (0, 0, 1)
            ),
        GLKVector3(
            v: (1, 0, 0)
            ),
        GLKVector3(
            v: (0, 0, -1)
            ),
        GLKVector3(
            v: (-1, 0, 0)
            ),
        GLKVector3(
            v: (0, -1, 0)
            )
    ]

    var bestIndex = 0
    var maxDot: Float = -1

    for i in 0..<6 {
        let dot = GLKVector3DotProduct(boxNormals[i], rotatedUp)
        if dot > maxDot {
            maxDot = dot
            bestIndex = i
        }
    }

    return bestIndex
  }

我还附加了虚拟 xcode 项目以在您的最后尝试。 https://github.com/amrit42087/Dice

任何指导都会很有帮助。提前致谢。

【问题讨论】:

    标签: ios objective-c swift scenekit scnnode


    【解决方案1】:

    我发现了这个问题。我做了两件事来获得面部朝上的确切索引。

    1) 我使用了一些其他的 3d 模型,而不是我之前使用的那个。实际上,之前的 3d 模型最初并不是从正确的位置开始的。所以。我必须将 SCNode 旋转到准确的位置才能获得向上的面的正确索引。

    2)我将获取人脸索引的代码修改为:

    func boxUpIndex(_ boxNode: SCNNode?) -> Int {
        let rotation = boxNode?.rotation
        var invRotation = rotation
        invRotation?.w = -(rotation?.w ?? 0.0)
    
        let up = SCNVector3Make(0, 1, 0)
    
        //rotate up by invRotation
        let transform = SCNMatrix4MakeRotation(invRotation?.w ?? 0.0, invRotation?.x ?? 0.0, invRotation?.y ?? 0.0, invRotation?.z ?? 0.0)
        let glkTransform = SCNMatrix4ToGLKMatrix4(transform)
        let glkUp = SCNVector3ToGLKVector3(up)
        let rotatedUp = GLKMatrix4MultiplyVector3(glkTransform, glkUp)
    
        let boxNormals = [
            GLKVector3(v: (0, 0, 1)),
            GLKVector3(v: (1, 0, 0)),
            GLKVector3(v: (0, 0, -1)),
            GLKVector3(v: (-1, 0, 0)),
            GLKVector3(v: (0, 1, 0)),
            GLKVector3(v: (0, -1, 0))
        ]
    
        var bestIndex = 0
        var maxDot: Float = -1
    
        for i in 0..<6 {
            let dot = GLKVector3DotProduct(boxNormals[i], rotatedUp)
            if dot > maxDot {
                maxDot = dot
                bestIndex = i
            }
        }
    
        return DiceFace(rawValue: bestIndex)?.value() ?? 0
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-29
      • 1970-01-01
      • 2015-01-05
      • 2019-08-15
      • 2019-01-27
      • 2020-07-16
      • 2013-01-11
      • 2016-05-05
      • 1970-01-01
      相关资源
      最近更新 更多