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

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

Страницы: 1 2 3 4 5 6 7 Следующая »
}:+()___ [Smile]Постоялецwww28 авг. 201617:49#60
Alerr
> Как такое с кватернионами возможно?
Из произвольного вращения невозможно, в принципе, однозначно выделить "вращение по оси Y".
При желании, можно найти что-то типа вращения по оси Y, наиболее близкого исходному, но, скорее всего, получится совсем не то, что ты надеешься получить.

> Ещё вот вопрос, как можно ускорить поиск среди вращений для прицепке к нужнгму углу?
Можно, но тебе не стоит этим заниматься.

AlerrПостоялецwww28 авг. 201618:11#61
>Можно, но тебе не стоит этим заниматься
Да мне много чем не стоило заниматься, вы скажите с чего начать. У меня есть предположение, что какую-то структуру данных нужно организовать + которая учитывает знаки.
}:+()___ [Smile]Постоялецwww28 авг. 201618:44#62
Alerr
Можно оставить 11 вариантов с положительными компонентами и сравнивать с модулями, а знаки потом скопировать из исходного кватерниона.
Еще сам список надо сделать линейным в памяти (в C# это, вроде, struct вместо class).

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

AlerrПостоялецwww28 авг. 201618:57#63
Нет, их будет несколько... Игроков хочу сделат несколько и у каждого будет такой куб (неважно, это будут npc игроки). Сейчас надеюсь успею добить выравнивание грани относительно игрока...
AlerrПостоялецwww28 авг. 201620:38#64
}:+()___ [Smile], все же вопрос остался:
>В смысле? Чтобы залипало в пространстве игрока, а не глобальном?
>Почитай про переводы систем координат друг в друга.

Я имею представление насчет переводов систем, но вот как быть с кватернионом - не понимаю.  Тут нужно по OY только переносить фиксацию в систему куба из системы игрока, а по остальным трогать не нужно. Вот, а вытащить вращение по OY не предоставляется возможным.
Пробовал вот так:

myTransform.rotation - вращение игрока
cubeRigid.rotation = Quaternion.Slerp(cubeRigid.rotation, tmp*Quaternion.AngleAxis(delta,ax)*myTransform.rotation, 5f*Time.fixedDeltaTime);

Как результат - не работает (вернее работает криво, что-то похожее не правду, но нет):
https://yadi.sk/i/lImbybI-uYjrd

AlerrПостоялецwww28 авг. 201622:29#65
Вообщем-то устранил мелкие проблемы, которые смог устранить.
Так и не смог придумать как прицепить куб по OY к локальному пространству игрока. Если я не могу изьять rotation игрока по OY, то я не понимаю как дальше быть. Нет у меня шалона на такие задачи, ну не сталкивался еще(
}:+()___ [Smile]Постоялецwww29 авг. 20161:27#66
Alerr
> Так и не смог придумать как прицепить куб по OY к локальному пространству игрока.
Для начала используй ориентацию игрока целиком, без выделения.

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

AlerrПостоялецwww29 авг. 20163:19#67
Да, угол и вращение персонажа по OY имеется.
Но это конечное вращение, не приращение.
Попробовал найти приращение, но пока не получилось сделать. Искал исходя из того что все углы куба кратны 90, а приращение находитсяшде-то между (0,90). В итоге на 45-и градусах куб перекручивает по OY.
Я думаю, что это связано с тем, что он пытается примкнуть к сетке из 90 градусов. Выходит надо менять непосредственно массив, который используется для поиска ближайшего вектора, который кратен 90?
}:+()___ [Smile]Постоялецwww29 авг. 20163:30#68
Alerr
> Но это конечное вращение, не приращение.
Тебе нужно именно оно.

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

AlerrПостоялецwww29 авг. 20164:16#69
Куб у меня относительно мира выравнивается.
Кватернионы задают его привязку относительно мира.
Вращение персонажа тоже вроде как на мировых координатах завязано.

Посмотрел насчет переходов между системами... Данные не собираются воедино) Вообщем что вижу, нужно как-то куб перенести в систему координат персонажа, вернее вращения куба. Пусть куб это система s2, персонаж - s1. Рассмотрим персонаж как мировую систему. Чтобы куб перешел в систему персонажа необходимо все его вращения "довращать".
Ну если бы это были углы эйлера и  персонаж повернут на 10 градусов, а куб всегда на 90, то нам нужно было бы (для того чтобы персонаж сделать родительским обьектом), сложить эти 2 угла. Теперь в системе родитея куб всегда выдержит 90 градусов.

