Search code examples
iosscenekitarkitscnnode

How to apply some changes to SCNNode with completion handler


Basically I want to apply some changed to SCNNode (e.g. change morpher.weights or change skeleton transform) and render scene after that.

scnRenderer.scene = sceneView?.scene
scnRenderer.pointOfView = sceneView?.pointOfView
scnRenderer.sceneTime = 1
scnRenderer.render(atTime: 0, viewport: viewport, commandBuffer: commandBuffer, passDescriptor:
                currentPassDescriptor)
commandBuffer.addCompletedHandler { (buffer) in
    animateNextStep?()
}
commandBuffer.commit()

And I want to do it for the whole animation. Pseudocode will look like:

func animateNextStep() { //will be called in render function after rendering
    guard step < count else { return }

    step += 1
    node.applySomeChanges()
    render()
}

Currently 80% of the images is good and contains model with correct position of bones and correct morpher weights and 20% not (looks like it was rendered with previous values). I want some completion handler after applying the changes to the node.

I can wrap rendering in DispathQueue.main.asyncAfter but I think there are should be some good solution.

How to do it right?


Solution

  • Could be an issue with the transactions but it's hard to say without more context.

    In applySomeChanges you can try to use an explicit transaction

    [SCNTransaction begin];
    [SCNTransaction setAnimationDuration:0];
    
    // changes to SceneKit objects
    
    [SCNTransaction commit];
    

    and you can also try to call [SCNTransaction flush]; at the beginning of your render method.