История:
В настоящее время я использую шейдер скелетной анимации в GLSL, и для экономии места и сложности я использую Quaternions для вращения костей с использованием взвешенного умножения кватернионов (каждой кости) для накопления "окончательного вращения" для каждой вершины.
Что-то вроде: (псевдокод, просто предположим, что математика кватернионов работает как ожидалось)
float weights[5];
int bones[5];
vec4 position;
uniform quaternion allBoneRotations[100];
uniform vec3 allBonePositions[100];
main(){
quaternion finalQuaternion;
for(i=0;i<5;i++){finalQuaternion *= allBoneRotations[bones[i]]*weights[i];}
gl_position = position.rotateByQuaternion(finalQuaternion);
}
Реальный код сложный, неаккуратный и работающий, как ожидалось, но это должно дать общую идею, так как это в основном математический вопрос, код не имеет большого значения, он просто предоставляется для ясности.
Проблема:
Я был в процессе добавления "опорных точек" / "совлокальных мест" к каждой кости (отрицательный перевод, поворот на "окончательный кватернион", перевод), когда я понял, что "окончательный кватернион" не будет принимать при совпадении самих кватернионов учитываются разные точки поворота. В этом случае каждое вращение кости будет обработано так, как если бы оно было вокруг точки (0,0,0).
Учитывая, что кватернионы представляют только поворот, кажется, мне нужно либо "добавить" позицию к кватернионам (если это возможно), либо просто преобразовать все кватернионы в матрицы, а затем умножить матрицу на объединение ряда переводов и поворотов. Я действительно надеюсь, что последнее не понадобится, поскольку кажется, что это будет действительно неэффективно, сравнительно.
Я искал mathoverflow, math.stackexchange и все, что еще предоставлял Google, и читал следующие ресурсы до сих пор в надежде выяснить сам ответ:
-
плюс различные другие небольшие обсуждения, найденные через Googling (я могу опубликовать только 2 ссылки)
Консенсус в том, что Quaternions не кодируют "перевод" или "позицию" в каком-либо смысле и, похоже, не обеспечивают интуитивно понятный способ имитации, поэтому чистая математика кватернионов вряд ли будет жизнеспособным решением.
Однако было бы неплохо получить окончательный ответ на этот вопрос. Кто-нибудь знает какой-либо способ "подделать" компонент позиции кватерниона, который каким-то образом сохранит математическую эффективность кватерниона или какой-либо другой метод "накапливать" вращения вокруг разных точек происхождения, что более эффективно, чем просто вычисление матрицы кватернионов и выполнения матричного перевода и умножения вращения для каждого кватерниона? Или, может быть, какая-то математическая уверенность в том, что разные точки поворота на самом деле не имеют никакого значения и могут быть применены позже (но я сомневаюсь).
Или использует кватернионы в этой ситуации только плохую идею на первый взгляд?