Ansariel 2025-04-18 19:39:05 +02:00
commit 5394c8b7a4
45 changed files with 1164 additions and 507 deletions

View File

@ -16,3 +16,5 @@ e2e37cced861b98de8c1a7c9c0d3a50d2d90e433
# ignore some of the merges of ws silliness to restore blame reporting # ignore some of the merges of ws silliness to restore blame reporting
5f1a19af725b90737d50a42a51a7bc1db12c7d13 5f1a19af725b90737d50a42a51a7bc1db12c7d13
a17fd2352a9746dd3116f956dcc554f95f17e770 a17fd2352a9746dd3116f956dcc554f95f17e770
# ignore beq's formatting derp
f8204c43e89d65d981a52aebf033ead5b4b3495a

View File

@ -107,7 +107,7 @@ if (WINDOWS)
/Oy- /Oy-
/Oi /Oi
/Ot /Ot
/fp:fast /fp:precise
/MP /MP
/permissive- /permissive-
) )

View File

@ -641,6 +641,11 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
if(discard_level > 0) if(discard_level > 0)
{ {
mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)discard_level); mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)discard_level);
// <FS:minerjr> [FIRE-35361] RenderMaxTextureResolution caps texture resolution lower than intended
// 2K textures could set the mMaxDiscardLevel above MAX_DISCARD_LEVEL, which would
// cause them to not be down-scaled so they would get stuck at 0 discard all the time.
mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)MAX_DISCARD_LEVEL);
// </FS:minerjr> [FIRE-35361]
} }
} }
else else

View File

