How insideFrustumOf works correctly!

Hello everybody,


I just would like to share my knowledge about some confusing issues in SceneKit. I tried to make a frustum test using


sceneView.isNode(nodeToTest, insideFrustumOf: cameraNode)


just to test whether or not this not is visible from the camera. There were many pittfalls and for me using SceneKit the very first time understanding the documentation was hard, despite my little experience with Direct3D and OpenGL.


First of all: using SCNLookAtConstraint is perhaps not always a good idea. It's a realy nice feature, but it might lead to additional confusions, unless you understand what's going on behind the scenes. This constraint will be used during rendering and does not update any of the camera's properties! For this reason a node will be visible in the scene but the test fails!!!


If you prefer to use this constraint and you are calling the insideFrustumOf test with your nodes it will always fail unless your node is located at (0,0,0) and the camera is pointing to this position! However, as the documentation states, every node has a property "presentation" reflecting its current state. You should always use this presentationNode for this test:


sceneView.isNode(nodeToTest.presentation, insideFrustumOf: cameraNode.presentation)


The lookAt constraint is not the only pitfall. Using the pivot property or other things manipulating the node's model view matrix will all lead to the same problem. The insideFrustumOf method also works for child nodes having geometry of a parent node with no geometry - I did test it! So everything works as expected.


if you prefer not to use SCNLookAtConstraint for some reason create the view matrix for the camera and assign it to the transform property. The pivot property is not the right place for this, even it it would work.


Finally: when a node's isHidden property is set to true the node's boundingBox and boundingSphere properties both return a zero boundingVolume by design. Only for nodes which are not hidden will a boundingVolume be returned. The node's geometry property will always return a valid boundingVolume, independent from the node's hidden state. And in the documentation you will find the important hint: the boundingVolume is always given in the node's local coordinate system, so if you need to implement your own frustum test for some reason you need to transform them into the worldspace using the wordTransform property.


I run into many pittfalls as you can see... but I hope this makes the things a little bit more clear for you and avoids that you run into the same problems. I'm still far away from beeing a SceneKit expert, but now I feel more comfortable with it. Hope I could help!


Best regards,

Jürgen

Replies

Thanks for taking the time to share your experience with SceneKit. There isn't a lot of material to learn from in regards to SceneKit, so post like yours are really valuable to all of us learning SceneKit. I feel like I have a much better idea of how to use insideFrustumOf now, thanks again.

Update: suggestion made by JuergenT does seem to work. It took me a little playing around to get the results i wanted to achieve.

In my case, i added 2 invisible nodes at the left and right of main node to determine if the node should be moved left or right