私は Metal を使用しており、ユーザーが画面上の特定のオブジェクトをタップできるようにしたいと考えています。タップジェスチャ認識エンジンを使用しているため、CGPoint がありますが、その時点でオブジェクトを見つける方法がわかりません。金属の画面上の座標を取得する方法、または CGPoint を金属座標空間に変換する方法はありますか?
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 に答える