@ -1249,7 +1249,7 @@ void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data)
// //
LLUrlEntryPlace::LLUrlEntryPlace() LLUrlEntryPlace::LLUrlEntryPlace()
{ {
mPattern = boost::regex("((hop://[-\\w\\.\\:\\@]+/)|((x-grid-location-info://[-\\w\\.]+/region/)|(secondlife://)))\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?", // <AW: hop:// protocol> mPattern = boost::regex("((hop://[-\\w\\.\\:\\@]+/)|((x-grid-location-info://[-\\w\\.]+/region/)|(secondlife://)))\\S+(?:/?(-?\\d+/-?\\d+/-?\\d+|-?\\d+/-?\\d+)/?)?", // <AW: hop:// protocol>
boost::regex::perl|boost::regex::icase); boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slurl.xml"; mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipSLURL"); mTooltip = LLTrans::getString("TooltipSLURL");

View File

@ -8080,17 +8080,6 @@
<key>Value</key> <key>Value</key>
<integer>0</integer> <integer>0</integer>
</map> </map>
<key>FSPoserAdvancedWindowState</key>
<map>
<key>Comment</key>
<string>Whether the 'advanced' pane is shown when opening the Avatar/Animesh Poser.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSPoserSaveExternalFileAlso</key> <key>FSPoserSaveExternalFileAlso</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
@ -8113,6 +8102,17 @@
<key>Value</key> <key>Value</key>
<integer>0</integer> <integer>0</integer>
</map> </map>
<key>FSPoserOnSaveConfirmOverwrite</key>
<map>
<key>Comment</key>
<string>Whether to confirm overwriting a save file.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSPoserStopPosingWhenClosed</key> <key>FSPoserStopPosingWhenClosed</key>
<map> <map>
<key>Comment</key> <key>Comment</key>

View File

@ -61,6 +61,7 @@ constexpr std::string_view POSER_TRACKPAD_SENSITIVITY_SAVE_KEY = "FSPoserTrackpa
constexpr std::string_view POSER_STOPPOSINGWHENCLOSED_SAVE_KEY = "FSPoserStopPosingWhenClosed"; constexpr std::string_view POSER_STOPPOSINGWHENCLOSED_SAVE_KEY = "FSPoserStopPosingWhenClosed";
constexpr std::string_view POSER_RESETBASEROTONEDIT_SAVE_KEY = "FSPoserResetBaseRotationOnEdit"; constexpr std::string_view POSER_RESETBASEROTONEDIT_SAVE_KEY = "FSPoserResetBaseRotationOnEdit";
constexpr std::string_view POSER_SAVEEXTERNALFORMAT_SAVE_KEY = "FSPoserSaveExternalFileAlso"; constexpr std::string_view POSER_SAVEEXTERNALFORMAT_SAVE_KEY = "FSPoserSaveExternalFileAlso";
constexpr std::string_view POSER_SAVECONFIRMREQUIRED_SAVE_KEY = "FSPoserOnSaveConfirmOverwrite";
} // namespace } // namespace
/// <summary> /// <summary>
@ -83,11 +84,10 @@ FSFloaterPoser::FSFloaterPoser(const LLSD& key) : LLFloater(key)
mCommitCallbackRegistrar.add("Poser.ToggleSympatheticChanges", [this](LLUICtrl*, const LLSD&) { onToggleSympatheticChange(); }); mCommitCallbackRegistrar.add("Poser.ToggleSympatheticChanges", [this](LLUICtrl*, const LLSD&) { onToggleSympatheticChange(); });
mCommitCallbackRegistrar.add("Poser.AdjustTrackPadSensitivity", [this](LLUICtrl*, const LLSD&) { onAdjustTrackpadSensitivity(); }); mCommitCallbackRegistrar.add("Poser.AdjustTrackPadSensitivity", [this](LLUICtrl*, const LLSD&) { onAdjustTrackpadSensitivity(); });
mCommitCallbackRegistrar.add("Poser.PositionSet", [this](LLUICtrl*, const LLSD&) { onAvatarPositionSet(); }); mCommitCallbackRegistrar.add("Poser.PositionSet", [this](LLUICtrl*, const LLSD&) { onPositionSet(); });
mCommitCallbackRegistrar.add("Poser.SetToTPose", [this](LLUICtrl*, const LLSD&) { onSetAvatarToTpose(); }); mCommitCallbackRegistrar.add("Poser.SetToTPose", [this](LLUICtrl*, const LLSD&) { onSetAvatarToTpose(); });
mCommitCallbackRegistrar.add("Poser.Advanced.PositionSet", [this](LLUICtrl*, const LLSD&) { onAdvancedPositionSet(); }); mCommitCallbackRegistrar.add("Poser.Advanced.ScaleSet", [this](LLUICtrl*, const LLSD&) { onScaleSet(); });
mCommitCallbackRegistrar.add("Poser.Advanced.ScaleSet", [this](LLUICtrl*, const LLSD&) { onAdvancedScaleSet(); });
mCommitCallbackRegistrar.add("Poser.UndoLastPosition", [this](LLUICtrl*, const LLSD&) { onUndoLastChange(); }); mCommitCallbackRegistrar.add("Poser.UndoLastPosition", [this](LLUICtrl*, const LLSD&) { onUndoLastChange(); });
mCommitCallbackRegistrar.add("Poser.RedoLastPosition", [this](LLUICtrl*, const LLSD&) { onRedoLastChange(); }); mCommitCallbackRegistrar.add("Poser.RedoLastPosition", [this](LLUICtrl*, const LLSD&) { onRedoLastChange(); });
mCommitCallbackRegistrar.add("Poser.ResetJoint", [this](LLUICtrl*, const LLSD& data) { onResetJoint(data); }); mCommitCallbackRegistrar.add("Poser.ResetJoint", [this](LLUICtrl*, const LLSD& data) { onResetJoint(data); });
@ -104,13 +104,14 @@ FSFloaterPoser::FSFloaterPoser(const LLSD& key) : LLFloater(key)
mCommitCallbackRegistrar.add("Poser.TogglePosingSelectedBones", [this](LLUICtrl*, const LLSD&) { onClickToggleSelectedBoneEnabled(); }); mCommitCallbackRegistrar.add("Poser.TogglePosingSelectedBones", [this](LLUICtrl*, const LLSD&) { onClickToggleSelectedBoneEnabled(); });
mCommitCallbackRegistrar.add("Poser.CommitSpinner", [this](LLUICtrl* spinner, const LLSD& data) { onCommitSpinner(spinner, data); }); mCommitCallbackRegistrar.add("Poser.CommitSpinner", [this](LLUICtrl* spinner, const LLSD& data) { onCommitSpinner(spinner, data); });
mCommitCallbackRegistrar.add("Poser.CommitSlider", [this](LLUICtrl* slider, const LLSD& data) { onCommitSlider(slider, data); });
mCommitCallbackRegistrar.add("Poser.Symmetrize", [this](LLUICtrl*, const LLSD& data) { onClickSymmetrize(data); }); mCommitCallbackRegistrar.add("Poser.Symmetrize", [this](LLUICtrl*, const LLSD& data) { onClickSymmetrize(data); });
} }
bool FSFloaterPoser::postBuild() bool FSFloaterPoser::postBuild()
{ {
mAvatarTrackball = getChild<FSVirtualTrackpad>("limb_rotation"); mAvatarTrackball = getChild<FSVirtualTrackpad>("limb_rotation");
mAvatarTrackball->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbTrackballChanged(); }); mAvatarTrackball->setCommitCallback([this](LLUICtrl *, const LLSD &) { onTrackballChanged(); });
mJointsTabs = getChild<LLTabContainer>("joints_tabs"); mJointsTabs = getChild<LLTabContainer>("joints_tabs");
mJointsTabs->setCommitCallback( mJointsTabs->setCommitCallback(
@ -164,6 +165,10 @@ bool FSFloaterPoser::postBuild()
mPosYSlider = getChild<LLSliderCtrl>("av_position_leftright"); mPosYSlider = getChild<LLSliderCtrl>("av_position_leftright");
mPosZSlider = getChild<LLSliderCtrl>("av_position_updown"); mPosZSlider = getChild<LLSliderCtrl>("av_position_updown");
mAdvRotXSlider = getChild<LLSliderCtrl>("limb_pitch_slider");
mAdvRotYSlider = getChild<LLSliderCtrl>("limb_yaw_slider");
mAdvRotZSlider = getChild<LLSliderCtrl>("limb_roll_slider");
mAdvPosXSlider = getChild<LLSliderCtrl>("Advanced_Position_X"); mAdvPosXSlider = getChild<LLSliderCtrl>("Advanced_Position_X");
mAdvPosYSlider = getChild<LLSliderCtrl>("Advanced_Position_Y"); mAdvPosYSlider = getChild<LLSliderCtrl>("Advanced_Position_Y");
mAdvPosZSlider = getChild<LLSliderCtrl>("Advanced_Position_Z"); mAdvPosZSlider = getChild<LLSliderCtrl>("Advanced_Position_Z");
@ -178,6 +183,7 @@ bool FSFloaterPoser::postBuild()
mBrowserFolderBtn = getChild<LLButton>("open_poseDir_button"); mBrowserFolderBtn = getChild<LLButton>("open_poseDir_button");
mLoadPosesBtn = getChild<LLButton>("load_poses_button"); mLoadPosesBtn = getChild<LLButton>("load_poses_button");
mSavePosesBtn = getChild<LLButton>("save_poses_button"); mSavePosesBtn = getChild<LLButton>("save_poses_button");
mSavePosesBtn->setMouseLeaveCallback([this](LLUICtrl*, const LLSD&) { onMouseLeaveSavePoseBtn(); });
mFlipPoseBtn = getChild<LLButton>("FlipPose_avatar"); mFlipPoseBtn = getChild<LLButton>("FlipPose_avatar");
mFlipJointBtn = getChild<LLButton>("FlipJoint_avatar"); mFlipJointBtn = getChild<LLButton>("FlipJoint_avatar");
@ -188,6 +194,7 @@ bool FSFloaterPoser::postBuild()
mToggleSympatheticRotationBtn = getChild<LLButton>("button_toggleSympatheticRotation"); mToggleSympatheticRotationBtn = getChild<LLButton>("button_toggleSympatheticRotation");
mToggleDeltaModeBtn = getChild<LLButton>("delta_mode_toggle"); mToggleDeltaModeBtn = getChild<LLButton>("delta_mode_toggle");
mRedoChangeBtn = getChild<LLButton>("button_redo_change"); mRedoChangeBtn = getChild<LLButton>("button_redo_change");
mUndoChangeBtn = getChild<LLButton>("undo_change");
mSetToTposeButton = getChild<LLButton>("set_t_pose_button"); mSetToTposeButton = getChild<LLButton>("set_t_pose_button");
mJointsParentPnl = getChild<LLPanel>("joints_parent_panel"); mJointsParentPnl = getChild<LLPanel>("joints_parent_panel");
@ -252,15 +259,23 @@ void FSFloaterPoser::onFocusLost()
LLEditMenuHandler::gEditMenuHandler = nullptr; LLEditMenuHandler::gEditMenuHandler = nullptr;
} }
} }
void FSFloaterPoser::enableVisualManipulators() void FSFloaterPoser::enableVisualManipulators()
{ {
if (!gAgentAvatarp || gAgentAvatarp.isNull())
{
mToggleVisualManipulators->setToggleState(false);
return;
}
if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset) if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset)
{ {
mLastToolset = LLToolMgr::getInstance()->getCurrentToolset(); mLastToolset = LLToolMgr::getInstance()->getCurrentToolset();
} }
LLToolMgr::getInstance()->setCurrentToolset(gPoserToolset); LLToolMgr::getInstance()->setCurrentToolset(gPoserToolset);
LLToolMgr::getInstance()->getCurrentToolset()->selectTool(FSToolCompPose::getInstance()); LLToolMgr::getInstance()->getCurrentToolset()->selectTool(FSToolCompPose::getInstance());
FSToolCompPose::getInstance()->setAvatar( gAgentAvatarp); FSToolCompPose::getInstance()->setAvatar(gAgentAvatarp);
} }
void FSFloaterPoser::disableVisualManipulators() void FSFloaterPoser::disableVisualManipulators()
@ -347,16 +362,22 @@ void FSFloaterPoser::onPoseFileSelect()
mPoseSaveNameEditor->setText(name); mPoseSaveNameEditor->setText(name);
bool isDeltaSave = !poseFileStartsFromTeePose(name); bool isDeltaSave = !poseFileStartsFromTeePose(name);
if (isDeltaSave) if (isDeltaSave && hasString("LoadDiffLabel"))
mLoadPosesBtn->setLabel(getString("LoadDiffLabel")); mLoadPosesBtn->setLabel(getString("LoadDiffLabel"));
else else if (hasString("LoadPoseLabel"))
mLoadPosesBtn->setLabel(getString("LoadPoseLabel")); mLoadPosesBtn->setLabel(getString("LoadPoseLabel"));
} }
void FSFloaterPoser::onClickPoseSave() void FSFloaterPoser::onClickPoseSave()
{ {
std::string filename = mPoseSaveNameEditor->getValue().asString(); std::string filename = mPoseSaveNameEditor->getValue().asString();
if (filename.empty()) if (filename.empty() && hasString("icon_save_failed_button"))
{
mSavePosesBtn->setImageOverlay(getString("icon_save_failed_button"), mSavePosesBtn->getImageOverlayHAlign());
return;
}
if (confirmFileOverwrite(filename))
return; return;
LLVOAvatar* avatar = getUiSelectedAvatar(); LLVOAvatar* avatar = getUiSelectedAvatar();
@ -372,8 +393,55 @@ void FSFloaterPoser::onClickPoseSave()
if (getSavingToBvh()) if (getSavingToBvh())
savePoseToBvh(avatar, filename); savePoseToBvh(avatar, filename);
// TODO: provide feedback for save if (hasString("icon_rotation_is_own_work"))
mSavePosesBtn->setImageOverlay(getString("icon_rotation_is_own_work"), mSavePosesBtn->getImageOverlayHAlign());
setSavePosesButtonText(!mPoserAnimator.allBaseRotationsAreZero(avatar));
} }
else
{
if (hasString("icon_save_failed_button"))
mSavePosesBtn->setImageOverlay(getString("icon_save_failed_button"), mSavePosesBtn->getImageOverlayHAlign());
}
}
bool FSFloaterPoser::confirmFileOverwrite(std::string fileName)
{
if (fileName.empty())
return false;
if (!gSavedSettings.getBOOL(POSER_SAVECONFIRMREQUIRED_SAVE_KEY))
return false;
if (!hasString("icon_save_query"))
return false;
if (mSavePosesBtn->getImageOverlay().notNull() && mSavePosesBtn->getImageOverlay()->getName() == getString("icon_save_query"))
return false;
std::string fullSavePath =
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, POSE_SAVE_SUBDIRECTORY, fileName + POSE_INTERNAL_FORMAT_FILE_EXT);
if (!gDirUtilp->fileExists(fullSavePath))
return false;
mSavePosesBtn->setImageOverlay(getString("icon_save_query"), mSavePosesBtn->getImageOverlayHAlign());
if (hasString("OverWriteLabel"))
mSavePosesBtn->setLabel(getString("OverWriteLabel"));
return true;
}
void FSFloaterPoser::onMouseLeaveSavePoseBtn()
{
if (hasString("icon_save_button"))
mSavePosesBtn->setImageOverlay(getString("icon_save_button"), mSavePosesBtn->getImageOverlayHAlign());
LLVOAvatar* avatar = getUiSelectedAvatar();
if (!avatar)
return;
setSavePosesButtonText(!mPoserAnimator.allBaseRotationsAreZero(avatar));
} }
void FSFloaterPoser::createUserPoseDirectoryIfNeeded() void FSFloaterPoser::createUserPoseDirectoryIfNeeded()
@ -552,6 +620,7 @@ void FSFloaterPoser::onClickFlipSelectedJoints()
} }
refreshRotationSlidersAndSpinners(); refreshRotationSlidersAndSpinners();
enableOrDisableRedoAndUndoButton();
refreshTrackpadCursor(); refreshTrackpadCursor();
} }
@ -596,13 +665,11 @@ void FSFloaterPoser::onClickRecaptureSelectedBones()
refreshRotationSlidersAndSpinners(); refreshRotationSlidersAndSpinners();
refreshTrackpadCursor(); refreshTrackpadCursor();
refreshTextHighlightingOnJointScrollLists(); refreshTextHighlightingOnJointScrollLists();
enableOrDisableRedoAndUndoButton();
} }
void FSFloaterPoser::updatePosedBones()
{
auto selectedJoints = getUiSelectedPoserJoints();
if (selectedJoints.size() < 1)
return;
void FSFloaterPoser::updatePosedBones(const std::string& jointName)
{
LLVOAvatar *avatar = getUiSelectedAvatar(); LLVOAvatar *avatar = getUiSelectedAvatar();
if (!avatar) if (!avatar)
return; return;
@ -610,18 +677,17 @@ void FSFloaterPoser::updatePosedBones()
if (!mPoserAnimator.isPosingAvatar(avatar)) if (!mPoserAnimator.isPosingAvatar(avatar))
return; return;
for (auto item : selectedJoints) const FSPoserAnimator::FSPoserJoint* poserJoint = mPoserAnimator.getPoserJointByName(jointName);
{ if (!poserJoint)
bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); return;
if (!currentlyPosing)
continue;
mPoserAnimator.recaptureJointAsDelta(avatar, *item, getJointTranslation(item->jointName()), getJointNegation(item->jointName())); mPoserAnimator.recaptureJointAsDelta(avatar, poserJoint, getUiSelectedBoneDeflectionStyle());
}
setSavePosesButtonText(true);
refreshRotationSlidersAndSpinners(); refreshRotationSlidersAndSpinners();
refreshPositionSlidersAndSpinners();
refreshScaleSlidersAndSpinners();
refreshTrackpadCursor(); refreshTrackpadCursor();
enableOrDisableRedoAndUndoButton();
refreshTextHighlightingOnJointScrollLists(); refreshTextHighlightingOnJointScrollLists();
} }
@ -633,11 +699,8 @@ void FSFloaterPoser::onClickBrowsePoseCache()
gViewerWindow->getWindow()->openFile(pathname); gViewerWindow->getWindow()->openFile(pathname);
} }
void FSFloaterPoser::onClickSymmetrize(S32 ID) void FSFloaterPoser::onClickSymmetrize(const S32 ID)
{ {
if (notDoubleClicked())
return;
LLVOAvatar* avatar = getUiSelectedAvatar(); LLVOAvatar* avatar = getUiSelectedAvatar();
if (!avatar) if (!avatar)
return; return;
@ -648,40 +711,35 @@ void FSFloaterPoser::onClickSymmetrize(S32 ID)
mPoserAnimator.symmetrizeLeftToRightOrRightToLeft(avatar, ID == 2); mPoserAnimator.symmetrizeLeftToRightOrRightToLeft(avatar, ID == 2);
refreshRotationSlidersAndSpinners(); refreshRotationSlidersAndSpinners();
enableOrDisableRedoAndUndoButton();
refreshTrackpadCursor(); refreshTrackpadCursor();
} }
void FSFloaterPoser::onCommitSpinner(LLUICtrl* spinner, S32 id) void FSFloaterPoser::onCommitSpinner(const LLUICtrl* spinner, const S32 id)
{ {
if (!spinner) if (!spinner)
return; return;
auto activeTab = mJointsTabs->getCurrentPanel();
if (!activeTab)
return;
bool changingBodyPosition = activeTab == mPositionRotationPnl;
F32 value = (F32)spinner->getValue().asReal(); F32 value = (F32)spinner->getValue().asReal();
switch (id) switch (id)
{ {
case 0: // av_position_updown_spinner case 0: // av_position_updown_spinner
{ {
mPosZSlider->setValue(value); mAdvPosZSpnr->setValue(value);
onAvatarPositionSet(); onPositionSet();
break; break;
} }
case 1: // av_position_leftright case 1: // av_position_leftright
{ {
mPosYSlider->setValue(value); mAdvPosYSpnr->setValue(value);
onAvatarPositionSet(); onPositionSet();
break; break;
} }
case 2: // av_position_inout_spinner case 2: // av_position_inout_spinner
{ {
mPosXSlider->setValue(value); mAdvPosXSpnr->setValue(value);
onAvatarPositionSet(); onPositionSet();
break; break;
} }
case 3: // trackpad_sensitivity_spinner case 3: // trackpad_sensitivity_spinner
@ -690,50 +748,100 @@ void FSFloaterPoser::onCommitSpinner(LLUICtrl* spinner, S32 id)
break; break;
} }
case 7: // adv_posx_spinner case 7: // adv_posx_spinner
{
if (changingBodyPosition)
mPosXSlider->setValue(value);
mAdvPosXSlider->setValue(value);
onAdvancedPositionSet();
break;
}
case 8: // adv_posy_spinner case 8: // adv_posy_spinner
{
if (changingBodyPosition)
mPosYSlider->setValue(value);
mAdvPosYSlider->setValue(value);
onAdvancedPositionSet();
break;
}
case 9: // adv_posz_spinner case 9: // adv_posz_spinner
{ {
if (changingBodyPosition) onPositionSet();
mPosZSlider->setValue(value);
mAdvPosZSlider->setValue(value);
onAdvancedPositionSet();
break; break;
} }
case 10: // adv_scalex_spinner case 10: // adv_scalex_spinner
{
mAdvScaleXSlider->setValue(value);
onAdvancedScaleSet();
break;
}
case 11: // adv_scaley_spinner case 11: // adv_scaley_spinner
{
mAdvScaleYSlider->setValue(value);
onAdvancedScaleSet();
break;
}
case 12: // adv_scalez_spinner case 12: // adv_scalez_spinner
{ {
mAdvScaleZSlider->setValue(value); onScaleSet();
onAdvancedScaleSet();
break; break;
} }
default:
LL_WARNS("Posing") << "onCommitSpinner passed invalid parameter: " << id << LL_ENDL;
break;
}
}
void FSFloaterPoser::onCommitSlider(const LLUICtrl* slider, const S32 id)
{
if (!slider)
return;
F32 value = (F32)slider->getValue().asReal();
switch (id)
{
case 0: // av_position_updown
case 9: // Advanced_Position_Z
{
mAdvPosZSpnr->setValue(value);
onPositionSet();
break;
}
case 1: // av_position_leftright
case 8: // Advanced_Position_Y
{
mAdvPosYSpnr->setValue(value);
onPositionSet();
break;
}
case 2: // av_position_inout
case 7: // Advanced_Position_X
{
mAdvPosXSpnr->setValue(value);
onPositionSet();
break;
}
case 4: // limb_pitch_slider
{
mPitchSpnr->setValue(value);
onYawPitchRollChanged();
break;
}
case 5: // limb_yaw_slider
{
mYawSpnr->setValue(value);
onYawPitchRollChanged();
break;
}
case 6: // limb_roll_slider
{
mRollSpnr->setValue(value);
onYawPitchRollChanged();
break;
}
case 10: // Advanced_Scale_X
{
mScaleXSpnr->setValue(value);
onScaleSet();
break;
}
case 11: // Advanced_Scale_Y
{
mScaleYSpnr->setValue(value);
onScaleSet();
break;
}
case 12: // Advanced_Scale_Z
{
mScaleZSpnr->setValue(value);
onScaleSet();
break;
}
default:
LL_WARNS("Posing") << "onCommitSlider passed invalid parameter: " << id << LL_ENDL;
break;
} }
} }
@ -779,27 +887,13 @@ void FSFloaterPoser::onPoseMenuAction(const LLSD& param)
setSavePosesButtonText(!mPoserAnimator.allBaseRotationsAreZero(avatar)); setSavePosesButtonText(!mPoserAnimator.allBaseRotationsAreZero(avatar));
} }
bool FSFloaterPoser::notDoubleClicked()
{
auto timeIntervalSinceLastExecution = std::chrono::system_clock::now() - mTimeLastExecutedDoubleClickMethod;
mTimeLastExecutedDoubleClickMethod = std::chrono::system_clock::now();
return timeIntervalSinceLastExecution > mDoubleClickInterval;
}
void FSFloaterPoser::onClickLoadLeftHandPose() void FSFloaterPoser::onClickLoadLeftHandPose()
{ {
if (notDoubleClicked())
return;
onClickLoadHandPose(false); onClickLoadHandPose(false);
} }
void FSFloaterPoser::onClickLoadRightHandPose() void FSFloaterPoser::onClickLoadRightHandPose()
{ {
if (notDoubleClicked())
return;
onClickLoadHandPose(true); onClickLoadHandPose(true);
} }
@ -1295,19 +1389,15 @@ void FSFloaterPoser::onUndoLastChange()
mPoserAnimator.undoLastJointChange(avatar, *item, getUiSelectedBoneDeflectionStyle()); mPoserAnimator.undoLastJointChange(avatar, *item, getUiSelectedBoneDeflectionStyle());
} }
enableOrDisableRedoButton(); enableOrDisableRedoAndUndoButton();
refreshRotationSlidersAndSpinners(); refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
refreshPositionSlidersAndSpinners(); refreshPositionSlidersAndSpinners();
refreshAvatarPositionSlidersAndSpinners();
refreshScaleSlidersAndSpinners(); refreshScaleSlidersAndSpinners();
refreshTrackpadCursor();
} }
void FSFloaterPoser::onSetAvatarToTpose() void FSFloaterPoser::onSetAvatarToTpose()
{ {
if (notDoubleClicked())
return;
LLVOAvatar* avatar = getUiSelectedAvatar(); LLVOAvatar* avatar = getUiSelectedAvatar();
if (!avatar) if (!avatar)
return; return;
@ -1315,13 +1405,11 @@ void FSFloaterPoser::onSetAvatarToTpose()
setSavePosesButtonText(false); setSavePosesButtonText(false);
mPoserAnimator.setAllAvatarStartingRotationsToZero(avatar); mPoserAnimator.setAllAvatarStartingRotationsToZero(avatar);
refreshTextHighlightingOnJointScrollLists(); refreshTextHighlightingOnJointScrollLists();
enableOrDisableRedoAndUndoButton();
} }
void FSFloaterPoser::onResetJoint(const LLSD data) void FSFloaterPoser::onResetJoint(const LLSD data)
{ {
if (notDoubleClicked())
return;
int resetType = data.asInteger(); int resetType = data.asInteger();
LLVOAvatar* avatar = getUiSelectedAvatar(); LLVOAvatar* avatar = getUiSelectedAvatar();
@ -1345,10 +1433,10 @@ void FSFloaterPoser::onResetJoint(const LLSD data)
} }
refreshRotationSlidersAndSpinners(); refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
refreshAvatarPositionSlidersAndSpinners();
refreshPositionSlidersAndSpinners(); refreshPositionSlidersAndSpinners();
refreshScaleSlidersAndSpinners(); refreshScaleSlidersAndSpinners();
refreshTrackpadCursor();
enableOrDisableRedoAndUndoButton();
} }
void FSFloaterPoser::onRedoLastChange() void FSFloaterPoser::onRedoLastChange()
@ -1371,16 +1459,18 @@ void FSFloaterPoser::onRedoLastChange()
mPoserAnimator.redoLastJointChange(avatar, *item, getUiSelectedBoneDeflectionStyle()); mPoserAnimator.redoLastJointChange(avatar, *item, getUiSelectedBoneDeflectionStyle());
} }
enableOrDisableRedoButton(); enableOrDisableRedoAndUndoButton();
refreshRotationSlidersAndSpinners(); refreshRotationSlidersAndSpinners();
refreshTrackpadCursor(); refreshTrackpadCursor();
refreshScaleSlidersAndSpinners(); refreshScaleSlidersAndSpinners();
refreshPositionSlidersAndSpinners(); refreshPositionSlidersAndSpinners();
refreshAvatarPositionSlidersAndSpinners();
} }
void FSFloaterPoser::enableOrDisableRedoButton() void FSFloaterPoser::enableOrDisableRedoAndUndoButton()
{ {
mRedoChangeBtn->setEnabled(false);
mUndoChangeBtn->setEnabled(false);
LLVOAvatar* avatar = getUiSelectedAvatar(); LLVOAvatar* avatar = getUiSelectedAvatar();
if (!avatar) if (!avatar)
return; return;
@ -1393,14 +1483,20 @@ void FSFloaterPoser::enableOrDisableRedoButton()
return; return;
bool shouldEnableRedoButton = false; bool shouldEnableRedoButton = false;
bool shouldEnableUndoButton = false;
for (auto item : selectedJoints) for (auto item : selectedJoints)
{ {
bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item);
if (currentlyPosing) if (!currentlyPosing)
shouldEnableRedoButton |= mPoserAnimator.canRedoJointChange(avatar, *item); continue;
shouldEnableRedoButton |= mPoserAnimator.canRedoOrUndoJointChange(avatar, *item);
shouldEnableUndoButton |= mPoserAnimator.canRedoOrUndoJointChange(avatar, *item, true);
} }
mRedoChangeBtn->setEnabled(shouldEnableRedoButton); mRedoChangeBtn->setEnabled(shouldEnableRedoButton);
mUndoChangeBtn->setEnabled(shouldEnableUndoButton);
} }
void FSFloaterPoser::onToggleVisualManipulators() void FSFloaterPoser::onToggleVisualManipulators()
@ -1504,6 +1600,7 @@ LLScrollListCtrl* FSFloaterPoser::getScrollListForTab(LLPanel * tabPanel) const
LL_WARNS() << "Unknown tab panel: " << tabPanel << LL_ENDL; LL_WARNS() << "Unknown tab panel: " << tabPanel << LL_ENDL;
return nullptr; return nullptr;
} }
std::vector<FSPoserAnimator::FSPoserJoint*> FSFloaterPoser::getUiSelectedPoserJoints() const std::vector<FSPoserAnimator::FSPoserJoint*> FSFloaterPoser::getUiSelectedPoserJoints() const
{ {
std::vector<FSPoserAnimator::FSPoserJoint*> joints; std::vector<FSPoserAnimator::FSPoserJoint*> joints;
@ -1542,21 +1639,23 @@ std::vector<FSPoserAnimator::FSPoserJoint*> FSFloaterPoser::getUiSelectedPoserJo
joints.push_back(userData); joints.push_back(userData);
} }
} }
auto avatarp = getUiSelectedAvatar();
if (avatarp) updateManipWithFirstSelectedJoint(joints);
{
if(joints.size() >= 1)
{
FSToolCompPose::getInstance()->setJoint( gAgentAvatarp->getJoint( JointKey::construct(joints[0]->jointName())) );
}
else
{
FSToolCompPose::getInstance()->setJoint( nullptr );
}
}
return joints; return joints;
} }
void FSFloaterPoser::updateManipWithFirstSelectedJoint(std::vector<FSPoserAnimator::FSPoserJoint*> joints)
{
if (!gAgentAvatarp || gAgentAvatarp.isNull())
return;
if (joints.size() >= 1)
FSToolCompPose::getInstance()->setJoint(gAgentAvatarp->getJoint(JointKey::construct(joints[0]->jointName())));
else
FSToolCompPose::getInstance()->setJoint(nullptr);
}
E_RotationStyle FSFloaterPoser::getUiSelectedBoneRotationStyle(const std::string& jointName) const E_RotationStyle FSFloaterPoser::getUiSelectedBoneRotationStyle(const std::string& jointName) const
{ {
if (jointName.empty()) if (jointName.empty())
@ -1663,130 +1762,100 @@ LLVOAvatar* FSFloaterPoser::getAvatarByUuid(const LLUUID& avatarToFind) const
return nullptr; return nullptr;
} }
void FSFloaterPoser::onAdvancedPositionSet() void FSFloaterPoser::onPositionSet()
{ {
F32 posX = mAdvPosXSlider->getValueF32(); F32 posX = (F32)mAdvPosXSpnr->getValue().asReal();
F32 posY = mAdvPosYSlider->getValueF32(); F32 posY = (F32)mAdvPosYSpnr->getValue().asReal();
F32 posZ = mAdvPosZSlider->getValueF32(); F32 posZ = (F32)mAdvPosZSpnr->getValue().asReal();
mAdvPosXSpnr->setValue(posX);
mInOutSpnr->setValue(posX); mInOutSpnr->setValue(posX);
mAdvPosYSpnr->setValue(posY);
mLeftRightSpnr->setValue(posY); mLeftRightSpnr->setValue(posY);
mAdvPosZSpnr->setValue(posZ);
mUpDownSpnr->setValue(posZ);
setSelectedJointsPosition(posX, posY, posZ);
refreshAvatarPositionSlidersAndSpinners();
}
void FSFloaterPoser::onAdvancedScaleSet()
{
F32 scX = mAdvScaleXSlider->getValueF32();
F32 scY = mAdvScaleYSlider->getValueF32();
F32 scZ = mAdvScaleZSlider->getValueF32();
mScaleXSpnr->setValue(scX);
mScaleYSpnr->setValue(scY);
mScaleZSpnr->setValue(scZ);
setSelectedJointsScale(scX, scY, scZ);
}
void FSFloaterPoser::onAvatarPositionSet()
{
F32 posX = mPosXSlider->getValueF32();
F32 posY = mPosYSlider->getValueF32();
F32 posZ = mPosZSlider->getValueF32();
mAdvPosXSpnr->setValue(posX);
mInOutSpnr->setValue(posX);
mAdvPosYSpnr->setValue(posY);
mLeftRightSpnr->setValue(posY);
mAdvPosZSpnr->setValue(posZ);
mUpDownSpnr->setValue(posZ); mUpDownSpnr->setValue(posZ);
mAdvPosXSlider->setValue(posX);
mAdvPosYSlider->setValue(posY);
mAdvPosZSlider->setValue(posZ);
mPosXSlider->setValue(posX);
mPosYSlider->setValue(posY);
mPosZSlider->setValue(posZ);
setSelectedJointsPosition(posX, posY, posZ); setSelectedJointsPosition(posX, posY, posZ);
refreshPositionSlidersAndSpinners(); refreshPositionSlidersAndSpinners();
enableOrDisableRedoAndUndoButton();
} }
void FSFloaterPoser::onLimbTrackballChanged() void FSFloaterPoser::onScaleSet()
{ {
LLVector3 trackPadPos, trackPadDeltaPos; F32 scX = (F32)mScaleXSpnr->getValue().asReal();
LLSD position = mAvatarTrackball->getValue(); F32 scY = (F32)mScaleYSpnr->getValue().asReal();
F32 scZ = (F32)mScaleZSpnr->getValue().asReal();
mAdvScaleXSlider->setValue(scX);
mAdvScaleYSlider->setValue(scY);
mAdvScaleZSlider->setValue(scZ);
setSelectedJointsScale(scX, scY, scZ);
refreshScaleSlidersAndSpinners();
enableOrDisableRedoAndUndoButton();
}
void FSFloaterPoser::onTrackballChanged()
{
LLVector3 trackPadDeltaPos;
LLSD deltaPosition = mAvatarTrackball->getValueDelta(); LLSD deltaPosition = mAvatarTrackball->getValueDelta();
if (position.isArray() && position.size() == 3 && deltaPosition.isArray() && deltaPosition.size() == 3) if (deltaPosition.isArray() && deltaPosition.size() == 3)
{
trackPadPos.setValue(position);
trackPadDeltaPos.setValue(deltaPosition); trackPadDeltaPos.setValue(deltaPosition);
}
else else
return; return;
F32 trackPadSensitivity = llmax(gSavedSettings.getF32(POSER_TRACKPAD_SENSITIVITY_SAVE_KEY), 0.0001f); F32 trackPadSensitivity = llmax(gSavedSettings.getF32(POSER_TRACKPAD_SENSITIVITY_SAVE_KEY), 0.0001f);
trackPadPos.mV[VX] *= trackPadSensitivity; trackPadDeltaPos[VX] *= NormalTrackpadRangeInRads * trackPadSensitivity * RAD_TO_DEG;
trackPadPos.mV[VY] *= trackPadSensitivity; trackPadDeltaPos[VY] *= NormalTrackpadRangeInRads * trackPadSensitivity * RAD_TO_DEG;
trackPadDeltaPos[VZ] *= NormalTrackpadRangeInRads * RAD_TO_DEG;
trackPadPos.mV[VX] = unWrapScale(trackPadPos.mV[VX]) * NormalTrackpadRangeInRads; F32 axis1 = clipRange((F32)mYawSpnr->getValue().asReal() + trackPadDeltaPos[VX]);
trackPadPos.mV[VY] = unWrapScale(trackPadPos.mV[VY]) * NormalTrackpadRangeInRads; F32 axis2 = (F32)mPitchSpnr->getValue().asReal() + trackPadDeltaPos[VY];
trackPadPos.mV[VZ] = unWrapScale(trackPadPos.mV[VZ]) * NormalTrackpadRangeInRads; F32 axis3 = (F32)mRollSpnr->getValue().asReal() + trackPadDeltaPos[VZ];
trackPadDeltaPos[VX] *= NormalTrackpadRangeInRads * trackPadSensitivity; mYawSpnr->setValue(axis1);
trackPadDeltaPos[VY] *= NormalTrackpadRangeInRads * trackPadSensitivity; mPitchSpnr->setValue(axis2);
trackPadDeltaPos[VZ] *= NormalTrackpadRangeInRads; mRollSpnr->setValue(axis3);
setSelectedJointsRotation(trackPadPos, trackPadDeltaPos); onYawPitchRollChanged(true);
// WARNING!
// as tempting as it is to refactor the following to refreshRotationSliders(), don't.
// getRotationOfFirstSelectedJoint/setSelectedJointsRotation are
// not necessarily symmetric functions (see their remarks).
mYawSpnr->setValue(trackPadPos.mV[VX] *= RAD_TO_DEG);
mPitchSpnr->setValue(trackPadPos.mV[VY] *= RAD_TO_DEG);
mRollSpnr->setValue(trackPadPos.mV[VZ] *= RAD_TO_DEG);
} }
F32 FSFloaterPoser::unWrapScale(F32 scale) F32 FSFloaterPoser::clipRange(F32 value)
{ {
if (scale > -1.f && scale < 1.f) F32 result = fmodf(value, 3600.f); // to avoid time consuming while loops
return scale; while (result > 180.f)
result -= 360.f;
F32 result = fmodf(scale, 100.f); // to avoid time consuming while loops while (result < -180.f)
while (result > 1) result += 360.f;
result -= 2;
while (result < -1)
result += 2;
return result; return result;
} }
void FSFloaterPoser::onYawPitchRollChanged() void FSFloaterPoser::onYawPitchRollChanged(bool skipUpdateTrackpad)
{ {
LLVector3 absoluteRotation, deltaRotation; LLVector3 absoluteRotation, deltaRotation;
absoluteRotation.mV[VX] = (F32)mYawSpnr->getValue().asReal() * DEG_TO_RAD; absoluteRotation.mV[VX] = (F32)mYawSpnr->getValue().asReal();
absoluteRotation.mV[VY] = (F32)mPitchSpnr->getValue().asReal() * DEG_TO_RAD; absoluteRotation.mV[VY] = (F32)mPitchSpnr->getValue().asReal();
absoluteRotation.mV[VZ] = (F32)mRollSpnr->getValue().asReal() * DEG_TO_RAD; absoluteRotation.mV[VZ] = (F32)mRollSpnr->getValue().asReal();
mAdvRotXSlider->setValue(absoluteRotation.mV[VY]);
mAdvRotYSlider->setValue(absoluteRotation.mV[VX]);
mAdvRotZSlider->setValue(absoluteRotation.mV[VZ]);
absoluteRotation *= DEG_TO_RAD;
deltaRotation = absoluteRotation - mLastSliderRotation; deltaRotation = absoluteRotation - mLastSliderRotation;
mLastSliderRotation = absoluteRotation; mLastSliderRotation = absoluteRotation;
setSelectedJointsRotation(absoluteRotation, deltaRotation); setSelectedJointsRotation(absoluteRotation, deltaRotation);
enableOrDisableRedoAndUndoButton();
// WARNING! if (!skipUpdateTrackpad)
// as tempting as it is to refactor the following to refreshTrackpadCursor(), don't. refreshTrackpadCursor();
// getRotationOfFirstSelectedJoint/setSelectedJointsRotation are
// not necessarily symmetric functions (see their remarks).
F32 trackPadSensitivity = llmax(gSavedSettings.getF32(POSER_TRACKPAD_SENSITIVITY_SAVE_KEY), 0.0001f);
absoluteRotation.mV[VX] /= trackPadSensitivity;
absoluteRotation.mV[VY] /= trackPadSensitivity;
absoluteRotation.mV[VX] /= NormalTrackpadRangeInRads;
absoluteRotation.mV[VY] /= NormalTrackpadRangeInRads;
absoluteRotation.mV[VZ] /= NormalTrackpadRangeInRads;
mAvatarTrackball->setValue(absoluteRotation.getValue());
} }
void FSFloaterPoser::onAdjustTrackpadSensitivity() void FSFloaterPoser::onAdjustTrackpadSensitivity()
@ -1796,38 +1865,14 @@ void FSFloaterPoser::onAdjustTrackpadSensitivity()
void FSFloaterPoser::refreshTrackpadCursor() void FSFloaterPoser::refreshTrackpadCursor()
{ {
F32 axis1 = (F32)mYawSpnr->getValue().asReal() * DEG_TO_RAD / NormalTrackpadRangeInRads; F32 trackPadSensitivity = llmax(gSavedSettings.getF32(POSER_TRACKPAD_SENSITIVITY_SAVE_KEY), 0.0001f);
F32 axis2 = (F32)mPitchSpnr->getValue().asReal() * DEG_TO_RAD / NormalTrackpadRangeInRads; F32 axis1 = (F32)mYawSpnr->getValue().asReal() * DEG_TO_RAD / NormalTrackpadRangeInRads / trackPadSensitivity;
F32 axis2 = (F32)mPitchSpnr->getValue().asReal() * DEG_TO_RAD / NormalTrackpadRangeInRads / trackPadSensitivity;
F32 axis3 = (F32)mRollSpnr->getValue().asReal() * DEG_TO_RAD / NormalTrackpadRangeInRads; F32 axis3 = (F32)mRollSpnr->getValue().asReal() * DEG_TO_RAD / NormalTrackpadRangeInRads;
F32 trackPadSensitivity = llmax(gSavedSettings.getF32(POSER_TRACKPAD_SENSITIVITY_SAVE_KEY), 0.0001f);
axis1 /= trackPadSensitivity;
axis2 /= trackPadSensitivity;
mAvatarTrackball->setValue(axis1, axis2, axis3); mAvatarTrackball->setValue(axis1, axis2, axis3);
} }
/// <summary>
/// This only sets the position sliders of the 'basic' view (not the advanced sliders).
/// </summary>
void FSFloaterPoser::refreshAvatarPositionSlidersAndSpinners()
{
auto activeTab = mJointsTabs->getCurrentPanel();
if (!activeTab)
return;
if (activeTab != mPositionRotationPnl)
return; // if the active tab isn't the av position one, don't set anything.
LLVector3 position = getPositionOfFirstSelectedJoint();
mPosXSlider->setValue(position.mV[VX]);
mInOutSpnr->setValue(position.mV[VX]);
mPosYSlider->setValue(position.mV[VY]);
mLeftRightSpnr->setValue(position.mV[VY]);
mPosZSlider->setValue(position.mV[VZ]);
mUpDownSpnr->setValue(position.mV[VZ]);
}
void FSFloaterPoser::refreshRotationSlidersAndSpinners() void FSFloaterPoser::refreshRotationSlidersAndSpinners()
{ {
LLVector3 rotation = getRotationOfFirstSelectedJoint(); LLVector3 rotation = getRotationOfFirstSelectedJoint();
@ -1836,6 +1881,9 @@ void FSFloaterPoser::refreshRotationSlidersAndSpinners()
mYawSpnr->setValue(rotation.mV[VX] *= RAD_TO_DEG); mYawSpnr->setValue(rotation.mV[VX] *= RAD_TO_DEG);
mPitchSpnr->setValue(rotation.mV[VY] *= RAD_TO_DEG); mPitchSpnr->setValue(rotation.mV[VY] *= RAD_TO_DEG);
mRollSpnr->setValue(rotation.mV[VZ] *= RAD_TO_DEG); mRollSpnr->setValue(rotation.mV[VZ] *= RAD_TO_DEG);
mAdvRotXSlider->setValue(rotation.mV[VY]);
mAdvRotYSlider->setValue(rotation.mV[VX]);
mAdvRotZSlider->setValue(rotation.mV[VZ]);
} }
void FSFloaterPoser::refreshPositionSlidersAndSpinners() void FSFloaterPoser::refreshPositionSlidersAndSpinners()
@ -1848,6 +1896,20 @@ void FSFloaterPoser::refreshPositionSlidersAndSpinners()
mAdvPosYSpnr->setValue(position.mV[VY]); mAdvPosYSpnr->setValue(position.mV[VY]);
mAdvPosZSlider->setValue(position.mV[VZ]); mAdvPosZSlider->setValue(position.mV[VZ]);
mAdvPosZSpnr->setValue(position.mV[VZ]); mAdvPosZSpnr->setValue(position.mV[VZ]);
auto activeTab = mJointsTabs->getCurrentPanel();
if (!activeTab)
return;
if (activeTab != mPositionRotationPnl)
return; // if the active tab isn't the av position one, don't set anything.
mPosXSlider->setValue(position.mV[VX]);
mInOutSpnr->setValue(position.mV[VX]);
mPosYSlider->setValue(position.mV[VY]);
mLeftRightSpnr->setValue(position.mV[VY]);
mPosZSlider->setValue(position.mV[VZ]);
mUpDownSpnr->setValue(position.mV[VZ]);
} }
void FSFloaterPoser::refreshScaleSlidersAndSpinners() void FSFloaterPoser::refreshScaleSlidersAndSpinners()
@ -2003,11 +2065,10 @@ LLVector3 FSFloaterPoser::getScaleOfFirstSelectedJoint() const
void FSFloaterPoser::onJointTabSelect() void FSFloaterPoser::onJointTabSelect()
{ {
refreshAvatarPositionSlidersAndSpinners(); refreshPositionSlidersAndSpinners();
refreshRotationSlidersAndSpinners(); refreshRotationSlidersAndSpinners();
refreshTrackpadCursor(); refreshTrackpadCursor();
enableOrDisableRedoButton(); enableOrDisableRedoAndUndoButton();
refreshPositionSlidersAndSpinners();
refreshScaleSlidersAndSpinners(); refreshScaleSlidersAndSpinners();
onClickSetBaseRotZero(); onClickSetBaseRotZero();
} }
@ -2276,7 +2337,8 @@ void FSFloaterPoser::refreshTextHighlightingOnJointScrollLists()
void FSFloaterPoser::setSavePosesButtonText(bool setAsSaveDiff) void FSFloaterPoser::setSavePosesButtonText(bool setAsSaveDiff)
{ {
setAsSaveDiff ? mSavePosesBtn->setLabel("Save Diff") : mSavePosesBtn->setLabel("Save Pose"); if (hasString("SavePoseLabel") && hasString("SaveDiffLabel"))
setAsSaveDiff ? mSavePosesBtn->setLabel(getString("SaveDiffLabel")) : mSavePosesBtn->setLabel(getString("SavePoseLabel"));
} }
void FSFloaterPoser::addBoldToScrollList(LLScrollListCtrl* list, LLVOAvatar* avatar) void FSFloaterPoser::addBoldToScrollList(LLScrollListCtrl* list, LLVOAvatar* avatar)
@ -2571,8 +2633,8 @@ S32 FSFloaterPoser::getBvhJointNegation(const std::string& jointName) const
return result; return result;
} }
bool FSFloaterPoser::getWhetherToResetBaseRotationOnEdit() { return gSavedSettings.getBOOL(POSER_RESETBASEROTONEDIT_SAVE_KEY); } bool FSFloaterPoser::getWhetherToResetBaseRotationOnEdit() { return gSavedSettings.getBOOL(POSER_RESETBASEROTONEDIT_SAVE_KEY); }
void FSFloaterPoser::onClickSetBaseRotZero() { mAlsoSaveBvhCbx->setEnabled(getWhetherToResetBaseRotationOnEdit()); } void FSFloaterPoser::onClickSetBaseRotZero() { mAlsoSaveBvhCbx->setEnabled(getWhetherToResetBaseRotationOnEdit()); }
bool FSFloaterPoser::getSavingToBvh() bool FSFloaterPoser::getSavingToBvh()

