“Морфинг по Вороному” - эффект преобразования одного объекта в другой при помощи Particle Flow, MAXScript и прикладной математики.
Всем привет, в этом уроке я снова буду демонстрировать возможности MAXScript применительно к эффектам Particle Flow. Кстати, могу сказать что Particle Flow это самый “скриптабельный” компонент 3ds max. Скрипты под него простые и короткие, а эффекты выглядят великолепно. Но в этом уроке я одними скриптами для Particle Flow не обойдусь. Мне понадобится еще и просто скрипт – так сказать, скрипт “сам в себе и для себя”.
Прочитав название урока вы, наверное, сразу подумали – а кто такой, собственно, Вороной? Это, скажу я вам без преувеличений великий математик, имеющий к компьютерной графике самое непосредственное отношение. Хотя в его время (начало прошлого века) еще и калькуляторов-то не изобрели. Но не буду пока забегать вперед (а точнее назад) и лучше начну с главного, а именно с идеи.
Идея урока в том, чтобы разделить на реалистичные осколки один объект, а потом из этих осколков собрать второй. Понятно, что не ко всякому объекту подойдут осколки от другого, поэтому в процессе преобразований и анимации первые осколки нужно трансформировать во вторые и сделать этот морфинг по возможности незаметно, т.к. чем незаметнее, тем реалистичнее и эффектнее будет выглядеть наша Particle Flow анимация. Выглядеть должно “как будто так и было”, а морфингом я назвал этот эффект потому, что в данном уроке меняется геометрия осколков, но сохраняется их количество (чтобы не усложнять, хотя в принципе от количества частиц-осколков ничего не зависит).
Обдумываю идею и разделяю урок на четыре основных этапа:
Для реализма вариант неудовлетворительный, так как осколки одинаковы по толщине, предсказуемы по форме, кроме того, если делать этим способом, внутри объекта получается пустота, которой там быть не должно. Возникает задача – как разбить объект на разнообразные осколки приемлемой формы, общий объем которых равен объему объекта, т.е. так, как в реальности. И вот тут мне пригодятся идеи Георгия Федосеевича Вороного (украинский математик 1868-1908) из области теории квадратичных форм. Тем, кто сейчас испугался и думает, что дальше начнется высшая математика и будет скучно, хочу сразу сказать, что не начнется и не будет. Будет определение многогранника Вороного и примеры, а дальше опять частицы, алгоритмы и скрипты. Итак, трехмерный многогранник Вороного это совокупность точек трехмерного пространства, каждая из которых находится не дальше от точки О данного пространства (назову ее центром), чем от других таких центров. Пусть вас не смущает слово пространство, оно в нашем случае ограничено поверхностью объекта, который бьется на осколки, а многогранники Вороного и будут являться собственно осколками. В картинках это выглядит так:
Многогранники Вороного покрывают пространство без щелей и наложений, их грани равноудалены от соседних центров, многогранники выпуклые, каждый можно построить, отсекая лишнее от общего объема, плоскости сечений проходят через середины отрезков, соединяющих соседние центры и перпендикулярны этим отрезкам. Вот и все, математика кончилась, теперь надо написать алгоритм разбиения объекта (любого) на такие вот многогранники. Дальше описывается мой алгоритм построения многогранников, точнее оптимизация существующего алгоритма (его еще до меня придумали) и в общем-то я делаю это для mir-vadim, Shiva и megavitus, которые тоже были озадачены проблемой скорости построения многогранников и медленной работой существующих скриптов для данной задачи. Короче, следующий раздел можете пропустить, если кому неинтересно. Скрипт в конце урока будет выложен уже готовый и вам не придется ломать над ним голову.
Математически решить задачу построения многогранника мне оказалось не под силу и промучавшись четыре дня я вернулся к истокам, а именно к скриптам для построения ячеек Вороного (Voronoi Cells, Voronoi Fracture – пользуясь случаем выражаю огромную благодарность их автору GARP), которые давно уже выложены на сайте scriptspot. Почему вернулся, а не начал с них? Потому что эти скрипты работают буквально так, как я описал раньше, т.е. отрезают от основного объема куски модификатором Slice, потом закрывают пустоту модификатором Cap Holes и делают это ровно n*(n-1) раз, где n – требуемое количество осколков. В результате получаются отличные многогранники Вороного, но для 1000 многогранников это выливается в 999000 операций обрезания. Зависимость от числа точек квадратичная - алгоритм работает слишком медленно, в программировании такой подход называется brute force (грубая сила), который используют, когда нет другого выхода. А я, увлекшись математикой, неделю изучал теорию и пытался найти решение другими способами, которые позволяли бы сразу определить соседние точки и пропустить оставшиеся, не перебирая весь массив центров для каждого многогранника. На пятую бессонную ночь скриптописательства и тестирования вероятных алгоритмов такой способ я нашел. Эврика, решение оказалось элементарным.
Создаю двумерный массив (у меня используется конструкция struct), в первом элементе которого содержится номер текущего центра, а во втором – массив номеров всех остальных центров, отсортированный по расстоянию до текущего (по возрастанию). То есть по уменьшению вероятности влияния этой точки на многогранник. Ведь чем дальше находится точка, тем меньше у нее возможностей отрезать кусок от рабочего объема, так как сначала отрезают ближайшие соседние точки и если они уже все отрезали, то секущая плоскость дальней по расстоянию точки не пересечется с создаваемым многогранником и отрежет пустоту. И теперь нужно определить только этот предел – за которым точки всегда будут резать пустоту и тогда их можно смело пропустить и перейти к построению нового многогранника. Итак, начинаем резать: первая точка отрезала часть от объема базовой фигуры, рабочий объем уменьшился, дальше вторая, объем опять уменьшился, третья и т.д. до тех пор, пока новая точка уже не сможет ничего отрезать. Критерий простой – эта точка будет та, половина расстояния от которой до центра многогранника больше, чем длина радиуса описанной вокруг многогранника сферы. Я даже делаю проще – беру сферу, описанную вокруг габаритного контейнера многогранника, ибо ее радиус заведомо больше, а поиск описанной сферы минимального радиуса – та еще задачка и ее внедрение в алгоритм его только замедлит. Радиус сферы, описанной вокруг габаритного контейнера находится элементарно – он равен половине расстояния между максимальной и минимальной точками контейнера. Габаритный контейнер с каждым обрезанием уменьшается вместе с многогранником и как только он будет достаточно малым, чтобы секущая плоскость новой точки не пересекла сферу – это значит, что дальше резать не нужно и бесполезно, текущий многогранник готов, можно пропустить оставшиеся точки и строить следующий многогранник Вороного. Написал много слов, поясняю на картинке:
Точки в массиве отсортированы по расстоянию, и идут в порядке красная, желтая, голубая. Зеленая сфера описана вокруг розового габаритного контейнера. Начинаю строить, красная точка отрезает объем от многогранника и формирует одну из граней. Идем дальше и видим, что плоскость от желтой точки не пересекает сферу габаритного контейнера. Ага, значит все, красная точка была последняя, многогранник готов и по плоскостям желтой и голубой точки можно не резать – новых пересечений все равно не будет и голубая алгоритмом даже вообще не проверяется. У себя в скрипте я не делаю эту проверку каждый проход, так как гарантированно первые 4 точки образуют грани и в принципе, если точек много, то можно начинать проверять примерно после 16-ой, а до этого отрезать не задумываясь. Вот такой простой и главное быстрый алгоритм. Например для 1000 точек будет около 20000 обрезаний. 20000 и 999000 – разница более чем заметная. Опишу фрагменты кода, разбив их на части, сначала идет код, потом его описание. Комментарии я пишу русскими большими буквами намеренно, так как маленькая русская буква “я” приведет к ошибке при запуске скрипта. Ее употреблять нельзя, даже в комментариях, это баг, и чтобы не думать об этом я приучился писать заглавными буквами.
Задаю глобальные переменные для хранения количества осколков и объектов самих осколков. Слово global означает, что эти переменные можно вызвать из любого скрипта в текущей сессии 3ds max. Конструкции pointprops и simplexprops позволяют создать многомерные массивы и обращаться к их элементам по ключевым словам, а не только по индексам.
fn compareFN v1 v2 valArray: centerpoint: = ( --ФУНКЦИЯ ИНДЕКСИРОВАННОЙ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ РАССТОЯНИЯ ДО ЗАДАННОЙ ТОЧКИЕдинственная пользовательская функция в скрипте используется алгоритмом сортировки. На вход поступает массив координат и точка отсчета. Функция выполняет простейшую проверку расстояний и должна возвращать числа -1, 1 или 0. В результате массив координат очень быстро сортируется по возрастанию расстояния до центральной точки.
Итак, во второй части происходят все необходимые приготовления и создаются рабочие массивы с данными. Массив с центрами получается, например, такого вида:
A[1]=verts: #(2, 3, 4) num:3Третья часть работает одновременно с двумя исходными массивами – массивом координат центров и массивом отсортированных индексов вершин.
Непосредственное создание осколков состоит из двух циклов, одного внутри другого. Первый цикл for идет по всем центрам, выбирая текущий центр вокруг которого строится текущий осколок, второй do...while – по всем остальным центрам, отсортированным относительно текущего. Второй цикл выполняет проверку алгоритма поиска стопроцентных соседей, если она выполняется – цикл прекращает свою работу.
Для создания эффекта морфинга по Вороному я использую три скрипта. Два из них работают непосредственно в Particle Flow, третий нужен, чтобы создать осколки для второго объекта – который собирается из осколков первого. Для краткости и удобства назову первый объект $Source (т.е. исходный), а второй $Destination (т.е. целевой). Знак $ перед именем объекта означает, что я в скрипте обращаюсь к нему по имени – это вам пригодится, когда будете разбираться в коде скриптов или править их под себя. Вообще в этом уроке названия играют не последнюю роль. Для справки - просто пустой $ в MAXScript означает текущее выделение, иными словами $=selection. Итак, в эффекте участвуют:
Если для объектов указаны не все параметры, значит, остальные берутся по умолчанию. Еще используется анимированная камера и два источника света - для наведения “марафета”, описывать их не буду, все равно у вас будет по-другому. В сцене 270 кадров (по 30 штук в одной секунде), единицы измерения – миллиметры. Значки объектов гравитации и системы частиц расположены слева от исходного объекта (если смотреть в окне Front), их стрелки направлены слева направо, т.е. в сторону, куда происходит все действие.
Первым делом я выделяю объект $TDestination01, запускаю скрипт “сам в себе”, смотрю что получилось и скрываю все это вместе с объектом. Больше мы их не увидим. Ах да, я же забыл рассказать, откуда скрипт узнает центры многогранников для разбиения. Очень просто – он создает внутри объекта облако частиц PCloud и берет координаты частиц. Потом сортирует по расстоянию, копирует общий объект и начинает резать. В статусной строке печатается ход процесса. Подробнее написано в комментариях внутри скрипта. Вот что получилось в итоге - крупным планом многоугольники Вороного themselves:
Теперь самое главное – Particle View и описание всего того, что я в нем использую. На частицы из источника PF Source 01 последовательно одно за другим влияют три события (events): Разбиение, Перемещение и Собирание, в которых находятся операторы (синие квадраты) и тесты (желтые ромбы) перехода к следующему событию. Вообще раз уж я берусь за описание операторов Particle Flow это получается и не урок по MAXScript, и не по Particle Flow, а по им обоим одновременно. Ну это вам судить, кому что понравится, тот там и прочитает. Описание операторов тоже можно пропустить, если вы это все уже знаете.
Оператор Birth Script особенный хотя бы потому что он представляет собой не синий квадрат как все остальные, а зеленый круг :-D. На деле это означает что его нельзя двигать вверх и вниз по событию, так как он “рождает” частицы. Как Birth Script это делает – он работает примерно также как и скрипт “сам в себе” но применительно к Particle Flow - разбивает объект $Source на осколки и присваивает частицам их геометрию, иными словами создает осколки из частиц. Частицы рождаются в нулевом кадре - единственный кроме скрипта параметр оператора оставляю по умолчанию. Это первый скрипт непосредственно для Particle Flow, второй и последний будет в третьем событии (видите, не все так сложно, скриптов оказывается нужно совсем чуть-чуть, чтобы добиться нужного эффекта). Скажу по секрету, когда я делал урок и тестировал различные варианты, у меня было 5 событий и в каждом по скрипту. Перестарался. Идем дальше, продолжаю описывать операторы и их интерфейс. Если операторы в событиях повторяются, например оператор Speed я использую дважды, а Spin трижды, или параметры в операторах повторяются, например Uniqueness присутствует едва ли не в каждом операторе, то я опишу их для первого оператора, в котором они встречаются, а дальше буду пропускать, т.к. принципы их работы везде одинаковые.
Speed - cкорость одной частицы в мм/с (у меня системные единицы миллиметры, а скорость измеряется в системных единицах на одну секунду). Положительные значения скорости двигают частицы в направлении, определяемом параметрами группы Direction, а отрицательные в противоположном направлении. Примечание: скорость для частицы задается один раз при поступлении частицы в событие (или при рождении, как в данном случае). Анимация параметра не даст никакого эффекта, так как каждая частица, поступившая в событие, получает постоянную скорость в соответствии с параметрами Speed и Variation.
Variation (отклонение) – величина, на которую меняется скорость каждой частицы относительно величины Speed (измеряется в системных единицах на секунду). Чтобы определить скорость каждой частицы, система умножает значение Variation на случайное число из диапазона от -1.0 до 1.0, а потом добавляет результат к значению параметра Speed. Например, если скорость 300, а отклонение 100, то каждая частица получит случайную скорость из диапазона от 200 до 400.
Direction (направление) - группа параметров, задающих направление скорости движения частиц. В большинстве случаев направление зависит от ориентации значка PF Source, которое, кстати, и я использую, т.к. из списка выбран вариант Along Icon Arrow. Но, тем не менее, расскажу о всех пунктах этого списка. Да, и еще о направлении – как правило, направление это всегда прямая линия, если только на частицу не влияют другие факторы в других операторах. Итак, варианты направления:
Reverse (наоборот) – флажок, во включенном состоянии меняет направление скорости частиц на противоположное. Отключен по умолчанию. Включение флажка эквивалентно умножению значения параметра Speed на -1. Флажок недоступен, если для направления выбран вариант Random 3D или Random Horizontal.
Divergence (расхождение) – угол конуса распыления в градусах. Значения больше нуля распыляют частицы в стороны от направления движения. Диапазон от 0 до 180. Этот параметр можно анимировать. Параметр недоступен, если для направления выбран вариант Random 3D.
Uniqueness (уникальность) – инструменты группы задают случайность для отклонения и вариантов направления Random 3D и Random Horizontal. Параметр Seed определяет величину случайности, а кнопка New запускает для системы новый расчет на основе этой новой случайности.
Оператор поворота позволяет задать и анимировать ориентацию частиц с дополнительными случайными отклонениями во время события. В данном уроке я не меняю никакие значения по умолчанию для этого оператора и поэтому описывать его не буду, тем более параметры Rotation во многом совпадают с параметрами следующего оператора Spin.
Вращение сообщает частицам угловую скорость с дополнительными случайными отклонениями во время события. Вращение применяется к каждой частице один раз в текущем событии, за исключением варианта Speed Space Hollow. Но, тем не менее, параметры вращения можно анимировать.
Spin Rate (скорость вращения) – скорость вращения, измеряемая в градусах на секунду. Т.е. 360 означает, что частица за секунду сделает один полный оборот.
Variation (отклонение) – максимальное отклонение в градусах на секунду, на которое скорость вращения может меняться. Реальное случайное значение вычисляется единожды для каждой частицы.
Spin Axis (ось вращения) – группа параметров, определяющих конкретные или случайные оси вращения с дополнительными случайными отклонениями. По умолчанию выбран вариант Random 3D. Варианты:
X/Y/Z – параметры для задания конкретной оси вращения. Недоступны при варианте Random 3D. По умолчанию равны 0,0,1. Диапазон для каждого от -1.0 до 1.0. Чтобы ось вращения совпадала с единичным вектором данной системы координат, задайте соответствующей параметр равным любому числу больше нуля, и поставьте нули в двух остальных. Отрицательные значения переворачивают ось и меняют направление вращения на противоположное. Числовые значения начинают работать, когда вы задаете ненулевые значения более чем для одной оси, в этом случае эффект от них будет суммироваться. Например, если вам нужно, чтобы ось вращения была посередине между положительными направлениями осей X и Y, задайте для них одинаковые положительные величины. Какие конкретно не имеет значения. Аналогично, если хотите, чтобы угол между осью вращения и осью X был равен 30 градусам в направлении оси Y (одна треть от угла между X и Y), задайте величину для Y в два раза больше, чем для X. Например, X=0.2 и Y=0.4 или X=0.5 и Y=1.0.
Divergence (расхождение) – задает предел расхождения для осей вращения в градусах. Реальное расхождение равно случайной величине из заданного диапазона. Общий диапазон от 0 до 180. По умолчанию значение равно нулю. Параметр недоступен для варианта Random 3D.
Uniqueness – уникальность влияет на отклонение скорости вращения, ось вращения для варианта Random 3D и на расхождение для остальных вариантов.
Оператор позволяет влиять на движение частиц посредством одной или нескольких пространственных деформаций (Space Warps) из категории Forces. Я использую Gravity для эффекта “сдувания” частиц. В списке отображаются названия используемых пространственных деформаций. Если деформацию удалить в сцене, на ее месте в списке оператора Force будет слово deleted. Примечание: Particle Flow применяет силы к движению частиц в таком же порядке, в каком деформации находятся в списке. Эффект суммируется сверху вниз. Сначала к движению частиц применяется верхняя деформация, потом следующая применяется к результату действия верхней и так далее вниз по списку. Меняя порядок деформаций можно повлиять на финальный результат. Описание кнопок:
Add – нажмите и выберите в сцене пространственную деформацию, чтобы добавить ее в конец списка.
By List – нажмите и из появившегося окна Select Force Space Warps выберите нужные деформации. Они занесутся в список в том же порядке, в каком были в окне.
Remove – выделите деформацию в списке и нажмите кнопку, чтобы ее удалить. Любая удаляемая деформация остается в сцене.
Поскольку у меня в сцене только одна деформация, радиокнопки группы Force Field Overlapping (пересечение силовых полей) неактивны. А вообще они нужны для определения способа влияния нескольких деформаций на один объем частиц. Если включен Additive, то деформации суммируются в соответствии с их средними силами. Если включен Maximum, на частицы влияет только та деформация, сила которой максимальна. Например, у вас в сцене есть две примененные к частицам деформации Wind (ветер) и Gravity (сила тяжести), у которых параметр Strength равен 1.5 и 1.0 соответственно. Если выбрать Additive, то влияние Wind на частицы будет примерно на 50% больше влияния Gravity. Но если выбрать Maximum, то на частицы будет влиять только Wind.
Influence (влияние) – задает мультипликатор, с которым силы пространственных деформаций применяются к частицам в процентах. По умолчанию 1000.0. Отрицательные значения параметра разворачивают силы в противоположную сторону.
Группа параметров Offset Influence задает синхронизацию для времени анимации. Пригодятся, если вы анимируете какие-либо параметры операторов Particle Flow. Я в данном уроке этого не делаю. Синхронизировать можно по:
Оператор позволяет вам определять способ отображения частиц в окнах проекций. По умолчанию режим Ticks (отметка – выглядит как знак +) самый простой и быстрый способ отображения, полезный для анимации с участием большого количества частиц. Его противоположность – режим Geometry (геометрия, который у меня кстати и используется), который отображает реальную геометрию частиц. Дополнительно оператор Display предлагает ряд простых форм частиц для быстрого обзора при тестировании анимации и возможность легко различать частицы в разных событиях. Это я вам скажу очень удобно, когда можно по цвету (щелкните на цветном квадратике, чтобы поменять цвет частиц для данного события) или форме легко отличить частицы в разных событиях, особенно если частица по каким-то причинам не может попасть из одного события в другое. Еще в операторе есть возможность управлять числом видимых в окнах проекций частиц, задавая процентное соотношение относительно их общего числа. Теперь обо всем этом по порядку:
Type (тип) – список с вариантами отображения частиц в окнах проекций. Двухразмерные маркеры показывают только положение частиц. Geometry показывает как частицы будут выглядеть при визуализации, в трех измерениях. Lines (линии) показывают скорость и направление движения. Bounding Boxes (габаритные контейнеры) демонстрируют масштаб и ориентацию. Варианты (в скобках размерность и перевод):
Visible % (видимость) – определяет процент отображаемых в окнах проекций частиц от общего их количества. Параметр позволяет увеличить скорость прорисовки частиц за счет уменьшения количества видимых.
Show Particle Ids (показывать индексы частиц) – если флажок включен, уникальный номер индекса для каждой частицы становится видимым в окнах проекций. Частицы нумеруются в порядке рождения, начиная с 1 для перворожденной частицы.
Selected – список с вариантами отображения выделенных частиц. Варианты те же самые, как и в списке Type.
Ну вот почти все с первым событием, операторы-квадратики в нем закончились, остался только желтый ромбик Age Test, но перед его описанием показываю, что же произошло с системой частиц в первом событии:
Тест возраста, включенный в систему частиц, заставляет ее проверять, сколько времени прошло с начала анимации или с рождения частицы, или сколько времени частица находится в текущем событии и направлять частицы по веткам событий в соответствии с результатом проверки. Список вверху интерфейса позволяет выбрать один из типов возраста на тестирование:
Test True if Particle Value – группа радиокнопок позволяет вам установить, в какой момент тест направит частицы в следующее событие если проверка по возрасту даст положительный или отрицательный результат. По умолчанию – Is Greater Than Test Value (если больше, чем значение теста). Т.е. по умолчанию Age Test возвращает истину (True) если тестируемый возраст превысит значение параметра Test Value (значение теста), но вы также можете выбрать вариант Is Less Than Test Value (если меньше, чем значение теста). Например, если вы используйте тип возраста Absolute Age, установите параметр Test Value равным 60, а параметр Variation равным нулю, и выберете вариант Is Less Than Test Value, то частицы будут проходить в следующее событие только до 60-го кадра. После 60-го кадра все оставшиеся частицы останутся в текущем событии до тех пор, пока другой тест не возвратит истину.
Test Value (значение теста) – определенный номер кадра, возраст частицы (в кадрах) или продолжительность события (в кадрах) для тестирования. По умолчанию 30. Анимировать этот параметр нельзя.
Variation (отклонение) – количество кадров, на которое тестируемая величина может расходиться со значением Test Value. По умолчанию 5. Анимировать этот параметр нельзя. Чтобы получить реальное значение на тест для каждой частицы, система умножает значение Variation на случайное число из диапазона от -1.0 до 1.0 и складывает результат со значением Test Value. Например, если Test Value=300 и Variation=10, то тестируемая величина для каждой частицы будет случайным число из диапазона от 290 до 310.
Subframe Sampling (межкадровое разбиение) – включение этого параметра помогает избегать прерывистости системы частиц в моменты переходов от одних событий к другим путем тестирования времени в более высоком межкадровом разбиении (т.е. во времени каждого кадра) по сравнению с использованием относительно грубого разрешения по кадрам. Параметр включен по умолчанию. Прерывистость это эффект создания отдельных наборов частиц, двигающихся рывками по сравнению с постоянным потоком. Если параметр отключить, тест будет выполняться точно в моменты кадров.
Событие Перемещение двигает частицы из пункта старта в пункт назначения. Параметры операторов я подобрал таким образом, чтобы перед созданием целевого объекта частицы примерно равномерным облаком окружили то место, где он должен появиться. В событии используется только один новый оператор Keep Apart и новый тест Find Target, остальные операторы подробно не описываю, т.к. сделал это для предыдущего событии. В них я уменьшил влияние силы тяжести, увеличил скорость, расхождение и скорость вращения также увеличил по сравнению с предыдущим событием, чтобы получить нужную анимацию облака из осколков частиц. Все параметры подбираются вручную и это, кстати, довольно долгий процесс, который приходится повторять и шлифовать каждый раз для разных положений и объектов пока не понравится, ну впрочем как всегда.
Оператор из семейства Speed, позволяет применить к частицам силы притяжения или отталкивания, чтобы держать их на некотором расстоянии от соседних частиц, предотвращая или уменьшая проникновение частиц друг в друга. Также вы можете использовать отрицательную силу, чтобы частицы при этом не слишком “разбегались” в стороны. Для этих целей оператором Keep Apart контролируются скорость и ускорение частиц. Примечание: Keep Apart не использует геометрию частиц, вместо этого он создает сферическое силовое поле с центром в опорной точке для каждой частицы. Можно настроить размер силового поля изменив размер частицы. Во многих случаях настройки по умолчанию не устраняют пересечения частиц. Чтобы увеличить разделение следует использовать большие величины для параметров Force (сила) и Accel Limit (предел ускорения), выбрать вариант Relative To Particle Size (относительно размеров частицы) и увеличить значение параметра Core % (ядро).
Force – величина силы, применяемой к частицам. Положительные значения направляют частицы в стороны друг от друга, отрицательные сдвигают плотнее. По умолчанию 100.
Accel(eration) Limit – предел ускорения, во включенном состоянии позволяет вам установить максимальный предел ускорения, который может повлиять на движение частиц. Если параметр отключен, система использует любое подходящее ускорение. Параметр включен по умолчанию, величина 1000. Подсказка: для плавного движения нужно использовать низкие значения параметра, а для точности высокие, например, в случаях, когда частицы должны ударять цель малого размера. Вы можете анимировать этот параметр (используйте синхронизацию Sync By > Event Duration), чтобы задать различные подходящие величины в зависимости от требуемых результатов.
Speed Limit – предел скорости, во включенном состоянии позволяет установить максимальный предел скорости, который может повлиять на движение частиц. Если параметр отключен, система использует любую подходящую скорость. По умолчанию отключен, значение по умолчанию 600.
Группа Range – эти параметры устанавливают объем и спад объема в пределах которых работает сила оператора. Можно задать как абсолютные размеры, так и относительные, установив процентную зависимость от размера частиц. По умолчанию Absolute Size.
Absolute Size (абсолютный размер) – выберите этот вариант, чтобы установить фиксированные абсолютные величины для радиуса ядра и зоны спада в системных единицах.
Core Radius (радиус ядра) – расстояние от опорной точки каждой частицы, в системных единицах. Внутри сферы с этим радиусом и центром в опорной точке действие силы максимально. По умолчанию 10.
Falloff Zone (зона спада) – расстояние за радиусом в системных единицах, в пределах которого сила уменьшается от максимального значения до нуля. По умолчанию 10.
Relative To Particle Size (относительно размеров частицы) – выберите этот вариант, чтобы установить радиус ядра и зону спада как процентные отношения от радиуса каждой частицы. Этот радиус определяется измерением расстояния от опорной точки до самого дальнего угла габаритного контейнера (ха, также как и у меня в алгоритме).
Core % (ядро) – расстояние от центра каждой частицы как процент от ее радиуса, в пределах которого действие силы максимально. По умолчанию 200.
Falloff % (спад) – расстояние за ядром как процент от радиуса, в пределах которого сила уменьшается от максимального значения до нуля. По умолчанию 100.
Variation % (отклонение) – значение, на которое расстояния могут случайно изменяться, как процент от соответствующих величин. Системой используется одинаковое случайное отклонение для величин ядра и спада в независимости от того, абсолютные они или относительные. По умолчанию 0. Пример: если вы выберите Absolute Size и установите 40 для Core Radius, 20 для Falloff Zone и 50 % для Variation, то тогда реальный радиус каждой частицы будет являться случайным числом из диапазона от 20 до 60, а зона спада – случайным числом в диапазоне от 10 до 30.
Группа Scope – эти настройки позволяют вам держать частицы на дистанции от других частиц в различных событиях и даже системах, без влияния на поведение последних. По умолчанию Current Event (текущее событие).
Current Event (текущее событие) – оператор Keep Apart работает только в текущем событии. Если используется глобально, держит частицы в каждом событии текущего потока отдельно друг от друга, но не отдельно от частиц других событий в этом потоке.
Current Particle System (текущая система частиц) – держит частицы текущего события отдельно друг от друга и от всех остальных частиц в текущем потоке (для справки у меня в сцене один единственный поток, т.к. один объект PF Source). Частицы, не состоящие в текущем событии, не попадают под влияние оператора. Когда используется глобально то держит по отдельности все частицы текущего потока.
Selected Events (выделенные события) – держит частицы текущего события отдельно от частиц событий, подсвеченных в нижнем списке. Частицы, не вошедшие в текущее событие, не попадают под влияние оператора. Когда используется глобально, держит все частицы текущего потока отдельно от частиц подсвеченных в списке событий, но действует только на частицы из текущего потока. Не забудьте щелкнуть на событиях в списке, чтобы их подсветить.
Selected Particle Systems (выделенные системы частиц) – держит частицы текущего события отдельно от всех частиц подсвеченных в списке потоков. Частицы, не вошедшие в текущее событие, не попадают под влияние оператора. Когда используется глобально, держит все частицы текущего потока отдельно от частиц подсвеченных в списке потоков, но влияет только на частицы текущего потока. Не забудьте щелкнуть на потоках в списке, чтобы их подсветить.
Так-с, в событии Перемещение остался только желтый ромбик теста Find Target и надо показать, как выглядят частицы на этом этапе.
По умолчанию оператор Find Target направляет частицы в сторону одной или нескольких заданных целей. После достижения цели, частицы получают право на переход к другому событию. Вы можете задать специальную скорость или время движения частицы до цели, а также определить место на цели, в которое частица будет направлена. А вообще можно использовать тест Find Target как простую проверку на близость: после сближения частицы до определенной дистанции с целью, она становится способной перейти в следующее событие. Когда вы добавляете Find Target в систему частиц в окне Particle View, то в начале координат сцены появляется специальный значок теста Find Target. Этот значок можно использовать как цель (я делаю это в третьем событии – значок стоит на месте объекта собирания осколков) либо в качестве целей можно использовать один или несколько объектов-сеток mesh objects, это я использую в данном событии, мои частицы бегут за объектом $Destination. Чтобы отобразить параметры теста на панели Modify, нужно выделить значок теста. Если удалить значок из сцены, тест из Particle View также удалится.
Control By (способ управления) – список вверху панели позволяет выбрать один из способов управления частицами, а именно направлять частицы к цели, задавая для них скорость и ускорение, либо задавая время движения, которое им понадобится, чтобы достичь цели. И, в качестве альтернативы, выбирая вариант No Control можно анализировать расстояние от цели до частиц. Варианты:
Группа Test True If Distance To: (условие истинно, если расстояние до:) – параметры данной группы позволяют вам выбрать точку на цели, расстояние до которой тест будет анализировать и задать это расстояние. Можно выбрать Target Pivot (цель – точка опоры) или Target Point (цель - точка) и задать расстояние в параметре Is Less Than: (меньше чем:).
Target Pivot – измеряет расстояние между частицей и точкой опоры цели. Если частицы направлены в стороны от цели, а значение параметра Is Less Than мало, то такое состояние может продолжаться бесконечно, и тест не сработает.
Target Point – измеряет расстояние между частицей и специальной точкой на цели.
Is Less Than – когда расстояние от частиц до точки опоры или до специальной точки на цели меньше, чем это расстояние, то такие частицы проходят тест и получают право перейти к следующему событию. Параметр измеряется в системных единицах. Примечание: если вы присвоите ноль параметру Is Less Than, то никакие частицы не пройдут тест с истиной. Такое может понадобиться, например, для анимации пчел, которые кружатся вокруг цветка, но не садятся на него. В этом случае можно задать небольшую величину параметру Accel Limit, чтобы пчелы не кружились слишком близко от цветка.
Группа Control By Speed (управление по скорости) – параметры этой группы используются для настройки скорости и ускорения частиц при выборе способов управления Control By Speed или Speed Then Time (скорость потом время). Группа доступна только при выборе управления Control By Speed (управление по скорости). Я ее в уроке не использую, но расскажу все равно. Параметры группы:
Use Cruise Speed (использовать скорость хода) – когда флажок включен, система предоставляет вам явный контроль над скоростью частицы и отклонением скорости. Когда флажок выключен – система вычисляет скорость частицы автоматически, используя значение параметра Accel Limit. По умолчанию флажок включен.
Speed (скорость) – скорость частицы в системных единицах на секунду. По умолчанию 300.
Variation (отклонение) – отклонение скорости частицы от величины скорости. Работает аналогично описанному ранее параметру Variation для оператора Speed.
Accel Limit (предел ускорения) – устанавливает предел ускорения. Это значение задает инерцию и скорость частиц. По умолчанию 1000. Значение по умолчанию для предела ускорения соотносится со значением скорости по умолчанию, поэтому рекомендуется менять пропорционально значение Accel Limit при изменении значения Speed. Подсказка: для плавного движения нужно использовать низкие значения параметра, а для точности высокие, например, в случаях, когда частицы должны ударять цель малого размера. Вы можете анимировать этот параметр (используйте синхронизацию Sync By > Event Duration) чтобы задать различные подходящие величины в зависимости от требуемых результатов.
Ease In % (замедлять на) – параметр задает темп, с которым частица будет снижать свою скорость по мере приближения к точке цели. Система вычисляет конечную скорость по следующей формуле: (100% - Ease In) * Speed. Следовательно, если значение Ease In равно 100%, то частицы достигнут цели с нулевой скоростью, а если Ease In равно 0%, то они вообще не будут замедляться на протяжении всего пути до цели. При средних значениях между нулем и сотней скорость вычисляется в соответствии с расстоянием до точки цели, как линейная интерполяция между начальной скоростью хода и конечной скоростью. Когда частица поступает в событие, расстояние до точки цели вычисляется и используется в дальнейшем для этой интерполяции. По умолчанию 0%.
Sync By – синхронизация анимации, работает аналогично одноименному и описанному ранее параметру теста Age Test.
Группа Control By Time (управление по времени) – позволяет вам задать время, за которое частицы должны достичь цели. Группа недоступна, если выбрано управление Control By Speed. Параметры группы:
Timing (синхронизация по времени) – определяет вариант, который система будет использовать при вычислении времени, задаваемом параметрами Time и Variation. Возможные варианты:
Time (время) – число кадров, которое потребуется частицам, чтобы достичь цели. По умолчанию 60.
Variation (отклонение) – число кадров, на которое реальное значение Time может отклониться от указанного значения. По умолчанию 5. Чтобы получить реальное время достижения цели для каждой частицы, система умножает значение Variation на случайное число из диапазона от -1.0 до 1.0, а результат прибавляет к значению Time. Например, если Time=60 и Variation=20, то время достижения цели для каждой частицы будет в интервале от 20 до 80 кадров.
Subframe Sampling (межкадровое разбиение) – включено по умолчанию, что это и зачем нужно я уже писал.
Use Docking Speed (использовать скорость стыковки) – флажок позволяет задать скорость частицы когда она достигает цели. Может потребоваться, чтобы частица “стыковалась” с целью из заданного положения и с определенной скоростью. Когда этот флажок выключен, система вычисляет путь стыковки как кратчайшее расстояние с минимальным ускорением вдоль пути. Когда флажок включен, система вычисляет конечную скорость частицы перед достижением цели (т.е. скорость стыковки) используя параметры Speed и Variation. Поэтому если нужно плавное приземление, установите параметр Speed равным нулю. Флажок по умолчанию выключен.
Speed (скорость) – стыковочная скорость в системных единицах на секунду. По умолчанию 100.
Variation (отклонение) – величина, на которую реальная скорость частицы может случайно изменяться. По умолчанию 0.
Группа Target (цель) – по умолчанию система использует в качестве цели значок Find Target, но вместо него можно задать и другую цель с помощью инструментов этой группы.
Icon (значок) – использовать в качестве цели значок Find Target. Каждый тест Find Target использует свой собственный значок. Даже если вы не используете его в качестве цели, он все равно влияет на поведение частиц, если установлен один из типов стыковки (docking type): Parallel, Spherical или Cylindrical.
Mesh Objects (объекты-сетки) – используйте в качестве целей один или несколько Mesh-объектов сцены. Если включить эту радиокнопку, становятся доступными список и управляющие кнопки. Если в качестве цели вы используйте более одного объекта, цель для каждой частицы определяется вариантом из выпадающего списка Object.
Add – нажмите кнопку и выберите объект в сцене, чтобы сделать его целью и занести в список.
By List – нажмите кнопку и в появившемся окне Select Target Objects выберите один или несколько объектов-сеток для добавления в список. В окне отображаются существующие в сцене объекты подходящего типа.
Remove – выделите объект в списке и нажмите на эту кнопку, чтобы его из списка удалить. Любой удаляемый объект остается в сцене.
Sync By (синхронизировать по) – выберите кадр анимации, когда частицы посылаются в направлении цели и включены флажки Animated Shape (анимированная форма) или Follow Target Animation (следовать анимации цели). Варианты:
Animated Shape (анимированная форма) – включите флажок, если требуется, чтобы частицы следовали к поверхности объекта, форма которого меняется посредством масштабирования, морфинга или модификаторов. Для этого требуется больше вычислений, поскольку цель должна обновляться на каждом шаге проверки.
Follow Target Animation (следовать анимации цели) – включите флажок, чтобы частицы следовали за двигающейся целью, т.е. целью с анимированным положением. Для этого требуется больше вычислений, поскольку цель должна обновляться на каждом шаге проверки.
Point (точка) – позволяет вам определить место на объекте, в которое частица должна “приземлиться”. Варианты:
Object (объект) – когда есть несколько объектов-целей, данный вариант позволяет вам указать, каким образом система должна выбирать из них конкретную. Вариант доступен только когда число целей больше одной. Выбирайте один из пунктов:
Lock On Target Object (прикрепить к целевому объекту) – когда флажок включен, система определяет целевой объект для каждой частицы один единственный раз: в момент поступления частицы в событие. После этого частица “прикрепляется” к своей цели. Когда флажок выключен, система может постоянно пересчитывать целевой объект для каждой частицы. Флажок доступен, когда задано несколько целевых объектов. Например, если вы указываете частицам нацеливаться на ближайшую поверхность (Closest Surface) в соответствии с анимацией этой поверхности и движением частицы, то определение ближайшей поверхности будет происходить постоянно. Это приведет к тому, что частица может сменить целевой объект в зависимости от ситуации. Примечание: каждый раз, когда тест Find Target устанавливает целевой объект, он “прикрепляется” к определенной точке на этом объекте. Точка может измениться, только если изменится объект. Поэтому, когда целевой объект один, точка закрепления всегда остается неизменной относительно объекта. Это происходит ввиду того, что если целевой объект или его поверхность анимированы и включен флажок Follow Target Animation либо флажок Animated Shape, абсолютные координаты целевой точки могут измениться. Когда флажок Lock On Target Object отключен, требуется больше вычислений, так как системе необходимо рассчитывать оптимальную целевую точку для каждой частицы в каждом кадре.
Группа Docking Direction (направление стыковки).
Параметры Docking Type (тип стыковки) позволяют вам определить направление, в котором частицы будут сближаться с целью. Варианты:
Примечание: выбор второго, третьего или четвертого варианта ведет к появлению стрелок на значке теста, указывающих, в каком направлении частицы последуют для стыковки. Вы можете это направление изменить, повернув значок. Работает всегда, даже если в качестве целей выбраны Mesh-объекты. При выборе пятого варианта на значке также появятся стрелки, сигнализирующие о том, что для направления стыковки будут использоваться нормали поверхностей. Реальные направления зависят от поверхности цели. Вариант работает всегда, даже если в качестве целей выбраны Mesh-объекты.
Distance (дистанция) – расстояние от частицы до цели, при достижении которого частица начинает процесс стыковки. В процесс включаются направление и скорость стыковки (в случае, когда используется контроль по времени – Control By Time).
Icon Size (размер значка) – устанавливает размер значка Find Target. Размер влияет на поведение частиц, когда значок используется в качестве цели. Обращаю ваше внимание – я в уроке это использую. Значок достаточно большой и расположен внутри объекта $TDestination01.
Color Coordinated (цветные координаты) – когда флажок включен, значок Find Target использует цвет события, содержащего этот тест. Цвет задается локальным оператором Display, если таковой существует. Это работает, даже когда оператор Display выключен. Когда флажок выключен, тест Find Target использует цвет гизмо-оболочек для тестов по умолчанию, как определено в меню Customize User Interface > Colors > Particle Flow. По умолчанию флажок включен. Включенный флажок позволяет легко найти значок Find Target, поскольку частицы в событии используют этот же цвет.
Наконец-то я до него добрался. Из новых операторов там к счастью только один – Script Operator, который используется тестом Find Target, чтобы направить осколки в нужные позиции и заодно этот скрипт меняет форму осколков, делая из них осколки целевого объекта. В самом начале урока я говорил, что хочу сделать это преобразование как можно более незаметно, так вот, незаметность достигается за счет того, что осколки крутятся на протяжении всей жизни, а подмена происходит в момент стыковки, когда они быстро устремляются на свои конечные позиции. И глаз не замечает замену, все легко и просто. Вообщем быстрое движение и короткая траектория – залог успеха в моем морфинге.
О скриптах для Particle Flow. Все подобные скрипты, как правило, состоят из четырех небольших блоков, pCont это контейнер (particeContainer) - имя переменной, в которой сохраняется текущий поток частиц, с которым работает скрипт, имя может быть любым:
Вот код скрипта, используемого в Script Operator третьего события. Меняю геометрию частиц на правильную, и ставлю их на места осколков объекта $TDestination. Все очень просто.
on ChannelsUsed pCont do --ВНУТРИ ЭТОГО БЛОКА ПЕРЕЧИСЛЯЮТСЯ КАНАЛЫ, КОТОРЫЕ БУДЕТ ИСПОЛЬЗОВАТЬ СКРИПТОбращаю ваше внимание на тесты Find Target в событиях. Синхронизация идет по абсолютному времени, а между вторым и третьим тестом проходит совсем небольшой интервал – в среднем чуть больше 10 кадров. Это сделано как раз для того, чтобы обмануть глаз и быстро собрать из частиц второй объект. Эффект сдвигания осколков достигается за счет настроек стыковки в Find Target третьего события.
Ну, вот и все. Надеюсь, урок поможет вам создать свой красивый эффект Particle Flow. Да, и последнее: просто так скрипты в Particle Flow работать не будут. Их нужно поместить в соответствующие операторы (у меня это Birth Script и Script Operator), нажав кнопку Edit Script и заменив текст по умолчанию на текст соответствующих скриптов, а потом запустить (CTRL+E). Комментарии по скриптам находятся у них внутри. Если вместо русских кириллических букв в редакторе максскрипта вы увидите "крякозябры" - надо в файле maxroot/MXS_Editor.properties заменить значение code.page на 0 вместо -1.