在 Swift 中识别触碰的立方体的面 - SceneKit [英] Identify face of a cube hit on touches began in Swift - SceneKit

查看:89
本文介绍了在 Swift 中识别触碰的立方体的面 - SceneKit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算用 SceneKit 创建一个应用程序来解决魔方问题.我为立方体制作了自己的 dae 文件.触摸开始时,我有被击中的对象

I'm tying to create an app with SceneKit to solve a Rubik's Cube. I've made my own dae file for the cube. Upon touches began I have the object that's been hit

  func tapGesture(sender: UITapGestureRecognizer){

    // check what nodes are tapped
    var p = sender.locationInView(sceneView)
    var hitResults = sceneView.hitTest(p, options: nil)
    if hitResults.count > 0
    {

        var hitnode = (hitResults.first)!.node
        print("\nName of node hit is \(hitnode.name)")
        
        //var indexvalue = hitResults.first?.faceIndex
        //print(indexvalue)
    }
  }

如何准确找到立方体的哪个面被击中?

How can I find exactly which face of the cube is being hit?

推荐答案

faceIndex 看起来很有希望,但实际上不会得到您可能认为有用的东西.该属性计算的面"是网格的细分,因此立方体不会是六个四边形的集合,而是十二个三角形.(或更多:在某些情况下,即使是平面立方体也会被镶嵌成每边超过一个四边形/两个三角形.如果您使用 SCNBox,您可以使用 widthSegmentCount<控制这些/code> 等)

faceIndex looks promising, but will not actually get something you're likely to consider useful. The "faces" counted by that property are the tessellation of the mesh, so a cube won't be a collection of six quads, it'll be twelve triangles. (Or more: in some cases, even a flat-sided cube will be tessellated with more than one quad / two triangles per side. If you're using SCNBox you control these with widthSegmentCount etc.)

相反——特别是如果你的立方体是一个 SCNBox——最简单的解决方案可能是利用该类的这个有趣的行为:

Instead — especially if your cube is an SCNBox — the easiest solution might be to leverage this interesting behavior of that class:

您最多可以将六个 SCNMaterial 实例分配给一个具有 materials 属性的盒子(每侧一个).SCNBox 类根据需要自动创建 SCNGeometryElement 对象来处理材料的数量.

You can assign up to six SCNMaterial instances to a box—one for each side—with its materials property. The SCNBox class automatically creates SCNGeometryElement objects as needed to handle the number of materials.

因此,如果您分配六种材料,则每一面都会得到一种:

So, if you assign six materials, you'll get one for each side:

let front = SCNMaterial()
let right = SCNMaterial()
let back = SCNMaterial()
let left = SCNMaterial()
let top = SCNMaterial()
let bottom = SCNMaterial()
cube.materials = [ front, right, back, left, top, bottom ]

这样做时,您的 SCNBox 将有六个几何元素 — 每种材料一个,每一面对应一个.

And in so doing, your SCNBox will have six geometry elements — one for each material, which corresponds to one for each side.

现在,您可以使用命中测试来找出被点击的几何元素:

Now, you can use hit testing to find out which geometry element was clicked:

if let result = hitResults.first {
    let node = result.node

    // Find the material for the clicked element
    // (Indices match between the geometryElements and materials arrays)
    let material = node.geometry!.materials[result.geometryIndex]

    // Do something with that material, for example:
    let highlight = CABasicAnimation(keyPath: "diffuse.contents")
    highlight.toValue = NSColor.redColor()
    highlight.duration = 1.0
    highlight.autoreverses = true
    highlight.removedOnCompletion = true
    material.addAnimation(highlight, forKey: nil)
}

或者,如果您不突出显示并希望使用人脸索引进行逻辑,那么您可以使用以下内容的开头:

Or if you're not highlighting and want to use the face index for logic, here's the beginning of something you could use for that:

enum CubeFace: Int {
    case Front, Right, Back, Left, Top, Bottom
}

// when processing hit test result:
print("hit face: \(CubeFace(rawValue: result.geometryIndex))")

这篇关于在 Swift 中识别触碰的立方体的面 - SceneKit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