View File

@ -79,7 +79,7 @@ class FSFloaterPoser : public LLFloater, public LLEditMenuHandler
friend class LLFloaterReg; friend class LLFloaterReg;
FSFloaterPoser(const LLSD &key); FSFloaterPoser(const LLSD &key);
public: public:
void updatePosedBones(); void updatePosedBones(const std::string& jointName);
void selectJointByName(const std::string& jointName); void selectJointByName(const std::string& jointName);
void undo() override { onUndoLastChange(); }; void undo() override { onUndoLastChange(); };
bool canUndo() const override { return true; } bool canUndo() const override { return true; }
@ -132,6 +132,12 @@ public:
/// <returns>The selected joints</returns> /// <returns>The selected joints</returns>
std::vector<FSPoserAnimator::FSPoserJoint*> getUiSelectedPoserJoints() const; std::vector<FSPoserAnimator::FSPoserJoint*> getUiSelectedPoserJoints() const;
/// <summary>
/// Updates the visual with the first selected joint from the supplied collection, if any.
/// </summary>
/// <param name="joints">The collection of selected joints.</param>
static void updateManipWithFirstSelectedJoint(std::vector<FSPoserAnimator::FSPoserJoint*> joints);
/// <summary> /// <summary>
/// Gets a detectable avatar by its UUID. /// Gets a detectable avatar by its UUID.
/// </summary> /// </summary>
@ -214,6 +220,7 @@ public:
void createUserPoseDirectoryIfNeeded(); void createUserPoseDirectoryIfNeeded();
void onToggleLoadSavePanel(); void onToggleLoadSavePanel();
void onClickPoseSave(); void onClickPoseSave();
void onMouseLeaveSavePoseBtn();
void onPoseFileSelect(); void onPoseFileSelect();
bool savePoseToXml(LLVOAvatar* avatar, const std::string& posePath); bool savePoseToXml(LLVOAvatar* avatar, const std::string& posePath);
bool savePoseToBvh(LLVOAvatar* avatar, const std::string& posePath); bool savePoseToBvh(LLVOAvatar* avatar, const std::string& posePath);
@ -223,11 +230,14 @@ public:
bool poseFileStartsFromTeePose(const std::string& poseFileName); bool poseFileStartsFromTeePose(const std::string& poseFileName);
void setPoseSaveFileTextBoxToUiSelectedAvatarSaveFileName(); void setPoseSaveFileTextBoxToUiSelectedAvatarSaveFileName();
void setUiSelectedAvatarSaveFileName(const std::string& saveFileName); void setUiSelectedAvatarSaveFileName(const std::string& saveFileName);
bool confirmFileOverwrite(std::string fileName);
void startPosingSelf();
void stopPosingAllAvatars();
// visual manipulators control // visual manipulators control
void enableVisualManipulators(); void enableVisualManipulators();
void disableVisualManipulators(); void disableVisualManipulators();
// UI Event Handlers: // UI Event Handlers
void onAvatarsRefresh(); void onAvatarsRefresh();
void onAvatarSelect(); void onAvatarSelect();
void onJointTabSelect(); void onJointTabSelect();
@ -239,15 +249,11 @@ public:
void onRedoLastChange(); void onRedoLastChange();
void onResetJoint(const LLSD data); void onResetJoint(const LLSD data);
void onSetAvatarToTpose(); void onSetAvatarToTpose();
void enableOrDisableRedoButton();
void onPoseStartStop(); void onPoseStartStop();
void startPosingSelf(); void onTrackballChanged();
void stopPosingAllAvatars(); void onYawPitchRollChanged(bool skipUpdateTrackpad = false);
void onLimbTrackballChanged(); void onPositionSet();
void onYawPitchRollChanged(); void onScaleSet();
void onAvatarPositionSet();
void onAdvancedPositionSet();
void onAdvancedScaleSet();
void onClickToggleSelectedBoneEnabled(); void onClickToggleSelectedBoneEnabled();
void onClickRecaptureSelectedBones(); void onClickRecaptureSelectedBones();
void onClickFlipPose(); void onClickFlipPose();
@ -257,15 +263,16 @@ public:
void onClickLoadRightHandPose(); void onClickLoadRightHandPose();
void onClickLoadHandPose(bool isRightHand); void onClickLoadHandPose(bool isRightHand);
void onClickSetBaseRotZero(); void onClickSetBaseRotZero();
void onCommitSpinner(LLUICtrl* spinner, S32 ID); void onCommitSpinner(const LLUICtrl* spinner, const S32 ID);
void onClickSymmetrize(S32 ID); void onCommitSlider(const LLUICtrl* slider, const S32 id);
void onClickSymmetrize(const S32 ID);
// UI Refreshments // UI Refreshments
void refreshRotationSlidersAndSpinners(); void refreshRotationSlidersAndSpinners();
void refreshAvatarPositionSlidersAndSpinners();
void refreshTrackpadCursor();
void refreshPositionSlidersAndSpinners(); void refreshPositionSlidersAndSpinners();
void refreshScaleSlidersAndSpinners(); void refreshScaleSlidersAndSpinners();
void refreshTrackpadCursor();
void enableOrDisableRedoAndUndoButton();
/// <summary> /// <summary>
/// Determines if we have permission to animate the supplied avatar. /// Determines if we have permission to animate the supplied avatar.
@ -341,12 +348,6 @@ public:
/// <param name="avatar">The avatar to whom the list is relevant.</param> /// <param name="avatar">The avatar to whom the list is relevant.</param>
void addBoldToScrollList(LLScrollListCtrl* list, LLVOAvatar* avatar); void addBoldToScrollList(LLScrollListCtrl* list, LLVOAvatar* avatar);
/// <summary>
/// Determines if the user has run this method twice within mDoubleClickInterval.
/// </summary>
/// <returns>true if this method has executed since mDoubleClickInterval seconds ago, otherwise false.</returns>
bool notDoubleClicked();
/// <summary> /// <summary>
/// Gets whether the user wishes to reset the base-rotation to zero when they start editing a joint. /// Gets whether the user wishes to reset the base-rotation to zero when they start editing a joint.
/// </summary> /// </summary>
@ -426,26 +427,15 @@ public:
std::string static vec3ToXYZString(const LLVector3& val); std::string static vec3ToXYZString(const LLVector3& val);
/// <summary> /// <summary>
/// The time when the last click of a button was made. /// Performs an angle module of the supplied value to between -180 & 180 (degrees).
/// Utilized for controls needing a 'double click do' function.
/// </summary> /// </summary>
std::chrono::system_clock::time_point mTimeLastExecutedDoubleClickMethod = std::chrono::system_clock::now(); /// <param name="value">The value to modulo.</param>
/// <returns>The modulo value.</returns>
/// <summary>
/// The constant time interval, in seconds, a user must execute the notDoubleClicked twice to successfully 'double-click' a button.
/// </summary>
std::chrono::duration<double> const mDoubleClickInterval = std::chrono::duration<double>(0.3);
/// <summary>
/// Unwraps a normalized value from the trackball to a slider value.
/// </summary>
/// <param name="scale">The scale value from the trackball.</param>
/// <returns>A value appropriate for fitting a slider.</returns>
/// <remarks> /// <remarks>
/// If the trackpad is in 'infinite scroll' mode, it can produce normalized-values outside the range of the sliders. /// If the trackpad is in 'infinite scroll' mode, it can produce normalized-values outside the range of the spinners.
/// This method ensures whatever value the trackpad produces, they work with the sliders. /// This method ensures whatever value the trackpad produces, they work with the spinners.
/// </remarks> /// </remarks>
static F32 unWrapScale(F32 scale); static F32 clipRange(F32 value);
LLToolset* mLastToolset{ nullptr }; LLToolset* mLastToolset{ nullptr };
LLTool* mJointRotTool{ nullptr }; LLTool* mJointRotTool{ nullptr };
@ -458,6 +448,9 @@ public:
LLSliderCtrl* mPosXSlider{ nullptr }; LLSliderCtrl* mPosXSlider{ nullptr };
LLSliderCtrl* mPosYSlider{ nullptr }; LLSliderCtrl* mPosYSlider{ nullptr };
LLSliderCtrl* mPosZSlider{ nullptr }; LLSliderCtrl* mPosZSlider{ nullptr };
LLSliderCtrl* mAdvRotXSlider{ nullptr };
LLSliderCtrl* mAdvRotYSlider{ nullptr };
LLSliderCtrl* mAdvRotZSlider{ nullptr };
LLSliderCtrl* mAdvPosXSlider{ nullptr }; LLSliderCtrl* mAdvPosXSlider{ nullptr };
LLSliderCtrl* mAdvPosYSlider{ nullptr }; LLSliderCtrl* mAdvPosYSlider{ nullptr };
LLSliderCtrl* mAdvPosZSlider{ nullptr }; LLSliderCtrl* mAdvPosZSlider{ nullptr };
@ -492,6 +485,7 @@ public:
LLButton* mToggleSympatheticRotationBtn{ nullptr }; LLButton* mToggleSympatheticRotationBtn{ nullptr };
LLButton* mToggleDeltaModeBtn{ nullptr }; LLButton* mToggleDeltaModeBtn{ nullptr };
LLButton* mRedoChangeBtn{ nullptr }; LLButton* mRedoChangeBtn{ nullptr };
LLButton* mUndoChangeBtn{ nullptr };
LLButton* mSetToTposeButton{ nullptr }; LLButton* mSetToTposeButton{ nullptr };
LLButton* mBtnJointRotate{ nullptr }; LLButton* mBtnJointRotate{ nullptr };

View File

