Чтение онлайн

ЖАНРЫ

Написание скриптов для Blender 2.49

Anders Michel

Шрифт:

Функция, показанная здесь, не делает ничего, но преобразует различные компоненты преобразования обратно в матрицы, используя методы API (где это доступно), и затем рекомбинирует их, используя матричное умножение в единственную матрицу, которая впоследствии возвращается.

Функция

doTarget
вызывается до вызова
doConstraint
и даёт нам возможность манипулировать целевой матрицей прежде, чем она будет передана в
doConstraint
. Аргументы - целевой объект, под-цель (или Кость или группа вершин для целевой арматуры или меша соответственно), целевая матрица, и свойства ограничения. В следующем разделе мы используем эту возможность для сохранения ссылки на целевой объект в свойствах, чтобы
doConstraint
могла иметь доступ к этой информации. Если мы не хотим ничего изменять, то достаточно возвратить целевую матрицу, как показано в следующем коде:

def doTarget(target_object, subtarget_bone, target_matrix,

id_properties_of_constraint):

return target_matrix

Точно также, если нет необходимости предлагать пользователю возможность определять дополнительные свойства,

getSettings
, может иметь просто оператор
return
(возврат). Если мы хотим показать всплывающее меню,
getSettings
– то место, где это нужно сделать. Мы также увидим такой пример в следующем разделе. Следующий код будет корректной реализацией "ничегонеделания":

def getSettings(idprop):

return

Вы тоже находите меня притягательным?

Когда Луна и Земля вращаются вокруг друг друга, каждая из них чувствует гравитационное притяжение другой. На земле это приводит к приливам и отливам, но твердые тела Земли и Луны также исказятся, хотя этот эффект небольшой. Теперь известно намного больше о приливах и отливах, чем только притяжение , но мы можем показать гравитационные искажения в гипертрофированном виде с применением ограничений.

Один из способов сделать это - использовать ограничение

TrackTo
, чтобы ориентировать ось нашего ограничиваемого объекта к притягивающему объекту и добавить второе ограничение, которое масштабирует ограничиваемый объект вдоль этой оси. Величина масштаба будет обратно зависима от расстояния между ограничиваемым объектом и целевым объектом. Эффект проиллюстрирован на следующем скриншоте, где эффект ограничения
TrackTo
объединен со скриптовым ограничением
moon_constraint.py
.

Мы должны написать это зависимое от расстояния масштабирование самостоятельно. Если мы возьмём шаблон ограничения, предоставляемый Блендером, мы можем оставить функции

doTarget
и
getSettings
как есть, но мы должны написать подходящую
doConstraint
(полный код доступен как
moon_constraint.py
):

def doConstraint(obmatrix, targetmatrices, idprop):

obloc = obmatrix.translationPart # Положение

obrot = obmatrix.toEuler # Вращение

obsca = obmatrix.scalePart # Масштаб

tloc = targetmatrices[0].translationPart

d = abs((obloc-tloc).length)

d = max(0.01,d)

f = 1.0+1.0/d

obsca[1]*=f

mtxloc = Mathutils.TranslationMatrix(obloc)

mtxrot = obrot.toMatrix.resize4x4

mtxsca = Mathutils.Matrix([obsca[0],0,0,0],

[0,obsca[1],0,0],[0,0,obsca[2],0], [0,0,0,1])

outputmatrix = mtxsca * mtxrot * mtxloc

return outputmatrix

Мы пропустили все строки, имеющие отношение к свойствам, так как мы не используем никаких настраиваемых пользователем свойств для этого ограничения. Выделенные строки показывают, что мы должны делать для вычисления зависимого от расстояния масштабирования.

В первой строке получаем позицию нашей цели. Затем мы вычисляем расстояние между ограничиваемым объектом и целью и определяем предел его минимума (чуть-чуть больше нуля), чтобы предотвратить деление на нуль в следующей выделенной строке. Используемая здесь формула отнюдь не является аппроксимацией какого-либо гравитационного влияния, но ведет себя достаточно хорошо для наших целей; коэффициент масштабирования будет близок к 1.0, если

d
очень большое, и гладко возрастает при уменьшении расстояния
d
. Последняя выделенная строка показывает, что мы изменяем масштаб только по оси y, то есть по оси, которую мы ориентируем на целевой объект с помощью ограничения
TrackTo
.

Циклическая зависимость:

Если оба объекта имеют сравнимую массу, гравитационное искажение должно быть сравнимого размера на обоих объектах. У нас может появиться искушение добавить ограничения

TrackTo
и
moon_constraint.py
к обоим объектам, чтобы видеть эффект воздействия их друг на друга, но, к несчастью, это не будет работать, поскольку это создаст циклическую зависимость, и Блендер запротестует.

Привязка к вершинам меша

Это похоже на режим "snap to vertex" (привязка к вершине), который доступен в Блендере из меню Object | Transform | Snap (информацию о привязках смотрите тут:Mesh), за исключением того, что эффект не постоянный (объект вернётся в свою изначальную позицию, как только ограничение будет удалено) и силу ограничения можно регулировать (даже анимировать), изменяя движок Influence (Влияние).

В ограничениях, которые мы до сих пор разрабатывали, нам нужна была только позиция целевого объекта для вычисления эффектов на ограничиваемом объекте. Эту позицию было легко применять в функции

doConstraint
, так как матрицы целей принимались в качестве аргументов. Теперь мы все же встречаем другой вызов: если мы хотим привязать к вершине, мы должны иметь доступ к данным меша целевого объекта, но целевой объект не передаётся в функцию
doConstraint
.

Поделиться с друзьями: