在金属中获取屏幕上位置的对象



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

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

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

最新更新