Can SCNGeometry.levelsOfDetail be used with animated models?

I have two animated models (each in it's own .dae file) representing the same character. One has a high polygon count for close up, the other is lower poly count for use when the model is farther away from the viewer. I have created and setup levelsOfDetail such that the model geometry is swapped out automatically by SceneKit based on it's distance from the viewer. This works fine. The problem I have is when geometry from the .levelsOfDetail collection is swapped in, the model loses it's animation. The swapped geometry appears fine but is static, and in it's pose before any skeletal deformation. As a test, I wrote code to manually swap to low poly geometry and the skinner from the low poly .dae. Using the test code everything works as expected.


Since levelsOfDetail is intialized with SCNGeometry and not an SCNNode, I don't see a way to associated the low poly geometery and skinner so they both get swapped. Before I abandon the Apple provided level of detail swapping for my own method (in render loop, check each node distance from viewer and swap geometry and skinner as needed) I thought I'd see if there is a way to make this work. I am unsure if levelsOfDetail is not designed for animated models or my problem is due to something in how the artist provided .dae files are setup.

Replies

This won't help you at all, but I'm wondering how you get levelsOfDetail to work in the first place. Appending SCNLevelofDetail objects to my geometry's levels of detail seems to do nothing, and the levelsOfDetail value returns nil after the object is appended. I'm stumped.

It does work for me. Not sure how what you are trying is different. I am instantiating a SCNLevelOfDetail object and assigning that (in a set) to the .levelsOfDetail property of the geometry. From there it just works. SceneKit swaps my model geometry based on distsance from viewer.


if let aGeometry = aLowResScene.rootNode.firstGeometryNodeInHeirarchy()?.geometry {
  // Create a low res level of detail
  let aLevelOfDetail = SCNLevelOfDetail(geometry: aGeometry, screenSpaceRadius: Constant.lowResModelMaxRadiusToAppear)

  // Add level of detail to the root node's geometry
  aModelRootNode.firstGeometryNodeInHeirarchy()?.geometry?.levelsOfDetail = [aLevelOfDetail]
}