Главная » Статьи » Учебник: теория

Управление анимацией. Часть1.

Управление анимацией

Поскольку актёр — класс, наследуемый от NodePath, то он наследует и его методы, такие как reparentTo(), setPos() ит.д, но так же расширяется за счёт собственных методов, позволяющих контролировать анимацию. Указатель на актёра должен постоянно храниться в памяти, о чём сказано в главе руководство по загрузке моделей.

Проигрывание анимации

Анимация может быть проиграна единожды, либо зацикленна. Панда не строит промежуточных кадров между первым и последним фреймом анимации, поэтому анимация, рассчитанная на циклическое воспроизведение должна изначально рассчитываться так чтобы избежать рывков при переключении. Анимация ожет быть остановлена в любой момент — актёр останется в том положении, в котором была остановлена анимация


actor.play('Animation Name')
actor.loop('Animation Name')
actor.stop()

Вы можете использовать метод pose() чтобы установить актёра в положение, соответствующее определённому фрейму анимации. Фреймы считаются с 0.
actor.pose('Animation Name', FrameNumber)

По умолчанию анимация будет стартовать не с фрейма указанного методом pose, а с первого фрейма. Если вам не нужно чтоб анимация проигрывалась с первого фрейма или заканчивалась на последнем, вы можете указать опциональные параметры fromFrame и toFrame в методах play() и loop():


actor.play('Animation Name', fromFrame = 10)
actor.loop('Animation Name', fromFrame = 24, toFrame = 36)

Тем не менее, метод loop имеет ещё один опциональный параметр - restart, по-умолчанию равный 1, и указывающий, что анимация должна стартовать с начала. Если вы установите его в 0, то анимация продолжит выполняться с текущего фрейма:

actor.pose('Animation Name', 30)
actor.loop('Animation Name', restart = 0, fromFrame = 24, toFrame = 36)

Вы можете получить информацию об анимации с помощью следующих функций:


print actor.getNumFrames('Animation Name') #возвращает количествофреймов в анимации
print actor.getCurrentAnim() #возвращает строку, содержащую название текущей анимации
print actor.getCurrentFrame('Animation Name') #возвращает текущий фрейм анимации

AnimControl

AnimControl — класс дающий управление над определённой анимацией. Нет необходимости использовать его напрямую, однако он может пригодиться для контроля анимации из других классов. Замечание: В версиях панды, ранее 1.4, требовался второй параметр для actor.getAnimControl, являющийся именем части актёра, или строкой "modelRoot" если актёр не составной.


myAnimControl=actor.getAnimControl('Animation Name') #получение AnimControl

myAnimControl.isPlaying() #проверка — проигрывается анимация или нет, возвращает логическое значение
myAnimControl.getFrame() #номер текущего фрейма
myAnimControl #скорость анимации: фреймов в секунду
myAnimControl.getFullFframe() #возвращает номер фрейма в виде значения с плавающей точкой, превышающий количество фреймов одного цикла. Не рекомендуется.
myAnimControl.getFullFrame() #Аналогично, но с целочисленным значением
myAnimControl.getNextFrame() #возвращает следующий в очереди фрейм.
myAnimControl.getNumFrames() #возвращает общее количество фреймов
myAnimControl.getPlayRate() #Возвращает скорость анимации
myAnimControl.loop() #старт циклического проигрывания анимации
myAnimControl.play() #старт однократного проигрывания анимации
myAnimControl.pose(frame) #установка позы актёра в соответствии с нужным фреймом
myAnimControl.setPlayRate(rate) #Установка скорости анимации
myAnimControl.stop() #Остановка анимации

Скорость анимации (Play rate)

Скорость анимации может быть любым значением с плавающей точкой. Это масштабирующий фактор относительно базовой скорости; 1.0 — проигрывание с нормальной скоростью; 2.0 — удвоенная скорость, а 0.5 — замедление вдвое. Это так же позволяет проигрывать анимацию в обратную сторону, если назначить скорости отрицательное значение.


actor.setPlayRate(newPlayRate, 'Animation Name')

Смешивание (Blending)

Можно проигрывать одновременно несколько анимаций для одного актёра. Результирующая поза будет средним значением всех поз для текущего фрейма каждой действующей анимации.

В режиме смешивания каждая анимация применяется ко всему телу. Если же вы хотите спроиграть одну анимацию, скажем, для левой руки, в то время как другая анимация будет проигрываться для ног, то вам нужно использовать режим half-body animation, который отличается от смешивания.

Для активации режима смешивания вам нужно вызватьметод enableBlend(). Пока модель находится в режиме смешивания анимации — проигрывание новой анимации не останавливает предыдущую. В режиме смешивания можно указать насколько та или иная анимация влияет на общий результат: метод setControlEffect().


actor.enableBlend()
actor.setControlEffect('animation1', 0.2)
actor.setControlEffect('animation2', 0.8)
actor.loop('animation1')
actor.loop('animation2')

В примере 20% animation1 и 80% animation2 будут отображены на модели. Запуск или остановка анимации в режиме смешивания не влияют на ControlEffect; вы должны установить его вручную в 0.0 если желаете чтоб она больше не оказывала влияния на модель.

В режиме смешивания вы можете остановить отдельную анимацию, вызвав метод Stop() со строковым параметром — именем останавливаемой анимации. Вызов без параметров останавливает все текущие анимации.

Для выхода из режима смешивания вызывается метод disableBlend():

actor.disableBlend()

Half-body animation

Если вы желаете проигрывать различные анимации для различных частей тела, то вам нужно разбить скелет на условные части. Каждая из них сможет проигрывать анимацию не влияя на другие. Необходимо вызвать метод actor.makeSubpart(), в качестве параметров — желаемое имя, список включаемых костей и список исключаемых костей. Указанные кости так же захватывают все зависимые кости. Исключения переписывают влючения.


actor.makeSubpart("legs", ["Left Thigh", "Right Thigh"])
actor.makeSubpart("torso", ["Head"], ["Left Thigh", "Right Thigh"])

Для проигрывания анимации на указанной части используется дополнительный параметр partName


actor.loop("walk", partName="legs")
actor.loop("reload", partName="torso")

Интерполяция

Интерполяция поддерживается начиная с версии 1.3.0. Интерполяция позволяет сглаживать переходы между фреймами анимации, позволяя избежать рывков. По-умолчанию интерполяция неактивна. Для включения добавьте следующие строки кода.


from pandac.PandaModules import loadPrcFileData
loadPrcFileData("", "interpolate-frames 1")

Если вы включили интерполяцию, то вам так же потребуется очистить директорию кэша моделей — иначе эффекта может не оказаться.
Разработчики не рекомендуют пользоваться интерполяцией, т. к. это глобальная опция, влияющая на все модели, вместо этого они советуют использовать actor.setBlend(frameBlend = True), что действует на целевую модель и не отражается в кэше.

Интервалы

Другой путь проигрывать анимацию - использовать ActorInterval, что даст вам больший контроль над анимацией. Однако ActorInterval несколько медленнее, поэтому лучше использовать обычную анимацию, если нет прямой необходимости в интервалах.

Категория: Учебник: теория | Добавил: ninth (29.01.2009)
Просмотров: 5251 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Онлайн всего: 1
Гостей: 1
Пользователей: 0