How to access modified geometry from SceneKit?

I am using SceneKit on Mac OS X to load a COLLADA (DAE) file containing an animated object.


      let modelNode = SCNNode()
      modelNode.name = "ModelNode"
      let modelScene = SCNScene(named: "art.scnassets/obj/Spiderman.dae")
      if let childNodes = modelScene?.rootNode.childNodes {
         for childNode in childNodes {
            modelNode.addChildNode(childNode as SCNNode)
         }
      }

      let modelNodeArmature = modelNode.childNodeWithName("Armature", recursively: true)


I then apply an action to animate the object which is then rendered. I would then like to get access to the modified geometry (i.e. the vertices). I tried doing the following:


      let armatureGeometry = modelNodeArmature?.geometry!.geometryElementAtIndex(0)
      let geometryData = NSData(data: armatureGeometry!.data)


However, when I compare the animated geometry to the original one, I find that the data has not changed. I have also read that only the SceneKit renderer applies the necessary transformations to render the geometry, and the original is left as is:


http://stackoverflow.com/questions/29533199/scenekit-how-to-update-scngeometrysource?rq=1


Is there another way that I can access the updated geometry? In particular, I want to extract the animated vertices.

Replies

Hi LeanneM,


This is not the way it works. Loading Vertices in the GPU memory is slow and therefore, they generally won't be changed once they're loaded.

There are two ways to animate them:

  1. changing the Model matrix. The matrix defines the position, scale and orientation of a Geometry, relative to the scene (“world”). In Scene Kit, the Geometry is attached to a node, and the transformations to this node and its parents define the Model matrix. I believe that this is the only kind of animations that a Collada file can define.
  2. using a Vertex or Geometry shader. The shader receives the list of vertices and transforms them, before they're rendered. The original data is untouched.


In both cases, the vertices are never changed. Scene Kits allows reading back the vertices of a Geometry, but the object is immutable.


Maybe could you tell us what you're trying to achieve instead ?

Hello ElRhino,


It is been a while since some activity has happend here. I have faced with exact same issue - I need to update the original vertex source that is located in SCNNode. More specifically I'm talking about geometry property (which is immutable).


Let me explain what I do:


1. I have a vetex shader modifier that performs both deformation and rotatation of a vertex. Both operations (re-orinetaiton or deformation in the context of geometry surface and rotation of vertex) are important to perform one after the other on each individual vertex. Here I have no issues, everything works great.
2. However after the animation is performed, the geometry is located in one position (deformed and rotated) and the original SCNNode is in other position. This leads to impossibiity to interact (perform hit test) with that deformed node since as you pointed out there is no way to mutate original source of vertex data in SCNNode instance.


I tried to use compute kernel and reengineer my mathematical model that deforms surface. And again - I cannot inteact with it after the deformation has happened. This is what I try to acheve - perform hit test with the deformed geometry. Aparently SceneKit does not allow that, even if I use Metal compute kernel that allows to mutate vertex data buffer - SceneKit geometry does not have API to perform that kind of operation.



It leads to a question: how to bring interactivity (hit test) to deformed geometry in SceneKit?