В настоящее время я пытаюсь создать инверсную кинематику для компонентов соединений. Компонент соединения имеет четыре настраиваемых значения, которые используются для ограничения поворотов соединения:
- Предел Low-X
- Предел High-X
- Y-limit
- Z-limit
Y- и Z-limit оба ограничивают вращение на его отрицательной и положительной стороне одновременно.
Я разложил вращение, которое я хочу ограничить по пределам, на два поворота, так что вращение = свинг * скрутить, используя решение из другого вопроса здесь:
Компонент кватернионавращение вокруг оси
/**
* Splits up a rotation into two other rotations(swing and twist), so that rotation = swing * twist
* The original rotation has 3 Degrees of freedom, swing has 2 dof and twist has 1 dof
*
* @see /3802118/komponent-kvaternionnogo-vrascheniya-vokrug-osi
* @see https://euclideanspace.com/maths/geometry/rotations/for/decomposition/
*
* @param rotation The rotation which moves direction onto the new direction vector
* @param direction The direction vector which would get moved by rotation into it's new position.
* rotation * direction == swing * twist * direction
* @param swing Pointer to the Quaternion which will become the swing rotation
* @param twist Pointer to the Quaternion which will become the twist rotation
*/
private void SwingTwistDecomposition(Quaternion rotation, Vector3 direction, out Quaternion swing, out Quaternion twist) {
Vector3 rotationAxis = new Vector3(rotation.x, rotation.y, rotation.z);
Vector3 twistAxis = Vector3.Project(rotationAxis, direction);
twist = new Quaternion(twistAxis.x, twistAxis.y, twistAxis.z, rotation.w);
twist = twist.normalized;
swing = rotation * Quaternion.Inverse(twist);
}
Затем я попытался:
- Ограничить вращение качания нижним пределом х, верхним пределом х и-limit
- Ограничить вращение кручения z-пределом
Был еще один ответ на вопрос, который дал мне решение ограничить вращение кручения (2 балла). :
Ограничение шага, рыскания и крена
ConstrainQuat(Quaternion quat, float angle)
const double maxMagnitude = sin( 0.5 * toRad(angle) );
const double maxMagnitudeW = sqrt(1.0 - maxMagnitude*maxMagnitude );
if(quat.vec().normSqr() > maxMagnitude*maxMagnitude)
{
quat.vec() = quat.vec().normalized() * maxMagnitude;
quat.w() = maxMagnitudeW;
}
}
Однако я не понимаю, как ограничить поворот качания "low-x-limit","high-x-limit" и "y-limit".
Спасибо за любую помощь заранее!