Zach Fuller Zach Fuller - 20 days ago 7
Swift Question

Detecting touch in SceneKit

I have a question that about detecting touch in SceneKit. I have been able to find questions about how to detect when a certain object is touched but I need something a bit more specific. I need to be able to tell when a certain part of an object is touched. To explain a little better, I have a 3d model of a human and I need to be able to tell when say the head is touched or the leg is touched etc. If any further clarification is needed I would be glad to provide it, I'm just not quite sure how to accomplish this.

Answer

To expand on NicoS's answer: hit testing is the way to do this. But you actually have several possible options for identifying model parts in a hit test result, so you can choose the one that best fits your content creation pipeline.

  1. As noted in other answers, if you can break your model up into separate models, each of which is hosted in the scene with its own node, you can use the SCNHitTestResult.node property to find out which node was clicked/tapped/grabbed.

  2. If you can't split the model completely, you may be able to split it into multiple parts that still live in the same asset/node. SceneKit calls these geometry elements, some authoring tools call them submeshes, low-level rendering code calls it a separate draw call with a separate index buffer, etc. When you have separate geometry elements (which are necessary for drawing one geometry with multiple materials on different parts of the geometry), you can identify them in hit-testing with the SCNHitTestResult.geometryIndex property. (This approach is used in the answer HalMueller linked to.)

  3. If you control the texture mapping data for the mesh, you can use textureCoordinates(withMappingChannel:) to get texture coordinates for the clicked point, then look them up in a texture image in which you've color-coded the ares of interest. (You can get a general overview for the theory behind this idea in this article, though the implementation isn't specific to SceneKit.)

  4. If your model is rigged for skeletal animation, you can use the SCNHitTestResult.boneNode property to get the bone most responsible for geometry deformation at the clicked point.

Comments