Вращение узла scenekit, примененное во время viewdidload, не имеет никакого эффекта

У меня есть сцена SceneKit, состоящая из эталонного узла из файла .dae (экспортированного из Blender) и различных камер и источников света, добавленных непосредственно в редакторе сцен. Чтобы опорный узел отображался в редакторе с правильной ориентацией, к нему применяется поворот (-90, 0, 0). Это не распространяется на представление в приложении, поэтому я успешно применил поворот в функции, вызываемой из viewDidLoad().

После сегодняшнего рефакторинга ротации не происходит. Код все еще пытается применить исправление таким же образом - это была просто наведение порядка.

Различные хаки успешно вращают узел:

  • Примените вращение как SCNAction.rotateTo() с нулевой продолжительностью, а не как node.eulerAngles =
  • Принятие мер для применения ротации позже (Timer.scheduledTimer(...))

Оба из них предполагают, что есть проблема со сроками, с которым я не работал до рефакторинга. Вращение узла SceneKit действует только в том случае, если узел был визуализирован хотя бы один раз? Определенно, есть некоторая оптимизация за кулисами, поскольку даже отложенное назначение node.eulerAngles влияет только на то, что отображается, если оно вызывает изменение значения.

Редактировать:

Тщательное сравнение версий кода «до» и «после» выявило, казалось бы, несущественное изменение порядка. В оригинале я добавил несколько сгенерированных узлов (подкласс SCNNode с плоскостью, использующей SKScene в качестве текстуры) до, вращающий опорный узел (который работал). После рефакторинга этот порядок был отменен. Узлы являются братьями и сестрами, а не потомками, поэтому я не понимаю, почему это должно иметь значение, если только SKScene-as-texture не замедляет работу достаточно, чтобы избежать некоторой оптимизации?

0
0
100
1

Ответы 1

Сгенерированный пример кода игры и применение поворота в 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 решает не применять запрошенную ротацию, я склонен оставить этот вопрос без ответа на какое-то время.

Chris 13.11.2018 11:35

Другие вопросы по теме