Тут я понимаю такая же ситуация. Так как операция произведения позволяет визуально складывать углы, то для переноса куба в систему перснонажа, кубу необходимо назначить угол: ВращениеПерсонажа*ВращениеКуба.

Вот такие мысли. Про системы координат почитать можно тут: http://www.znannya.org/?view=system_koord_na_ploskosti  Насчет переходов между системами кватернионов не смог найти...
Но все же где-то я ошибаюсь. Возможно вектора к которым цепляется куб тоже нужно перенести в новую систему?
Верно мыслю? Где ошибка в рассуждениях?

AlerrПостоялецwww29 авг. 20164:30#70
Да, думал я правильно (Правда у меня идея была более изощренносложная, до того как Вы сказали, что нужно конечное вращение персонажа использовать.):
int NearestRot(Quaternion cubeRot){
    int maxIndex = 0;
    float maxDot = Quaternion.Dot(cubeRot, player.GetRightLeftRotationAngle() *rot[0]);
    for (int i = 1; i < rot.Length; ++i) {
      float dot = Quaternion.Dot(cubeRot, player.GetRightLeftRotationAngle() *rot[i]);//Mathf.Abs();
      if (dot > maxDot) {
        maxDot = dot;
        maxIndex = i;
      }
    }
    return maxIndex;
  }

Вот тут не домножал. Либо наоборот, домножал тут, а в NearestRot пропускал...

rigidBody.rotation = Quaternion.Slerp(rigidBody.rotation, 
        player.GetRightLeftRotationAngle() * newRotation*Quaternion.AngleAxis(delta,playerRotationAxis),
        5f*Time.fixedDeltaTime);

Верно? Но тут какой-то ужас... У меня компьютер зависает от таких операций... Перебор 48 векторков подсаживает производительность, а эти умножения вообще все остановили. Умножения я произвожу в Update. У Вас та же идея? Может можно без домножения массива rot?

}:+()___ [Smile]Постоялецwww29 авг. 201613:33#71
Alerr
> Может можно без домножения массива rot?
Можно. Перевести в локальную систему координат, заснэпить к константному массиву поворотов, вернуть в глобальную СК.
AlerrПостоялецwww29 авг. 201614:25#72
>Можно. Перевести в локальную систему координат
Не понимаю как с кватернионами это реализовать и поэтому картина того как это работает не складывается. Как с имеющейся операцией умножения перевести кватернион в ловакльную СК игрока?
1) Домножаем в NearestRot player.GetRightLeftRotationAngle() на cubeRot. Получаем поворот в СК игрока.
2) Тут же, далее идет привязка к сетке.
3) Вот тут кажется ошибка, неверно возвращаю назад
Quaternion NearestRot(Quaternion cubeRot){
    int maxIndex = 0;
    // (1) To playerSpace:
    Quaternion playerSpaceRotation = cubeRot * player.GetRightLeftRotationAngle ();
    // (2)
    float maxDot = Quaternion.Dot(playerSpaceRotation, rot[0]);
    for (int i = 1; i < rot.Length; ++i) {
      float dot = Quaternion.Dot(playerSpaceRotation, rot[i]);//Mathf.Abs();
      if (dot > maxDot) {
        maxDot = dot;
        maxIndex = i;
      }
    }

    // (3) Back, to WorldSpace
    Quaternion toWorldSpaceRotation = player.GetRightLeftRotationAngle ();
    toWorldSpaceRotation.w *= -1f;

    return rot[maxIndex] * toWorldSpaceRotation;
  }
Куб, в результате, цепляется к мировой сетке. Неверно возвращаю в мировую систему (toWorldSpaceRotation.w *= -1f;)?
}:+()___ [Smile]Постоялецwww29 авг. 201615:16#73
Alerr
> Как с имеющейся операцией умножения перевести кватернион в ловакльную СК игрока?
Почитать про комбинации поворотов и нахождение обратного на кватернионах.

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

Еще может быть неправильный порядок умножения — он свой для каждого конкретного движка, поэтому попробуй оба варианта.

AlerrПостоялецwww29 авг. 201615:16#74
Как оказалось, код что выше не работает, привяка к сетке ломается.
Страницы: 1 2 3 4 5 6 7 Следующая »

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

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