Get the index of the face pointing up of SCNNode

只愿长相守 提交于 2020-06-16 19:12:11

问题


I am stuck in a difficult scenario as I had never worked with scenekit earlier. I had to create a dice that when rolled should print the number selected. I had implemented the dice using scenekit and then rolled it using the below function:

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)")
    }
 }

Then I try to get the selected number using the below code, however it doesnot print the correct selected side.

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
  }

I am also attaching the dummy xcode project to try it at your end. https://github.com/amrit42087/Dice

Any guidance would be more than helpful. Thanks in advance.


回答1:


I figured out the issue. I did two things to get the exact index of the face facing upwards.

1) I used some other 3d model instead of the one that I was using earlier. Actually the previous 3d model was not starting from the correct position initially. So. I had to roate the SCNode to the exact position to get the correct index of the upward facing face.

2) I modified the code for getting the index of the face to:

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
}


来源:https://stackoverflow.com/questions/62155439/get-the-index-of-the-face-pointing-up-of-scnnode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!