Reputation: 5347
I'm trying to detect a touch within a given area using SceneKit. It's fairly trivial to do this with one geometry (you just perform a hit test on the scene view) however, I have a custom area defined by an array of SCNNode
s (SCNVector3
s).
I create my custom area like so:
- (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;
}
}
}
}
So given my array of SCNBox
es how can I detect if another point falls in the middle of them?
Upvotes: 2
Views: 1226
Reputation: 2897
SCNView
conforms to the SCNSceneRenderer
protocol and this provides a method projectPoint:(SCNVector3)point
that takes a point within your 3D scene and projects it to 2D view coordinates.
I'd try projecting the position of your box nodes into 2D view coordinates, then check if your 2D touch coordinates are within this 2D shape. There's another SO question that will help with this.
Upvotes: 4