Кватернионная коррекция - PullRequest
0 голосов
/ 11 мая 2018

Я пытаюсь реализовать коррекцию сети для имитируемого клиентом Rigidbody.30 раз в секунду я получаю целевое вращение, из которого вычисляю поправку вращения.Затем я применяю это исправление для нескольких кадров.

Обновление сети:

rotationCorrection = receivedRotation * Quaternion.Inverse(transform.rotation);

Каждый кадр:

var a = Mathf.Min(1, Time.deltaTime * 8);

var final = Quaternion.Slerp(transform.rotation, transform.rotation * rotationCorrection, a);
var actualCorrection = final * Quaternion.Inverse(transform.rotation);
rotationCorrection *= Quaternion.Inverse(actualCorrection);
//rotationCorrection = Quaternion.Slerp(rotationCorrection, Quaternion.identity, a); // First try

_rigidbody.MoveRotation(final);

Причина, по которой я не просто интерполируютекущее вращение с исправленным значением - это GameObject, содержащий Rigidbody, который должен имитировать объект в дополнение к коррекции.

Иногда это работает (по крайней мере, в первой версии), за исключением углов между приблизительно -90 и90. Я подозреваю, что это код для поворота Коррекция на идентичность.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Неправильное обновление сети.Исправлено:

rotationCorrection = Quaternion.Inverse(transform.rotation) * receivedRotation;
0 голосов
/ 11 мая 2018

(работа в процессе, так как вопрос не был ясен на 100%)

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

Вы уверены, что вам не нужен Lerp вместо Slerp?

В любом случае, финал не должен использовать Lerp или Slerp.

Если в качестве final вы хотите transform.rotation * rotationCorrection (который является текущим поворотом плюс коррекция), то просто используйте его как таковой. Умножения фактически добавляют вращение.

Lerp и Slerp должны использоваться с a, параметрическим по времени, где a == 0 вернет начальный поворот, a == 1 вернет окончательный поворот. Так что a следует масштабировать со временем. Если, с другой стороны, сетевое исправление - это именно то, что вам нужно, и вы получаете его при определенных обновлениях с фиксированным временем, тогда без какого-либо Lerp, вы можете попробовать transform.rotation = transform.rotation*rotationCorrection.

rotationCorrection = receivedRotation * Quaternion.Inverse(transform.rotation);

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

так:

Вы устанавливаете окончательный кватернион как currentRot * change

a, начиная с currentRot

, а затем обновите transform.rotation, сделав его = (S) Lerp с начала, конца и параметром, равным 0 в начальный момент времени и 1 в конечный момент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...