In SceneKit, when creating an .scn file from a rigged model, the framework created an SCNNode for each bone/joint, so you could add and remove child nodes directly to and from joints, and like any other SCNNode, you could access world position and world orientation for each joint. The analog would be for joints to be accessible as child entities of a ModelEntity in RealityKit. I am unable to proceed with migrating my project from SceneKit because of this, as there does not seem to be a way to even access the true world position of a joint with the current jointNames/jointTransforms paradigm.
The translation information from the given transforms is insufficient to determine the location of a joint at any given time, and other approaches like creating a GeometricPin for the given joint name and attaching it to another entity do not seem to work. So conveniently being able to attach an item to the hand of a rigged model was trivial in SceneKit and now feels impossible in RealityKit.
I am not the first person to notice this, and am feeling demoralized about proceeding with RealityKit with such a critical piece of functionality blocked https://stackoverflow.com/questions/76726241/how-do-i-attach-an-entity-to-a-skeletons-joint-in-realitykit
Will this be addressed in some way?
Hello @AlphaHalcyonInteractive , thank you for your question!
I recommend downloading our BOT-anist sample, and take a look at how the head and backpack are attached to the body.
In RealityKit, the skeleton joint positions are not separate entities with transform components, as you might expect. This means you don't interact with them by placing other Entities as descendants of the skeleton joints. Instead, to get the position of a joint for the purpose of attaching another Entity to it, you calculate its transform by multiplying a chain of joint transforms together each frame.
There are a few steps to this, first you will need to get the indices for the chain of joints starting from the root joint that connect to your "head" or "backpack" or "arm_cannon" or whatever joint you're looking for.
In BOT-anist, see the function getJointHierarchy
in RobotCharacter.swift
for a code implementation.
Then, you will need to set the pin on the skeleton, which occurs on lines 92 and 93 in that same file, which will return an entity with a position you can use as an offset later.
Finally, the code for setting the position each frame exists in JointPinSystem.swift
in the function named pinEntity
. This contains the relevant code for multiplying your chain of joint transforms together and setting the position of the pinned entity.
This isn't as straight forward as placing a ModelEntity as a descendent of a joint entity, so I recommend detailing your use case and submitting your feedback using Feedback Assistant.
Let me know if you have any more questions!