Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Сложный поворот тела с помошью кватернионов (3 стр)

Сложный поворот тела с помошью кватернионов (3 стр)

Страницы: 1 2 3 4 5 6 7 Следующая »
AlerrПостоялецwww27 авг. 20162:24#30
Не выдержал и решил прямо сейчас посмотреть как это работает на компе.
Еще глупый вопрос, CubeQuat - это массив чего?
Quaternion[] rotations = new Quaternion[] {
    Quaternion.AngleAxis(-90, Vector3.up),
    Quaternion.AngleAxis(90, Vector3.up),
    Quaternion.AngleAxis(-90, Vector3.right),
    Quaternion.AngleAxis(90, Vector3.right),
    Quaternion.AngleAxis(-90, Vector3.forward),
    Quaternion.AngleAxis(90, Vector3.forward);
Это он?
По поведению куба похоже что нет... Цепляется к какому-то одному вращению, углы эйлера которого кратны 90 градусам.

Сделал от так, не работает (не привязывается к сетке из 90 градусов):

float Dot(Quaternion q1, Quaternion q2) {
    return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
  }

  int NearestQuaternion(Quaternion CurrentQuat, Quaternion []CubeQuat){
    float maxD = -10000.0f; //NEG INF
    int maxIndex = -1;
    for (int i = 0; i < 6; i++) {
      float D = Mathf.Abs(Dot(CurrentQuat, CubeQuat[i]));
      if (D > maxD){
        maxIndex = i;
        maxD = D;
      }
    }
    return maxIndex;
  }

void FixedUpdate() {
  cubeRigid.rotation = Quaternion.Slerp(cubeRigid.rotation, rotations[NearestQuaternion(cubeRigid.rotation,rotations)], 10f*Time.fixedDeltaTime);
}

   

MrShoorУчастникwww27 авг. 20163:52#31
Alerr
> Еще глупый вопрос, CubeQuat - это массив чего?
Это массив кватернионов, которые поворачивают куб одной из сторон к пользователю.
p.s. На самом деле тебе скорее всего нужно будет 24 комбинации. По 4 на каждую сторону:

Это кватернионы на все стороны (6 штук)
    Quaternion.AngleAxis(0, Vector3.up),
    Quaternion.AngleAxis(90, Vector3.up),
    Quaternion.AngleAxis(-90, Vector3.up),
    Quaternion.AngleAxis(-90, Vector3.right),
    Quaternion.AngleAxis(90, Vector3.right),
    Quaternion.AngleAxis(180, Vector3.right),

и каждый из этих вариантов надо умножить на один из вот этих 4:
    Quaternion.AngleAxis(0, Vector3.forward),
    Quaternion.AngleAxis(90, Vector3.forward),
    Quaternion.AngleAxis(180, Vector3.forward),
    Quaternion.AngleAxis(270, Vector3.forward),

ну и должно получится 24 квартерниона.

}:+()___ [Smile]Постоялецwww27 авг. 20168:04#32
MrShoor
> должно получится 24 квартерниона.
Вот полный набор:
+ Показать

Кстати, при желании, выбор ближайшего можно оптимизировать, ибо кардинально разных вариантов всего 3.
По крайней мере, можно сразу выкинуть знаки.
AlerrПостоялецwww27 авг. 201612:38#33
Попробовал, не работает, толкаю другим предметом и куб отходит от сетки.
+ Показать
MrShoorУчастникwww27 авг. 201616:14#34
Alerr
> Попробовал, не работает, толкаю другим предметом и куб отходит от сетки.
Видимо не судьба... но можно попробовать себя в чем то другом. Либо изменить свой взгляд на это, ведь ходячий куб на кватернионе не каждый может сделать.
AlerrПостоялецwww27 авг. 201617:00#35
MrShoor, не судьба для слабовольных, я буду дальше пытаться получить результат. Лучше бы сказали где у меня промах в коде, если видите ошибку.
MrShoorУчастникwww27 авг. 201618:40#36
float maxDot = 100000.0f;
AlerrПостоялецwww27 авг. 201619:44#37
Да, извиняюсь, исправил. Но это не помогло. Что происходит при запуске симуляции:
1) Сперва куб выворачивает на угол кратный 90 градусам, но не тот который был при старте (грани разного цвета и это видно).
2) Начинаю пытаться "перекрутить" куб, чтобы он перешел на следующий угол крантый 90. В каких-то случаях он перекручивается, но не возвращается. В каких-то упирается и не хочет крутиться.

Код вы видел какой, float maxDot = 100000.0f; - исправил.
Пробовал Slerp заменять на Lerp:

cubeRigid.rotation = Quaternion.Lerp(cubeRigid.rotation, rot[NearestRot(cubeRigid.rotation)], 5f*Time.fixedDeltaTime);

Если метод NearestRot  верно работает, то в чем может быть проблема? rot - перепроверял несколько раз по тому что }:+()___ [Smile] прислал. Попробую сам перебрать все варианты и посмотреть, может в набое }:+()___ [Smile] закралась ошибка.

}:+()___ [Smile]Постоялецwww27 авг. 201621:21#38
Alerr
> Попробовал, не работает, толкаю другим предметом и куб отходит от сетки.
Очевидно, что включенный физдвижок противоречит заявленной цели.
Если ты хочешь сделать привязку с рабочим физдвижком, то вместо насильного поворота надо добавить вращающий момент сил.
Но лучше просто отключи объект от симуляции.

> Сперва куб выворачивает на угол кратный 90 градусам, но не тот который был при старте (грани разного цвета и это видно).
Кватернионы двузначны — т. е. одному повороту соответствуют два кватерниона, однако Slerp/Lerp устроят разворот на 360° в случае если вариант выбран не правильно.
Можешь убрать Mathf.Abs из NearestRot и добавить еще 24 кватерниона в список: надо взять те, что уже есть и поменять знак у всех компонент.
А еще лучше, вообще, убрать знаки из списка.

> Начинаю пытаться "перекрутить" куб, чтобы он перешел на следующий угол крантый 90. В каких-то случаях он перекручивается, но не возвращается. В каких-то упирается и не хочет крутиться.
Ты же не отключаешь возврат на время поворота, вот он и упирается твоему вращению.

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

AlerrПостоялецwww27 авг. 201623:02#39
Вот видео того, что пытаюсь сделать. Это сделано чрез большие костыли и не работает:
https://yadi.sk/i/Lp47twAPuRm7t
https://yadi.sk/i/16Fx4RNTuRmGy

Еще раз, как это должно работать. Играли в игру Portal? Видел там куб?
с 0:20-й секунды.

+ Показать

Как сейчас ведет себя куб:
https://yadi.sk/i/OOj90RdQuXux8
Как видите, к углам кратным 90 градусам куб не лерпится, хотя я в FixedUpdate постоянно вызываю присвоение нового вращения.

Смотрите, вот если бы углы эйлера работали, то я бы брал и по нужным осям лерпил к нужному углу кратному 90. Все время бы лерпил и работало бы оно, привязывался бы куб к углам кратным 90. Подобное с кватернионами возможно? Я так понимаю, что делаю подобную операцию, а она не работает.

}:+()___ [Smile]Постоялецwww28 авг. 20161:02#40
Alerr
> Еще раз, как это должно работать. Играли в игру Portal? Видел там куб?
> с 0:20-й секунды.
Там никакого снаппинга нету, в принципе.
Только дампинг вращений.

> Как видите, к углам кратным 90 градусам куб не лерпится, хотя я в FixedUpdate постоянно вызываю присвоение нового вращения.
Судя по всему, у тебя скорость слишком мелкая. Оставь в кривом положении и подожди подольше, в видео ты постоянно дергаешь кубик, ничего не понятно.
Еще проблема в том, что ты делаешь это в обход физдвижка.

AlerrПостоялецwww28 авг. 20161:42#41
Да, куб оооочень медленно поворачивается. Вы правы. Я коэффициент в лерп огромный поставил, все равно очень медленно. Насчёт обхода физ. движка не понимаю чем крутящий момент поможет. Поможет вернуть к углам кратным 90? Почему кватернионы еле крутят куб?  Иногда они действуют на куб с одной визуальной скоростью, иногда с в непонятно скольо раз меньшей.
}:+()___ [Smile]Постоялецwww28 авг. 20162:48#42
Alerr
> Иногда они действуют на куб с одной визуальной скоростью, иногда с в непонятно скольо раз меньшей.
Ты заменил список из 24 вариантов на 48?
AlerrПостоялецwww28 авг. 20168:34#43
Да, вот код:
+ Показать

А тут видео того как это работает:
https://yadi.sk/i/SshfbKIMuY5e8
Работает почти так же плохо, вращается чутка быстрее чем в варианте вектора из 24 компоненты, но все равно очень медленно.
Еще куб не цепляется к углам кратным 90.
AlerrПостоялецwww28 авг. 201611:00#44
Если все верно, я так понимаю, Quaternion.Lerp выдает слишком маленькое смещение. Сейчас посмотрю как он устроен.
Страницы: 1 2 3 4 5 6 7 Следующая »

/ Форум / Программирование игр / Физика

2001—2018 © GameDev.ru — Разработка игр