@ -144,21 +144,15 @@ void FSJointPose::recaptureJoint()
addStateToUndo(FSJointState(mCurrentState)); addStateToUndo(FSJointState(mCurrentState));
mCurrentState = FSJointState(joint); mCurrentState = FSJointState(joint);
} }
void FSJointPose::recaptureJointAsDelta() void FSJointPose::recaptureJointAsDelta()
{ {
if (mIsCollisionVolume)
{
return;
}
LLJoint* joint = mJointState->getJoint(); LLJoint* joint = mJointState->getJoint();
if (!joint) if (!joint)
{
return; return;
}
addStateToUndo(mCurrentState); addStateToUndo(FSJointState(mCurrentState));
mCurrentState = FSJointState(joint); mCurrentState.updateFromJoint(joint);
} }
void FSJointPose::swapRotationWith(FSJointPose* oppositeJoint) void FSJointPose::swapRotationWith(FSJointPose* oppositeJoint)
@ -209,6 +203,9 @@ void FSJointPose::zeroBaseRotation()
if (mIsCollisionVolume) if (mIsCollisionVolume)
return; return;
if (!isBaseRotationZero())
purgeUndoQueue();
mCurrentState.zeroBaseRotation(); mCurrentState.zeroBaseRotation();
} }
@ -219,3 +216,22 @@ bool FSJointPose::isBaseRotationZero() const
return mCurrentState.baseRotationIsZero(); return mCurrentState.baseRotationIsZero();
} }
void FSJointPose::purgeUndoQueue()
{
mUndoneJointStatesIndex = 0;
mLastSetJointStates.clear();
}
bool FSJointPose::canPerformUndo() const
{
switch (mLastSetJointStates.size())
{
case 0: // nothing to undo
return false;
case 1: // there is only one change
return true;
default: // current state is not the bottom of the deque
return mUndoneJointStatesIndex != (mLastSetJointStates.size() - 1);
}
}

View File

@ -108,6 +108,12 @@ class FSJointPose
/// <returns>True if the represented joint is zero, otherwise false.</returns> /// <returns>True if the represented joint is zero, otherwise false.</returns>
bool isBaseRotationZero() const; bool isBaseRotationZero() const;
/// <summary>
/// Gets whether an undo of this joint may be performed.
/// </summary>
/// <returns>true if the joint may have a undo applied, otherwise false.</returns>
bool canPerformUndo() const;
/// <summary> /// <summary>
/// Gets whether a redo of this joint may be performed. /// Gets whether a redo of this joint may be performed.
/// </summary> /// </summary>
@ -143,11 +149,16 @@ class FSJointPose
/// Resets the beginning properties of the joint this represents. /// Resets the beginning properties of the joint this represents.
/// </summary> /// </summary>
void recaptureJoint(); void recaptureJoint();
/// <summary> /// <summary>
/// Recalculates the delta reltive to the base for a new rotation. /// Recalculates the delta reltive to the base for a new rotation.
/// </summary> /// </summary>
void recaptureJointAsDelta(); void recaptureJointAsDelta();
/// <summary>
/// Clears the undo/redo deque.
/// </summary>
void purgeUndoQueue();
/// <summary> /// <summary>
/// Reverts the position/rotation/scale to their values when the animation begun. /// Reverts the position/rotation/scale to their values when the animation begun.
@ -186,7 +197,6 @@ class FSJointPose
mDeltaRotation = newRotation * inv_base; mDeltaRotation = newRotation * inv_base;
}; };
void reflectRotation() void reflectRotation()
{ {
mBaseRotation.mQ[VX] *= -1; mBaseRotation.mQ[VX] *= -1;
@ -215,6 +225,18 @@ class FSJointPose
joint->setScale(mBaseScale); joint->setScale(mBaseScale);
} }
void updateFromJoint(LLJoint* joint)
{
if (!joint)
return;
LLQuaternion invRot = mBaseRotation;
invRot.conjugate();
mRotation = joint->getRotation() * invRot;
mPosition.set(joint->getPosition() - mBasePosition);
mScale.set(joint->getScale() - mBaseScale);
}
private: private:
FSJointState(FSJointState* state) FSJointState(FSJointState* state)
{ {

View File

@ -1012,9 +1012,9 @@ bool FSManipRotateJoint::handleMouseUp(S32 x, S32 y, MASK mask)
if (hasMouseCapture()) if (hasMouseCapture())
{ {
// Update the UI, by causing it to read back the position of the selected joints and aply those relative to the base rot // Update the UI, by causing it to read back the position of the selected joints and aply those relative to the base rot
if (poser) if (poser && mJoint)
{ {
poser->updatePosedBones(); poser->updatePosedBones(mJoint->getName());
} }
// Release mouse // Release mouse

View File

@ -220,10 +220,10 @@ void getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo channel, F32&
// //
// local preview of material changes // local preview of material changes
class LLRenderMaterialFunctor : public LLSelectedTEFunctor class FSRenderMaterialFunctor : public LLSelectedTEFunctor
{ {
public: public:
LLRenderMaterialFunctor(const LLUUID &id) FSRenderMaterialFunctor(const LLUUID &id)
: mMatId(id) : mMatId(id)
{ {
} }
@ -243,21 +243,23 @@ private:
}; };
// //
// keep LLRenderMaterialOverrideFunctor in sync with llmaterialeditor.cpp just take // keep LLRenderMaterialOverrideFunctor in sync with llmaterialeditor.cpp just take out the
// out the reverting functionality as it makes no real sense with all the texture // reverting functionality of non texture and color related GLTF settings as it makes no
// controls visible for the material at all times. // real sense with all the texture controls visible for the material at all times.
// TODO: look at how to handle local textures, especially when saving materials // TODO: look at how to handle local textures, especially when saving materials
// - Would be nice if we had this in its own file so we could include it from both sides ... -Zi // - Would be nice if we had this in its own file so we could include it from both sides ... -Zi
// //
class LLRenderMaterialOverrideFunctor : public LLSelectedNodeFunctor class FSRenderMaterialOverrideFunctor : public LLSelectedNodeFunctor
{ {
public: public:
LLRenderMaterialOverrideFunctor( FSRenderMaterialOverrideFunctor(
LLGLTFMaterial* material_to_apply, LLGLTFMaterial* material_to_apply,
U32 unsaved_changes U32 unsaved_changes,
U32 reverted_changes
) )
: mMaterialToApply(material_to_apply) : mMaterialToApply(material_to_apply)
, mUnsavedChanges(unsaved_changes) , mUnsavedChanges(unsaved_changes)
, mRevertedChanges(reverted_changes)
{ {
} }
@ -314,12 +316,32 @@ public:
material = new LLGLTFMaterial(*material); material = new LLGLTFMaterial(*material);
} }
LLPointer<LLGLTFMaterial> revert_mat;
if (nodep->mSavedGLTFOverrideMaterials.size() > te)
{
if (nodep->mSavedGLTFOverrideMaterials[te].notNull())
{
revert_mat = nodep->mSavedGLTFOverrideMaterials[te];
}
else
{
// mSavedGLTFOverrideMaterials[te] being present but null
// means we need to use a default value
revert_mat = new LLGLTFMaterial();
}
}
// else can not revert at all
// Override object's values with values from editor where appropriate // Override object's values with values from editor where appropriate
if (mUnsavedChanges & MATERIAL_BASE_COLOR_DIRTY) if (mUnsavedChanges & MATERIAL_BASE_COLOR_DIRTY)
{ {
LL_DEBUGS("APPLY_GLTF_CHANGES") << "applying MATERIAL_BASE_COLOR_DIRTY" << LL_ENDL; LL_DEBUGS("APPLY_GLTF_CHANGES") << "applying MATERIAL_BASE_COLOR_DIRTY" << LL_ENDL;
material->setBaseColorFactor(mMaterialToApply->mBaseColor, true); material->setBaseColorFactor(mMaterialToApply->mBaseColor, true);
} }
else if ((mRevertedChanges & MATERIAL_BASE_COLOR_DIRTY) && revert_mat.notNull())
{
material->setBaseColorFactor(revert_mat->mBaseColor, false);
}
if (mUnsavedChanges & MATERIAL_BASE_COLOR_TEX_DIRTY) if (mUnsavedChanges & MATERIAL_BASE_COLOR_TEX_DIRTY)
{ {
@ -333,6 +355,17 @@ public:
} }
*/ */
} }
else if ((mRevertedChanges & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull())
{
material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false);
/*
LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY);
if (tracking_id.notNull())
{
LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
}
*/
}
if (mUnsavedChanges & MATERIAL_NORMAL_TEX_DIRTY) if (mUnsavedChanges & MATERIAL_NORMAL_TEX_DIRTY)
{ {
@ -346,6 +379,17 @@ public:
} }
*/ */
} }
else if ((mRevertedChanges & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull())
{
material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false);
/*
LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY);
if (tracking_id.notNull())
{
LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
}
*/
}
if (mUnsavedChanges & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) if (mUnsavedChanges & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)
{ {
@ -359,6 +403,17 @@ public:
} }
*/ */
} }
else if ((mRevertedChanges & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull())
{
material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false);
/*
LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
if (tracking_id.notNull())
{
LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
}
*/
}
if (mUnsavedChanges & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) if (mUnsavedChanges & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY)
{ {
@ -377,6 +432,10 @@ public:
LL_DEBUGS("APPLY_GLTF_CHANGES") << "applying MATERIAL_EMISIVE_COLOR_DIRTY" << LL_ENDL; LL_DEBUGS("APPLY_GLTF_CHANGES") << "applying MATERIAL_EMISIVE_COLOR_DIRTY" << LL_ENDL;
material->setEmissiveColorFactor(LLColor3(mMaterialToApply->mEmissiveColor), true); material->setEmissiveColorFactor(LLColor3(mMaterialToApply->mEmissiveColor), true);
} }
else if ((mRevertedChanges & MATERIAL_EMISIVE_COLOR_DIRTY) && revert_mat.notNull())
{
material->setEmissiveColorFactor(revert_mat->mEmissiveColor, false);
}
if (mUnsavedChanges & MATERIAL_EMISIVE_TEX_DIRTY) if (mUnsavedChanges & MATERIAL_EMISIVE_TEX_DIRTY)
{ {
@ -390,6 +449,17 @@ public:
} }
*/ */
} }
else if ((mRevertedChanges & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull())
{
material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false);
/*
LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY);
if (tracking_id.notNull())
{
LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
}
*/
}
if (mUnsavedChanges & MATERIAL_DOUBLE_SIDED_DIRTY) if (mUnsavedChanges & MATERIAL_DOUBLE_SIDED_DIRTY)
{ {
@ -418,6 +488,7 @@ public:
private: private:
LLGLTFMaterial* mMaterialToApply; LLGLTFMaterial* mMaterialToApply;
U32 mUnsavedChanges; U32 mUnsavedChanges;
U32 mRevertedChanges;
}; };
// //
@ -621,6 +692,7 @@ FSPanelFace::FSPanelFace() :
LLPanel(), LLPanel(),
mNeedMediaTitle(true), mNeedMediaTitle(true),
mUnsavedChanges(0), mUnsavedChanges(0),
mRevertedChanges(0),
mExcludeWater(false) mExcludeWater(false)
{ {
// register callbacks before buildFromFile() or they won't work! // register callbacks before buildFromFile() or they won't work!
@ -660,9 +732,6 @@ void FSPanelFace::onMatTabChange()
static S32 last_mat = -1; static S32 last_mat = -1;
if( auto curr_mat = getCurrentMaterialType(); curr_mat != last_mat ) if( auto curr_mat = getCurrentMaterialType(); curr_mat != last_mat )
{ {
// Fixes some UI desync
updateUI(true);
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
LLViewerObject* objectp = node ? node->getObject() : NULL; LLViewerObject* objectp = node ? node->getObject() : NULL;
if(objectp) if(objectp)
@ -688,6 +757,16 @@ void FSPanelFace::onMatTabChange()
} }
} }
} }
// Since we allow both PBR and BP textures to be applied at the same time,
// we need to hide or show the GLTF material only locally based on the current tab.
if (curr_mat != MATMEDIA_PBR)
LLSelectMgr::getInstance()->hideGLTFMaterial();
else
LLSelectMgr::getInstance()->showGLTFMaterial();
// Fixes some UI desync
updateUI(true);
} }
} }
@ -1092,7 +1171,7 @@ void FSPanelFace::draw()
// not sure if there isn't a better place for this, but for the time being this seems to work, // not sure if there isn't a better place for this, but for the time being this seems to work,
// and trying other places always failed in some way or other -Zi // and trying other places always failed in some way or other -Zi
static U64MicrosecondsImplicit next_update_time = 0LL; static U64MicrosecondsImplicit next_update_time = 0LL;
if (mUnsavedChanges && gFrameTime > next_update_time) if ((mUnsavedChanges || mRevertedChanges) && gFrameTime > next_update_time)
{ {
LL_DEBUGS("APPLY_GLTF_CHANGES") << "detected unsaved changes: " << mUnsavedChanges << LL_ENDL; LL_DEBUGS("APPLY_GLTF_CHANGES") << "detected unsaved changes: " << mUnsavedChanges << LL_ENDL;
@ -1100,12 +1179,13 @@ void FSPanelFace::draw()
getGLTFMaterial(mat); getGLTFMaterial(mat);
LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
LLRenderMaterialOverrideFunctor override_func(mat, mUnsavedChanges); FSRenderMaterialOverrideFunctor override_func(mat, mUnsavedChanges, mRevertedChanges);
selected_objects->applyToNodes(&override_func); selected_objects->applyToNodes(&override_func);
LLGLTFMaterialList::flushUpdates(); LLGLTFMaterialList::flushUpdates();
mUnsavedChanges = 0; mUnsavedChanges = 0;
mRevertedChanges = 0;
next_update_time = gFrameTime + 100000LL; // 100 ms next_update_time = gFrameTime + 100000LL; // 100 ms
@ -3790,12 +3870,114 @@ void FSPanelFace::updatePBROverrideDisplay()
void FSPanelFace::onCancelPbr(const LLUICtrl* map_ctrl) void FSPanelFace::onCancelPbr(const LLUICtrl* map_ctrl)
{ {
// TODO -Zi if (map_ctrl == mBaseTexturePBR)
{
mRevertedChanges |= MATERIAL_BASE_COLOR_TEX_DIRTY;
}
else if (map_ctrl == mNormalTexturePBR)
{
mRevertedChanges |= MATERIAL_NORMAL_TEX_DIRTY;
}
else if (map_ctrl == mEmissiveTexturePBR)
{
mRevertedChanges |= MATERIAL_EMISIVE_TEX_DIRTY;
}
else if (map_ctrl == mORMTexturePBR)
{
mRevertedChanges |= MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY;
}
else if (map_ctrl == mBaseTintPBR)
{
mRevertedChanges |= MATERIAL_BASE_COLOR_DIRTY;
}
else if (map_ctrl == mEmissiveTintPBR)
{
mRevertedChanges |= MATERIAL_EMISIVE_COLOR_DIRTY;
}
} }
void FSPanelFace::onSelectPbr(const LLUICtrl* map_ctrl) void FSPanelFace::onSelectPbr(const LLUICtrl* map_ctrl)
{ {
onCommitPbr(map_ctrl); onCommitPbr(map_ctrl);
struct f : public LLSelectedNodeFunctor
{
f(const LLUICtrl* ctrl, S32 dirty_flag) : mCtrl(ctrl), mDirtyFlag(dirty_flag)
{
}
virtual bool apply(LLSelectNode* nodep)
{
LLViewerObject* objectp = nodep->getObject();
if (!objectp)
{
return false;
}
S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces
for (S32 te = 0; te < num_tes; ++te)
{
if (nodep->isTESelected(te) && nodep->mSavedGLTFOverrideMaterials.size() > te)
{
if (nodep->mSavedGLTFOverrideMaterials[te].isNull())
{
// populate with default values, default values basically mean 'not in use'
nodep->mSavedGLTFOverrideMaterials[te] = new LLGLTFMaterial();
}
switch (mDirtyFlag)
{
//Textures
case MATERIAL_BASE_COLOR_TEX_DIRTY:
{
nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorId(mCtrl->getValue().asUUID(), true);
//update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
break;
}
case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY:
{
nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true);
//update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
break;
}
case MATERIAL_EMISIVE_TEX_DIRTY:
{
nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveId(mCtrl->getValue().asUUID(), true);
//update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
break;
}
case MATERIAL_NORMAL_TEX_DIRTY:
{
nodep->mSavedGLTFOverrideMaterials[te]->setNormalId(mCtrl->getValue().asUUID(), true);
//update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
break;
}
// Colors
case MATERIAL_BASE_COLOR_DIRTY:
{
LLColor4 ret = linearColor4(LLColor4(mCtrl->getValue()));
// except transparency
ret.mV[3] = nodep->mSavedGLTFOverrideMaterials[te]->mBaseColor.mV[3];
nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorFactor(ret, true);
break;
}
case MATERIAL_EMISIVE_COLOR_DIRTY:
{
nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveColorFactor(LLColor3(mCtrl->getValue()), true);
break;
}
default:
break;
}
}
}
return true;
}
const LLUICtrl* mCtrl;
S32 mDirtyFlag;
} func(map_ctrl, mUnsavedChanges);
LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func);
} }
bool FSPanelFace::onDragTexture(const LLUICtrl* texture_ctrl, LLInventoryItem* item) bool FSPanelFace::onDragTexture(const LLUICtrl* texture_ctrl, LLInventoryItem* item)

View File

@ -485,6 +485,7 @@ private:
// Dirty flags - taken from llmaterialeditor.cpp ... LL please put this in a .h! -Zi // Dirty flags - taken from llmaterialeditor.cpp ... LL please put this in a .h! -Zi
U32 mUnsavedChanges; // flags to indicate individual changed parameters U32 mUnsavedChanges; // flags to indicate individual changed parameters
U32 mRevertedChanges; // flags to indicate individual reverted parameters
// Hey look everyone, a type-safe alternative to copy and paste! :) // Hey look everyone, a type-safe alternative to copy and paste! :)
// //

View File

@ -138,7 +138,7 @@ void FSPoserAnimator::resetJoint(LLVOAvatar* avatar, const FSPoserJoint& joint,
oppositeJointPose->setPublicScale(LLVector3()); oppositeJointPose->setPublicScale(LLVector3());
} }
bool FSPoserAnimator::canRedoJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint) bool FSPoserAnimator::canRedoOrUndoJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint, bool canUndo)
{ {
if (!isAvatarSafeToUse(avatar)) if (!isAvatarSafeToUse(avatar))
return false; return false;
@ -154,6 +154,9 @@ bool FSPoserAnimator::canRedoJointChange(LLVOAvatar* avatar, const FSPoserJoint&
if (!jointPose) if (!jointPose)
return false; return false;
if (canUndo)
return jointPose->canPerformUndo();
return jointPose->canPerformRedo(); return jointPose->canPerformRedo();
} }
@ -303,7 +306,7 @@ void FSPoserAnimator::setAllAvatarStartingRotationsToZero(LLVOAvatar* avatar)
if (!posingMotion) if (!posingMotion)
return; return;
posingMotion->setAllRotationsToZero(); posingMotion->setAllRotationsToZeroAndClearUndo();
} }
void FSPoserAnimator::recaptureJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation) void FSPoserAnimator::recaptureJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation)
@ -322,7 +325,8 @@ void FSPoserAnimator::recaptureJoint(LLVOAvatar* avatar, const FSPoserJoint& joi
jointPose->recaptureJoint(); jointPose->recaptureJoint();
setPosingAvatarJoint(avatar, joint, true); setPosingAvatarJoint(avatar, joint, true);
} }
void FSPoserAnimator::recaptureJointAsDelta(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation)
void FSPoserAnimator::recaptureJointAsDelta(LLVOAvatar* avatar, const FSPoserJoint* joint, E_BoneDeflectionStyles style)
{ {
if (!isAvatarSafeToUse(avatar)) if (!isAvatarSafeToUse(avatar))
return; return;
@ -331,12 +335,34 @@ void FSPoserAnimator::recaptureJointAsDelta(LLVOAvatar* avatar, const FSPoserJoi
if (!posingMotion) if (!posingMotion)
return; return;
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName()); FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
if (!jointPose) if (!jointPose)
return; return;
jointPose->recaptureJointAsDelta(); jointPose->recaptureJointAsDelta();
setPosingAvatarJoint(avatar, joint, true);
if (style == NONE || style == DELTAMODE)
return;
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
if (!oppositeJointPose)
return;
switch (style)
{
case SYMPATHETIC:
case SYMPATHETIC_DELTA:
oppositeJointPose->cloneRotationFrom(jointPose);
break;
case MIRROR:
case MIRROR_DELTA:
oppositeJointPose->mirrorRotationFrom(jointPose);
break;
default:
break;
}
} }
LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation) const LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation) const

