获取SCNNode向上的人脸索引 [英] Get the index of the face pointing up of SCNNode
问题描述
我陷入了一个困难的境地,因为我之前从未使用过 Scenekit.我必须创建一个骰子,滚动时应打印所选的数字.我使用scenekit实现了骰子,然后使用以下函数滚动它:
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
}
我还附上了虚拟的 xcode 项目,以便在您的最后尝试.https://github.com/amrit42087/Dice
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.
推荐答案
我发现了这个问题.我做了两件事来获得面朝上的确切索引.
I figured out the issue. I did two things to get the exact index of the face facing upwards.
1) 我使用了其他一些 3d 模型,而不是我之前使用的模型.实际上,之前的 3d 模型最初并没有从正确的位置开始.所以.我必须将 SCNode 旋转到准确位置才能获得正确的朝上面索引.
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) 我修改了获取人脸索引的代码:
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
}
这篇关于获取SCNNode向上的人脸索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!