SceneKit: понимание сводного свойства SCNNode

Цель состоит в том, чтобы увеличить длину SCNBox таким образом, чтобы он рос только в направлении положительного z.

Этот ответ предлагает поиграть с pivot имущество.

Тем не менее, документация для pivot на странице SCNNode свойство разрежено, а на странице SCNBox ничего нет.

Может кто-нибудь объяснить, как pivot собственность работает?

3 ответа

Решение

Изменение узла pivot концептуально то же самое, что вставка промежуточного узла между этим узлом и его родителем. Это может быть полезно в разных случаях. Один из примеров - когда центр геометрии узла находится не там, где вы ожидаете.

Например, если у вас есть SCNBoxограничивающая коробка

  • мин: (-0.5 * width, -0.5 * height, -0.5 * length)
  • Максимум: (+0.5 * width, +0.5 * height, +0.5 * length)
  • центр: (0.0, 0.0, 0.0)

Если вы хотите length из SCNBox только увеличить положительную ось Z, то, что вы хотите, это

  • мин: (-0.5 * width, -0.5 * height, 0.0)
  • Максимум: (+0.5 * width, +0.5 * height, length)
  • центр: (0.0, 0.0, +0.5 * length)

Ограничивающий прямоугольник геометрии никогда не изменится, но есть способы упорядочить узлы и изменить их ограничивающие прямоугольники.


Решение 1: Промежуточный узел

Одним из распространенных решений при работе с преобразованиями является использование промежуточных узлов, чтобы лучше понять, как применяются преобразования.

В вашем случае вы захотите изменить иерархию узлов с

- parentNode
  | - node
  |   * geometry
  |   * transform = SCNMatrix4MakeScale(...)

в

- parentNode
  | - intermediateNode
  |   * transform = SCNMatrix4MakeScale(...)
  |   | - node
  |   |   * geometry
  |   |   * transform = SCNMatrix4MakeTranslation(0, 0, +0.5 * length)

С этой новой иерархией, центр ограничительной рамки node все еще (0.0, 0.0, 0.0), но центр ограничительной рамки intermediateNode является (0.0, 0.0, +0.5 * length),

Путем масштабирования intermediateNode вместо node Вы получите желаемый результат.

Решение 2: Pivot

Оказывается, это именно то, что pivot свойство делает:

node.pivot = SCNMatrix4MakeTranslation(0, 0, -0.5 * length);

После того, как вы мысленно выяснили преобразование промежуточного узла, просто установите его инверсию в pivot имущество.


Вы можете найти больше информации о pivot свойство здесь: https://developer.apple.com/reference/scenekit/scnnode/1408044-pivot

Это очень похоже на Core Animation's anchorPoint собственность на CALayerза исключением того, что в Core Animation точка привязки указывается относительно ограничивающей рамки слоя (идет от 0 в 1 в процентах от ширины и высоты слоя), в то время как в SceneKit он абсолютен.

Скажем, у вас есть коробка, созданная так:

SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)

Точка разворота будет находиться в центре этого поля, теперь вы хотите переместить его на один из краев. Это может быть сделано путем перевода сводного узла на 0,5. (Это половина ширины рамки или расстояния между центром и краем.)

boxNode.pivot = SCNMatrix4MakeTranslation(0, 0, -0.5)

Точка поворота теперь будет расположена в центре X, центре Y и нулевом Z объекта. Если вы теперь масштабируете прямоугольник, он будет расти только в положительном направлении Z.

Похоже, вы хотите увеличить длину SCNBox(геометрия). Таким образом, вы можете просто увеличить свойство длины. Ответ, который вы упомянули, о pivot имущество. Как вы можете видеть из документа:

Точка поворота для положения, поворота и масштаба узла.

Например, установив ось в трансляционное преобразование, вы можете расположить узел, содержащий геометрию сферы, относительно места, где сфера будет лежать на полу, а не относительно его центра.

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