From 327bb00c7e163705a2f05ce1dcba67930c01a1bd Mon Sep 17 00:00:00 2001 From: Angeldark Raymaker Date: Thu, 12 Sep 2024 11:57:13 +0100 Subject: [PATCH] FIRE-30873: first pass at swapping axes for the UI control --- indra/newview/fsfloaterposer.cpp | 8 --- indra/newview/fsposeranimator.cpp | 61 ++++++++++++++++++- indra/newview/fsposeranimator.h | 42 ++++++++++++- indra/newview/fsvirtualtrackpad.h | 1 - .../skins/default/xui/en/floater_poser.xml | 12 ++-- 5 files changed, 104 insertions(+), 20 deletions(-) diff --git a/indra/newview/fsfloaterposer.cpp b/indra/newview/fsfloaterposer.cpp index fd068a9816..adb22b6b7b 100644 --- a/indra/newview/fsfloaterposer.cpp +++ b/indra/newview/fsfloaterposer.cpp @@ -908,14 +908,6 @@ void FSFloaterPoser::onAvatarPositionSet() setSelectedJointsPosition(posX, posY, posZ); } -/// -/// The trackball controller is not friendly to photographers (or normal people). -/// This method could be streamlined but at the high cost of picking apart what it does. -/// The simplest thing to do would be to reimplement the code behind the slider! -/// TLDR: we just want the trackball to behave like a 2-axis slider. -/// -/// BEWARE! Changes to behaviour here require their inverse to be applied on the slider-callback. -/// void FSFloaterPoser::onLimbTrackballChanged() { FSVirtualTrackpad *trackBall = getChild(POSER_AVATAR_TRACKBALL_NAME); diff --git a/indra/newview/fsposeranimator.cpp b/indra/newview/fsposeranimator.cpp index af05a25005..c839f87668 100644 --- a/indra/newview/fsposeranimator.cpp +++ b/indra/newview/fsposeranimator.cpp @@ -99,7 +99,34 @@ LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar *avatar, FSPoserJoint joi return vec3; LLQuaternion rot = avJoint->getRotation(); - rot.getEulerAngles(&vec3.mV[VX], &vec3.mV[VZ], &vec3.mV[VY]); + + return translateRotationFromQuaternion(joint.boneTranslation(), rot); +} + +// from the bone to the UI; this is the 'forwards' use of the enum +LLVector3 FSPoserAnimator::translateRotationFromQuaternion(E_BoneAxisTranslation translation, LLQuaternion rotation) +{ + LLVector3 vec3; + + switch (translation) + { + case SWAP_YAW_AND_ROLL: + rotation.getEulerAngles(&vec3.mV[VY], &vec3.mV[VZ], &vec3.mV[VX]); + break; + + case SWAP_YAW_AND_PITCH: + rotation.getEulerAngles(&vec3.mV[VZ], &vec3.mV[VX], &vec3.mV[VY]); + break; + + case SWAP_ROLL_AND_PITCH: + rotation.getEulerAngles(&vec3.mV[VX], &vec3.mV[VY], &vec3.mV[VZ]); + break; + + case SWAP_NOTHING: + default: + rotation.getEulerAngles(&vec3.mV[VX], &vec3.mV[VZ], &vec3.mV[VY]); + break; + } return vec3; } @@ -115,10 +142,38 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar *avatar, const FSPoserJoint *j if (!avJoint) return; - LLMatrix3 rot_mat = LLMatrix3(rotation.mV[VX], rotation.mV[VY], rotation.mV[VZ]); + LLQuaternion rot_quat = translateRotationToQuaternion(joint->boneTranslation(), rotation); + avJoint->setRotation(rot_quat); +} + +// from the UI to the bone, the inverse translation, the un-swap, the backwards +LLQuaternion FSPoserAnimator::translateRotationToQuaternion(E_BoneAxisTranslation translation, LLVector3 rotation) +{ + LLMatrix3 rot_mat; + switch (translation) + { + case SWAP_YAW_AND_ROLL: + rot_mat = LLMatrix3(rotation.mV[VZ], rotation.mV[VY], -1 * rotation.mV[VX]); + break; + + case SWAP_YAW_AND_PITCH: + rot_mat = LLMatrix3(rotation.mV[VY], rotation.mV[VX], rotation.mV[VZ]); + break; + + case SWAP_ROLL_AND_PITCH: + rot_mat = LLMatrix3(rotation.mV[VX], rotation.mV[VZ], rotation.mV[VY]); + break; + + case SWAP_NOTHING: + default: + rot_mat = LLMatrix3(rotation.mV[VX], rotation.mV[VY], rotation.mV[VZ]); + break; + } + LLQuaternion rot_quat; rot_quat = LLQuaternion(rot_mat) * rot_quat; - avJoint->setRotation(rot_quat); + + return rot_quat; } LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar *avatar, FSPoserJoint joint) diff --git a/indra/newview/fsposeranimator.h b/indra/newview/fsposeranimator.h index 51114568e1..f964c14665 100644 --- a/indra/newview/fsposeranimator.h +++ b/indra/newview/fsposeranimator.h @@ -58,6 +58,20 @@ typedef enum E_BoneDeflectionStyles SYMPATHETIC = 2, // change the other joint, but opposite to a mirrored way, eg: both go right or both go left } E_BoneDeflectionStyles; +/// +/// When we're going from bone-rotation to the UI sliders, some of the axes need swapping so they make sense in UI-terms. +/// eg: for one bone, the X-axis may mean up and down, but for another bone, the x-axis might be left-right. +/// These are translations of bone-TO-UI; an inverse translation needs to happen the other way. +/// It would be nice if these were defined in XML; but then they're not const, and I want const. +/// +typedef enum E_BoneAxisTranslation +{ + SWAP_NOTHING = 0, + SWAP_YAW_AND_ROLL = 1, + SWAP_YAW_AND_PITCH = 2, + SWAP_ROLL_AND_PITCH = 3, +} E_BoneAxisTranslation; + class FSPoserAnimator { public: @@ -73,6 +87,7 @@ public: std::string _jointName; // expected to be a match to LLJoint.getName() for a joint implementation. std::string _mirrorJointName; E_BoneTypes _boneList; + E_BoneAxisTranslation _boneTranslation; public: /// /// Gets the name of the joint. @@ -89,6 +104,11 @@ public: /// E_BoneTypes boneType() const { return _boneList; } + /// + /// Gets the E_BoneAxisTranslation of the joint. + /// + E_BoneAxisTranslation boneTranslation() const { return _boneTranslation; } + /// /// Creates a new instance of a PoserJoint. /// @@ -99,11 +119,12 @@ public: /// /// The opposite joint name, if any. Also expected to be a well-known name. /// The - FSPoserJoint(std::string a, std::string b, E_BoneTypes c) + FSPoserJoint(std::string a, std::string b, E_BoneTypes c, E_BoneAxisTranslation d = SWAP_NOTHING) { _jointName = a; _mirrorJointName = b; _boneList = c; + _boneTranslation = d; } }; @@ -122,7 +143,7 @@ public: /// const std::vector PoserJoints { // head, torso, legs - {"mPelvis", "", WHOLEAVATAR}, {"mTorso", "", BODY}, {"mChest", "", BODY}, {"mNeck", "", BODY}, {"mHead", "", BODY}, + {"mPelvis", "", WHOLEAVATAR}, {"mTorso", "", BODY, SWAP_YAW_AND_ROLL}, {"mChest", "", BODY}, {"mNeck", "", BODY}, {"mHead", "", BODY}, {"mCollarLeft", "mCollarRight", BODY}, {"mShoulderLeft", "mShoulderRight", BODY}, {"mElbowLeft", "mElbowRight", BODY}, {"mWristLeft", "mWristRight", BODY}, {"mCollarRight", "mCollarLeft", BODY}, {"mShoulderRight", "mShoulderLeft", BODY}, {"mElbowRight", "mElbowLeft", BODY}, {"mWristRight", "mWristLeft", BODY}, {"mHipLeft", "", BODY}, {"mKneeLeft", "", BODY}, {"mAnkleLeft", "", BODY}, @@ -269,6 +290,23 @@ public: private: bool _currentlyPosingSelf = false; + /// + /// Translates a rotation vector from the UI to a Quaternion for the bone. + /// This also performs the axis-swapping the UI needs for up/down/left/right to make sense. + /// + /// The axis translation to perform. + /// The rotation to transform to quaternion. + /// The rotation quaternion. + LLQuaternion translateRotationToQuaternion(E_BoneAxisTranslation translation, LLVector3 rotation); + + /// + /// Translates a bone-rotation quaternion to a vector usable easily on the UI. + /// + /// The axis translation to perform. + /// The rotation to transform to matrix. + /// The rotation vector. + LLVector3 translateRotationFromQuaternion(E_BoneAxisTranslation translation, LLQuaternion rotation); + // public: // static LLMotion *create(const LLUUID &id) { return new FSPoserAnimator(id); } diff --git a/indra/newview/fsvirtualtrackpad.h b/indra/newview/fsvirtualtrackpad.h index c12b097936..648b8ff169 100644 --- a/indra/newview/fsvirtualtrackpad.h +++ b/indra/newview/fsvirtualtrackpad.h @@ -43,7 +43,6 @@ public: Optional border; Optional image_moon_back, image_moon_front, image_sphere, image_sun_back, image_sun_front; Optional pinch_mode; - Optional allow_drag_outside; Params(); }; diff --git a/indra/newview/skins/default/xui/en/floater_poser.xml b/indra/newview/skins/default/xui/en/floater_poser.xml index add6511759..2d5a0b60e8 100644 --- a/indra/newview/skins/default/xui/en/floater_poser.xml +++ b/indra/newview/skins/default/xui/en/floater_poser.xml @@ -594,10 +594,10 @@ width="565"> left_delta="0" top_pad="2" width="200">Up/Down: - left_delta="-5" top_pad="0" width="200">Left/Right: - left_delta="-5" top_pad="-1" width="200">Roll: -