- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Написание скриптов для Blender 2.49 - Michel Anders
Шрифт:
Интервал:
Закладка:
loc1 = obs[1].getLocation()
bb0 = obs[0].getBoundBox()
bb1 = obs[1].getBoundBox()
w = (diagonal(bb0)+diagonal(bb1))/4.0
Прежде, чем мы сможем вычислить траектории обоих объектов, мы сначала создадим два новых и пустых объекта кривых IPO:
ipo0 = Ipo.New('Object','ObjectIpo0')
ipo1 = Ipo.New('Object','ObjectIpo1')
Мы произвольно выбираем начальный и конечный кадры нашей операции обмена в 1 и 30 соответственно, но скрипт легко может быть адаптирован для того, чтобы пользователь вводил эти величины. Мы итерируем по каждой отдельной кривой IPO для IPO местоположения и создаем первую точку (или ключевой кадр) и этим самым фактически назначается кортеж (номер кадра, значение) на кривую (выделенные строки следующего кода). Последующие точки могут быть добавлены к этим кривым по индексу - их номеру кадра присвоением значения, как это сделано для кадра 30 в следующем коде:
for i,icu in enumerate((Ipo.OB_LOCX,
Ipo.OB_LOCY,Ipo.OB_LOCZ)):
ipo0[icu]=(1,loc0[i])
ipo0[icu][30]=loc1[i]
ipo1[icu]=(1,loc1[i])
ipo1[icu][30]=loc0[i]
ipo0[icu].interpolation =
IpoCurve.InterpTypes.BEZIER
ipo1[icu].interpolation =
IpoCurve.InterpTypes.BEZIER
Заметьте, что ключ позиции первого объекта в кадре 1 является текущей позицией, а ключ позиции в кадре 30 - позиция второго объекта. Для другого объекта всё с точностью до наоборот. Мы установили режимы интерполяции этих кривых на "Bezier", чтобы получить плавное движение. У нас теперь есть две кривые IPO, которые делают взаимообмен позиций двух объектов, но расчёт пока таков, что они будут двигаться сквозь друг друга.
Следовательно, нашим следующим шагом нужно добавить ключ в кадре 15 со скорректированной компонентой z. Ранее мы вычислили w, чтобы запомнить половину расстояния, на которое нужно сдвинуться каждому с пути другого. Здесь мы добавляем это расстояние к компоненте z в середине пути для первого объекта и вычитаем его для другого:
mid_z = (loc0[2]+loc1[2])/2.0
ipo0[Ipo.OB_LOCZ][15] = mid_z + w
ipo1[Ipo.OB_LOCZ][15] = mid_z - w
Наконец, мы добавляем новые кривые IPO к нашим объектам:
obs[0].setIpo(ipo0)
obs[1].setIpo(ipo1)
Полный код доступен как swap2.py в файле orbit.blend. Результирующие пути двух объектов схематически отображены на следующем скриншоте:
Много проглотил - определение поз
Часто мультяшные персонажи, как кажется, имеют трудности, пытаясь поглощать свою пищу, и даже когда они наслаждаются своим обедом, скорее всего будут вынуждены пропускать его через слишком узкую глотку, чтобы он проходил удобно без всяких видимых изменений формы.
Трудно анимировать проглатывание или любое другое перистальтическое движение, используя ключи формы, так как это не общая форма меша, которая изменяется однородным способом: мы хотим двигать вдоль него локализованную деформацию. Один из способов сделать это - соединить арматуру, состоящую из линейной цепи костей с мешем, который мы хотим деформировать (показано на иллюстрации) и анимировать масштаб каждой индивидуальной кости во времени. Этим путём мы можем значительно расширить возможность управлять перемещением 'куска' внутри. Например, возможно сделать перемещение работающим слегка с перебоями, как будто он перемещается от кости к кости, чтобы имитировать поглощение чего-то что жесткого.
(ПЕРИСТАЛЬТИКА (peristalsis) - волнообразные сокращения, распространяющиеся вдоль некоторых полых органов в теле человека. Эти сокращения возникают самопроизвольно и характерны для таких полых органов, которые снабжены круговыми и продольными мышцами (например, обычно они наблюдаются в кишечнике). Перистальтика усиливается благодаря растяжению стенок полого органа. Как только стенки органа растягиваются, происходит сокращение круговых мышц. Перед их растяжением происходит расслабление круговых мышц и сокращение продольных, благодаря чему содержимое органа (чаще всего, кишечника) продвигается в дистальном направлении. - с сайта http://vocabulary.ru— пожелание приятного аппетита от переводчика ☺)
Для того, чтобы синхронизировать масштабирование индивидуальных костей таким образом, чтобы оно следовало по цепочке от родителя к ребенку, мы должны отсортировать наши кости, поскольку атрибут bones объекта Pose, который мы получаем, вызвав getPose() в арматуре, является словарём. Цикл по ключам или значениям этого словаря будет возвращать эти величины в произвольном порядке.
Следовательно, мы определяем функцию sort_by_parent(), которая принимает список костей Позы pbones и возвращает список строк, каждая из которых является именем кости Позы. Список будет отсортирован так, чтобы родитель был первым пунктом, со следующими за ним его детьми. Очевидно, что такая функция не будет возвращать значимый список для арматур, которые имеют кости с более чем одним ребенком, но для нашей линейной цепи костей это работает прекрасно.
В следующем коде, мы используем список имен bones, чтобы хранить имена костей Позы в правильном порядке. Мы выталкиваем (pop) кость из списка костей Позы pbones и добавляем её имя достаточно долго, пока она ещё не добавлена (выделено). (Я не cмог адекватно перевести это предложение, потому что здесь логика и программы и текста, как мне кажется, дают сбой, подробнее смотрите ниже — прим. пер.) Мы сравниваем имена вместо объектов костей Позы, поскольку текущая реализация костей Позы надежно не поддерживает оператора in:
def sort_by_parent(pbones):
bones=[]
if len(pbones)<1 : return bones
bone = pbones.pop(0)
while(not bone.name in bones):
bones.append(bone.name)
Затем, мы получаем родителя кости, которую мы только что добавили к нашему списку, и настолько долго, насколько мы можем просматривать цепь родителей, мы включаем такого родителя (или, точнее, его имя) в наш список перед текущим элементом (выделено ниже). Если цепь не может следовать дальше, мы выталкиваем новую кость Позы. Когда больше нет костей, метод pop() вызовет исключение IndexError, и мы выходим из нашего цикла while:
parent = bone.parent
while(parent):
if not parent.name in bones:
bones.insert(bones.index(bone.name),
parent.name)
bone = parent
parent = parent.parent
try:
bone = pbones.pop(0)
except IndexError:
break
return bones
Чем дольше я пытался разобраться с логикой этой функции, чтобы адекватно перевести два предыдущих абзаца, тем сильнее мне это не нравилось, ибо логики я не наблюдал. Тогда я немного потестировал эту функцию в файле peristaltic.blend, и убедился, что она правильно работает не во всех случаях. Цепочка костей в файле по направлению от родительских к дочерним выглядит так: ['Bone', 'Bone.001', 'Bone.002', 'Bone.003', 'Bone.004', 'Bone.005']. Если на вход функции список pbones приходит в таком порядке: ["Bone.001", "Bone.002", "Bone.003", "Bone.004", "Bone.005", "Bone"], то результат получается таким, каким надо, но если на вход придёт, например, список ["Bone.002", "Bone.001", "Bone.003", "Bone.004", "Bone.005", "Bone"] (первые два элемента поменяны местами), то на выходе будет всего 3 кости: ['Bone', 'Bone.001', 'Bone.002']. Вот мой исправленный вариант функции:
def sort_by_parent(pbones):
bones=[]
while True: # Бесконечный цикл гарантирует перебор
# всех костей из входного списка
try:
bone = pbones.pop(0)
except IndexError:
break # Единственное условие выхода из цикла
if not bone.name in bones:
bones.append(bone.name)
parent = bone.parent
while(parent):
if not parent.name in bones:
bones.insert(bones.index(bone.name),
parent.name)
bone = parent
parent = parent.parent
return bones
- Добавление переводчика.
Следующий шаг - это определение самого скрипта. Сначала, мы получаем активный объект в текущей сцене и проверяем, что это - на самом деле арматура. Если нет, мы предупреждаем об этом пользователя с помощью всплывающего сообщения (выделенная часть следующего кода), в противном случае мы продолжаем и получаем связанные с арматурой данные методом getData():