Align To Spline в кустарных условиях
Ты ж знаешь чо такое Align To Spline? Ща покажу как он внутри работает, чтобы ты смог его сделать в любом софте, в котором его не окажется, либо сделать кустомный со своими фичами.
Синя позволяет получить позишн и тангенту(направление вдоль) в любой точке сплайна (если б не позволяла — можно и без её помощи получить, об этом в другой день расскажу).
Позишн в точке сплайна понятно — сразу в позишн объекта суёшь, и тот на сплайне, в конкретной точке. Надо как-то определить ориентацию объекта на сплайне, чтоб он осью Z совпадал с направлением сплайна. Как помнишь — матрица есть набор векторов, в 3-мерном пространстве набор 3 векторов, соответствующих осям X Y Z. Направление сплайна — это как раз тангента, так что её в ось Z матрицы и впихну.
С осью X разобраться нехер делать — векторное произведение (cross product, ниже покажу) Z и Y. А вот откуда Y взять хз, в обычном случае прога спрашивает для неё Up Vector, потому что ну откуда ей в натуре знать, как ты хочешь повернуть объект вокруг направления сплайна. Либо прога спрашивает Rail Spline, который помогает вычислить Up Vector для каждой точки сплайна.
Но этот же Up Vector или Rail пугает юзеров до усрачки, потому что откуда простому юзеру знать что это за хуйня воще, чо в неё сувать, инопланетная блять настройка какая-то. У меня есть предложение, как это сделать проще для юзера (и сложнее для тебя бггг), но сначала векторное произведение. Когда кроссишь два вектора — результатом получается вектор, перпендикулярный обоим. Ну и вот, в вектор X матрицы можно сувать Cross(Y,Z).
Теперь я хочу сделать немного поюзерфрендовее, убрав на хрен Rail. Если участок сплайна не прямой, то на нём можно выявить нормаль. Она там прям в глаз бросается, осталось только проге объяснить, где она. Ну это можно сделать каскадом из векторных произведений, смотри как:
направление сплайна в нужной мне точке обозначу t1, направление в предыдущей точке — t2. Если их скроссить, получится вектор куда-то влево от направления (эту парашу иногда называют бинормалью). Если этот результат скроссить с t1, то алилуйя блять, у нас нормаль! Вот так получается:
cross(cross(t1, t2), t1).
Можно её нормировать и сувать в Y, а бинормаль в X. И нужно побороть пару ексепшенов. Первый — если сплайн прямой, т.е. t1 = t2, нормаль здесь будет неопределена. Предлагаю голову не ебать, и взять какой-нибудь умолчательный t2, например глобальную ось Z. Или локальную сплайновую. Да в общем-то можно её брать как t2 во всех случаях, потому что сама нормаль особо не нужна, нужен просто определённый устойчивый вектор поперёк сплайна. Теперь все ексепшены сами отваливаются, но плодится один новый: нормаль будет не определена в местах, где тангента будет совпадать с осью Z. Да и хуй с ним, вот увидишь. В XPresso здесь начинается уже какое-то безбашенное нодовое месиво, так что предлагаю пересесть на питон, рот ёб.
Теперь добавлю вращение объекта вокруг тангенты. Это может быть немного сложно, так что читай медленно и два раза, периодически поглядывай в эту гифку.
У меня значит есть базисные вектора — binorm, norm, t1. Вращать я собрался binorm вокруг t1. Вращнутый вектор v раскладывается на базисные вот так:
v = binorm * cos(a) + norm * sin(a). В шпаргалке binorm соответсвует иксу, а norm игреку. Окай, вектор binorm вращнул, теперь на его основе norm нужно заново посчитать, чтоб они были перпендикулярны.
Теперь можно добавить фичу — смещение объекта поперёк сплайна. Это к позишну добавлять norm умноженный на велечину смещения, здесь всё изи-пизи.
Ну вот и всё ебать. Вот тебе этот сетапчик, собранный на XPresso.
