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

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

Страницы: 1 2 3 4 5 6 7 Следующая »
AlerrПостоялецwww25 авг. 201615:23#15
bykabak, если угол тела был изменен извне(другой персонаж толкнул куб), то поможет ли завершение начатого вращения?
bykabakПостоялецwww25 авг. 201615:36#16
Тогда у вам нужна система вращения постоянно хранящая поворот куба вокруг всех осей и доворачивать куб нужно только в определённых условиях а не постоянно, но при довороте блокировать возможность вращения извне.
AlerrПостоялецwww25 авг. 201616:16#17
Теперь Вы меня поняли, хотя я кидал ссылки на видео и по ним, по моему, понятно как игрок берет куб, как он его крутит.
Вот это совсем не подойдет:
> только в определённых условиях а не постоянно, но при довороте блокировать возможность вращения извне.
Этот куб лежит на полу как попало, его углы могут быть любыми. Игрок берет куб и он должен пытаться выровняться в соответствии с тем какая ось сейчас используется как ось вращения и какие 2-е не используются. К тому же этот куб может подвергаться попыткам изменения угла извне, не зря ему Rigidbody прицепил.

> нужна система вращения постоянно хранящая поворот куба вокруг всех осей
Я что пытаюсь сделать: берем куб и получаем его rotation (конечное вращение) относительно каждой из его осей:

Quaternion qq = rigidBody.rotation;
      Quaternion qq1 = qq;

      if (axisIndex==0) {
        localAxis = rigidTransform.InverseTransformPoint (Vector3.up + rigidTransform.position);

        // получаем 0Y rotation:
        qq1.x = 0f;
        qq1.z = 0f;
        float magnitude = Mathf.Sqrt(qq1.w*qq1.w + qq1.y*qq1.y);
        if (magnitude != 0f) {
          qq1.w /= magnitude;// invert rotation
          qq1.y /= magnitude;
        } else {
          qq1.y = 0f;
          qq1.w = 1f;
        }
И так для каждой оси.

В итоге у меня есть все такие конечные вращения относительно каждой из осей. И это очень хорошо, теперь известно составляющие вращения, значит можно судить на сколько они отклонены от 90градусной сетки.
В случае, если свободна ось OY, то мне нужны отклонения по OX и OZ. Чтобы:
1) не трогать вращение по OY
2) параллельно докручивать по OX и OZ. Тут выходит, что хоть извне его будут толкнать, он постоянно смотрит на свое вращение относительно OX и OZ и пытается выровняться по ним.

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

AlerrПостоялецwww25 авг. 201618:01#18
Времени больше нет возиться с этим эффектом, убил несколько дней, понял что такое кватернионы, но на деле не могу реализовать все качественно. Постоянно где-то передергивает( Ребят, кто асс и может помочь кодом, помогите, в долгу не останусь :)
На видео видно как это должно работать, только без передергов.
romgermanПостоялецwww25 авг. 201620:54#19
Посмотрел первое видео — ты будто не завершаешь предыдущее вращение и начинаешь следующее.
LaynosПостоялецwww26 авг. 201615:30#20
Alerr
Возьми GLM, там за тебя уже всё сделали.
Попользуйся, посмотри работает ли. Потом если захочешь свою реализацию сделать - посмотри в исходный код
ancooperПостоялецwww26 авг. 201621:08#21
Alerr
Могу предложить свой вариант.

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

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

Вращаешь куб нижней гранью вниз и фронтальной к себе на небольшие углы.

AlerrПостоялецwww26 авг. 201621:20#22
ancooper, спасибо. Думал о таком, важно вращать тело за rigidBody. Я так понимаю, оно не сразу переназначится т.к. rigidBody завязан на физику.
Мне не понятно почему куб не цепляется к сетке из 90 градусов. Вернее цепляется, но потом слетает.
Вот простая задача привязки к сетке из 90 грд. и я не могу понять как ее решить: игрок держит куб, затем силы извне случайным образом вращают куб. После того как внешние силы закончили вращение куб должен пробовать прицепиться к сетке из 90 градусов. Я попробовал реализовать и ничего хорошего. Если тут проблемы, то далее мне нет смысла искать ось по которой куб будет свободно крутиться.
}:+()___ [Smile]Постоялецwww26 авг. 201623:39#23
Alerr
> После того как внешние силы закончили вращение куб должен пробовать прицепиться к сетке из 90 градусов. Я попробовал реализовать и ничего хорошего.
Таких выровненных позиций конечное число.
Забей их все в массив и находи ближайшую (путем скалярного произведения кватернионов).
Только тут надо иметь ввиду, что кватернионы двузначны.
AlerrПостоялецwww27 авг. 20160:15#24
Где тут смайлик смех сквозь слезы?)
Я думаю, что не понимаю вас. Да, позиций конечное число. Я пытался цеплять кватернион к ним, но он гад какой-то не человеческий: нецепляется; Выделить вращение по одной из осей вроде вышло, но как крутнешь куб как попало, то вся работа коту под хвост. Как работает отображение кватернионов на углы? Нет, не одной из этих формул (https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles) преобразования в эйлера, а как это в голове должно представляться?
}:+()___ [Smile]Постоялецwww27 авг. 20161:12#25
Alerr
> Я пытался цеплять кватернион к ним, но он гад какой-то не человеческий: нецепляется;
Что ты подразумеваешь под словом "цеплять"?
Я предлагаю приравнивать ближайшему подходящему положению.

> Как работает отображение кватернионов на углы?
Никак. При работе с произвольными вращениями такой вопрос, в принципе, не должен возникать.
Если он возник, значит ты кватернионы используешь неправильно или не там, где надо.

AlerrПостоялецwww27 авг. 20161:42#26
Под "цеплять" я тоже понимаю приравнивание к ближайшему подходящему положению. Как приравнивал: повороты на 90 градусов соответствуют значениям из таблицы которая есть тут: http://www.ogre3d.org/tikiwiki/Quaternion+and+Rotation+Primer.  Я брал каждую составляющую кватерниона и делал так q.i=Round(q.i/sqrt(0.5))*sqrt(0.5);  это должно делать углы вращения кратными 90 градусам?

Насчёт отображения не понял вас. Как никак? То есть нет связи никакой?

MrShoorУчастникwww27 авг. 20161:55#27
Alerr
> Я брал каждую составляющую кватерниона и делал так
> q.i=Round(q.i/sqrt(0.5))*sqrt(0.5);
А надо было делать так:
float Dot(quat q1, quat q2) {
  return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
}

int NearestQuaternion(quat CurrentQuat, quat CubeQuat[6]){
  float maxD = -10000.0; //NEG INF
  int maxIndex = -1;
  for (int i = 0; i < 6; i++) {
    float D = abs(Dot(CurrentQuat, CubeQuat[i]));
    if (D > maxD){
      maxIndex = i;
      maxD = D;
    }
  }
  return maxIndex;
}
AlerrПостоялецwww27 авг. 20162:09#28
MrShoor, пояснит пожалуйста смысл скалярного пооизведения? Как оно даёт ближайшее вращение?
MrShoorУчастникwww27 авг. 20162:23#29
Alerr
> MrShoor, пояснит пожалуйста смысл скалярного пооизведения? Как оно даёт
> ближайшее вращение?
Найдет ближайший кватернион.
Извиняюсь, в спешке набирал, конечно же нужно максимальное скалярное произведение брать. Поправил код выше на max.
Страницы: 1 2 3 4 5 6 7 Следующая »

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

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