获取指向SCNNode的脸部索引

问题描述 投票:1回答:1

我陷入困境,因为我以前从未使用过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个回答
0
投票

我知道了这个问题。我做了两件事来获得面朝上的准确索引。

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
}
© www.soinside.com 2019 - 2024. All rights reserved.