Procedurally Driven Scene

Материал из Blender3D.

Перейти к: навигация, поиск

‘Процедурно-управляемая сцена’

Автор: Daniel Salazar

image:Pds_figure1.jpg

Содержание

Введение

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

Завершенный скрипт движения можно найти здесь.

Основные вычисления

Мой подход состоит из двух простых и предсказуемых алгоритмов, один из которых управляет падением (ось Z), а другой контролирует перемещения (translations) (оси X и Y) объекта. Для движения по Z я пользуюсь формулой свободного падения, которую мы все изучали в школе (Википедия и Google - это замечательные инструменты для тех, у кого плохо с памятью/математическими способностями, как у меня):

z = (- 0.5 * Gravity * Time ** 2) + (Initial_Velocity * Time) + Initial_Altitude

Вы можете увидеть соответствующую функцию в 87-й строке скрипта. Таким образом, использование формулы свободного падения даёт мне хорошие правдоподобные значения Z Loc, с которых можно начать; теперь для части перемещения (translation part) используем простую формулу двухмерной линейной экстраполяции, работающую примерно так:

a = 2
b = 10

Сначала найдём разность между a и b с помощью вычитания

b - a = 8

Теперь разделим эту разность на какое-нибудь большое число, допустим, на 100

8 / 100 = 0.08

Это даёт нам 100 равномерно распределённых шагов между позициями a и b. Например, если мы хотим найти срединную позицию, мы делаем так

0.08 * 50 = 4

И смещаем это значение относительно a

4 + a = 6

То же самое можно сделать для любого другого значения от 0 до 100:

(b - a) / 100 * 175 + a = 16

Из этого следует ещё вот что: мы можем использовать значения больше 100, чтобы сделать экстраполяцию. Возьмём, к примеру, 175:

(b - a) / 100 * 175 + a = 16

В скрипте я пользуюсь этим для получения значений X Loc и Y Loc каждого объекта исходя из их желаемого конечного положения (b) и центра беседки (a), взятых мной из пустого объекта, так что я могу анимировать их с колебательными движениями для получения интересных эффектов, см. строки 68 и 78 в окончательной реализации.

Добавление отклонений

Python поставляется с модулем 'random', который хорош для лёгкого добавления отклонений к результатам каждого запуска формул. На самом деле он даёт не случайные, а псевдослучайные числа, это значит, что он берёт заданное инициирующее число (seed number) и на его основе генерирует много чисел и, если позднее вы дадите ему то же инициирующее число, то он сгенерирует те же самые числа. Это хорошая характеристика, поскольку она позволяет нам сохранять вещи полностью предсказуемыми, как я упомянул ранее.

Если вы вернётесь к функциям Loc и Rot, то увидите как сгенерированные случайные числа используются для добавления отклонений к результатам. Строка 39 показывает как задать разные инициирующие числа для каждого объекта, остающиеся постоянными во времени, избегая дрожания в движении объекта.

Доводка

Прежде чем запустить главный скрипт я сохранил исходные положения (rest positions) в свойствах старого доброго Game-Engine, используя на этот раз другой скрипт. Он также сохраняет значение смещения начального времени (starting time offset value) для каждого объекта. Пример, которым я делюсь, был здесь использован для крыши; он устанавливает стартовое время в соответствии с расстоянием от центра по формуле, которую вы можете видеть в строке 38 и именно поэтому черепица крыши начинает падать в положения начиная от внешней кромки к центру. Я также немного использую здесь генераторы случайных чисел. Таким образом, скрипт использует много случайных чисел и разных формул, и нам по-прежнему нужно контролировать конечное или начальное положение каждого объекта так, чтобы вся совокупность их корректно строила беседку; в нашем случае предсказуемые формулы и генераторы псевдослучайных чисел спасают положение.

Фокус состоит в предсказании того, где объект должен оказаться в конце движения и скорректировать текущее движение таким образом, чтобы объект в действительности достиг того положения, где вы хотели бы его видеть. В строках 96-98 и 113-115 я вызываю формулы смещения и поворота (location and rotation), но скармливаю им значение времени 100, соответствующее концу движения (что-то вроде заглядывания в будущее!). Далее в строках 130-135 я просто вычитаю это значение из результатов формул реального времени -- и все объекты волшебным образом правильно приземляются в центре мира. Под конец я добавляю значения расположения (location values), ранее сохранённые в каждом объекте с помощью вторичного скрипта, и теперь они приземляются в желаемой позиции!

image:Pds_figure2.png

Сглаживание движения

Формулы, используемые в данный момент, особенно экстраполирующий перенос, возвращают линейное перемещение, которое производит очень механистичное движение. Однако, оно выглядит лучше, когда прямо перед тем, как каждый кусочек достигает своей позиции, происходит некоторое замедление. Это то, с чем лучше всего справляются кривые IPO, так что я пользуюсь ими для управления временным промежутком всех формул. Посмотрите в строке 52 функцию, берущую текущее значение из кривой с простым именем "IPO" и, если вы проверите возвращаемые значения всех функций вращения и перемещения, то увидите как это значение используется там для преобразования линейного временного интервала.

Теперь, когда вы понимаете, как это работает, можете сами попробовать, следуя этим инструкциям:

  1. Добавьте к объектам свойства игрового движка (game engine), где будут сохраняться их исходное положение (rest location) и смещение стартового времени; это делается вторым скриптом , обрабатывающим выбранные объекты. Свойство Start присваивается разными формулами, которые вы напишете для разных особых случаев.
  2. Добавьте ваши объекты в группу "Main", когда вы захотите прекратить их анимацию просто удалите объекты из этой группы.
  3. Добавьте основной скрипт как ScriptLink, запускающийся от "FrameChange", и продирайтесь сквозь фреймы!
  4. Вам нужна кривая "Time" в объекте Empty на IPO с простым названием "IPO", идущая от (0, 0) до (100, 10); она управляет интерполяцией каждого куска, так что вы можете добавить эффект "замедления" и т.д.
  5. Вам нужен ещё один объект Empty с названием "Center" в центре сцены или в центре эффекта строительства, вы можете анимировать этот объект для получения красивых колебательных движений.
  6. Запустите анимацию с помощью Alt A или timeline

image:Pds_figure3.png

image:Pds_figure4.png

Credits:

Wow Factor создан martestudio.com

Отрендерил Oliver 'imshadi' Zúñiga

Особая благодарность Joshua 'aligorith' Leung и Geoffrey 'briggs' Bantle за инструменты разработки, необходимые для завершения этого ролика. contact@zanqdo.com

Вы можете просмотреть финальную версию ролика здесь: http://zanqdo.com/tmp/Rancho.mov (Пожалуйста, не ссылайтесь напрямую).

Личные инструменты