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
имущество. Как вы можете видеть из документа:
Точка поворота для положения, поворота и масштаба узла.
Например, установив ось в трансляционное преобразование, вы можете расположить узел, содержащий геометрию сферы, относительно места, где сфера будет лежать на полу, а не относительно его центра.