3

This is my problem. I have create an object on maya that have the following hierarchy:

bigButton
   | 
   |--  redDome
   |       |
   |       |-- polySurface1
   |       |__ polySurface2
   |
   |--  greenDome
          |
          |-- polySurface3
          |__ polySurface4

I convert that to DAE and import it on SceneKit. Two more nodes are added to the hierarchy by Xcode. The hierarchy is now:

bitButton Reference
   |
   |_ referenceRoot
          |
          |
          |__ bigButton 
                   | 
                   |--  redDome
                   |       |
                   |       |-- polySurface1
                   |       |__ polySurface2
                   |
                   |--  greenDome
                           |
                           |-- polySurface3
                           |__ polySurface4

Now I touch the button and I am trying to determine if the button was tapped. The only node that matters to me is bigButton. WHen I tap the object and use this method:

- (void) handleTap:(UIGestureRecognizer*)gestureRecognize
{
    // retrieve the SCNView
    SCNView *scnView = (SCNView *)self.view;

    // check what nodes are tapped
    CGPoint p = [gestureRecognize locationInView:scnView];
    NSArray *hitResults = [scnView hitTest:p options:nil];

    // check that we clicked on at least one object
    if([hitResults count] > 0){
        // retrieved the first clicked object
        SCNHitTestResult *result = [hitResults objectAtIndex:0];

result.node tells me that the node touched was polySurface1 or polySurface2 whatever. It will never tell me that bigButton was tapped because that is just a node, not a surface.

OK, I can use parentNode to detect the parent's node but this is stupid because result.node can be on different hierarchy levels above or below bigButton. Is this the only lame mode to do that? To transverse the hierarchy searching for the correct node or is is there a beautiful way?

thanks.

Duck
  • 34,902
  • 47
  • 248
  • 470

1 Answers1

2

The only node that matters to me is bigButton.

If by that you mean that you'll never be interested in knowing that any other node was hit, then you should take a look at the SCNHitTestRootNodeKey hit-testing option.

Specifying bigButton as the root node implies that getting any hit-test result means that bigButton was hit, without having to do any check.

mnuages
  • 13,049
  • 2
  • 23
  • 40
  • I mean that `bigButton` is composed of several descendant members. Any touch on any of these members should be detected as `bigButton` being touched. If this can be done like you say, can you give an example of the code I have to use? Apple documentation, as usual, is useless. – Duck Mar 06 '16 at 06:33
  • 1
    I have used these options and it gives me a `nil` `hitResults` ... `@{SCNHitTestRootNodeKey : bigButton, SCNHitTestIgnoreChildNodesKey : @(YES)}` – Duck Mar 06 '16 at 06:44
  • you must not set `SCNHitTestIgnoreChildNodesKey` to `YES`. This would mean that exactly one node (`bigButton`) will be tested, but as you said this node has no geometry and can't be hit. Use only `SCNHitTestRootNodeKey`, it will restrict hit-testing to `bigButton` **and** its child nodes. This way you can be sure that if there's a result, it comes from node under `bigButton`. – mnuages Mar 06 '16 at 09:16
  • sorry, I did that but it stills continue to detect `polySurface1`, `polySurface2`, `polySurface3`... I want this: the user taps on `polySurface1`, code detects "user tapped bigButton"... user taps on `polySurface2`, code detects "user tapped bigButton". Everything that is part of `bigButton` should be detected as `bigButton` not `polySurface1`, etc. – Duck Mar 06 '16 at 09:21
  • 1
    you can't have a `SCNHitTestResult` lie about which node was hit. But because you restricted hit-testing to `bigButton` and its child nodes, there's no further logic to implement. Getting any result means that something under `bigButton` was hit. So it's exactly what you want. – mnuages Mar 06 '16 at 09:31
  • ah, I see, duuuh!! Please add this information to your answer so I can accept it. – Duck Mar 06 '16 at 11:01
  • For posterity I was having an issue where a SCNView's hitTest wasn't finding a node that was behind another node, even though `SCNHitTestOption.firstFoundOnly` was false. Restricting the test to the node I wanted to find via `SCNHitTestOption.rootNode` did the trick. – John Scalo Sep 27 '17 at 19:49