2017-01-05 9 views
1

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

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

Мне нужно, чтобы ваша голова попала справа налево в течение нескольких кадров. Моя первая идея состоит в том, чтобы отразить направление источника с моей осью X (между плечами), и если отраженное направление соответствует ограничениям ограничения - верните его. Если он не соответствует ограничениям - скопируйте отраженное направление вместо исходного.

Это должно дать мне приятное и непрерывное движение, и это не наука о ракете, но есть много деталей, о которых нужно позаботиться. Мои лимиты могут быть как min < max, но также max < min, они могут проходить через значение угла переключения (например, 360->0, или 180->-180) или нет. Кроме того, когда мой разрешенный диапазон больше 180 градусов, логика должна быть немного иной.

Количество разных случаев нарастает очень быстро, поэтому мне интересно, смогу ли я найти его уже где-то?

BTW: Я использую двигатель Unreal, если он делает любое различие.

EDIT:

Я извиняюсь, если я ошибочный вас с моей головой, например - это просто аналогия визуализировать мои потребности. Я не буду использовать этот код для ориентации головной кости (или любой другой) в финальной анимации. Я планирую использовать его в качестве очень простой операции в решении IK. Он будет использоваться на каждой итерации в каждой цепочке IK, для каждой кости, много раз. Поэтому нужно быть как можно быстрее. Все концепции более высокого уровня, такие как планирование движения, динамика и т. Д., Будут добавляться на другой уровень, если это необходимо.

На данный момент я просто просят функции, как:

float clampAngle(float angle, float min, float max) 

что бы вернуть непрерывное значение для изменения входов.

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

+0

Обрезка сама по себе недостаточна, вам нужно запланировать поворот с + клипа на -clip в течение нескольких кадров – Alnitak

+0

@Alnitak Я не хочу добавлять какое-либо планирование, потому что я не знаю будущего , Мне нужно, чтобы это было как можно проще, но с непрерывным выходом. Я думаю, что мое описание сделает это, мне просто нужно закодировать его :). – kolenda

+0

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

ответ

0

один подход:

  • определить область, где ограничение не может быть удовлетворено (конус позади головы)
  • мера того, как далеко в этой области ваша цель (угол между мишенью и центром конуса разделены на половину угла конуса)
  • к нам это скалярное значение плавно смешивать с ограничениями объект обратно в некоторой заранее определенной нейтральное положение (то есть повернуть голову обратно в центр/исходное положение плавно, как цель перемещается за головой)
1

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

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

Затем настройте второй идентичный шарнир и напишите угловую пружину, которая будет вращать его в направлении первого стыка с течением времени. Регулируя коэффициенты пружины - прочность, демпфирование и т. Д. - у вас будет контроль над тем, как вращается голова.

Как написать угловую пружину?

Это не может лучшим образом, но код очень короткий и легкий, так что здесь идет ...

Назовём мастер 2 суставов и раб. Вам необходимо сохранить вращение phi и угловую скорость omega на рабском суставе.

phi и omega are axis-angle vectors - 3d-вектор, величина которого представляет собой число радианов для поворота вокруг оси, определенной вектором. Это упрощает имитацию вращения. Независимо от того, хранятся ли ваши совместные вращения в виде углов или матриц эйлеров или кватернионов, вы, вероятно, будете иметь некоторые классы, не поддерживающие UE API, чтобы помочь извлечь векторы оси/угла.

При изменении главного сустава преобразуйте его поворот на ось. Позволяет называть это phi_m.

На стартовой раме поворот ведомого phi должен быть установлен на то же значение, что и главный. phi = phi_m. Он не имеет угловой скорости, поэтому omega установлен на нулевой вектор (0,0,0).

Затем вы двигаетесь вперед на один кадр. Длина рамки dt составляет, может быть, 1/60 секунды или что-то еще.

При моделировании вы сначала разрабатываете новое значение для phi_m. Тогда разница между ведущим и ведомым (вектор phi_m - phi) представляет собой крутящий момент, действующий на подчиненный шарнир. The bigger the angle the stronger the torque. Предположим, что масса равна 1,0, тогда как F = ma, угловое ускорение alpha равно крутящему моменту. Это означает, что изменение угловой скорости для подчиненного соединения над этой рамой составляет alpha*dt. Теперь мы можем разработать новую угловую скорость: omega = omega + (alpha*dt). Аналогичным образом, новое вращение - это старое вращение плюс изменение во времени (угловая скорость). phi = phi + (omega * dt)

Собираем все вместе и добавить в коэффициента для весны strength и damping, шаг моделирования может пойти что-то вроде этого:

damping = 0.01 // between 0 and 1 
strength = 0.2 // ..experiment 
dt = currentTime-lastTimeEvaluated 

phi_m = eulerToAxisAngle(master.rotate) 
if (currentTime <= startTime || dt < 0) { 
    slave.phi = phi_m 
    slave.omega = (0,0,0) 
} else { 
    alpha = (phi_m - slave.phi)*strength 
    slave.omega = (slave.omega * (1.0 - damping)) + (alpha*dt) 
    slave.phi = slave.phi + slave.omega*dt 
} 
slave.rotate = axisAngleToEuler(slave.phi) 
lastTimeEvaluated = currentTime 

Обратите внимание, что затухание просто убивает немного сохраненной скорости. Если демпфирование очень низкое, сустав будет превышать и колебаться на месте - бои !!

 Смежные вопросы

  • Нет связанных вопросов^_^