SceneKit检测给定区域的触摸

时间:2015-10-14 14:14:46

标签: objective-c 3d scenekit

我尝试使用SceneKit检测给定区域内的触摸。使用一个几何体来执行此操作相当简单(您只需在场景视图上执行命中测试)但是,我有一个由SCNNode s(SCNVector3 s数组定义的自定义区域)。

我像这样创建自定义区域:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    if (!self.isMakingLine) {
        [super touchesBegan:touches withEvent:event];
    } else {
        self.vectors = [[NSMutableArray alloc] init];
        NSArray <SCNHitTestResult *> *res = [self.sceneView hitTest:[[touches anyObject] locationInView:self.sceneView] options:@{SCNHitTestFirstFoundOnlyKey : @YES}];
        if (res.count) {
            SCNHitTestResult *result = res.lastObject;
            if (result.node == self.sphereNode) {
                SCNNode *n = [SCNNode nodeWithGeometry:[SCNBox boxWithWidth:0.01 height:0.01 length:0.01 chamferRadius:0]];
                n.geometry.firstMaterial.diffuse.contents = [UIColor greenColor];
                n.position = result.localCoordinates;
                [self.sphereNode addChildNode:n];
                [self.vectors addObject:n];
            }
        }
    }
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    if (!self.isMakingLine) {
        [super touchesMoved:touches withEvent:event];
    } else {
        NSArray <SCNHitTestResult *> *res = [self.sceneView hitTest:[[touches anyObject] locationInView:self.sceneView] options:@{SCNHitTestFirstFoundOnlyKey : @YES}];
        if (res.count) {
            SCNHitTestResult *result = res.lastObject;
            if (result.node == self.sphereNode) {
                SCNNode *n = [SCNNode nodeWithGeometry:[SCNBox boxWithWidth:0.01 height:0.01 length:0.01 chamferRadius:0]];
                n.geometry.firstMaterial.diffuse.contents = [UIColor greenColor];
                n.position = result.localCoordinates;
                [self.sphereNode addChildNode:n];
                [self.vectors addObject:n];
            }
        }
    }
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    if (!self.isMakingLine) {
        [super touchesEnded:touches withEvent:event];
    } else {
        NSArray <SCNHitTestResult *> *res = [self.sceneView hitTest:[[touches anyObject] locationInView:self.sceneView] options:@{SCNHitTestFirstFoundOnlyKey : @YES}];
        if (res.count) {
            SCNHitTestResult *result = res.lastObject;
            if (result.node == self.sphereNode) {
                SCNNode *n = [SCNNode nodeWithGeometry:[SCNBox boxWithWidth:0.01 height:0.01 length:0.01 chamferRadius:0]];
                n.geometry.firstMaterial.diffuse.contents = [UIColor greenColor];
                n.position = result.localCoordinates;
                [self.sphereNode addChildNode:n];
                [self.vectors addObject:n];
                self.isMakingLine = NO;
            }
        }
    }
}

所以给定我的SCNBox数组我怎样才能检测出另一个点是否落在它们中间?

1 个答案:

答案 0 :(得分:4)

SCNView符合SCNSceneRenderer协议,这提供了一种方法projectPoint:(SCNVector3)point,可以在3D场景中占据一个点并将其投影到2D视图坐标。

我会尝试将您的盒子节点的位置投影到2D视图坐标,然后检查您的2D触摸坐标是否在此2D形状内。 There's another SO question会对此有所帮助。