Процедурная линия электропередач
Здравствуйте,меня зовут Виталий,я из славного города-героя Севастополя.
Занимаюсь 3D уже лет 8-9, в основном это 3d max, After Effect.Один раз мне пришлось "протягивать" провода вдоль лини электропередач. Делал сплайнами,с привязкой по вертексам...короче,я очень сильно ээээ...устал это делать. Мне это задание запомнилось надолго))).Прошло время.
Год назад увидел программу Houdini. Когда я понял ЧТО можно делать в ней,я понял,что это ОНО!))Пословица,говорящая, "что нельзя сделать в Гудини, то нельзя сделать нигде" реально приобретает смысл.
Естественно, первым делом, когда я начал его изучать, то начал ковырять в сторону построения процедурной линии электропередач, со временем оформилось и вылилось в вполне работоспособную систему, которую хочу предложить.
Здесь раскрываются принципы, на которых можно построить что угодно - дороги, заборы, линию фронта (с колючей проволокой и окопами) и т.д. Естественно, внимание мелочам не уделял, будь то гвозди, травка, крепление, сами понимаете - это лишнее, засоряющее основную суть.
Здесь продемонстрировано, как приблизитильно это работает. Рисуем сплайн, заходим в наш изготовленный инструмент и указываем на наш сплайн. Дальше всё понятно.
Ну что ж, приступим.
Выбираем инструмент Curve и рисуем кривую.
Получится в окне кривая, а справа появится нода. Это и есть наш объект. Все действия будут происходить внутри этого объекта. Все трансформации, изменения, моделинг, текстуринг с набором текстур, всё это можно хранить внутри объекта. В принципе, основная работа в Гудини, как раз-таки и происходит там, с нодами.
Зайдём внутрь этой ноды, два раза кликнув, либо Enter, либо клавиша "I". Нам нужно поменять количество точек на кривой, это будет в дальнейшем количество столбов на линии. Для этого нам понадобится нода Resample. Нажмите Tab и начните вбивать первые буквы нужного инструмента.
Включите отображение точек, снимите галочку с Maximum Segment Lenght, и поставте на Maximum Segments это позволит регулировать количество точек вам вручную и оно не будет зависить от длины кривой.
Теперь мы создадим некие хелперы, на которые будут ориентироваться наши столбы, лежащие на нашей кривой. Как я писал выше, гудиневские объекты могут в себе содержать что угодно. Поэтому вызовем ТАБом опять инструментарий и найдём Circle. Включим отображение номеров точек, поменяем объект на полигональный и количество сторон выставим на 3. С помощью стрелок трансформаций выставте объект в нулевую точку (чтоб точка под номером "ноль" стояла в центре координат).
Вызовем ноду Sweep, которая позволяет распространять объекты вдоль некоего пути.
Вяжем сетку вот таким вот образом. В левый инпут подаём ЧТО нужно распространять, во второй ВДОЛЬ ЧЕГО нужно распространять.
Должно получиться что-то типа такого.
Нам от этих "хелперов" понадобятся точки, которые лежат на нашей кривой. Так как в Гудини аттрибуты могут передаваться напрямую\принудительно\сами по себе\"по наследству", то точки так сказать "запомнят" положение своих "родителей" в пространстве. Следующая операция занесёт нужные нам точки в группу. Потом, с этой группой можно творить что угодно, не затрагивая остальные части объекта.
Нода Group. Указываем имя группы. Какое угодно, лишь бы вы потом сами не запутались. Логично давать имена, которые отображают суть действия. Потом выбираем тип, с которым будем работать. Заносить нужно точки, поэтому,е стественно выбираем Point. Потом выбираем тип операции.Pattern это тот,в котором мы явно указываем номера, Expression это тип,который позволяет с помощью некоего выражения заносить точки в группу, и наконец нужный нам тип-Group by Range.
Чуть ниже появятся две строчки, по два окошечка каждая. Смысл их таков: в отборе участвуют точки с нулевой по N (где N это количество ВСЕХ точек, находящиеся в данном объекте), выделяться будет одна точка, пропуская три. То есть выделяет нулевую, пропускает три точки, опять выделяет,пропускает и т.д... Цифра "три" это просто количество точек в наших "хелперах". Если б они были четырёхугольные, то мы там поставили цифру "4". Должно получиться вот так.
Путь подготовлен. Теперь приступим собственно к созданию столба, который просто будет копироваться по точкам, лежащим на пути. В сторонке создайте Line, убедитесь, что в среднем окне Direction была единица, остальные - по нулям. Первое окно соответствует оси Х, второе-Y, третье-Z. В Гудини ось "игрек" является вертикальной(верх-низ), в Максе например это ось "зет". Выставив единицу в этом окошечке мы создадим отрезок направленный вверх. Distance это, собственно длина нашего отрезка. Это будет основой нашего столба. Прицепите ноду PolyWire,ч то она делает поймёте сразу). Грубо говоря, можно этой нодой "нарастить мясо" на кривую, отрезок, линию.
Теперь сделаем перекладину. Создадим рядом с линией ноду Box. В окошечках Size сделайте так, чтобы вас устраивала эта перекладина(толстая,короткая,длинная - какую хотите). Нам нужно чтоб перекладина была постоянно на некотором расстоянии от земли, независимо от высоты столба. Например изменяется высота столба и дабы не менять вручную высоту расположения перекладины, воспользуемся волшебными свойствами Гудини (за что его и полюбил:) ). Например, я решил, что перекладина будет в верхней четверти столба. С помощью ноды Transform мы можем манипулировать объектом. Поднять-опустить, вертеть и т.д. Чтоб руками не двигать перекладину, воспользуемся експрешном. Не пугайтесь, писать ничего не надо, Гудини сейчас его напишет сам. Идём в ноду Line и ПКМ клацаем на цифре Distance. Выбираем Copy Parameter. Идём обратно в ноду Transform и в окошечко Translate, в среднее, (нам же вверх поднять нужно!) опять клацаем ПКМ и выбираем Paste Copied Relative References. Смысл сего действа - копируем какую-то информацию и вставляем, и эта, новая информация будет реагировать на предыдущие изменения. То есть, меняя Distance в ноде Line, будет меняться высота перекладины, то есть положение будет приравниваться длине всего столба. Чтоб перекладина была, допустим, в верхней четверти столба, то нам из этого значения нужно вычесть это же значение, поделённое на 4. Например, высота столба равна единице. Получается нехитрая формула 1-1/4. Единица,делённая на четыре даёт 0.25 (четверть) и мы эту четверть вычитаем из длины столба. С помощью ctr+C и ctr+V в этом же окошечке копируем\вставляем этот експрешн и по вышеприведённой формуле составляем выражение. Выглядит это так:
Для того чтоб провода "знали" куда им цепляться, на перекладине нужно выбрать точку (например нулевую) и занести её в группу. Опять нода Group, называем её как-нибудь(например zero), режим Pattern и там вбиваем просто цифру, нужной нам точки. На рисунке эта нода под названием Group2.
Теперь перекладину и столб нужно соединить, дабы это был один объект. Нода Merge позволяет это сделать. Теперь с помощью ноды Copy расклонируем наши столбы по пути. По аналогии со Sweep в левый вход подаём сам объект, в правый вход - по которому нужно раскидать клоны.Количество копий - один, по умолчанию. У меня на рисунке - 110, это ошибка!!!
Если объекты как то неадекватно расположились по пути, то ПОСЛЕ ноды Merge и ПЕРЕД нодой Copy вставте ноду Transform. Смысл таков: после ноды Merge у нас и перекладина и столб УЖЕ являются единым объектом (поэтому ПОСЛЕ), т.е мы будем поворачивать уже целый объект, который и будет уже клонироваться адекватно (поэтому ПЕРЕД). На след. рисунке вы как раз это и увидите. Так, теперь нужно подготовить точки, по которым лягут наши провода. Помните, создавали группу zero? В неё входила только одна точка на перекладине, теперь, благодаря тому, что столбов много, этих точек в этой группе тоже много. Убедиться можно в этом нажав средней кнопкой мыши по ноде Copy1, там увидите количество точек, занесённых в группу zero. Эта нода Copy1 сейчас является узловой, тут у нас заканчивается собственно расположение столбов и т.д. Отсюда пойдёт ответвление для наших проводов, которое потом соединим с этой нодой и получатся провода плюс уже созданные столбы. Итак, приступим. От ноды Copy1 ответвляем ноду Delete и там в поле group выбираем нашу группу zero. Выбираем режим Delete Non-Selected и получаем на выходе наши точки. То есть, мы удалили ВСЁ кроме нужных нам точек. Теперь подключаем ноду Add. Выбираем вкладку Poligons, режим By Group. С помощью этой ноды можно создавать точки, но она ещё и может их содинять по некоему признаку. Например сейчас мы создали полигональный (хоть он и выглядит, как отрезок) объект из группы точек. С помощью этой ноды например, можно создать 4 точки, объединить их и "закрыть", получится полигон. Ну, и дальше можно моделить, экструдить и т.д. Ладно, я отвлёкся)))
Далее, нам нужно добавить точек МЕЖДУ точками, принадлежащих столбам. Эти новые точки будут отвечать за прогиб проводов МЕЖДУ столбами. Нода Edge Divide сделает это. Только в поле group нужно поставить цифру "ноль". Мы ж создали перед эти полигональный объект, а так как он не замкнут, то по умолчанию его несуществующему полигону присваивается порядковый номер - ноль. Так,поделили, теперь нужно привести в порядок точки, видите как они расположены (порядковые номера)? Вяжем ноду Sort и выбираем режим By Vertex Order. Получится, что он расставит точки по - порядку, что нам и нужно. Теперь, как делали выше, создадим группу, в которую будут входить только те точки, которые находятся между столбами. Опять тот же алгоритм действий - нода Group, режим Group by Range. Так как нулевая точка - это столб,то отсчёт нужно делать с точки номер "один". Следующую он пропустит (опять столб) и выделит только следующую(это опять точка МЕЖДУ столбами). Таким образом мы выделим все точки,лежащие между столбами.
Назовём эту группу, например, middle.
Дальше, интуитивно, уже можно понять, что нам нужно опустить эти точки вниз, создав провисание проводов. Нода Transform, как мы помним, отвечает как раз за это. Так же, в поле group выбираем нашу группу middle. И опускаем насколько нам нужно эти точки. Кстати, чтоб вручную не вбивать цифири в поля, можно с зажатой средней клавишей нажать на нужное поле и выбрать дробное или целое значение и двигать влево - вправо, меняя значение. Переименуйте ноду в DROOP, потом легче искать. Лучше всякие вот такие ключевые ноды отмечать как то(переименовывать, выделять цветом и тд).
Дальше нодой Convert превращаем наш полигональный объект в кривую Безье. Признаюсь, в математике у меня пробел по таким темам, поэтому я незнаю почему именно кривая порядка трёх даёт именно такой результат. Я хотел сделать сглаженную линию,поэтому конвертнул в Безье, будучи уверенный, что разглажу там, но...потыкавшись туда - сюда толком ничего не добился и чисто случайно поменял порядок кривой с четырёх на три и получился вот такой результат.Каюсь, пробел в этой части урока пока мною не заполнен(((
Теперь нужно превратить эту кривую обратно в полигональный объект (ещё раз нода Convert, настройки по умолчанию), ибо толщину мы несможем применить. Толщину можно сделать либо вышеприведённой нодой PolyWire, либо Wireframe, он по-проще.
Теперь свяжем наш провод с созданными ранее столбами. Помните ключевую ноду Copy1, на которой я заострил внимание? Вот теперь выход с неё связываем с выходом Wireframe очередной нодой Merge и, вуаля, у вас готовая линия электропередач.
Теперь меня кривую,двигая точки будет меняться и двигаться вся конструкция. Но что делать,если нам нужно резко поменять высоту столбов,их толщину и т.д.? Лезть во все эти хитросплетения и выискивать ноды, отвечающие за тот или иной параметр? Как выражается мой коллега: "Это отстрел башки!"
Мы пойдём дальше и улучшим наш объект, выведем наружу нужные нам ползунки, окошечки и т.д.
Давайте выйдем на один уровень наверх, в контекст obj. Там у нас одна единственная нода, Curve1, это и есть наш объект, включающий себя все эти ноды. Переименуйте объект в Column.
Нажмите иконку шестерни, справа - вверху. Из контекстного меню выбираете Edite Parameter Interface. Откроется диалоговое окно для создания собственных параметров.
Нам нужно насоздавать несколько параметров, например ползунок отвечающий за рост столбов,или толщину провода и т.д.
Начнём - с. Из левой колонки вытянем параметр float и перенесём в правую колонку. В поле Name пишем имя канала (так сказать объявляем переменную) это название не отображается, это чисто технический элемент, в следующей строке - это имя, которе будет отображаться. Range - здесь задаёте диапазон, видимый. Естественно вам никто не помешает вбивать туда ДРУГИЕ цифры. Например если вы по умолчанию сделаете диапазон 0-12, то вам потом не составит труда вбить в ползунок другую цифру, например 13, не залазая опять в это диалоговое окно и меняя настройки с 12-ти на 13-ть.
Таким образом создаём нужные нам параметры. Я вывел Высоту столбов, Степень провисания и Количество столбов. Вы можете этих параметров насоздавать сколько душе угодно!
Ещё я вывел функцию выбора, чтоб из выпадающего списка мог выбрать любую кривую в сцене и применить ей этот инструмент (Column). Эту полезную штуку ищете там же,в диалоговом окне(через "шестерню"), называется Operator Path.
Получается как-то вот так:
Теперь остаётся сделать так, чтоб нашим ползункам повиновались нужные нам параметры. После того, что вы УЖЕ сделали это не самое трудное))). Тут главное внимательность, чтоб не скопипастить не туда или не тот параметр.
Поехали!
ПКМ тыкаем на нашем параметре Height Column, выбираем Copy Parameter.Заходим опять внутрь и ищем ноду Line (помните, это основа нашего столба, где параметр Distance является нашей высотой), и нажав ПКМ на этом параметре выбираем Paste Copied Relative Reference. Теперь двигая ползунок, созданный нами, можно регулировать высоту столбов, не заходя внутрь всей этой сетки и не выискивая нужную нам ноду. Так же можно сделать со всеми параметрами. Теперь мы сделаем так, чтоб наш инструмент воспринимал ЛЮБУЮ кривую, которую мы ему "скормим".
Помните, у нас всё начиналось с ноды Curve1 в нашем объекте, который мы недавно переименовали в Column ?
Так вот, заходим ещё раз внутрь объекта и создаём в самом начале ноду Object Merge. Она позволяет внутрь данного объекта запихивать элементы с других,внешних объектов. Например, в другом объекте,есть элемент,который мы хотим сюда присовокупить, например ручку от кастрюли, мы создаём эту ноду и указываем там путь Некий Объект->Кастрюля->Ручка от кастрюли. Это очень грубый пример, но как то так. Отсоединяем ноду Curve и вместо ней цепляем Object Merge.
Ставим режим Into this object.
Теперь мы можем нашему инструменту "скармливать" любую кривую в сцене. Дабы не заходить сюда постоянно мы в наших параметрах
так же ПКМ клацаем на параметре Path (см. рис. 18), выбираем опять Copy Parameter, заходим внутрь объекта и в строку Object1 ПКМ и опять опцию Paste Copied Relative Reference.
Всё!
Теперь сюда, внутрь, можете не возвращаться.Теперь рисуете новую кривую, выбираете наш инструмент, выбираете из списка Path свою кривую и...
Теперь вы можете, получив болванку улицы, дороги и тд. смело рисовать кривую вдоль этого и пользоваться своим(!!!) инструментом. И когда вас попросят изменить направление, толщину или ещё что-нибудь, то вы не будете рвать волосы и вопрошать "...и где ж вы раньше были, почему сразу не сказали???..." и т.д, а спокойно подвигаете ползунки и напраляющие точки и спокойно будете попивать чаёк, пока другие моделлеры будут чертыхаться и перемоделивать это всё.
Всем спасибо за внимание, я очень старался не лить воды, чтоб всё было по-существу,ч тоб урок не получился громоздким,ч тоб не отпугнуть никого))) Но этовсё делается бысрее, чем я это всё написал, честно). Всем удачи, и помните:"Если это нельзя сделать в Гудини, то это нельзя сделать нигде."