Skeleton node not set when creating SCNSkinner + other bone issues.

Hey! Hope you are well 🙂


I am exploring the SceneKit API, and have been experimenting with building models and animations from scratch (rather with an external tool/dae files as most documentation seems to suggest). This experiment has been primarily for XCode 9.4, on macOS 10.13.5, building for the macOS environment and occasionally duplicating the functionality over to a sister iOS project for version 11.4 running on an iPhone SE.


One thing I've noticed is that when I create an SCNSkinner is that the skeleton property returns nil and none of the bones seems to have preserved their node hierarchy. This means that when I move a parent/root bone node, only that node moves along with it's associated mesh. What might be causing the skeleton property to not be set, and why isn't this bone node hierarchy being preserved?


This is also connected to another issue. When I attempt to apply any kind of animation directly to the bones, I don't seem to be able to get any kind of response. The node that is holding the skinner appears to receive animation as when I attach child nodes to it along with animation, I can see these child nodes are animating as they should. However, the bones and mesh as part of the skinner property do not animate. The only way I can affect these bone nodes, and see the resulting change reflected in the skinner mesh, is to run single operations to alter the bone node somehow, such as changing its position. Therefore, the only way I can animate a skinner is to attach a custom SCNAction to the base model node, then use the elapsed time and duration to calculate changes to the property value over time, which to me seems overly manual considering the options available in the API.


This missing functionality appears to extend to other properties such as constraints, which are really in my opinion the meat of skeletal animations as they allow access to IK and Ball/Joint relationships necessary to make the animation process relatively painless. The gist of this project is to explore the possibility of 3D modeling and animation tooling built upon Swift/SceneKit rather than utilising third-party software, or rebuilding what SceneKit is attempting to do from scratch due to the lack of documentation and access to the source code.


Despite some undocumented caveats that I discovered when creating the SCNSkinner, is there anything that I may be missing which is preventing these properties from operating as it seems they should?


The project source code is available here: https://github.com/louisfoster/glob and I am specifically referring to the work on this file: https://github.com/louisfoster/glob/blob/master/glob/Components/AnimGeo.swift


Of course, another option would be to continually generate and parse a DAE file as I edit (model/rig/animate) a 3D file, changing it too and frome a SCNScene etc. However, I believe this is probably a much too brute force method. I have also found there are issues with SceneKit's interaction with some DAE file structures, and requires workarounds or the utilisation of Model I/O which is a fairly round-about way to solve the problems I am facing.


Thanks for your time, and I hope I have clearly outlined the problem I am facing.

Replies

A few years late, but hopefully this is helpful to someone. I was in exactly the same situation you were and stumbled across this post while looking for solutions.


Through trial and error, I found that bone animation will work if you create and manage the skeleton node manually. You can create a node, add all the bone nodes as children, assign it to the skinner, and finally add it to the node hierarchy. I got tripped up because it seems like SCNSkinner should be able to handle all of that automatically since you're already providing the bone nodes to it and associating it with a node in the hierarchy. But everything seems to be working as expected now after setting it up this way.


Good luck!