View File

@ -417,8 +417,9 @@ public:
/// </summary> /// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param> /// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint to query.</param> /// <param name="joint">The joint to query.</param>
/// <returns>True if a redo action is available, otherwise false.</returns> /// <param name="canUndo">Supply true to query if we can perform an Undo, otherwise query redo.</param>
bool canRedoJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint); /// <returns>True if an undo or redo action is available, otherwise false.</returns>
bool canRedoOrUndoJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint, bool canUndo = false);
/// <summary> /// <summary>
/// Re-does the last undone change (rotation, position or scale) to the supplied PoserJoint. /// Re-does the last undone change (rotation, position or scale) to the supplied PoserJoint.
@ -503,20 +504,27 @@ public:
/// <summary> /// <summary>
/// Symmetrizes the rotations of the joints from one side of the supplied avatar to the other. /// Symmetrizes the rotations of the joints from one side of the supplied avatar to the other.
/// </summary> /// </summary>
/// <param name="avatar">The avatar whose joints to symmetrizet.</param> /// <param name="avatar">The avatar to symmetrize.</param>
/// <param name="rightToLeft">Whether to symmetrize rotations from right to left, otherwise symmetrize left to right.</param> /// <param name="rightToLeft">Whether to symmetrize rotations from right to left, otherwise symmetrize left to right.</param>
void symmetrizeLeftToRightOrRightToLeft(LLVOAvatar* avatar, bool rightToLeft); void symmetrizeLeftToRightOrRightToLeft(LLVOAvatar* avatar, bool rightToLeft);
/// <summary> /// <summary>
/// Recaptures the rotation, position and scale state of the supplied joint for the supplied avatar. /// Recaptures the rotation, position and scale state of the supplied joint for the supplied avatar.
/// AsDelta variant retians the original base and creates a delta relative to it. /// AsDelta variant retains the original base and creates a delta relative to it.
/// </summary> /// </summary>
/// <param name="avatar">The avatar whose joint is to be recaptured.</param> /// <param name="avatar">The avatar whose joint is to be recaptured.</param>
/// <param name="joint">The joint to recapture.</param> /// <param name="joint">The joint to recapture.</param>
/// <param name="translation">The axial translation form the supplied joint.</param> /// <param name="translation">The axial translation form the supplied joint.</param>
/// <param name="negation">The style of negation to apply to the recapture.</param> /// <param name="negation">The style of negation to apply to the recapture.</param>
void recaptureJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation); void recaptureJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation);
void recaptureJointAsDelta(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation);
/// <summary>
/// Recaptures any change in joint state.
/// </summary>
/// <param name="avatar">The avatar whose joint is to be recaptured.</param>
/// <param name="joint">The joint to recapture.</param>
/// <param name="style">Any ancilliary action to be taken with the change to be made.</param>
void recaptureJointAsDelta(LLVOAvatar* avatar, const FSPoserJoint* joint, E_BoneDeflectionStyles style);
/// <summary> /// <summary>
/// Sets all of the joint rotations of the supplied avatar to zero. /// Sets all of the joint rotations of the supplied avatar to zero.
@ -525,14 +533,11 @@ public:
void setAllAvatarStartingRotationsToZero(LLVOAvatar* avatar); void setAllAvatarStartingRotationsToZero(LLVOAvatar* avatar);
/// <summary> /// <summary>
/// Determines if the kind of save to perform should be a 'delta' save, or a complete save. /// Determines if the supplied joint has a base rotation of zero.
/// </summary> /// </summary>
/// <param name="avatar">The avatar whose pose-rotations are being considered for saving.</param> /// <param name="avatar">The avatar owning the supplied joint.</param>
/// <returns>True if the save should save only 'deltas' to the rotation, otherwise false.</returns> /// <param name="joint">The joint to query.</param>
/// <remarks> /// <returns>True if the supplied joint has a 'base' rotation of zero (thus user-supplied change only), otherwise false.</returns>
/// A save of the rotation 'deltas' facilitates a user saving their changes to an existing animation.
/// Thus the save represents 'nothing other than the changes the user made', to some other pose which they may have limited rights to.
/// </remarks>
bool baseRotationIsZero(LLVOAvatar* avatar, const FSPoserJoint& joint) const; bool baseRotationIsZero(LLVOAvatar* avatar, const FSPoserJoint& joint) const;
/// <summary> /// <summary>

View File

@ -255,7 +255,7 @@ bool FSPosingMotion::allStartingRotationsAreZero() const
return true; return true;
} }
void FSPosingMotion::setAllRotationsToZero() void FSPosingMotion::setAllRotationsToZeroAndClearUndo()
{ {
for (auto poserJoint_iter = mJointPoses.begin(); poserJoint_iter != mJointPoses.end(); ++poserJoint_iter) for (auto poserJoint_iter = mJointPoses.begin(); poserJoint_iter != mJointPoses.end(); ++poserJoint_iter)
{ {

View File

@ -119,9 +119,9 @@ public:
bool allStartingRotationsAreZero() const; bool allStartingRotationsAreZero() const;
/// <summary> /// <summary>
/// Sets all of the non-Collision Volume rotations to zero. /// Sets all of the non-Collision Volume base-and-delta rotations to zero, and clears the undo/redo queue.
/// </summary> /// </summary>
void setAllRotationsToZero(); void setAllRotationsToZeroAndClearUndo();
private: private:
/// <summary> /// <summary>

View File

@ -1462,13 +1462,6 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
// LLMaterial* mat = tep->getMaterialParams().get(); // LLMaterial* mat = tep->getMaterialParams().get();
LLMaterial* mat = tep ? tep->getMaterialParams().get() : 0; LLMaterial* mat = tep ? tep->getMaterialParams().get() : 0;
// </FS:ND> // </FS:ND>
// <FS:Beq> show legacy when editing the fallback materials.
static LLCachedControl<bool> showSelectedinBP(gSavedSettings, "FSShowSelectedInBlinnPhong");
if( gltf_mat && getViewerObject()->isSelected() && showSelectedinBP )
{
gltf_mat = nullptr;
}
// </FS:Beq>
F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;

View File

@ -57,6 +57,8 @@
#include "llnotificationsutil.h" #include "llnotificationsutil.h"
#include "llregionhandle.h" #include "llregionhandle.h"
#include "llscrolllistctrl.h" #include "llscrolllistctrl.h"
#include "llviewernetwork.h" // <FS/> Access to GridManager
#include "lfsimfeaturehandler.h" // <FS/> hyperGridURL()
#include "llslurl.h" #include "llslurl.h"
#include "lltextbox.h" #include "lltextbox.h"
#include "lltoolbarview.h" #include "lltoolbarview.h"
@ -77,6 +79,7 @@
#include "llmapimagetype.h" #include "llmapimagetype.h"
#include "llweb.h" #include "llweb.h"
#include "llsliderctrl.h" #include "llsliderctrl.h"
#include "llspinctrl.h" // <FS/> setMinValue
#include "message.h" #include "message.h"
#include "llwindow.h" // copyTextToClipboard() #include "llwindow.h" // copyTextToClipboard()
#include <algorithm> #include <algorithm>
@ -396,9 +399,16 @@ bool LLFloaterWorldMap::postBuild()
mLandmarkIcon = getChild<LLUICtrl>("landmark_icon"); mLandmarkIcon = getChild<LLUICtrl>("landmark_icon");
mLocationIcon = getChild<LLUICtrl>("location_icon"); mLocationIcon = getChild<LLUICtrl>("location_icon");
// <FS> [FIRE-35333] OpenSim needs to be able to adjust the minValue
/*
mTeleportCoordSpinX = getChild<LLUICtrl>("teleport_coordinate_x"); mTeleportCoordSpinX = getChild<LLUICtrl>("teleport_coordinate_x");
mTeleportCoordSpinY = getChild<LLUICtrl>("teleport_coordinate_y"); mTeleportCoordSpinY = getChild<LLUICtrl>("teleport_coordinate_y");
mTeleportCoordSpinZ = getChild<LLUICtrl>("teleport_coordinate_z"); mTeleportCoordSpinZ = getChild<LLUICtrl>("teleport_coordinate_z");
*/
mTeleportCoordSpinX = getChild<LLSpinCtrl>("teleport_coordinate_x");
mTeleportCoordSpinY = getChild<LLSpinCtrl>("teleport_coordinate_y");
mTeleportCoordSpinZ = getChild<LLSpinCtrl>("teleport_coordinate_z");
// </FS>
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo"); LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
avatar_combo->selectFirstItem(); avatar_combo->selectFirstItem();
@ -521,6 +531,15 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
{ {
centerOnTarget(false); centerOnTarget(false);
} }
// <FS> [FIRE-35333] OpenSim allows Z coordinates to be negative based on MinSimHeight
if (!LLGridManager::getInstance()->isInSecondLife())
{
LLViewerRegion* regionp = gAgent.getRegion();
F32 min_sim_height = regionp ? regionp->getMinSimHeight() : 0.f;
mTeleportCoordSpinZ->setMinValue(min_sim_height);
}
// </FS>
} }
// static // static
@ -1006,7 +1025,12 @@ void LLFloaterWorldMap::updateLocation()
// Set the current SLURL // Set the current SLURL
// <FS:CR> Aurora-sim var region teleports // <FS:CR> Aurora-sim var region teleports
//mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionGlobal()); //mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionGlobal());
// <FS> [FIRE-35268] OpenSim support for when on other grids
if (LLGridManager::getInstance()->isInSecondLife())
mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionAgent()); mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionAgent());
else
mSLURL = LLSLURL(LFSimFeatureHandler::instance().hyperGridURL(), agent_sim_name, gAgent.getPositionAgent());
// </FS>
// </FS:CR> // </FS:CR>
} }
} }
@ -1059,7 +1083,12 @@ void LLFloaterWorldMap::updateLocation()
// if ( gotSimName ) // if ( gotSimName )
{ {
// mSLURL = LLSLURL(sim_name, pos_global); // mSLURL = LLSLURL(sim_name, pos_global);
mSLURL = LLSLURL(sim_info->getName(), sim_info->getGlobalOrigin(), pos_global); // <FS> [FIRE-35268] OpenSim support for when on other grids
if (LLGridManager::getInstance()->isInSecondLife())
mSLURL = LLSLURL(sim_info->getName(), gAgent.getPositionAgent());
else
mSLURL = LLSLURL(LFSimFeatureHandler::instance().hyperGridURL(), sim_info->getName(), gAgent.getPositionAgent());
// </FS>
} }
// </FS:Beq pp Oren> // </FS:Beq pp Oren>
else else
@ -1082,7 +1111,18 @@ void LLFloaterWorldMap::updateLocation()
void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S32 y_coord, S32 z_coord) void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S32 y_coord, S32 z_coord)
{ {
LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromName(region_name); LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromName(region_name);
// <FS> [FIRE-35333] OpenSim allows Z coordinates to be negative based on MinSimHeight
if (!LLGridManager::getInstance()->isInSecondLife())
{
LLViewerRegion* regionp = gAgent.getRegion();
F32 min_sim_height = regionp ? regionp->getMinSimHeight() : 0.f;
z_coord = llclamp(z_coord, min_sim_height, 4096);
}
else
{
z_coord = llclamp(z_coord, 0, 4096); z_coord = llclamp(z_coord, 0, 4096);
}
// </FS>
if (sim_info) if (sim_info)
{ {
LLVector3 local_pos; LLVector3 local_pos;

View File

@ -245,9 +245,16 @@ private:
LLUICtrl* mLocationIcon = nullptr; LLUICtrl* mLocationIcon = nullptr;
LLSearchEditor* mLocationEditor = nullptr; LLSearchEditor* mLocationEditor = nullptr;
// <FS> [FIRE-35333] OpenSim needs to be able to adjust the minValue
/*
LLUICtrl* mTeleportCoordSpinX = nullptr; LLUICtrl* mTeleportCoordSpinX = nullptr;
LLUICtrl* mTeleportCoordSpinY = nullptr; LLUICtrl* mTeleportCoordSpinY = nullptr;
LLUICtrl* mTeleportCoordSpinZ = nullptr; LLUICtrl* mTeleportCoordSpinZ = nullptr;
*/
LLSpinCtrl* mTeleportCoordSpinX = nullptr;
LLSpinCtrl* mTeleportCoordSpinY = nullptr;
LLSpinCtrl* mTeleportCoordSpinZ = nullptr;
// </FS>
LLSliderCtrl* mZoomSlider = nullptr; LLSliderCtrl* mZoomSlider = nullptr;

View File

@ -6236,6 +6236,13 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
// might need to be moved to LLGLTFMaterialOverrideDispatchHandler // might need to be moved to LLGLTFMaterialOverrideDispatchHandler
node->saveGLTFMaterials(material_ids, override_materials); node->saveGLTFMaterials(material_ids, override_materials);
} }
// <FS> [FIRE-35138] Show or hide the GLTF Material based on showSelectedinBP
static LLCachedControl<bool> showSelectedinBP(gSavedSettings, "FSShowSelectedInBlinnPhong");
if (showSelectedinBP)
LLSelectMgr::instance().hideGLTFMaterial();
else
LLSelectMgr::instance().showGLTFMaterial();
} }
node->mValid = true; node->mValid = true;
@ -9074,6 +9081,88 @@ bool LLSelectMgr::selectGetNoIndividual()
} }
// </FS:Zi> // </FS:Zi>
// <FS> [FIRE-35138] Hide the GLTF Material since we are currently in BP
void LLSelectMgr::hideGLTFMaterial()
{
struct f : public LLSelectedObjectFunctor
{
f() {}
bool apply(LLViewerObject* objectp)
{
if (!objectp || !objectp->permModify())
{
return false;
}
// Save the current GLTF materials so they can be restored later
objectp->saveGLTFMaterials();
for (S32 te = 0; te < objectp->getNumTEs(); ++te)
{
// Blank out most override data on the object and don't send to server
objectp->setRenderMaterialID(te, LLUUID(), false);
}
return true;
}
};
f setfunc;
getSelection()->applyToObjects(&setfunc);
}
// </FS>
// <FS> [FIRE-35138] Show the GLTF Material since we are no longer in BP
void LLSelectMgr::showGLTFMaterial()
{
struct f : public LLSelectedObjectFunctor
{
f() {}
bool apply(LLViewerObject* objectp)
{
if (!objectp || !objectp->permModify())
{
return false;
}
const uuid_vec_t& saved_gltf_material_ids = objectp->getSavedGLTFMaterialIds();
const gltf_materials_vec_t& saved_gltf_override_materials = objectp->getSavedGLTFOverrideMaterials();
if (saved_gltf_material_ids.empty())
{
return false;
}
for (S32 te = 0; te < objectp->getNumTEs(); ++te)
{
if (te >= saved_gltf_material_ids.size())
{
LL_WARNS("FS") << "TE index out of bounds for saved GLTF materials" << LL_ENDL;
break;
}
// Restore gltf material
LLUUID asset_id = saved_gltf_material_ids[te];
LLGLTFMaterial* material = saved_gltf_override_materials[te];
// Update material locally
objectp->setRenderMaterialID(te, asset_id, false);
if (material)
{
material = new LLGLTFMaterial(*material);
objectp->setTEGLTFMaterialOverride(te, material);
}
// Do not enqueue update to server
}
objectp->clearSavedGLTFMaterials();
return true;
}
} setfunc;
getSelection()->applyToObjects(&setfunc);
}
// </FS>
template<> template<>
bool LLCheckIdenticalFunctor<F32>::same(const F32& a, const F32& b, const F32& tolerance) bool LLCheckIdenticalFunctor<F32>::same(const F32& a, const F32& b, const F32& tolerance)
{ {

View File

@ -1024,6 +1024,8 @@ public:
// (edit linked parts, select face) // (edit linked parts, select face)
bool selectGetNoIndividual(); bool selectGetNoIndividual();
// </FS:Zi> // </FS:Zi>
void showGLTFMaterial(); // <FS/> [FIRE-35138] Show the GLTF Material since we are no longer in BP
void hideGLTFMaterial(); // <FS/> [FIRE-35138] Hide the GLTF Material since we are currently in BP
}; };
// *DEPRECATED: For callbacks or observers, use // *DEPRECATED: For callbacks or observers, use

View File

@ -546,7 +546,12 @@ void LLTracker::drawBeacon(LLVector3 pos_agent, std::string direction, LLColor4
height = pos_agent.mV[2]; height = pos_agent.mV[2];
} }
// <FS> [FIRE-35333] OpenSim allows Z coordinates to be negative based on MinSimHeight
if (height < 0.f)
nRows = 0;
else
nRows = (U32)ceil((BEACON_ROWS * height) / MAX_HEIGHT); nRows = (U32)ceil((BEACON_ROWS * height) / MAX_HEIGHT);
// </FS>
if(nRows<2) nRows=2; if(nRows<2) nRows=2;
rowHeight = height / nRows; rowHeight = height / nRows;
@ -557,7 +562,10 @@ void LLTracker::drawBeacon(LLVector3 pos_agent, std::string direction, LLColor4
F32 x = x_axis.mV[0]; F32 x = x_axis.mV[0];
F32 y = x_axis.mV[1]; F32 y = x_axis.mV[1];
F32 z = 0.f; // <FS> [FIRE-35333] OpenSim allows Z coordinates to be negative based on MinSimHeight
//F32 z = 0.f;
F32 z = llmin(height, 0.f);
// </FS>
F32 z_next; F32 z_next;
F32 a,an; F32 a,an;

View File

@ -7887,6 +7887,39 @@ void LLViewerObject::setRenderMaterialIDs(const LLUUID& id)
setRenderMaterialID(-1, id); setRenderMaterialID(-1, id);
} }
// <FS> [FIRE-35138] Helpers for GLTF Materials since we support PBR and BP at same time
void LLViewerObject::saveGLTFMaterials()
{
if (!mSavedGLTFMaterialIds.empty())
{
// Already saved, no need to do it again
return;
}
for (S32 te = 0; te < getNumTEs(); ++te)
{
mSavedGLTFMaterialIds.emplace_back(getRenderMaterialID(te));
LLPointer<LLGLTFMaterial> old_override = getTE(te)->getGLTFMaterialOverride();
if (old_override.notNull())
{
LLGLTFMaterial* copy = new LLGLTFMaterial(*old_override);
mSavedGLTFOverrideMaterials.emplace_back(copy);
}
else
{
mSavedGLTFOverrideMaterials.emplace_back(nullptr);
}
}
}
void LLViewerObject::clearSavedGLTFMaterials()
{
mSavedGLTFMaterialIds.clear();
mSavedGLTFOverrideMaterials.clear();
}
// </FS>
void LLViewerObject::setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin) void LLViewerObject::setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin)
{ {
if (!local_origin) if (!local_origin)

View File

@ -100,6 +100,8 @@ typedef void (*inventory_callback)(LLViewerObject*,
S32 serial_num, S32 serial_num,
void*); void*);
typedef std::vector<LLPointer<LLGLTFMaterial> > gltf_materials_vec_t; // <FS/> [FIRE-35138] typedef for saved GLTF override materials
// for exporting textured materials from SL // for exporting textured materials from SL
struct LLMaterialExportInfo struct LLMaterialExportInfo
{ {
@ -135,6 +137,10 @@ protected:
LLNetworkData *data; LLNetworkData *data;
}; };
std::unordered_map<U16, ExtraParameter*> mExtraParameterList; std::unordered_map<U16, ExtraParameter*> mExtraParameterList;
// <FS> [FIRE-35138] Saved GLTF materials to be restored when needed
uuid_vec_t mSavedGLTFMaterialIds;
gltf_materials_vec_t mSavedGLTFOverrideMaterials;
// </FS>
public: public:
typedef std::list<LLPointer<LLViewerObject> > child_list_t; typedef std::list<LLPointer<LLViewerObject> > child_list_t;
@ -204,6 +210,13 @@ public:
void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true, bool local_origin = true); void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true, bool local_origin = true);
void setRenderMaterialIDs(const LLUUID& id); void setRenderMaterialIDs(const LLUUID& id);
// <FS> [FIRE-35138] Helpers for GLTF Materials since we support PBR and BP at same time
const uuid_vec_t& getSavedGLTFMaterialIds() const { return mSavedGLTFMaterialIds; };
const gltf_materials_vec_t& getSavedGLTFOverrideMaterials() const { return mSavedGLTFOverrideMaterials; };
void saveGLTFMaterials();
void clearSavedGLTFMaterials();
// </FS>
virtual bool isHUDAttachment() const { return false; } virtual bool isHUDAttachment() const { return false; }
virtual bool isTempAttachment() const; virtual bool isTempAttachment() const;

