У меня также есть анимация для этой модели, находящаяся в отдельном файле fbx. Я конвертирую ее в dae в Blender.
Их иерархия одинаковая, поэтому я просматриваю каждую анимацию в своем файле анимации и добавляю ее в соответствующий узел моей модели
func applyAnimation(on scene: SCNScene) {
guard
let animationSource = getAnimationSource()
else {
return
}
let identifiers = animationSource.identifiersOfEntries(
withClass: SCNAnimation.self
)
identifiers.forEach {
guard
let animation = animationSource.entryWithIdentifier($0, withClass: SCNAnimation.self)
else {
return
}
guard
let fullKeyPath = animation.keyPath,
let keyPath = fullKeyPath.dropFirst().components(separatedBy: ".").first
else {
return
}
animation.repeatCount = .greatestFiniteMagnitude
guard
let node = find(keypath: keyPath, in: scene.rootNode)
else {
return
}
normalize(node: node)
node.addAnimation(animation, forKey: "animationKey-\(fullKeyPath)")
}
}
func find(keypath: String, in node: SCNNode) -> SCNNode? {
if node.name == keypath {
return node
}
if let node = node.childNodes.first(
where: {
$0.name == keypath
}
) {
return node
}
for childNode in node.childNodes {
if let node = find(keypath: keypath, in: childNode) {
return node
}
}
return nil
}
К сожалению, после применения анимации моя модель сильно искажается. Как будто масштаб моей анимации намного больше, чем моей модели. Каждая кость в моей модели расходится, но иерархия остается неизменной, а анимация правильная (что касается геометрии, она вообще больше не похожа на мою модель)

Думая, что проблема в масштабе/координатах моей анимации, я попробовал чтобы нормализовать и мою модель, и анимацию, но похоже, что я не могу изменить какие-либо свойства моей анимации, поскольку результат выглядит одинаково.
В Blender и то и другое файл анимации и файл модели имеют одинаковый размер/масштаб.
Как можно настроить преобразование анимации, чтобы оно соответствовало моей модели? Или что еще может быть не так с моим потоком данных?
func normalizeAllNodes(for node: SCNNode) {
for node in node.childNodes {
normalize(node: node)
normalizeAllNodes(for: node)
}
}
// Normalize coordinates
func normalize(node: SCNNode) {
node.transform = SCNMatrix4Identity
node.position = SCNVector3(1.0, 1.0, 1.0)
node.rotation = SCNVector4(1.0, 1.0, 1.0, 1.0)
node.scale = SCNVector3(1.0, 1.0, 1.0)
}
Окончательный метод выглядит так
public func makeUIView(context: Context) -> UIView {
let view = SCNView()
guard
let modelUrl = Bundle.main.url(
forResource: "model",
withExtension: "glb"
)
else {
return view
}
extractSceneSource(from: modelUrl) { source in
guard
let scene = source?.defaultScene
else {
return
}
normalizeAllNodes(for: scene.rootNode)
printNodeHierarchy(node: scene.rootNode)
applyAnimation(on: scene)
view.scene = scene
}
view.autoenablesDefaultLighting = true
view.allowsCameraControl = true
view.showsStatistics = true
view.backgroundColor = .black
return view
}
Подробнее здесь: https://stackoverflow.com/questions/787 ... enekit-ios