FIRE-30873: change azi and ele to yaw/pitch/roll
and fix trackball to sliders; sliders to trackball still todomaster
parent
eab80128ab
commit
55aab0a164
|
|
@ -57,9 +57,9 @@ static const std::string POSER_AVATAR_TAB_MISC = "misc_joints_panel";
|
|||
|
||||
// standard controls
|
||||
static const std::string POSER_AVATAR_TRACKBALL_NAME = "limb_rotation";
|
||||
static const std::string POSER_AVATAR_SLIDER_AZI_NAME = "limb_azimuth";
|
||||
static const std::string POSER_AVATAR_SLIDER_ELE_NAME = "limb_elevation";
|
||||
static const std::string POSER_AVATAR_SLIDER_ROLL_NAME = "limb_roll";
|
||||
static const std::string POSER_AVATAR_SLIDER_YAW_NAME = "limb_yaw"; // turning your nose left or right
|
||||
static const std::string POSER_AVATAR_SLIDER_PITCH_NAME = "limb_pitch"; // pointing your nose up or down
|
||||
static const std::string POSER_AVATAR_SLIDER_ROLL_NAME = "limb_roll"; // your ear touches your shoulder
|
||||
static const std::string POSER_AVATAR_TOGGLEBUTTON_MIRROR = "button_toggleMirrorRotation";
|
||||
static const std::string POSER_AVATAR_TOGGLEBUTTON_SYMPATH = "button_toggleSympatheticRotation";
|
||||
static const std::string POSER_AVATAR_SLIDER_POSX_NAME = "av_position_inout";
|
||||
|
|
@ -97,6 +97,8 @@ static const std::string POSER_AVATAR_SCROLLLIST_FACEJOINTS_NAME = "face_joi
|
|||
static const std::string POSER_AVATAR_SCROLLLIST_HANDJOINTS_NAME = "hand_joints_scroll";
|
||||
static const std::string POSER_AVATAR_SCROLLLIST_MISCJOINTS_NAME = "misc_joints_scroll";
|
||||
|
||||
const LLVector3 VectorZero(1.0f, 0.0f, 0.0f);
|
||||
|
||||
FSFloaterPoser::FSFloaterPoser(const LLSD& key) : LLFloater(key)
|
||||
{
|
||||
// bind requests, other controls are find-and-binds, see postBuild()
|
||||
|
|
@ -118,6 +120,8 @@ FSFloaterPoser::FSFloaterPoser(const LLSD& key) : LLFloater(key)
|
|||
mCommitCallbackRegistrar.add("Pose.Save", boost::bind(&FSFloaterPoser::onClickPoseSave, this));
|
||||
mCommitCallbackRegistrar.add("Pose.Menu", boost::bind(&FSFloaterPoser::onPoseMenuAction, this, _2));
|
||||
mCommitCallbackRegistrar.add("Poser.BrowseCache", boost::bind(&FSFloaterPoser::onClickBrowsePoseCache, this));
|
||||
|
||||
mCommitCallbackRegistrar.add("Poser.TrackBallMove", boost::bind(&FSFloaterPoser::onLimbTrackballChanged, this)); // so I can debug
|
||||
}
|
||||
|
||||
FSFloaterPoser::~FSFloaterPoser()
|
||||
|
|
@ -129,9 +133,9 @@ bool FSFloaterPoser::postBuild()
|
|||
{
|
||||
// find-and-binds
|
||||
getChild<LLUICtrl>(POSER_AVATAR_TRACKBALL_NAME)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbTrackballChanged(); });
|
||||
getChild<LLUICtrl>(POSER_AVATAR_SLIDER_AZI_NAME)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbAziEleRollChanged(); });
|
||||
getChild<LLUICtrl>(POSER_AVATAR_SLIDER_ELE_NAME)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbAziEleRollChanged(); });
|
||||
getChild<LLUICtrl>(POSER_AVATAR_SLIDER_ROLL_NAME)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbAziEleRollChanged(); });
|
||||
getChild<LLUICtrl>(POSER_AVATAR_SLIDER_YAW_NAME)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbYawPitchRollChanged(); });
|
||||
getChild<LLUICtrl>(POSER_AVATAR_SLIDER_PITCH_NAME)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbYawPitchRollChanged(); });
|
||||
getChild<LLUICtrl>(POSER_AVATAR_SLIDER_ROLL_NAME)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbYawPitchRollChanged(); });
|
||||
|
||||
LLScrollListCtrl *scrollList = getChild<LLScrollListCtrl>(POSER_AVATAR_SCROLLLIST_AVATARSELECTION);
|
||||
if (scrollList)
|
||||
|
|
@ -753,9 +757,9 @@ void FSFloaterPoser::clearRecentlySetRotations()
|
|||
_lastSetRotations.pop();
|
||||
}
|
||||
|
||||
void FSFloaterPoser::addRotationToRecentlySet(F32 aziInRadians, F32 eleInRadians, F32 rollInRadians)
|
||||
void FSFloaterPoser::addRotationToRecentlySet(F32 yawInRadians, F32 pitchInRadians, F32 rollInRadians)
|
||||
{
|
||||
_lastSetRotations.push(LLVector3(aziInRadians, eleInRadians, rollInRadians));
|
||||
_lastSetRotations.push(LLVector3(yawInRadians, pitchInRadians, rollInRadians));
|
||||
}
|
||||
|
||||
void FSFloaterPoser::onToggleAdvancedPanel()
|
||||
|
|
@ -883,11 +887,11 @@ void FSFloaterPoser::onAdvancedRotationSet()
|
|||
if (!xRotAdvSlider || !yRotAdvSlider || !zRotAdvSlider)
|
||||
return;
|
||||
|
||||
F32 azimuth = xRotAdvSlider->getValue().asReal();
|
||||
F32 elevation = yRotAdvSlider->getValue().asReal();
|
||||
F32 yaw = xRotAdvSlider->getValue().asReal();
|
||||
F32 pitch = yRotAdvSlider->getValue().asReal();
|
||||
F32 roll = zRotAdvSlider->getValue().asReal();
|
||||
|
||||
setSelectedJointsRotation(azimuth, elevation, roll);
|
||||
setSelectedJointsRotation(yaw, pitch, roll);
|
||||
}
|
||||
|
||||
void FSFloaterPoser::onAdvancedScaleSet()
|
||||
|
|
@ -920,60 +924,89 @@ void FSFloaterPoser::onAvatarPositionSet()
|
|||
setSelectedJointsPosition(posX, posY, posZ);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
void FSFloaterPoser::onLimbTrackballChanged()
|
||||
{
|
||||
LLVirtualTrackball *trackBall = getChild<LLVirtualTrackball>(POSER_AVATAR_TRACKBALL_NAME);
|
||||
if (!trackBall)
|
||||
return;
|
||||
|
||||
LLSliderCtrl *aziSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_AZI_NAME);
|
||||
LLSliderCtrl *eleSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_ELE_NAME);
|
||||
LLSliderCtrl *pitchSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_PITCH_NAME); // up/down
|
||||
LLSliderCtrl *yawSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_YAW_NAME); // left right
|
||||
LLSliderCtrl *rollSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_ROLL_NAME);
|
||||
if (!aziSlider || !eleSlider || !rollSlider)
|
||||
if (!yawSlider || !pitchSlider || !rollSlider)
|
||||
return;
|
||||
|
||||
LLQuaternion quat = trackBall->getRotation();
|
||||
LLQuaternion trackBallQuat = trackBall->getRotation();
|
||||
|
||||
F32 azimuth, elevation;
|
||||
LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
|
||||
// Convert the quaternion to a cartesian (x,y,z) point on a unit-sphere
|
||||
LLVector3 cartesionPoint = VectorZero * trackBallQuat; // VX is +up/-down screen; VY is +right/-left screen; VZ is +in/-out; all are ranged 1..-1
|
||||
|
||||
aziSlider->setValue(azimuth);
|
||||
eleSlider->setValue(elevation);
|
||||
F32 yaw, pitch, roll;
|
||||
if (cartesionPoint.mV[VZ] >= 0) // the sun is in front of the trackball, easy math
|
||||
{
|
||||
yaw = cartesionPoint.mV[VX] * F_PI_BY_TWO;
|
||||
pitch = cartesionPoint.mV[VY] * F_PI_BY_TWO;
|
||||
}
|
||||
else // when the sun is behind the trackball (VZ < 0), we want to keep increasing the angle
|
||||
{
|
||||
// this is a first pass, and does not consider sensitivity changes around the edges.
|
||||
// it could be worth disallowing VZ < 0, or only allowing as an advanced feature.
|
||||
|
||||
F32 roll = rollSlider->getValue().asReal();
|
||||
azimuth *= DEG_TO_RAD;
|
||||
elevation *= DEG_TO_RAD;
|
||||
if (cartesionPoint.mV[VX] >= 0) // sun is in top hemisphere
|
||||
yaw = F_PI_BY_TWO * (2 - cartesionPoint.mV[VX]);
|
||||
else
|
||||
yaw = -1 * F_PI_BY_TWO - F_PI_BY_TWO * (1 + cartesionPoint.mV[VX]);
|
||||
|
||||
if (cartesionPoint.mV[VY] >= 0) // sun is in screen-right hemisphere
|
||||
pitch = F_PI_BY_TWO * (2 - cartesionPoint.mV[VY]);
|
||||
else
|
||||
pitch = -1 * F_PI_BY_TWO - F_PI_BY_TWO * (1 + cartesionPoint.mV[VY]);
|
||||
}
|
||||
|
||||
roll = rollSlider->getValue().asReal(); // roll comes from the slider
|
||||
roll *= DEG_TO_RAD;
|
||||
|
||||
setSelectedJointsRotation(azimuth, elevation, roll);
|
||||
setSelectedJointsRotation(yaw, pitch, roll);
|
||||
|
||||
yaw *= RAD_TO_DEG;
|
||||
pitch *= RAD_TO_DEG;
|
||||
yawSlider->setValue(yaw);
|
||||
pitchSlider->setValue(pitch);
|
||||
}
|
||||
|
||||
void FSFloaterPoser::onLimbAziEleRollChanged()
|
||||
void FSFloaterPoser::onLimbYawPitchRollChanged()
|
||||
{
|
||||
LLSliderCtrl *aziSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_AZI_NAME);
|
||||
LLSliderCtrl *eleSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_ELE_NAME);
|
||||
LLSliderCtrl *yawSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_YAW_NAME);
|
||||
LLSliderCtrl *pitchSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_PITCH_NAME);
|
||||
LLSliderCtrl *rollSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_ROLL_NAME);
|
||||
if (!aziSlider || !eleSlider || !rollSlider)
|
||||
if (!yawSlider || !pitchSlider || !rollSlider)
|
||||
return;
|
||||
|
||||
F32 azimuth = aziSlider->getValue().asReal();
|
||||
F32 elevation = eleSlider->getValue().asReal();
|
||||
F32 roll = rollSlider->getValue().asReal();
|
||||
F32 yaw = yawSlider->getValue().asReal();
|
||||
F32 pitch = pitchSlider->getValue().asReal();
|
||||
F32 roll = rollSlider->getValue().asReal();
|
||||
|
||||
azimuth *= DEG_TO_RAD;
|
||||
elevation *= DEG_TO_RAD;
|
||||
yaw *= DEG_TO_RAD;
|
||||
pitch *= DEG_TO_RAD;
|
||||
roll *= DEG_TO_RAD;
|
||||
|
||||
if (is_approx_zero(elevation))
|
||||
elevation = F_APPROXIMATELY_ZERO;
|
||||
|
||||
setSelectedJointsRotation(azimuth, elevation, roll);
|
||||
setSelectedJointsRotation(yaw, pitch, roll);
|
||||
|
||||
yaw *= F_PI;
|
||||
pitch *= F_PI;
|
||||
roll *= F_PI; // roll needs to be recalculated from unit sphere based on ranges of yaw and roll
|
||||
LLVector3 vec3 = LLVector3(yaw, pitch, roll);
|
||||
LLQuaternion quat;
|
||||
quat.setAngleAxis(-elevation, 0, 1, 0);
|
||||
LLQuaternion az_quat;
|
||||
az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
|
||||
quat *= az_quat;
|
||||
quat.unpackFromVector3(vec3);
|
||||
quat.setAngleAxis(pitch, 0, 1, 0);
|
||||
|
||||
LLVirtualTrackball *trackBall = getChild<LLVirtualTrackball>(POSER_AVATAR_TRACKBALL_NAME);
|
||||
if (!trackBall)
|
||||
|
|
@ -998,7 +1031,7 @@ void FSFloaterPoser::setSelectedJointsPosition(F32 x, F32 y, F32 z)
|
|||
_poserAnimator.setJointPosition(avatar, item, vec3, defl);
|
||||
}
|
||||
|
||||
void FSFloaterPoser::setSelectedJointsRotation(F32 aziInRadians, F32 eleInRadians, F32 rollInRadians)
|
||||
void FSFloaterPoser::setSelectedJointsRotation(F32 yawInRadians, F32 pitchInRadians, F32 rollInRadians)
|
||||
{
|
||||
LLVOAvatar *avatar = getUiSelectedAvatar();
|
||||
if (!avatar)
|
||||
|
|
@ -1007,10 +1040,10 @@ void FSFloaterPoser::setSelectedJointsRotation(F32 aziInRadians, F32 eleInRadian
|
|||
if (!_poserAnimator.isPosingAvatar(avatar))
|
||||
return;
|
||||
|
||||
addRotationToRecentlySet(aziInRadians, eleInRadians, rollInRadians);
|
||||
addRotationToRecentlySet(yawInRadians, pitchInRadians, rollInRadians);
|
||||
|
||||
E_BoneDeflectionStyles defl = getUiSelectedBoneDeflectionStyle();
|
||||
LLVector3 vec3 = LLVector3(aziInRadians, eleInRadians, rollInRadians);
|
||||
LLVector3 vec3 = LLVector3(yawInRadians, pitchInRadians, rollInRadians);
|
||||
|
||||
for (auto item : getUiSelectedPoserJoints())
|
||||
_poserAnimator.setJointRotation(avatar, item, vec3, defl);
|
||||
|
|
@ -1047,17 +1080,17 @@ void FSFloaterPoser::onJointSelect()
|
|||
|
||||
clearRecentlySetRotations();
|
||||
LLVector3 rotation = _poserAnimator.getJointRotation(avatar, *selectedJoints.front());
|
||||
F32 azimuth = rotation.mV[VX];
|
||||
F32 elevation = rotation.mV[VY];
|
||||
F32 yaw = rotation.mV[VX];
|
||||
F32 pitch = rotation.mV[VY];
|
||||
F32 roll = rotation.mV[VZ];
|
||||
|
||||
if (is_approx_zero(elevation))
|
||||
elevation = F_APPROXIMATELY_ZERO;
|
||||
if (is_approx_zero(pitch))
|
||||
pitch = F_APPROXIMATELY_ZERO;
|
||||
|
||||
LLQuaternion quat;
|
||||
quat.setAngleAxis(-elevation, 0, 1, 0);
|
||||
quat.setAngleAxis(-pitch, 0, 1, 0);
|
||||
LLQuaternion az_quat;
|
||||
az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
|
||||
az_quat.setAngleAxis(F_TWO_PI - yaw, 0, 0, 1);
|
||||
quat *= az_quat;
|
||||
|
||||
LLVirtualTrackball *trackBall = getChild<LLVirtualTrackball>(POSER_AVATAR_TRACKBALL_NAME);
|
||||
|
|
@ -1066,14 +1099,14 @@ void FSFloaterPoser::onJointSelect()
|
|||
|
||||
trackBall->setRotation(quat);
|
||||
|
||||
LLSliderCtrl *aziSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_AZI_NAME);
|
||||
LLSliderCtrl *eleSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_ELE_NAME);
|
||||
LLSliderCtrl *yawSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_YAW_NAME);
|
||||
LLSliderCtrl *pitchSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_PITCH_NAME);
|
||||
LLSliderCtrl *rollSlider = getChild<LLSliderCtrl>(POSER_AVATAR_SLIDER_ROLL_NAME);
|
||||
if (!aziSlider || !eleSlider || !rollSlider)
|
||||
if (!yawSlider || !pitchSlider || !rollSlider)
|
||||
return;
|
||||
|
||||
aziSlider->setValue(azimuth *= RAD_TO_DEG);
|
||||
eleSlider->setValue(elevation *= RAD_TO_DEG);
|
||||
yawSlider->setValue(yaw *= RAD_TO_DEG);
|
||||
pitchSlider->setValue(pitch *= RAD_TO_DEG);
|
||||
rollSlider->setValue(roll *= RAD_TO_DEG);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,9 +77,9 @@ class FSFloaterPoser : public LLFloater
|
|||
std::vector<FSPoserAnimator::FSPoserJoint *> getUiSelectedPoserJoints();
|
||||
LLVOAvatar *getUiSelectedAvatar();
|
||||
E_BoneDeflectionStyles getUiSelectedBoneDeflectionStyle();
|
||||
void addRotationToRecentlySet(F32 aziInRadians, F32 eleInRadians, F32 rollInRadians);
|
||||
void addRotationToRecentlySet(F32 yawInRadians, F32 pitchInRadians, F32 rollInRadians);
|
||||
void clearRecentlySetRotations();
|
||||
void setSelectedJointsRotation(F32 aziInRadians, F32 eleInRadians, F32 rollInRadians);
|
||||
void setSelectedJointsRotation(F32 yawInRadians, F32 pitchInRadians, F32 rollInRadians);
|
||||
void setSelectedJointsPosition(F32 x, F32 y, F32 z);
|
||||
void setSelectedJointsScale(F32 x, F32 y, F32 z);
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ class FSFloaterPoser : public LLFloater
|
|||
void onUndoLastRotation();
|
||||
void onPoseStartStop();
|
||||
void onLimbTrackballChanged();
|
||||
void onLimbAziEleRollChanged();
|
||||
void onLimbYawPitchRollChanged();
|
||||
void onAvatarPositionSet();
|
||||
void onAdvancedPositionSet();
|
||||
void onAdvancedRotationSet();
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ width="565">
|
|||
top="0"
|
||||
width="235">
|
||||
<text follows="left|top"
|
||||
name="sun_azimuth_label"
|
||||
name="av_position_updown_label"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
|
|
@ -289,7 +289,7 @@ width="565">
|
|||
function="Poser.PositionSet"/>
|
||||
</slider>
|
||||
<text follows="left|top"
|
||||
name="sun_elevation_label"
|
||||
name="av_position_leftright_label"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="-5"
|
||||
|
|
@ -313,7 +313,7 @@ width="565">
|
|||
function="Poser.PositionSet"/>
|
||||
</slider>
|
||||
<text follows="left|top"
|
||||
name="sun_roll_label"
|
||||
name="av_position_inout_label"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="-5"
|
||||
|
|
@ -516,7 +516,7 @@ width="565">
|
|||
top_delta="15"
|
||||
height="153"
|
||||
width="153"
|
||||
tool_tip="Change the rotation of the currently selected joint(s)"
|
||||
tool_tip="Change the rotation of the currently selected joint(s). Hold CTRL/CMD while changing for easy-rolling"
|
||||
thumb_mode="sun"/>
|
||||
<panel
|
||||
follows="left|top|bottom"
|
||||
|
|
@ -525,7 +525,7 @@ width="565">
|
|||
layout="topleft"
|
||||
visible="true"
|
||||
mouse_opaque="false"
|
||||
Left="0"
|
||||
left="0"
|
||||
top_pad="2"
|
||||
name="trackball_button_panel"
|
||||
width="232">
|
||||
|
|
@ -588,42 +588,42 @@ width="565">
|
|||
</button>
|
||||
</panel>
|
||||
<text follows="left|top"
|
||||
name="limb_azimuth_label"
|
||||
name="limb_pitch_label"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="2"
|
||||
width="200">Azimuth:</text>
|
||||
<slider decimal_digits="2"
|
||||
width="200">Up/Down:</text>
|
||||
<slider decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
increment="0.01"
|
||||
increment="1"
|
||||
initial_value="0"
|
||||
layout="topleft"
|
||||
left_delta="5"
|
||||
min_val="0"
|
||||
max_val="359.99"
|
||||
name="limb_azimuth"
|
||||
min_val="-180"
|
||||
max_val="180"
|
||||
name="limb_pitch"
|
||||
top_pad="2"
|
||||
width="150"
|
||||
can_edit_text="true"/>
|
||||
<text follows="left|top"
|
||||
name="limb_elevation_label"
|
||||
name="limb_yaw_label"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="-5"
|
||||
top_pad="0"
|
||||
width="200">Elevation:</text>
|
||||
<slider decimal_digits="2"
|
||||
width="200">Left/Right:</text>
|
||||
<slider decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
increment="0.01"
|
||||
increment="1"
|
||||
initial_value="0"
|
||||
layout="topleft"
|
||||
left_delta="5"
|
||||
min_val="-90"
|
||||
max_val="90"
|
||||
name="limb_elevation"
|
||||
min_val="-180"
|
||||
max_val="180"
|
||||
name="limb_yaw"
|
||||
top_pad="0"
|
||||
width="150"
|
||||
can_edit_text="true"/>
|
||||
|
|
@ -634,10 +634,10 @@ width="565">
|
|||
left_delta="-5"
|
||||
top_pad="-1"
|
||||
width="200">Roll:</text>
|
||||
<slider decimal_digits="2"
|
||||
<slider decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
increment="0.01"
|
||||
increment="1"
|
||||
initial_value="0"
|
||||
layout="topleft"
|
||||
left_delta="5"
|
||||
|
|
|
|||
Loading…
Reference in New Issue