View File

@ -3142,25 +3142,25 @@ void LLViewerLODTexture::processTextureStats()
F32 min_discard = 0.f; F32 min_discard = 0.f;
*/ */
// Use a S32 value for the discard level
S32 discard_level = 0;
// Find the best discard that covers the entire mMaxVirtualSize of the on screen texture
for (; discard_level <= MAX_DISCARD_LEVEL; discard_level++)
{
// If the max virtual size is greater then the current discard level, then break out of the loop and use the current discard level
if (mMaxVirtualSize > getWidth(discard_level) * getHeight(discard_level))
{
break;
}
}
// Use a S32 instead of a float // Use a S32 instead of a float
S32 min_discard = 0; S32 min_discard = 0;
if (mFullWidth > max_tex_res || mFullHeight > max_tex_res) if (mFullWidth > max_tex_res || mFullHeight > max_tex_res)
min_discard = 1; min_discard = 1;
// Use a S32 value for the discard level
S32 discard_level = min_discard;
// Find the best discard that covers the entire mMaxVirtualSize of the on screen texture (Use MAX_DISCARD_LEVEL as a max discard instead of MAX_DISCARD_LEVEL+1)
for (; discard_level < MAX_DISCARD_LEVEL; discard_level++) // <FS:minerjr> [FIRE-35361] RenderMaxTextureResolution caps texture resolution lower than intended
{
// If the max virtual size is greater then or equal to the current discard level, then break out of the loop and use the current discard level
if (mMaxVirtualSize >= getWidth(discard_level) * getHeight(discard_level)) // <FS:minerjr> [FIRE-35361] RenderMaxTextureResolution caps texture resolution lower than intended
{
break;
}
}
//discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL); //discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL);
discard_level = llclamp(discard_level, min_discard, MAX_DISCARD_LEVEL); // Don't convert to float and back again
// </FS:minerjr> [FIRE-35081] // </FS:minerjr> [FIRE-35081]
// Can't go higher than the max discard level // Can't go higher than the max discard level

View File

@ -391,6 +391,7 @@ void LLViewerTextureList::dump()
std::array<S32, MAX_DISCARD_LEVEL * 2 + 2> image_counts{0}; // Double the size for higher discards from textures < 1024 (2048 can make a 7 and 4096 could make an 8) std::array<S32, MAX_DISCARD_LEVEL * 2 + 2> image_counts{0}; // Double the size for higher discards from textures < 1024 (2048 can make a 7 and 4096 could make an 8)
std::array<S32, 12 * 12> size_counts{0}; // Track the 12 possible sizes (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048) std::array<S32, 12 * 12> size_counts{0}; // Track the 12 possible sizes (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048)
std::array<S32, (MAX_DISCARD_LEVEL * 2 + 2) * 12> discard_counts{0}; // Also need to an 1 additional as -1 is a valid discard level (not loaded by reported as a 1x1 texture) std::array<S32, (MAX_DISCARD_LEVEL * 2 + 2) * 12> discard_counts{0}; // Also need to an 1 additional as -1 is a valid discard level (not loaded by reported as a 1x1 texture)
std::array<S32, LLViewerTexture::BOOST_MAX_LEVEL * 12> boost_counts{0}; // Track the # of textures at boost levels by 12 possible sizes
// Don't Init the buffers with 0's like it's the the 1980's... // Don't Init the buffers with 0's like it's the the 1980's...
// </FS:minerjr> [FIRE-35081] // </FS:minerjr> [FIRE-35081]
@ -432,7 +433,9 @@ void LLViewerTextureList::dump()
S32 y_index = (S32)log2(image->getHeight()); // Convert the height into a 0 based index by taking the Log2 of the size to get the exponent of the size. (1 = 2^0, 2 = 2^1, 4 = 2^2...) S32 y_index = (S32)log2(image->getHeight()); // Convert the height into a 0 based index by taking the Log2 of the size to get the exponent of the size. (1 = 2^0, 2 = 2^1, 4 = 2^2...)
size_counts[x_index + y_index * 12] += 1; // Add this texture's dimensions to the size count size_counts[x_index + y_index * 12] += 1; // Add this texture's dimensions to the size count
// Onlyuse the largest size for the texture's discard level(for non-square textures) // Onlyuse the largest size for the texture's discard level(for non-square textures)
discard_counts[(image->getDiscardLevel() + 1) + (y_index > x_index ? y_index : x_index) * (MAX_DISCARD_LEVEL * 2 + 2)] += 1; S32 max_dimension = (y_index > x_index ? y_index : x_index);
discard_counts[(image->getDiscardLevel() + 1) + max_dimension * (MAX_DISCARD_LEVEL * 2 + 2)] += 1;
boost_counts[image->getBoostLevel() + max_dimension * (LLViewerTexture::BOOST_MAX_LEVEL)] += 1;
texture_count++; texture_count++;
textures_close_to_camera += S32(image->getCloseToCamera()); textures_close_to_camera += S32(image->getCloseToCamera());
// </FS:minerjr> [FIRE-35081] // </FS:minerjr> [FIRE-35081]
@ -510,6 +513,12 @@ void LLViewerTextureList::dump()
} }
} }
header_break = "";
for (S32 x = 0; x < header.length(); x++)
{
header_break += "-";
}
LL_INFOS() << header_break << LL_ENDL; LL_INFOS() << header_break << LL_ENDL;
LL_INFOS() << header << LL_ENDL; // Discard Level Vs Size counts header LL_INFOS() << header << LL_ENDL; // Discard Level Vs Size counts header
LL_INFOS() << header_break << LL_ENDL; LL_INFOS() << header_break << LL_ENDL;
@ -538,6 +547,54 @@ void LLViewerTextureList::dump()
LL_INFOS() << header_break << LL_ENDL; LL_INFOS() << header_break << LL_ENDL;
LL_INFOS() << header << LL_ENDL; // Discard Level Vs Size counts footer LL_INFOS() << header << LL_ENDL; // Discard Level Vs Size counts footer
LL_INFOS() << header_break << LL_ENDL; LL_INFOS() << header_break << LL_ENDL;
// This is the Boost Level Vs Size counts table
header = "Boost: ";
for (S32 x = 0; x < LLViewerTexture::BOOST_MAX_LEVEL; x++)
{
std::string newValue = std::to_string(x);
header += newValue;
for (S32 tab = 0; tab <= 8 - newValue.length(); tab++)
{
header += " ";
}
}
header_break = "";
for (S32 x = 0; x < header.length(); x++)
{
header_break += "-";
}
LL_INFOS() << header_break << LL_ENDL;
LL_INFOS() << header << LL_ENDL; // Boost Level Vs Size counts header
LL_INFOS() << header_break << LL_ENDL;
// Y Axis is the current possible max dimension of the textures (X or Y, which ever is larger is used)
for (S32 y = 0; y < 12; y++)
{
std::string newValue = std::to_string((S32)pow(2, y));
std::string boost_count_string = "" + newValue;
for (S32 tab = 0; tab <= 8 - newValue.length(); tab++)
{
boost_count_string += " ";
}
// X Axis is the boost level starging from BOOST_NONE up to BOOST_MAX_LEVEL
for (S32 x = 0; x < (LLViewerTexture::BOOST_MAX_LEVEL); x++)
{
std::string newValue = std::to_string(boost_counts[x + y * (LLViewerTexture::BOOST_MAX_LEVEL)]);
boost_count_string += newValue;
for (S32 tab = 0; tab <= 8 - newValue.length(); tab++)
{
boost_count_string += " ";
}
}
LL_INFOS() << boost_count_string << LL_ENDL;
}
LL_INFOS() << header_break << LL_ENDL;
LL_INFOS() << header << LL_ENDL; // Boost Level Vs Size counts footer
LL_INFOS() << header_break << LL_ENDL;
// </FS:minerjr> [FIRE-35081] // </FS:minerjr> [FIRE-35081]
} }

View File

