在Metal的屏幕上获取对象

时间:2015-04-25 15:01:23

标签: ios graphics 3d uitapgesturerecognizer metal

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

1 个答案:

答案 0 :(得分: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))
            }
        }
    }