0

我正在使用 Metal,我希望用户能够点击屏幕上的某些对象。我正在使用轻击手势识别器,所以我有一个 CGPoint,但我不知道如何在那个时候找到对象。有没有办法获取金属的屏幕坐标,或者有办法将 CGPoint 转换为金属坐标空间?

4

1 回答 1

0

我最终用光线追踪类型的技术做到了这一点。我为每个对象使用了一个边界球,并计算了光线是否与它相交以及相交点距离光线原点的距离有多远,光线来自相机通过屏幕上的点击点。代码如下:

    var location = gestureRecognizer.locationInView(self.view)
    var proj_matrix = projectionMatrix.copy()
    var view_matrix = worldMatrix.copy()
    var x = (2.0 * location.x) / self.view.bounds.size.width - 1.0;
    var y = 1.0 - (2.0 * location.y) / self.view.bounds.size.height;
    var newLocation = simpleVertex(x: Float(x), y: Float(y), z: Float(-1.0))
    var projSpaceLoc = GLKMatrix4MultiplyVector4(GLKMatrix4Invert(proj_matrix.matrix(), nil), GLKVector4Make(newLocation.x, newLocation.y, newLocation.z, 1.0))
    projSpaceLoc = GLKVector4Make(projSpaceLoc.x, projSpaceLoc.y, -1.0, 0.0)
    var viewSpaceLoc = GLKMatrix4MultiplyVector4(GLKMatrix4Invert(view_matrix.matrix(), nil), projSpaceLoc)
    GLKVector4Normalize(viewSpaceLoc)
    //tappable is an array of nodes that can be tapped
    for node in tappable {
        var r: Float = node.r //this is the radius of the bounding sphere for that node
        var c: GLKVector4 = node.origin //this is the origin of the bounding sphere
        var little_c = GLKVector4DotProduct(c, c) - powf(r, 2)
        var b = GLKVector4DotProduct(viewSpaceLoc, c)
        var discriminant = powf(b, 2) - little_c
        //If the discriminant is positive, their are two points of intersection, if it is 0, one point, and if it is negative, no points.
     if (discriminant >= 0) {
            var t_1 = (Float(-1.0)*b) + sqrtf(discriminant)
            var t_2 = (Float(-1.0)*b) - sqrtf(discriminant)
            if (intersect != nil) {
                if (min(t_1, t_2) < intersect.intersect_point) {
                    intersect = (node, min(t_1, t_2))
                }
            } else {
                intersect = (node, min(t_1, t_2))
            }
        }
    }
于 2015-04-25T23:09:36.157 回答