Эти пульсации не были предназначены быть анимированными, но в следующем разделе мы разработаем нод, который это сможет.
Капли - анимированные Pynodes
Множество узоров не являются статическими, а изменяются во времени. Одним из примеров являются пульсации, сформированные каплями, падающими в пруд. Блендер представляет параметры времени рендера, такие как, например, стартовый кадр, частота кадров, и текущий кадр, так что у нас есть много зацепок, чтобы сделать наши Pynodes зависимыми от времени. Мы увидим как использовать эти зацепки в скрипте, который генерирует рисунок капель. Узор, который изменяется достоверно, имеет сходство с расширяющимися волнами, вызванными каплями, падающими в пруд. На пути мы также приобретём несколько полезных хитростей, чтобы ускорить вычисления, сохраняя результаты дорогих вычислений в самом Pynode, чтобы позже многократно их использовать.
Наиболее важные параметры рендера при работе с изменяющимися во времени вещами - текущий номер кадра и частота кадров (количество кадров в секунду). Эти параметры предусмотрены сгруппированными вместе, в виде контекста рендера в модуле Scene, большинство через вызовы функций, некоторые как переменные:
scn = Scene.GetCurrent()
context = scn.getRenderingContext()
current_frame = context.currentFrame() #Текущий кадр
start_frame = context.startFrame() #Начальный кадр
end_frame = context.endFrame() #Конечный кадр
frames_per_second = context.fps #Частота
#кадров, fps
Теперь, с этой информацией, мы можем вычислить время, или абсолютное, или относительно стартового кадра:
absolute_time = current_frame/float(frames_per_second)
relative_time = (current_frame-start_frame)/ \
float(frames_per_second)
Заметьте преобразование во float (число с плавающей точкой) в знаменателе (выделено). Этим способом мы гарантируем, чтобы деление рассматривалось как операция с плавающей точкой. Не строго необходимо, поскольку fps возвращается с типом плавающей точки, но множество людей считают частоту кадров как некоторую целую величину, например, 25 или 30. Тем не менее, так бывает не всегда (например, кодировка NTSC использует дробную частоту кадров), так что мы лучше сделаем это явно. Также заметьте, что мы не можем покончить с этим делением, в противном случае, когда люди захотят изменить своё решение о выбранной частоте кадров, скорость анимации должна измениться.
Точно имитировать то, как выглядят пульсации, вызванные падением капелек, может показаться трудным, но это просто, хотя и немного запутано. Читатели, интересующиеся базовой математикой, могут проверить какие-нибудь ссылки (например, http://en.wikipedia.org/wiki/Wave). Нашей целью, тем не менее, не является моделирование реального мира с максимально возможной точностью, а обеспечение художника текстурой, которая выглядит хорошо и управляется так, чтобы текстуру можно было применить даже в нереалистичных ситуациях.
Так, вместо определения скорости, с которой двигается волна в зависимости от чего-нибудь, например, вязкости воды, мы делаем скорость в виде регулируемого входа в наш Pynode. То же самое для высоты и ширины волн, и показателя, с которым высота волн уменьшается по мере расширения. В основном, мы аппроксимируем наш небольшой пакет пульсаций, его расхождение наружу из точки падения капельки, функцией косинуса, умноженной на экспоненциальную функцию и показатель торможения. Это снова может показаться опасным погружением в математику, но может легко быть визуализировано:
Для того, чтобы вычислить высоту в любой позиции x, y на нашей текстуре, вышеуказанное можно осуществить следующим образом:
position_of_maximum=speed*time
damping = 1.0/(1.0+dampf*position_of_maximum)
distance = sqrt((x-dropx)**2+(y-dropy)**2)
height = damping*a*exp(-(distance-
position_of_maximum)**2/c)* \
cos(freq*(distance-position_of_maximum))
Здесь, dropx и dropy - позиция ударившей капли, a - наш регулируемый параметр высоты.