@ -851,8 +851,12 @@ public:
ypos += y_inc; ypos += y_inc;
} }
// disable use of glReadPixels which messes up nVidia nSight graphics debugging // disable use of glReadPixels which messes up nVidia nSight graphics debugging
static LLCachedControl<bool> debug_show_color(gSavedSettings, "DebugShowColor", false); // <FS:minerjr>
if (debug_show_color() && !LLRender::sNsightDebugSupport) //static LLCachedControl<bool> debug_show_color(gSavedSettings, "DebugShowColor", false);
//if (debug_show_color() && !LLRender::sNsightDebugSupport)
static LLCachedControl<S32> debug_show_color(gSavedSettings, "DebugShowColor", 0); // <FS:minerjr> The value is stored as a S32 and not a Bool
if (debug_show_color == 1 && !LLRender::sNsightDebugSupport) // <FS:minerjr> Which causes an exception when in RelWithDebug
// </FS:minerjr>
{ {
U8 color[4]; U8 color[4];
LLCoordGL coord = gViewerWindow->getCurrentMouse(); LLCoordGL coord = gViewerWindow->getCurrentMouse();

View File

@ -5663,14 +5663,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
auto* gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial(); auto* gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial();
llassert(gltf_mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(te->getGLTFRenderMaterial()) != nullptr); llassert(gltf_mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(te->getGLTFRenderMaterial()) != nullptr);
// <FS:Beq> show legacy when editing the fallback materials.
static LLCachedControl<bool> showSelectedinBP(gSavedSettings, "FSShowSelectedInBlinnPhong");
if( gltf_mat && facep->getViewerObject()->isSelected() && showSelectedinBP )
{
gltf_mat = nullptr;
}
// </FS:Beq>
if (gltf_mat != nullptr) if (gltf_mat != nullptr)
{ {
mat_id = gltf_mat->getHash(); // TODO: cache this hash mat_id = gltf_mat->getHash(); // TODO: cache this hash
@ -6881,14 +6873,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
const LLTextureEntry* te = facep->getTextureEntry(); const LLTextureEntry* te = facep->getTextureEntry();
LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
// <FS:Beq> show legacy when editing the fallback materials.
static LLCachedControl<bool> showSelectedinBP(gSavedSettings, "FSShowSelectedInBlinnPhong");
if( gltf_mat && facep->getViewerObject()->isSelected() && showSelectedinBP )
{
gltf_mat = nullptr;
}
// </FS:Beq>
if (hud_group && gltf_mat == nullptr) if (hud_group && gltf_mat == nullptr)
{ //all hud attachments are fullbright { //all hud attachments are fullbright
fullbright = true; fullbright = true;

View File

@ -1042,7 +1042,7 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)
// <FS:Beq> create an independent preview screen target // <FS:Beq> create an independent preview screen target
{LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("PreviewScreenBuffer"); {LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("PreviewScreenBuffer");
mPreviewScreen.allocate(MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT, GL_RGBA); mPreviewScreen.allocate(MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT, GL_RGBA, true);
} // </FS:Beq> } // </FS:Beq>
{LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("BakeMapBuffer");// <FS:Beq/> create an independent preview screen target {LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("BakeMapBuffer");// <FS:Beq/> create an independent preview screen target
mBakeMap.allocate(LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH, LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT, GL_RGBA); mBakeMap.allocate(LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH, LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT, GL_RGBA);

View File

@ -14,7 +14,7 @@ Teksturlar
Teksturlar Teksturlar
</text> </text>
<button label="ID-lərin konsola çıxarışı" label_selected=ıxarış" name="Dump"/> <button label="ID-lərin konsola çıxarışı" label_selected=ıxarış" name="Dump"/>
<panel name="scroll_content_panel"> <panel name="scroll_content_panel2">
<texture_picker label="Saçlar" name="hair-baked"/> <texture_picker label="Saçlar" name="hair-baked"/>
<texture_picker label="Saçlar" name="hair_grain"/> <texture_picker label="Saçlar" name="hair_grain"/>
<texture_picker label="Saç alfası" name="hair_alpha"/> <texture_picker label="Saç alfası" name="hair_alpha"/>

View File

@ -11,6 +11,9 @@ width="430">
<string name="icon_bone" translate="false"></string> <string name="icon_bone" translate="false"></string>
<string name="icon_object" translate="false">Inv_Object</string> <string name="icon_object" translate="false">Inv_Object</string>
<string name="icon_rotation_is_own_work" translate="false">Check_Mark</string> <string name="icon_rotation_is_own_work" translate="false">Check_Mark</string>
<string name="icon_save_button" translate="false">Icon_Dock_Foreground</string>
<string name="icon_save_failed_button" translate="false">Parcel_Exp_Color</string>
<string name="icon_save_query" translate="false">Info</string>
<!-- Provides for axis-swapping per joint for slider/trackpad control --> <!-- Provides for axis-swapping per joint for slider/trackpad control -->
<!-- Begins with joint_transform_ then has an internal joint name, ONE swap choice of: <!-- Begins with joint_transform_ then has an internal joint name, ONE swap choice of:
@ -278,7 +281,10 @@ width="430">
<string name="bvh_joint_transform_mHead" translate="false">SWAP_X2Y_Y2Z_Z2X</string> <string name="bvh_joint_transform_mHead" translate="false">SWAP_X2Y_Y2Z_Z2X</string>
<string name="LoadPoseLabel">Load Pose</string> <string name="LoadPoseLabel">Load Pose</string>
<string name="SavePoseLabel">Save Pose</string>
<string name="LoadDiffLabel">Load Diff</string> <string name="LoadDiffLabel">Load Diff</string>
<string name="SaveDiffLabel">Save Diff</string>
<string name="OverWriteLabel">Overwrite?</string>
<!-- The layout is a vertical stack of 3 rows, and each row a horizontal stack of panels --> <!-- The layout is a vertical stack of 3 rows, and each row a horizontal stack of panels -->
<layout_stack <layout_stack
@ -369,7 +375,8 @@ width="430">
tool_tip="Move the selected avatar up or down" tool_tip="Move the selected avatar up or down"
can_edit_text="true"> can_edit_text="true">
<slider.commit_callback <slider.commit_callback
function="Poser.PositionSet"/> function="Poser.CommitSlider"
parameter="0"/>
</slider> </slider>
<spinner <spinner
height="16" height="16"
@ -413,7 +420,8 @@ width="430">
tool_tip="Move the selected avatar left or right" tool_tip="Move the selected avatar left or right"
can_edit_text="true"> can_edit_text="true">
<slider.commit_callback <slider.commit_callback
function="Poser.PositionSet"/> function="Poser.CommitSlider"
parameter="1"/>
</slider> </slider>
<spinner <spinner
height="16" height="16"
@ -457,7 +465,8 @@ width="430">
tool_tip="Move the selected avatar in or out" tool_tip="Move the selected avatar in or out"
can_edit_text="true"> can_edit_text="true">
<slider.commit_callback <slider.commit_callback
function="Poser.PositionSet"/> function="Poser.CommitSlider"
parameter="2"/>
</slider> </slider>
<spinner <spinner
height="16" height="16"
@ -637,7 +646,7 @@ width="430">
layout="topleft" layout="topleft"
label="Set Left" label="Set Left"
name="button_loadHandPoseLeft" name="button_loadHandPoseLeft"
tool_tip="Double click to set your left hand to the selected preset" tool_tip="Click to set your left hand to the selected preset"
top_delta="238" top_delta="238"
left_pad="1" left_pad="1"
left="2" left="2"
@ -651,7 +660,7 @@ width="430">
layout="topleft" layout="topleft"
label="Set Right" label="Set Right"
name="button_loadHandPoseRight" name="button_loadHandPoseRight"
tool_tip="Double click to set your right hand to the selected preset" tool_tip="Click to set your right hand to the selected preset"
left_pad="2" left_pad="2"
top_delta="0" top_delta="0"
width="85" > width="85" >
@ -819,7 +828,7 @@ width="430">
label="Set to T-Pose" label="Set to T-Pose"
image_unselected="Toolbar_Middle_Off" image_unselected="Toolbar_Middle_Off"
name="set_t_pose_button" name="set_t_pose_button"
tool_tip="Double-click to set the selected avatar to a 'T-Pose'" tool_tip="Click to set the selected avatar to a 'T-Pose'"
width="172"> width="172">
<button.commit_callback <button.commit_callback
function="Poser.SetToTPose"/> function="Poser.SetToTPose"/>
@ -922,6 +931,16 @@ width="430">
tool_tip="When you save your pose, also write a BVH file, which can be uploaded via the 'Build > Upload > Animation' to pose yourself or others in-world. This needs joints to reset their 'base' to zero, because BVH requires original work." tool_tip="When you save your pose, also write a BVH file, which can be uploaded via the 'Build > Upload > Animation' to pose yourself or others in-world. This needs joints to reset their 'base' to zero, because BVH requires original work."
top_pad="2" top_pad="2"
width="134" /> width="134" />
<check_box
control_name="FSPoserOnSaveConfirmOverwrite"
name="confirm_overwrite_on_save_checkbox"
height="16"
label="Confirm Overwrite"
follows="left|top"
left="5"
tool_tip="When you save a pose, if the file already exists, you need to click the save button again to confirm you are sure you want to overwrite."
top_pad="5"
width="134" />
</panel> </panel>
</tab_container> </tab_container>
<button <button
@ -956,7 +975,7 @@ width="430">
<tab_container <tab_container
follows="all" follows="all"
halign="center" halign="center"
height="235" height="263"
layout="topleft" layout="topleft"
name="modifier_tabs" name="modifier_tabs"
tab_height="20" tab_height="20"
@ -967,7 +986,7 @@ width="430">
width="215"> width="215">
<panel <panel
follows="left|right|top|bottom" follows="left|right|top|bottom"
height="290" height="265"
background_visible="false" background_visible="false"
layout="topleft" layout="topleft"
mouse_opaque="false" mouse_opaque="false"
@ -981,9 +1000,9 @@ width="430">
name="limb_rotation" name="limb_rotation"
follows="left|right|top" follows="left|right|top"
top="2" top="2"
height="170" height="160"
width="170" width="160"
left="10" left="15"
tool_tip="Change the rotation of the currently selected body part(s). Hold Ctrl to move slow. Roll the wheel to adjust the 3rd axis. Use Shift or Alt to swap which rotations change" tool_tip="Change the rotation of the currently selected body part(s). Hold Ctrl to move slow. Roll the wheel to adjust the 3rd axis. Use Shift or Alt to swap which rotations change"
pinch_mode="false" pinch_mode="false"
infinite_scroll_mode="true"/> infinite_scroll_mode="true"/>
@ -992,72 +1011,129 @@ width="430">
name="limb_pitch_label" name="limb_pitch_label"
height="10" height="10"
layout="topleft" layout="topleft"
left="2" left="5"
top_pad="2" top_pad="2"
width="57"> width="200">
Up/Down: Up/Down:
</text> </text>
<slider
label=""
label_width="0"
follows="left|top"
height="14"
increment="0.1"
initial_value="0"
layout="topleft"
show_text="false"
left="3"
min_val="-180"
max_val="180"
name="limb_pitch_slider"
top_pad="2"
width="130" >
<slider.commit_callback
function="Poser.CommitSlider"
parameter="4"/>
</slider>
<spinner
height="16"
decimal_digits="2"
follows="left|top"
increment="0.1"
top_pad="-19"
left_pad="0"
name="limb_pitch_spinner"
min_val="-180"
max_val="180"
width="53">
<spinner.commit_callback
function="Poser.CommitSpinner"
parameter="4"/>
</spinner>
<text <text
follows="left|top" follows="left|top"
name="limb_yaw_label" name="limb_yaw_label"
height="10" height="10"
layout="topleft" layout="topleft"
left_pad="5" left="5"
top_pad="-10" top_pad="2"
width="57"> width="200">
Left/Right: Left/Right:
</text> </text>
<slider
label=""
label_width="0"
follows="left|top"
height="14"
increment="0.1"
initial_value="0"
layout="topleft"
show_text="false"
left="3"
min_val="-180"
max_val="180"
name="limb_yaw_slider"
top_pad="2"
width="130" >
<slider.commit_callback
function="Poser.CommitSlider"
parameter="5"/>
</slider>
<spinner
height="16"
decimal_digits="2"
follows="left|top"
increment="0.1"
top_pad="-19"
left_pad="0"
name="limb_yaw_spinner"
min_val="-180"
max_val="180"
width="53">
<spinner.commit_callback
function="Poser.CommitSpinner"
parameter="5"/>
</spinner>
<text <text
follows="left|top" follows="left|top"
name="limb_roll_label" name="limb_roll_label"
height="10" height="10"
layout="topleft" layout="topleft"
left_pad="5" left="5"
top_pad="-10" top_pad="2"
width="200"> width="200">
Roll: Roll:
</text> </text>
<spinner <slider
height="16" label=""
decimal_digits="2" label_width="0"
follows="left|top" follows="left|top"
height="14"
increment="0.1" increment="0.1"
left="2" initial_value="0"
top_pad="5" layout="topleft"
name="limb_pitch_spinner" show_text="false"
left="3"
min_val="-180" min_val="-180"
max_val="180" max_val="180"
width="57"> name="limb_roll_slider"
<spinner.commit_callback top_pad="2"
function="Poser.CommitSpinner" width="130" >
parameter="4"/> <slider.commit_callback
</spinner> function="Poser.CommitSlider"
parameter="6"/>
</slider>
<spinner <spinner
height="16" height="16"
decimal_digits="2" decimal_digits="2"
follows="left|top" follows="left|top"
increment="0.1" increment="0.1"
top_pad="-16" top_pad="-19"
left_pad="5" left_pad="0"
name="limb_yaw_spinner"
min_val="-180"
max_val="180"
width="57">
<spinner.commit_callback
function="Poser.CommitSpinner"
parameter="5"/>
</spinner>
<spinner
height="16"
decimal_digits="2"
follows="left|top"
increment="0.1"
top_pad="-16"
left_pad="5"
name="limb_roll_spinner" name="limb_roll_spinner"
min_val="-180" min_val="-180"
max_val="180" max_val="180"
width="57"> width="53">
<spinner.commit_callback <spinner.commit_callback
function="Poser.CommitSpinner" function="Poser.CommitSpinner"
parameter="6"/> parameter="6"/>
@ -1099,19 +1175,20 @@ width="430">
top_pad="2" top_pad="2"
width="130" > width="130" >
<slider.commit_callback <slider.commit_callback
function="Poser.Advanced.PositionSet"/> function="Poser.CommitSlider"
parameter="7"/>
</slider> </slider>
<spinner <spinner
height="20" height="20"
decimal_digits="2" decimal_digits="3"
follows="left|top" follows="left|top"
increment="0.01" increment="0.001"
top_pad="-19" top_pad="-19"
left_pad="2" left_pad="0"
name="adv_posx_spinner" name="adv_posx_spinner"
min_val="-1.5" min_val="-1.5"
max_val="1.5" max_val="1.5"
width="47"> width="53">
<spinner.commit_callback <spinner.commit_callback
function="Poser.CommitSpinner" function="Poser.CommitSpinner"
parameter="7"/> parameter="7"/>
@ -1142,19 +1219,20 @@ width="430">
top_pad="2" top_pad="2"
width="130" > width="130" >
<slider.commit_callback <slider.commit_callback
function="Poser.Advanced.PositionSet"/> function="Poser.CommitSlider"
parameter="8"/>
</slider> </slider>
<spinner <spinner
height="20" height="20"
decimal_digits="2" decimal_digits="3"
follows="left|top" follows="left|top"
increment="0.01" increment="0.001"
top_pad="-19" top_pad="-19"
left_pad="2" left_pad="0"
name="adv_posy_spinner" name="adv_posy_spinner"
min_val="-1.5" min_val="-1.5"
max_val="1.5" max_val="1.5"
width="47"> width="53">
<spinner.commit_callback <spinner.commit_callback
function="Poser.CommitSpinner" function="Poser.CommitSpinner"
parameter="8"/> parameter="8"/>
@ -1185,19 +1263,20 @@ width="430">
top_pad="2" top_pad="2"
width="130" > width="130" >
<slider.commit_callback <slider.commit_callback
function="Poser.Advanced.PositionSet"/> function="Poser.CommitSlider"
parameter="9"/>
</slider> </slider>
<spinner <spinner
height="20" height="20"
decimal_digits="2" decimal_digits="3"
follows="left|top" follows="left|top"
increment="0.01" increment="0.001"
top_pad="-19" top_pad="-19"
left_pad="2" left_pad="0"
name="adv_posz_spinner" name="adv_posz_spinner"
min_val="-1.5" min_val="-1.5"
max_val="1.5" max_val="1.5"
width="47"> width="53">
<spinner.commit_callback <spinner.commit_callback
function="Poser.CommitSpinner" function="Poser.CommitSpinner"
parameter="9"/> parameter="9"/>
@ -1228,7 +1307,8 @@ width="430">
top_pad="2" top_pad="2"
width="130" > width="130" >
<slider.commit_callback <slider.commit_callback
function="Poser.Advanced.ScaleSet"/> function="Poser.CommitSlider"
parameter="10"/>
</slider> </slider>
<spinner <spinner
height="20" height="20"
@ -1271,7 +1351,8 @@ width="430">
top_pad="2" top_pad="2"
width="130" > width="130" >
<slider.commit_callback <slider.commit_callback
function="Poser.Advanced.ScaleSet"/> function="Poser.CommitSlider"
parameter="11"/>
</slider> </slider>
<spinner <spinner
height="20" height="20"
@ -1314,7 +1395,8 @@ width="430">
top_pad="2" top_pad="2"
width="130" > width="130" >
<slider.commit_callback <slider.commit_callback
function="Poser.Advanced.ScaleSet"/> function="Poser.CommitSlider"
parameter="12"/>
</slider> </slider>
<spinner <spinner
height="20" height="20"
@ -1379,7 +1461,7 @@ width="430">
image_overlay="Inv_TrashOpen" image_overlay="Inv_TrashOpen"
image_unselected="Toolbar_Middle_Off" image_unselected="Toolbar_Middle_Off"
name="poser_joint_reset" name="poser_joint_reset"
tool_tip="Double click to reset the selected body part(s) to when you first started posing" tool_tip="Click to reset the selected body part(s) to when you first started posing"
width="18" width="18"
top_delta="0" top_delta="0"
left_pad="1"> left_pad="1">
@ -1443,12 +1525,13 @@ width="430">
</button> </button>
<button <button
follows="left|top" follows="left|top"
height="21" height="18"
layout="topleft" layout="topleft"
label="Copy L &gt; R" label="Copy L &gt; R"
name="button_symmetrize_left_to_right" name="button_symmetrize_left_to_right"
tool_tip="Double click to copy change from left side to right side." tool_tip="Click to copy change from left side to right side."
left="14" left="14"
top_pad="0"
width="70" > width="70" >
<button.commit_callback <button.commit_callback
function="Poser.Symmetrize" function="Poser.Symmetrize"
@ -1456,11 +1539,11 @@ width="430">
</button> </button>
<button <button
follows="left|top" follows="left|top"
height="21" height="19"
layout="topleft" layout="topleft"
label="Copy R &gt; L" label="Copy R &gt; L"
name="button_symmetrize_right_to_left" name="button_symmetrize_right_to_left"
tool_tip="Double click to copy change from right side to left side." tool_tip="Click to copy change from right side to left side."
left_pad="23" left_pad="23"
top_delta="0" top_delta="0"
width="70" > width="70" >

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="emojipicker" title="Choisir un émoji"> <floater name="emojipicker" title="Choisir un émoji">
<floater.string name="title_for_recently_used" value="Récemment utilisé"/>
<floater.string name="title_for_frequently_used" value="Souvent utilisé"/> <floater.string name="title_for_frequently_used" value="Souvent utilisé"/>
<floater.string name="text_no_emoji_for_filter" value="Aucun emoji trouvé pour '[FILTER]'"/> <floater.string name="text_no_emoji_for_filter" value="Aucun emoji trouvé pour '[FILTER]'"/>
<text name="Dummy"> <text name="Dummy">

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="emojipicker" title="Scegli Emoji"> <floater name="emojipicker" title="Scegli Emoji">
<floater.string name="title_for_recently_used" value="Usate di recente"/>
<floater.string name="title_for_frequently_used" value="Usate di frequente"/> <floater.string name="title_for_frequently_used" value="Usate di frequente"/>
<floater.string name="text_no_emoji_for_filter" value="Nessuna emoji trovata per '[FILTER]'"/> <floater.string name="text_no_emoji_for_filter" value="Nessuna emoji trovata per '[FILTER]'"/>
<text name="Dummy"> <text name="Dummy">

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="emojipicker" title="Wybierz emoji"> <floater name="emojipicker" title="Wybierz emoji">
<floater.string name="title_for_recently_used" value="Ostatnio używane"/>
<floater.string name="title_for_frequently_used" value="Często używane"/> <floater.string name="title_for_frequently_used" value="Często używane"/>
<floater.string name="text_no_emoji_for_filter" value="Brak emoji dla '[FILTER]'"/> <floater.string name="text_no_emoji_for_filter" value="Brak emoji dla '[FILTER]'"/>
<text name="Dummy"> <text name="Dummy">

View File

@ -142,7 +142,10 @@
<string name="title_LEFT_PEC">Lewa pierś</string> <string name="title_LEFT_PEC">Lewa pierś</string>
<string name="title_RIGHT_PEC">Prawa pierś</string> <string name="title_RIGHT_PEC">Prawa pierś</string>
<string name="LoadPoseLabel">Ładuj pozę</string> <string name="LoadPoseLabel">Ładuj pozę</string>
<string name="SavePoseLabel">Zapis pozy</string>
<string name="LoadDiffLabel">Ładuj różn.</string> <string name="LoadDiffLabel">Ładuj różn.</string>
<string name="SaveDiffLabel">Zapis różn.</string>
<string name="OverWriteLabel">Nadpisać?</string>
<layout_stack name="poser_stack"> <layout_stack name="poser_stack">
<layout_panel name="regular_controls_layout"> <layout_panel name="regular_controls_layout">
<panel name="joints_parent_panel"> <panel name="joints_parent_panel">
@ -186,8 +189,8 @@
<scroll_list name="hand_presets_scroll"> <scroll_list name="hand_presets_scroll">
<scroll_list.columns label="Ustawienie" name="name" /> <scroll_list.columns label="Ustawienie" name="name" />
</scroll_list> </scroll_list>
<button label="Ustaw: Lewa" name="button_loadHandPoseLeft" tool_tip="Kliknij dwukrotnie, aby ustawić lewą rękę na wybranym ustawieniu" /> <button label="Ustaw: Lewa" name="button_loadHandPoseLeft" tool_tip="Kliknij, aby ustawić lewą rękę na wybranym ustawieniu" />
<button label="Ustaw: Prawa" name="button_loadHandPoseRight" tool_tip="Kliknij dwukrotnie, aby ustawić prawą rękę na wybranym ustawieniu" /> <button label="Ustaw: Prawa" name="button_loadHandPoseRight" tool_tip="Kliknij, aby ustawić prawą rękę na wybranym ustawieniu" />
</panel> </panel>
</tab_container> </tab_container>
<panel title="Różne" name="misc_joints_panel"> <panel title="Różne" name="misc_joints_panel">
@ -206,7 +209,7 @@
</scroll_list> </scroll_list>
<button name="refresh_avatars" tool_tip="Odśwież listę awatarów i animeszy" /> <button name="refresh_avatars" tool_tip="Odśwież listę awatarów i animeszy" />
<button label="Zacznij pozować" label_selected="Przestań pozować" tool_tip="Rozpocznij pozowanie wybranego awatara lub animesza, jeśli masz na to prawa" name="start_stop_posing_button" /> <button label="Zacznij pozować" label_selected="Przestań pozować" tool_tip="Rozpocznij pozowanie wybranego awatara lub animesza, jeśli masz na to prawa" name="start_stop_posing_button" />
<button label="Ustaw na T-Pozę" name="set_t_pose_button" tool_tip="Kliknij dwukrotnie, aby ustawić wybrany awatar w pozycji 'T'." /> <button label="Ustaw na T-Pozę" name="set_t_pose_button" tool_tip="Kliknij, aby ustawić wybranego awatara w pozycji 'T'." />
</panel> </panel>
<panel title="Inne" name="settings_panel"> <panel title="Inne" name="settings_panel">
<text name="trackpad_sensitivity_label">Czułość trackpada:</text> <text name="trackpad_sensitivity_label">Czułość trackpada:</text>
@ -215,6 +218,7 @@
<check_box name="stop_posing_on_close_checkbox" label="Stop pozy po zamknięciu" tool_tip="Brak zatrzymywania pozy może być pomocny, jeśli nie chcesz jej przypadkowo stracić." /> <check_box name="stop_posing_on_close_checkbox" label="Stop pozy po zamknięciu" tool_tip="Brak zatrzymywania pozy może być pomocny, jeśli nie chcesz jej przypadkowo stracić." />
<check_box name="reset_base_rotation_on_edit_checkbox" label="Reset bazy rotacji na edycji" tool_tip="Gdy po raz pierwszy edytujesz obrót, zresetuj go do zera. Oznacza to, że Twoja praca może zapisać pozę (a nie różnicę, patrz ładowanie / zapisywanie). Zielony 'ptaszek' pojawia się obok każdego wyzerowanego tak, wyeksportowanego stawu." /> <check_box name="reset_base_rotation_on_edit_checkbox" label="Reset bazy rotacji na edycji" tool_tip="Gdy po raz pierwszy edytujesz obrót, zresetuj go do zera. Oznacza to, że Twoja praca może zapisać pozę (a nie różnicę, patrz ładowanie / zapisywanie). Zielony 'ptaszek' pojawia się obok każdego wyzerowanego tak, wyeksportowanego stawu." />
<check_box name="also_save_bvh_checkbox" label="Twórz BVH podczas zapisu**" tool_tip="Podczas zapisywania pozy twórz również plik BVH, który można przesłać za pomocą 'Buduj > Prześlij > Animację', aby móc ustawiać siebie lub innych w świecie. Należy zresetować 'bazę' stawów do zera, ponieważ BVH wymaga oryginalnej pracy." /> <check_box name="also_save_bvh_checkbox" label="Twórz BVH podczas zapisu**" tool_tip="Podczas zapisywania pozy twórz również plik BVH, który można przesłać za pomocą 'Buduj > Prześlij > Animację', aby móc ustawiać siebie lub innych w świecie. Należy zresetować 'bazę' stawów do zera, ponieważ BVH wymaga oryginalnej pracy." />
<check_box name="confirm_overwrite_on_save_checkbox" label="Potwierdź nadpisanie" tool_tip="Gdy zapisujesz pozę, a plik już istnieje, musisz kliknąć przycisk zapisu ponownie, aby potwierdzić, że na pewno chcesz ją nadpisać." />
</panel> </panel>
</tab_container> </tab_container>
<button name="toggleVisualManipulators" tool_tip="Włącz / wyłącz manipulatory wizualne." /> <button name="toggleVisualManipulators" tool_tip="Włącz / wyłącz manipulatory wizualne." />
@ -257,12 +261,12 @@
<panel name="trackball_button_panel"> <panel name="trackball_button_panel">
<button name="undo_change" tool_tip="Cofnij ostatnią zmianę" /> <button name="undo_change" tool_tip="Cofnij ostatnią zmianę" />
<button name="button_redo_change" tool_tip="Ponów ostatnią cofniętą zmianę" /> <button name="button_redo_change" tool_tip="Ponów ostatnią cofniętą zmianę" />
<button name="poser_joint_reset" tool_tip="Kliknij dwukrotnie, aby zresetować wszystkie wybrane części ciała do stanu z momentu, w którym po raz pierwszy zacząłeś/aś pozować" /> <button name="poser_joint_reset" tool_tip="Kliknij, aby zresetować wszystkie wybrane części ciała do stanu z momentu, w którym po raz pierwszy zacząłeś/aś pozować" />
<button name="delta_mode_toggle" tool_tip="Jeśli zmienisz wiele stawów, każdy z nich zmieni się o tę samą wartość, zamiast wszystkie o taki sam obrót. Stosowany również do pozbywania się blokady Gimbala." /> <button name="delta_mode_toggle" tool_tip="Jeśli zmienisz wiele stawów, każdy z nich zmieni się o tę samą wartość, zamiast wszystkie o taki sam obrót. Stosowany również do pozbywania się blokady Gimbala." />
<button label="Odbij" name="button_toggleMirrorRotation" tool_tip="Zmień przeciwległy staw, jak w lustrze." /> <button label="Odbij" name="button_toggleMirrorRotation" tool_tip="Zmień przeciwległy staw, jak w lustrze." />
<button label="Sym." name="button_toggleSympatheticRotation" tool_tip="Zmień przeciwległy staw, ale w ten sam sposób." /> <button label="Sym." name="button_toggleSympatheticRotation" tool_tip="Zmień przeciwległy staw, ale w ten sam sposób." />
<button label="Kopia L &gt; P" name="button_symmetrize_left_to_right" tool_tip="Kliknij dwukrotnie, aby skopiować zmiany z lewej strony na prawą." /> <button label="Kopia L &gt; P" name="button_symmetrize_left_to_right" tool_tip="Kliknij, aby skopiować zmiany z lewej strony na prawą." />
<button label="Kopia P &gt; L" name="button_symmetrize_right_to_left" tool_tip="Kliknij dwukrotnie, aby skopiować zmiany z prawej strony na lewą." /> <button label="Kopia P &gt; L" name="button_symmetrize_right_to_left" tool_tip="Kliknij, aby skopiować zmiany z prawej strony na lewą." />
</panel> </panel>
</panel> </panel>
<panel name="poses_loadSave"> <panel name="poses_loadSave">

View File

@ -27,7 +27,7 @@
<combo_box.item label="Pokazuj tylko znajomych" name="2" /> <combo_box.item label="Pokazuj tylko znajomych" name="2" />
</combo_box> </combo_box>
<slider tool_tip="Kontroluje w jakim momencie awatar, który jest graficznie złożony zostanie zastąpiony przez mniej obciążającą komputer formę (tzw. JellyDoll)" label="Maks. szczegółowość awatarów:" name="IndirectMaxComplexity" /> <slider tool_tip="Kontroluje w jakim momencie awatar, który jest graficznie złożony zostanie zastąpiony przez mniej obciążającą komputer formę (tzw. JellyDoll)" label="Maks. szczegółowość awatarów:" name="IndirectMaxComplexity" />
<slider label="Maks. il. wyświetlanych awatarów:" name="IndirectMaxNonImpostors" /> <slider label="Maks. il. animowanych awatarów:" name="IndirectMaxNonImpostors" />
<slider label="Detale:" name="AvatarMeshDetail" /> <slider label="Detale:" name="AvatarMeshDetail" />
<text name="AvatarMeshDetailText"> <text name="AvatarMeshDetailText">
Mało Mało
@ -116,6 +116,15 @@
<combo_box.item label="Ręczne + podłoże" name="2" /> <combo_box.item label="Ręczne + podłoże" name="2" />
<combo_box.item label="Pełna scena" name="3" /> <combo_box.item label="Pełna scena" name="3" />
</combo_box> </combo_box>
<text name="ReflectionProbeCount">
Il. sond refleksyjnych:
</text>
<combo_box label="Il. sond refleksyjnych:" name="ProbeCount">
<combo_box.item label="Brak" name="1" />
<combo_box.item label="Mało" name="32" />
<combo_box.item label="Średnio" name="64" />
<combo_box.item label="Dużo" name="128" />
</combo_box>
<slider label="Ekspozycja:" name="RenderExposure" /> <slider label="Ekspozycja:" name="RenderExposure" />
<check_box label="Lustra" name="Mirrors" /> <check_box label="Lustra" name="Mirrors" />
<text name="MirrorResolutionText"> <text name="MirrorResolutionText">

View File

@ -89,6 +89,7 @@
<menu_item_call label="Nie chroń" name="UnprotectFolder" /> <menu_item_call label="Nie chroń" name="UnprotectFolder" />
<menu_item_call label="Przeładuj folder" name="ReloadFolder" /> <menu_item_call label="Przeładuj folder" name="ReloadFolder" />
<menu_item_call label="Kopiuj identyfikator UUID" name="Copy Asset UUID"/> <menu_item_call label="Kopiuj identyfikator UUID" name="Copy Asset UUID"/>
<menu_item_call label="Kopiuj UUID" name="Copy UUID" />
<menu_item_call label="Przywróć na ostatnią pozycję" name="Restore to Last Position" /> <menu_item_call label="Przywróć na ostatnią pozycję" name="Restore to Last Position" />
<menu_item_call label="Znajdź w widoku ogólnym" name="Show in Main Panel"/> <menu_item_call label="Znajdź w widoku ogólnym" name="Show in Main Panel"/>
<menu_item_call label="Pokaż w nowym oknie" name="Show in new Window" /> <menu_item_call label="Pokaż w nowym oknie" name="Show in new Window" />

View File

@ -463,6 +463,8 @@
<menu_item_call label="Wymuś wyjątek programu" name="Force Software Exception"/> <menu_item_call label="Wymuś wyjątek programu" name="Force Software Exception"/>
<menu_item_call label="Wymuś wyjątek systemu operacyjnego" name="Force OS Exception" /> <menu_item_call label="Wymuś wyjątek systemu operacyjnego" name="Force OS Exception" />
<menu_item_call label="Wymuś wyjątek we współprogramie (coroutine)" name="Force Software Exception in Coroutine" /> <menu_item_call label="Wymuś wyjątek we współprogramie (coroutine)" name="Force Software Exception in Coroutine" />
<menu_item_call label="Wymuś wyjątek w koroprocedurze" name="Force a Crash in a Coroprocedure" />
<menu_item_call label="Wymuś wyjątek w kolejce roboczej" name="Force a Crash in a Work Queue" />
<menu_item_call label="Wymuś awarię w wątku" name="Force a Crash in a Thread" /> <menu_item_call label="Wymuś awarię w wątku" name="Force a Crash in a Thread" />
<menu_item_call label="Wymuś rozłączenie Przeglądarki" name="Force Disconnect Viewer"/> <menu_item_call label="Wymuś rozłączenie Przeglądarki" name="Force Disconnect Viewer"/>
<menu_item_call label="Symulacja wycieku pamięci" name="Memory Leaking Simulation"/> <menu_item_call label="Symulacja wycieku pamięci" name="Memory Leaking Simulation"/>
@ -603,6 +605,7 @@
<menu_item_call label="Pokaż ustawienia kolorów" name="Color Settings" /> <menu_item_call label="Pokaż ustawienia kolorów" name="Color Settings" />
<menu_item_call label="Przeładuj ustawienia koloru" name="Reload Color Settings"/> <menu_item_call label="Przeładuj ustawienia koloru" name="Reload Color Settings"/>
<menu_item_call label="Pokaż test czcionki" name="Show Font Test"/> <menu_item_call label="Pokaż test czcionki" name="Show Font Test"/>
<menu_item_call label="Pokaż test SLapps" name="Show SLapps Test" />
<menu_item_call label="Wczytaj z XML" name="Load from XML"/> <menu_item_call label="Wczytaj z XML" name="Load from XML"/>
<menu_item_call label="Zapisz do XML" name="Save to XML"/> <menu_item_call label="Zapisz do XML" name="Save to XML"/>
<menu_item_check label="Pokaż nazwy XUI" name="Show XUI Names"/> <menu_item_check label="Pokaż nazwy XUI" name="Show XUI Names"/>

View File

@ -881,6 +881,11 @@ Plik może być za duży. Spróbuj zmniejszyć rozdzielczość, jakość lub spr
Przesyłanie zdjęcia nie powiodło się. Przesyłanie zdjęcia nie powiodło się.
Plik może być za duży. Spróbuj zmniejszyć rozdzielczość, jakość lub spróbować ponownie później. Plik może być za duży. Spróbuj zmniejszyć rozdzielczość, jakość lub spróbować ponownie później.
</notification>
<notification name="CannotOpenFileTooBig">
Nie można otworzyć pliku.
Podczas otwierania pliku w przeglądarce zabrakło pamięci. Plik może być za duży.
</notification> </notification>
<notification name="LandmarkCreated"> <notification name="LandmarkCreated">
Dodano "[LANDMARK_NAME]" do folderu [FOLDER_NAME]. Dodano "[LANDMARK_NAME]" do folderu [FOLDER_NAME].
@ -5424,6 +5429,10 @@ Czy chcesz kontynuować?
<notification name="NoSupportGLTFShader"> <notification name="NoSupportGLTFShader">
Sceny GLTF nie są jeszcze obsługiwane przez Twoją kartę graficzną. Sceny GLTF nie są jeszcze obsługiwane przez Twoją kartę graficzną.
</notification> </notification>
<notification name="WaterExclusionSurfacesWarning">
Zaznaczenie pola wyboru "ukryj wodę" spowoduje nadpisanie wybranych opcji tekstury, powierzchni i połysku.
<usetemplate name="okcancelbuttons" notext="Anuluj" yestext="Kontynuuj" />
</notification>
<notification name="EnableAutoFPSWarning"> <notification name="EnableAutoFPSWarning">
Zamierzasz włączyć funkcję AutoFPS. Wszystkie niezapisane ustawienia grafiki zostaną utracone. Zamierzasz włączyć funkcję AutoFPS. Wszystkie niezapisane ustawienia grafiki zostaną utracone.

View File

@ -272,9 +272,7 @@
<spinner name="rptctrl" label="Powtórzenia / metr" /> <spinner name="rptctrl" label="Powtórzenia / metr" />
<check_box label="Synchronizuj materiały" name="checkbox_sync_settings" tool_tip="Synchronizuj parametry map tekstur" /> <check_box label="Synchronizuj materiały" name="checkbox_sync_settings" tool_tip="Synchronizuj parametry map tekstur" />
<check_box label="Równaj powierzchnie planarne" name="checkbox planar align" tool_tip="Wyrównuj tekstury na wszystkich wybranych powierzchniach z powierzchnią wybraną jako ostatnia. Wymaga planarnego mapowania tekstur." /> <check_box label="Równaj powierzchnie planarne" name="checkbox planar align" tool_tip="Wyrównuj tekstury na wszystkich wybranych powierzchniach z powierzchnią wybraną jako ostatnia. Wymaga planarnego mapowania tekstur." />
<text name="tex gen"> <check_box label="Ukryj wodę" name="checkbox_hide_water" />
Mapowanie
</text>
<combo_box name="combobox texgen"> <combo_box name="combobox texgen">
<combo_box.item label="Domyślne" name="Default" /> <combo_box.item label="Domyślne" name="Default" />
<combo_box.item label="Planarne" name="Planar" /> <combo_box.item label="Planarne" name="Planar" />

View File

@ -204,6 +204,15 @@
<slider label="Jakość cieni" tool_tip="Określa jakość cieni (domyślnie 1)" name="ShadowResolution"/> <slider label="Jakość cieni" tool_tip="Określa jakość cieni (domyślnie 1)" name="ShadowResolution"/>
<slider label="Wielkość tekstur terenu (wymaga restartu)" name="RenderTerrainScale" tool_tip="Określa wielkość tekstur terenu - mniej oznacza: bardziej skompresowane (wymaga restartu)."/> <slider label="Wielkość tekstur terenu (wymaga restartu)" name="RenderTerrainScale" tool_tip="Określa wielkość tekstur terenu - mniej oznacza: bardziej skompresowane (wymaga restartu)."/>
<slider label="Wyostrzanie:" name="RenderSharpness" /> <slider label="Wyostrzanie:" name="RenderSharpness" />
<text name="ReflectionProbeCount">
Il. sond refleksyjnych:
</text>
<combo_box name="ProbeCount">
<combo_box.item label="Brak" name="1" />
<combo_box.item label="Mało" name="32" />
<combo_box.item label="Średnio" name="64" />
<combo_box.item label="Dużo" name="128" />
</combo_box>
<text name="TonemapTypeText"> <text name="TonemapTypeText">
Tone mapping: Tone mapping:
</text> </text>

View File

@ -23,6 +23,7 @@
Blask Blask
</text> </text>
<check_box label="Superjasność" name="checkbox fullbright" /> <check_box label="Superjasność" name="checkbox fullbright" />
<check_box label="Ukryj wodę" name="checkbox_hide_water" />
<button name="copy_face_btn" tool_tip="Skopiuj parametry tekstury do schowka" /> <button name="copy_face_btn" tool_tip="Skopiuj parametry tekstury do schowka" />
<button name="paste_face_btn" tool_tip="Wklej parametry tekstury ze schowka" /> <button name="paste_face_btn" tool_tip="Wklej parametry tekstury ze schowka" />
<text name="label_matmedia"> <text name="label_matmedia">

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="emojipicker" title="Выберите эмодзи"> <floater name="emojipicker" title="Выберите эмодзи">
<floater.string name="title_for_recently_used" value="Недавно использованный"/>
<floater.string name="title_for_frequently_used" value="Часто используемый"/> <floater.string name="title_for_frequently_used" value="Часто используемый"/>
<floater.string name="text_no_emoji_for_filter" value="Не найдено эмодзи для '[FILTER]'"/> <floater.string name="text_no_emoji_for_filter" value="Не найдено эмодзи для '[FILTER]'"/>
<text name="Dummy">Эмодзи не выбраны</text> <text name="Dummy">Эмодзи не выбраны</text>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="emojipicker"> <floater name="emojipicker">
<floater.string name="title_for_recently_used" value="最近" />
<floater.string name="text_no_emoji_for_filter" value="未找到'[FILTER]'表情符號" /> <floater.string name="text_no_emoji_for_filter" value="未找到'[FILTER]'表情符號" />
<floater.string name="title_for_frequently_used" value="常用" /> <floater.string name="title_for_frequently_used" value="常用" />
<text name="Dummy">未選擇表情符號</text> <text name="Dummy">未選擇表情符號</text>

View File

@ -309,38 +309,38 @@ if [ ! -d `dirname "$LOG"` ] ; then
mkdir -p `dirname "$LOG"` mkdir -p `dirname "$LOG"`
fi fi
echo -e "configure_firestorm.sh" > $LOG echo -e "configure_firestorm.sh" > "$LOG"
echo -e " PLATFORM: $TARGET_PLATFORM" | tee -a $LOG echo -e " PLATFORM: $TARGET_PLATFORM" | tee -a "$LOG"
echo -e " KDU: `b2a $WANTS_KDU`" | tee -a $LOG echo -e " KDU: `b2a $WANTS_KDU`" | tee -a "$LOG"
echo -e " FMODSTUDIO: `b2a $WANTS_FMODSTUDIO`" | tee -a $LOG echo -e " FMODSTUDIO: `b2a $WANTS_FMODSTUDIO`" | tee -a "$LOG"
echo -e " OPENAL: `b2a $WANTS_OPENAL`" | tee -a $LOG echo -e " OPENAL: `b2a $WANTS_OPENAL`" | tee -a "$LOG"
echo -e " OPENSIM: `b2a $WANTS_OPENSIM`" | tee -a $LOG echo -e " OPENSIM: `b2a $WANTS_OPENSIM`" | tee -a "$LOG"
if [ $WANTS_SINGLEGRID -eq $TRUE ] ; then if [ $WANTS_SINGLEGRID -eq $TRUE ] ; then
echo -e " SINGLEGRID: `b2a $WANTS_SINGLEGRID` ($SINGLEGRID_URI)" | tee -a $LOG echo -e " SINGLEGRID: `b2a $WANTS_SINGLEGRID` ($SINGLEGRID_URI)" | tee -a "$LOG"
else else
echo -e " SINGLEGRID: `b2a $WANTS_SINGLEGRID`" | tee -a $LOG echo -e " SINGLEGRID: `b2a $WANTS_SINGLEGRID`" | tee -a "$LOG"
fi fi
echo -e " HAVOK: `b2a $WANTS_HAVOK`" | tee -a $LOG echo -e " HAVOK: `b2a $WANTS_HAVOK`" | tee -a "$LOG"
echo -e " AVX: `b2a $WANTS_AVX`" | tee -a $LOG echo -e " AVX: `b2a $WANTS_AVX`" | tee -a "$LOG"
echo -e " AVX2: `b2a $WANTS_AVX2`" | tee -a $LOG echo -e " AVX2: `b2a $WANTS_AVX2`" | tee -a "$LOG"
echo -e " TRACY: `b2a $WANTS_TRACY`" | tee -a $LOG echo -e " TRACY: `b2a $WANTS_TRACY`" | tee -a "$LOG"
echo -e " CRASHREPORTING: `b2a $WANTS_CRASHREPORTING`" | tee -a $LOG echo -e " CRASHREPORTING: `b2a $WANTS_CRASHREPORTING`" | tee -a "$LOG"
if [ $WANTS_TESTBUILD -eq $TRUE ] ; then if [ $WANTS_TESTBUILD -eq $TRUE ] ; then
echo -e " TESTBUILD: `b2a $WANTS_TESTBUILD` ($TESTBUILD_PERIOD days)" | tee -a $LOG echo -e " TESTBUILD: `b2a $WANTS_TESTBUILD` ($TESTBUILD_PERIOD days)" | tee -a "$LOG"
else else
echo -e " TESTBUILD: `b2a $WANTS_TESTBUILD`" | tee -a $LOG echo -e " TESTBUILD: `b2a $WANTS_TESTBUILD`" | tee -a "$LOG"
fi fi
echo -e " PACKAGE: `b2a $WANTS_PACKAGE`" | tee -a $LOG echo -e " PACKAGE: `b2a $WANTS_PACKAGE`" | tee -a "$LOG"
echo -e " CLEAN: `b2a $WANTS_CLEAN`" | tee -a $LOG echo -e " CLEAN: `b2a $WANTS_CLEAN`" | tee -a "$LOG"
echo -e " BUILD: `b2a $WANTS_BUILD`" | tee -a $LOG echo -e " BUILD: `b2a $WANTS_BUILD`" | tee -a "$LOG"
echo -e " CONFIG: `b2a $WANTS_CONFIG`" | tee -a $LOG echo -e " CONFIG: `b2a $WANTS_CONFIG`" | tee -a "$LOG"
echo -e " NINJA: `b2a $WANTS_NINJA`" | tee -a $LOG echo -e " NINJA: `b2a $WANTS_NINJA`" | tee -a "$LOG"
echo -e " VSCODE: `b2a $WANTS_VSCODE`" | tee -a $LOG echo -e " VSCODE: `b2a $WANTS_VSCODE`" | tee -a "$LOG"
echo -e " COMPILER CACHE: `b2a $WANTS_CACHE`" | tee -a $LOG echo -e " COMPILER CACHE: `b2a $WANTS_CACHE`" | tee -a "$LOG"
echo -e " PASSTHRU: $LL_ARGS_PASSTHRU" | tee -a $LOG echo -e " PASSTHRU: $LL_ARGS_PASSTHRU" | tee -a "$LOG"
echo -e " BTYPE: $BTYPE" | tee -a $LOG echo -e " BTYPE: $BTYPE" | tee -a "$LOG"
if [ $TARGET_PLATFORM == "linux" -o $TARGET_PLATFORM == "darwin" ] ; then if [ $TARGET_PLATFORM == "linux" -o $TARGET_PLATFORM == "darwin" ] ; then
echo -e " JOBS: $JOBS" | tee -a $LOG echo -e " JOBS: $JOBS" | tee -a "$LOG"
fi fi
echo -e " Logging to $LOG" echo -e " Logging to $LOG"
@ -590,7 +590,7 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then
cmake -G "$TARGET" $CMAKE_ARCH ../indra $CHANNEL ${GITHASH} $FMODSTUDIO $OPENAL $KDU $OPENSIM $SINGLEGRID $HAVOK $AVX_OPTIMIZATION $AVX2_OPTIMIZATION $TRACY_PROFILER $TESTBUILD $PACKAGE \ cmake -G "$TARGET" $CMAKE_ARCH ../indra $CHANNEL ${GITHASH} $FMODSTUDIO $OPENAL $KDU $OPENSIM $SINGLEGRID $HAVOK $AVX_OPTIMIZATION $AVX2_OPTIMIZATION $TRACY_PROFILER $TESTBUILD $PACKAGE \
$UNATTENDED -DLL_TESTS:BOOL=OFF -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DCMAKE_BUILD_TYPE:STRING=$BTYPE $CACHE_OPT \ $UNATTENDED -DLL_TESTS:BOOL=OFF -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DCMAKE_BUILD_TYPE:STRING=$BTYPE $CACHE_OPT \
$CRASH_REPORTING -DVIEWER_SYMBOL_FILE:STRING="${VIEWER_SYMBOL_FILE:-}" $LL_ARGS_PASSTHRU ${VSCODE_FLAGS:-} | tee $LOG $CRASH_REPORTING -DVIEWER_SYMBOL_FILE:STRING="${VIEWER_SYMBOL_FILE:-}" $LL_ARGS_PASSTHRU ${VSCODE_FLAGS:-} | tee "$LOG"
if [ $TARGET_PLATFORM == "windows" -a $USE_VSTOOL -eq $TRUE ] ; then if [ $TARGET_PLATFORM == "windows" -a $USE_VSTOOL -eq $TRUE ] ; then
echo "Setting startup project via vstool" echo "Setting startup project via vstool"
@ -610,16 +610,16 @@ if [ $WANTS_BUILD -eq $TRUE ] ; then
else else
JOBS="-jobs $JOBS" JOBS="-jobs $JOBS"
fi fi
xcodebuild -configuration $BTYPE -project Firestorm.xcodeproj $JOBS 2>&1 | tee -a $LOG xcodebuild -configuration $BTYPE -project Firestorm.xcodeproj $JOBS 2>&1 | tee -a "$LOG"
elif [ $TARGET_PLATFORM == "linux" ] ; then elif [ $TARGET_PLATFORM == "linux" ] ; then
if [ $JOBS == "0" ] ; then if [ $JOBS == "0" ] ; then
JOBS=`cat /proc/cpuinfo | grep processor | wc -l` JOBS=`cat /proc/cpuinfo | grep processor | wc -l`
echo $JOBS echo $JOBS
fi fi
if [ $WANTS_NINJA -eq $TRUE ] ; then if [ $WANTS_NINJA -eq $TRUE ] ; then
ninja -j $JOBS | tee -a $LOG ninja -j $JOBS | tee -a "$LOG"
else else
make -j $JOBS | tee -a $LOG make -j $JOBS | tee -a "$LOG"
fi fi
elif [ $TARGET_PLATFORM == "windows" ] ; then elif [ $TARGET_PLATFORM == "windows" ] ; then
msbuild.exe Firestorm.sln -p:Configuration=${BTYPE} -flp:LogFile="logs\\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log" \ msbuild.exe Firestorm.sln -p:Configuration=${BTYPE} -flp:LogFile="logs\\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log" \