У меня есть сцена SceneKit, состоящая из эталонного узла из файла .dae
(экспортированного из Blender) и различных камер и источников света, добавленных непосредственно в редакторе сцен. Чтобы опорный узел отображался в редакторе с правильной ориентацией, к нему применяется поворот (-90, 0, 0). Это не распространяется на представление в приложении, поэтому я успешно применил поворот в функции, вызываемой из viewDidLoad()
.
После сегодняшнего рефакторинга ротации не происходит. Код все еще пытается применить исправление таким же образом - это была просто наведение порядка.
Различные хаки успешно вращают узел:
SCNAction.rotateTo()
с нулевой продолжительностью, а не как node.eulerAngles =
Timer.scheduledTimer(...)
)Оба из них предполагают, что есть проблема со сроками, с которым я не работал до рефакторинга. Вращение узла SceneKit действует только в том случае, если узел был визуализирован хотя бы один раз? Определенно, есть некоторая оптимизация за кулисами, поскольку даже отложенное назначение node.eulerAngles
влияет только на то, что отображается, если оно вызывает изменение значения.
Тщательное сравнение версий кода «до» и «после» выявило, казалось бы, несущественное изменение порядка. В оригинале я добавил несколько сгенерированных узлов (подкласс SCNNode
с плоскостью, использующей SKScene
в качестве текстуры) до, вращающий опорный узел (который работал). После рефакторинга этот порядок был отменен. Узлы являются братьями и сестрами, а не потомками, поэтому я не понимаю, почему это должно иметь значение, если только SKScene-as-texture не замедляет работу достаточно, чтобы избежать некоторой оптимизации?
Сгенерированный пример кода игры и применение поворота в viewDidLoad сработало как для вызовов repeatForever, так и для rotateBy, но код примера на самом деле мало что делает. Не уверен, что это что-то доказывает, поскольку цикл рендеринга фактически обрабатывается в собственном потоке. Не видя кода или того, сколько всего происходит в вашем цикле рендеринга, вполне возможно, что ваши команды вращения не всегда обрабатываются, поскольку они не вводятся в поток очереди рендеринга.
В качестве альтернативы поверните модель в желаемое положение в блендере, затем установите Y-Up для Scenekit. Я не очень хорошо разбираюсь в Blender, поэтому я сохранил некоторую документацию о том, как вращать, сохранять и экспортировать в Blender - я могу опубликовать это, если вам это нужно. Затем обработайте модель для Y-Up с помощью этой командной строки.
/Applications/Xcode.app/Contents/Developer/usr/bin/scntool --convert fighter0.dae --format c3d --output out.dae --force-y-up --force-interleaved --look-for- pvrtc-изображение
Не уверен, как далеко вы продвинулись, но я долго боролся с этим и обнаружил, что для меня это работает лучше, если моя модель блендера с самого начала настроена на правильное вращение, а также будет правильно предварительно просматривать в XCode. В какой-то момент вы можете выполнять вращение или SCNLookat и мои модели всегда были выключены. Возможно, существовал более простой способ исправить их, но зачем проводить дополнительные вычисления, если их можно установить в желаемое состояние с самого начала.
Надеюсь, это поможет.
Там есть несколько полезных напоминаний, спасибо. Поскольку он напрямую не касается вопроса о том, почему SceneKit решает не применять запрошенную ротацию, я склонен оставить этот вопрос без ответа на какое-то время.