Ansariel 2024-10-31 18:34:32 +01:00
commit 79dd14565d
38 changed files with 1916 additions and 1740 deletions

View File

@ -134,8 +134,12 @@ jobs:
# Create the Tag (Conditional)
- name: Create tag
if: >
${{ steps.get_inputs.outputs.dry_run != 'true' &&
steps.check_tag.outputs.tag_exists == 'false' }}
${{
steps.get_inputs.outputs.release_type != 'Nightly' &&
steps.get_inputs.outputs.release_type != 'Manual' &&
steps.get_inputs.outputs.release_type != 'Profiling' &&
steps.get_inputs.outputs.dry_run != 'true' &&
steps.check_tag.outputs.tag_exists == 'false' }}
run: |
echo "Creating tag: ${{ steps.get_tag.outputs.tag_name }}"
git tag ${{ steps.get_tag.outputs.tag_name }}

View File

@ -573,7 +573,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
{
motion_list_t::iterator curiter = iter++;
LLMotion* motionp = *curiter;
if (motionp->getBlendType() != anim_type)
if (!motionp || motionp->getBlendType() != anim_type) // <FS:Beq/> FIRE-34767 - null pointer dereference
{
continue;
}

View File

@ -571,7 +571,7 @@ bool LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
return true;
}
bool LLPanel::hasString(std::string_view name)
bool LLPanel::hasString(std::string_view name) const
{
return mUIStrings.find(name) != mUIStrings.end();
}

View File

@ -169,7 +169,7 @@ public:
void initFromParams(const Params& p);
bool initPanelXML( LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node, const LLPanel::Params& default_params);
bool hasString(std::string_view name);
bool hasString(std::string_view name) const;
std::string getString(std::string_view name, const LLStringUtil::format_map_t& args) const;
std::string getString(std::string_view name) const;

View File

@ -726,7 +726,7 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl)
}
void LLWebRTCPeerConnectionImpl::terminate()
{
mWebRTCImpl->SignalingBlockingCall(
mWebRTCImpl->PostSignalingTask(
[this]()
{
if (mPeerConnection)

View File

@ -3403,7 +3403,7 @@ bool LLXMLNode::fromXMLRPCValue(LLSD& target)
if (childp->hasName("string"))
{
target.assign(LLStringFn::xml_decode(childp->getTextContents()));
target.assign(childp->getValue());
return true;
}

View File

@ -8067,17 +8067,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>FSPoserSaveBvhFileAlso</key>
<map>
<key>Comment</key>
<string>Whether to save a BVH file as well when saving a pose.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSPoserTrackpadSensitivity</key>
<map>
<key>Comment</key>

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,14 @@
#include "llfloater.h"
#include "fsposeranimator.h"
class FSVirtualTrackpad;
class LLButton;
class LLCheckBoxCtrl;
class LLLineEditor;
class LLScrollListCtrl;
class LLSliderCtrl;
class LLTabContainer;
/// <summary>
/// Describes how to load a pose file.
/// </summary>
@ -68,23 +76,16 @@ class FSFloaterPoser : public LLFloater
friend class LLFloaterReg;
FSFloaterPoser(const LLSD &key);
private:
/*virtual*/ ~FSFloaterPoser();
/*virtual*/ bool postBuild();
/*virtual*/ void draw();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
private:
bool postBuild() override;
void onOpen(const LLSD& key) override;
void onClose(bool app_quitting) override;
/// <summary>
/// The amount of deflection 'one unit' on the trackpad translates to in radians.
/// The trackpad ordinarily has a range of +1..-1; multiplied by PI, gives PI to -PI, or all 360 degrees of deflection.
/// </summary>
const F32 normalTrackpadRangeInRads = F_PI;
/// <summary>
/// Refreshes the supplied pose list from the supplued subdirectory.
/// </summary>
void refreshPoseScroll(std::string_view scrollListName, std::string_view subDirectory);
void refreshPoseScroll(LLScrollListCtrl* posesScrollList, std::optional<std::string_view> subDirectory = std::nullopt);
/// <summary>
/// (Dis)Enables all of the posing controls; such as when you can't pose for reasons.
@ -105,7 +106,7 @@ class FSFloaterPoser : public LLFloater
/// This does a lookup into the poser XML for a friendly header title by joint name, if it exists.
/// </param>
/// <param name="bodyJointsScrollList">The scroll list to add the header-row to.</param>
void AddHeaderRowToScrollList(std::string jointName, LLScrollListCtrl *bodyJointsScrollList);
void addHeaderRowToScrollList(const std::string& jointName, LLScrollListCtrl* bodyJointsScrollList);
/// <summary>
/// Generates the data for a row to add to a scroll-list.
@ -114,52 +115,52 @@ class FSFloaterPoser : public LLFloater
/// <param name="jointName">The well-known joint name of the joint to add the row for, eg: mChest.</param>
/// <param name="isHeaderRow">Whether the joint is one which should come immediately after a header.</param>
/// <returns>The data required to make the row.</returns>
LLSD createRowForJoint(std::string jointName, bool isHeaderRow);
LLSD createRowForJoint(const std::string& jointName, bool isHeaderRow);
/// <summary>
/// Gets the collection of poser joints currently selected on the active bones-tab of the UI.
/// </summary>
/// <returns>The selected joints</returns>
std::vector<FSPoserAnimator::FSPoserJoint *> getUiSelectedPoserJoints() const;
std::vector<FSPoserAnimator::FSPoserJoint*> getUiSelectedPoserJoints() const;
/// <summary>
/// Gets a detectable avatar by its UUID.
/// </summary>
/// <param name="avatarToFind">The ID of the avatar to find.</param>
/// <returns>The avatar, if found, otherwise nullptr.</returns>
LLVOAvatar* getAvatarByUuid(LLUUID avatarToFind);
LLVOAvatar* getAvatarByUuid(const LLUUID& avatarToFind) const;
/// <summary>
/// Gets the currently selected avatar or animesh.
/// </summary>
/// <returns>The currently selected avatar or animesh.</returns>
LLVOAvatar *getUiSelectedAvatar();
LLVOAvatar* getUiSelectedAvatar() const;
/// <summary>
/// Gets the current bone-deflection style: encapsulates 'anything else you want to do' while you're manipulating a joint.
/// Such as: fiddle the opposite joint too.
/// </summary>
/// <returns>A E_BoneDeflectionStyles member.</returns>
E_BoneDeflectionStyles getUiSelectedBoneDeflectionStyle();
E_BoneDeflectionStyles getUiSelectedBoneDeflectionStyle() const;
/// <summary>
/// Gets the collection of UUIDs for nearby avatars.
/// </summary>
/// <returns>A the collection of UUIDs for nearby avatars.</returns>
uuid_vec_t getNearbyAvatarsAndAnimeshes();
uuid_vec_t getNearbyAvatarsAndAnimeshes() const;
/// <summary>
/// Gets a collection of UUIDs for avatars currently being presented on the UI.
/// </summary>
/// <returns>A the collection of UUIDs.</returns>
uuid_vec_t getCurrentlyListedAvatarsAndAnimeshes();
uuid_vec_t getCurrentlyListedAvatarsAndAnimeshes() const;
/// <summary>
/// Gets the scroll-list index of the supplied avatar.
/// </summary>
/// <param name="toFind">The avatar UUID to find on the avatars scroll list.</param>
/// <returns>The scroll-list index for the supplied avatar, if found, otherwise -1.</returns>
S32 getAvatarListIndexForUuid(LLUUID toFind);
S32 getAvatarListIndexForUuid(const LLUUID& toFind) const;
/// <summary>
/// There are several control-callbacks manipulating rotations etc, they all devolve to these.
@ -182,21 +183,20 @@ class FSFloaterPoser : public LLFloater
/// There may be +/- PI difference two axes, because harmonics.
/// Thus keep your UI synced with less gets.
/// </remarks>
LLVector3 getRotationOfFirstSelectedJoint();
LLVector3 getPositionOfFirstSelectedJoint();
LLVector3 getScaleOfFirstSelectedJoint();
LLVector3 getRotationOfFirstSelectedJoint() const;
LLVector3 getPositionOfFirstSelectedJoint() const;
LLVector3 getScaleOfFirstSelectedJoint() const;
// Pose load/save
void onToggleLoadSavePanel();
void onClickPoseSave();
void onPoseFileSelect();
bool savePoseToXml(LLVOAvatar* avatar, std::string posePath);
bool savePoseToBvh(LLVOAvatar* avatar, std::string posePath);
bool savePoseToXml(LLVOAvatar* avatar, const std::string& posePath);
void onClickBrowsePoseCache();
void onPoseMenuAction(const LLSD& param);
void loadPoseFromXml(LLVOAvatar* avatar, std::string poseFileName, E_LoadPoseMethods loadMethod);
void loadPoseFromXml(LLVOAvatar* avatar, const std::string& poseFileName, E_LoadPoseMethods loadMethod);
void setPoseSaveFileTextBoxToUiSelectedAvatarSaveFileName();
void setUiSelectedAvatarSaveFileName(std::string saveFileName);
void setUiSelectedAvatarSaveFileName(const std::string& saveFileName);
void showOrHideAdvancedSaveOptions();
// UI Event Handlers:
@ -246,20 +246,20 @@ class FSFloaterPoser : public LLFloater
/// </summary>
/// <param name="avatar">The avatar to animate.</param>
/// <returns>True if we have permission to animate, otherwise false.</returns>
bool havePermissionToAnimateAvatar(LLVOAvatar *avatar);
bool havePermissionToAnimateAvatar(LLVOAvatar* avatar) const;
/// <summary>
/// Determines if we could animate the supplied avatar.
/// </summary>
/// <param name="avatar">The avatar to animate.</param>
/// <returns>True if the avatar is non-null, not dead, in the same region as self, otherwise false.</returns>
bool couldAnimateAvatar(LLVOAvatar *avatar);
bool couldAnimateAvatar(LLVOAvatar* avatar) const;
/// <summary>
/// Our instance of the class which lets us do the business of manipulating the avatar.
/// This separates that business from the code-behind the UI.
/// </summary>
FSPoserAnimator _poserAnimator;
FSPoserAnimator mPoserAnimator;
/// <summary>
/// The supplied Joint name has a quaternion describing its rotation.
@ -274,14 +274,14 @@ class FSFloaterPoser : public LLFloater
/// No the translation isn't untangling all of that, it's not needed until it is.
/// We're not landing on Mars with this code, just offering a user reasonable thumb-twiddlings.
/// </remarks>
E_BoneAxisTranslation getJointTranslation(std::string jointName);
E_BoneAxisTranslation getJointTranslation(const std::string& jointName) const;
/// <summary>
/// Gets the collection of E_BoneAxisNegation values for the supplied joint.
/// </summary>
/// <param name="jointName">The name of the joind to get the axis transformation for.</param>
/// <returns>The kind of axis transformation to perform.</returns>
S32 getJointNegation(std::string jointName);
S32 getJointNegation(const std::string& jointName) const;
/// <summary>
/// The smallest text embiggens the noble selection.
@ -293,18 +293,18 @@ class FSFloaterPoser : public LLFloater
/// </summary>
/// <param name="listName">The name of the list to adjust text-face for.</param>
/// <param name="avatar">The avatar to whom the list is relevant.</param>
void addBoldToScrollList(std::string listName, LLVOAvatar *avatar);
void addBoldToScrollList(LLScrollListCtrl* list, LLVOAvatar* avatar);
/// <summary>
/// The time when the last click of a button was made.
/// Utilized for controls needing a 'double click do' function.
/// </summary>
std::chrono::system_clock::time_point _timeLastClickedJointReset = std::chrono::system_clock::now();
std::chrono::system_clock::time_point mTimeLastClickedJointReset = std::chrono::system_clock::now();
/// <summary>
/// The constant time interval, in seconds, a user must click twice within to successfully double-click a button.
/// </summary>
std::chrono::duration<double> const _doubleClickInterval = std::chrono::duration<double>(0.3);
std::chrono::duration<double> const mDoubleClickInterval = std::chrono::duration<double>(0.3);
/// <summary>
/// Unwraps a normalized value from the trackball to a slider value.
@ -312,6 +312,65 @@ class FSFloaterPoser : public LLFloater
/// <param name="scale">The scale value from the trackball.</param>
/// <returns>A value appropriate for fitting a slider.</returns>
static F32 unWrapScale(F32 scale);
FSVirtualTrackpad* mAvatarTrackball{ nullptr };
LLSliderCtrl* mTrackpadSensitivitySlider{ nullptr };
LLSliderCtrl* mLimbYawSlider{ nullptr };
LLSliderCtrl* mLimbPitchSlider{ nullptr }; // pointing your nose up or down
LLSliderCtrl* mLimbRollSlider{ nullptr }; // your ear touches your shoulder
LLSliderCtrl* mPosXSlider{ nullptr };
LLSliderCtrl* mPosYSlider{ nullptr };
LLSliderCtrl* mPosZSlider{ nullptr };
LLSliderCtrl* mAdvPosXSlider{ nullptr };
LLSliderCtrl* mAdvPosYSlider{ nullptr };
LLSliderCtrl* mAdvPosZSlider{ nullptr };
LLSliderCtrl* mAdvScaleXSlider{ nullptr };
LLSliderCtrl* mAdvScaleYSlider{ nullptr };
LLSliderCtrl* mAdvScaleZSlider{ nullptr };
LLTabContainer* mJointsTabs{ nullptr };
LLTabContainer* mHandsTabs{ nullptr };
LLScrollListCtrl* mAvatarSelectionScrollList{ nullptr };
LLScrollListCtrl* mBodyJointsScrollList{ nullptr };
LLScrollListCtrl* mFaceJointsScrollList{ nullptr };
LLScrollListCtrl* mHandJointsScrollList{ nullptr };
LLScrollListCtrl* mMiscJointsScrollList{ nullptr };
LLScrollListCtrl* mCollisionVolumesScrollList{ nullptr };
LLScrollListCtrl* mEntireAvJointScroll{ nullptr };
LLScrollListCtrl* mPosesScrollList{ nullptr };
LLScrollListCtrl* mHandPresetsScrollList{ nullptr };
LLButton* mToggleAdvancedPanelBtn{ nullptr };
LLButton* mStartStopPosingBtn{ nullptr };
LLButton* mToggleLoadSavePanelBtn{ nullptr };
LLButton* mBrowserFolderBtn{ nullptr };
LLButton* mLoadPosesBtn{ nullptr };
LLButton* mSavePosesBtn{ nullptr };
LLButton* mFlipPoseBtn{ nullptr };
LLButton* mFlipJointBtn{ nullptr };
LLButton* mRecaptureBtn{ nullptr };
LLButton* mTogglePosingBonesBtn{ nullptr };
LLButton* mToggleMirrorRotationBtn{ nullptr };
LLButton* mToggleSympatheticRotationBtn{ nullptr };
LLButton* mToggleDeltaModeBtn{ nullptr };
LLButton* mRedoChangeBtn{ nullptr };
LLCheckBoxCtrl* mAlsoSaveBvhCbx{ nullptr };
LLLineEditor* mPoseSaveNameEditor{ nullptr };
LLPanel* mAdvancedParentPnl{ nullptr };
LLPanel* mJointsParentPnl{ nullptr };
LLPanel* mTrackballPnl{ nullptr };
LLPanel* mPositionRotationPnl{ nullptr };
LLPanel* mBodyJointsPnl{ nullptr };
LLPanel* mFaceJointsPnl{ nullptr };
LLPanel* mHandsJointsPnl{ nullptr };
LLPanel* mMiscJointsPnl{ nullptr };
LLPanel* mCollisionVolumesPnl{ nullptr };
LLPanel* mSaveFilePptionsPnl{ nullptr };
LLPanel* mPosesLoadSavePnl{ nullptr };
};
#endif

View File

@ -567,7 +567,7 @@ void FSPanelLogin::setFields(LLPointer<LLCredential> credential, bool from_start
// We don't actually use the password input field,
// fill it with MAX_PASSWORD_SL characters so we get a
// nice row of asterisks.
const std::string filler("123456789!123456");
const std::string filler("Enter a password");
sInstance->getChild<LLLineEditor>("password_edit")->setText(filler);
sInstance->mPasswordLength = filler.length();
sInstance->updateLoginButtons();

View File

@ -31,11 +31,9 @@
#include "llagent.h"
#include "fsposingmotion.h"
FSPoserAnimator::FSPoserAnimator() {}
FSPoserAnimator::~FSPoserAnimator() {}
std::map<LLUUID, LLAssetID> FSPoserAnimator::_avatarIdToRegisteredAnimationId;
std::map<LLUUID, LLAssetID> FSPoserAnimator::sAvatarIdToRegisteredAnimationId;
bool FSPoserAnimator::isPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint)
bool FSPoserAnimator::isPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint)
{
if (!isAvatarSafeToUse(avatar))
return false;
@ -54,7 +52,7 @@ bool FSPoserAnimator::isPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint
return posingMotion->currentlyPosingJoint(jointPose);
}
void FSPoserAnimator::setPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint, bool shouldPose)
void FSPoserAnimator::setPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, bool shouldPose)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -80,7 +78,7 @@ void FSPoserAnimator::setPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint join
posingMotion->removeJointFromState(jointPose);
}
void FSPoserAnimator::resetAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint)
void FSPoserAnimator::resetAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -100,7 +98,7 @@ void FSPoserAnimator::resetAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint)
jointPose->setTargetRotation(jointPose->getBeginningRotation());
}
void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -128,7 +126,7 @@ void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joi
oppositeJointPose->undoLastRotationSet();
}
void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -156,7 +154,7 @@ void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joi
oppositeJointPose->undoLastPositionSet();
}
void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -184,7 +182,7 @@ void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint,
oppositeJointPose->undoLastScaleSet();
}
void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -212,7 +210,7 @@ void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, FSPoserJoint joint,
oppositeJointPose->setTargetPosition(oppositeJointPose->getBeginningPosition());
}
void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -240,7 +238,7 @@ void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_
oppositeJointPose->setTargetScale(oppositeJointPose->getBeginningScale());
}
bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, FSPoserJoint joint)
bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint)
{
if (!isAvatarSafeToUse(avatar))
return false;
@ -259,7 +257,7 @@ bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, FSPoserJoint join
return jointPose->canRedoRotation();
}
void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -287,7 +285,7 @@ void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joi
oppositeJointPose->redoLastRotationSet();
}
void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -315,7 +313,7 @@ void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joi
oppositeJointPose->redoLastPositionSet();
}
void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -343,7 +341,7 @@ void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint,
oppositeJointPose->redoLastScaleSet();
}
LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, bool forRecapture)
LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture) const
{
LLVector3 pos;
if (!isAvatarSafeToUse(avatar))
@ -365,7 +363,7 @@ LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, FSPoserJoint joi
return pos;
}
void FSPoserAnimator::setJointPosition(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 position, E_BoneDeflectionStyles style)
void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& position, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -414,7 +412,7 @@ void FSPoserAnimator::setJointPosition(LLVOAvatar *avatar, const FSPoserJoint *j
}
}
LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar *avatar, FSPoserJoint joint, E_BoneAxisTranslation translation, S32 negation, bool forRecapture)
LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation, bool forRecapture) const
{
LLVector3 vec3;
if (!isAvatarSafeToUse(avatar))
@ -437,7 +435,7 @@ LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar *avatar, FSPoserJoint joi
return translateRotationFromQuaternion(translation, negation, rot);
}
void FSPoserAnimator::setJointRotation(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 rotation, E_BoneDeflectionStyles style,
void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& rotation, E_BoneDeflectionStyles style,
E_BoneAxisTranslation translation, S32 negation)
{
if (!isAvatarSafeToUse(avatar))
@ -492,7 +490,7 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar *avatar, const FSPoserJoint *j
}
}
void FSPoserAnimator::reflectJoint(LLVOAvatar *avatar, const FSPoserJoint *joint)
void FSPoserAnimator::reflectJoint(LLVOAvatar* avatar, const FSPoserJoint* joint)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -526,7 +524,7 @@ void FSPoserAnimator::reflectJoint(LLVOAvatar *avatar, const FSPoserJoint *joint
oppositeJointPose->setTargetRotation(first_inv);
}
void FSPoserAnimator::flipEntirePose(LLVOAvatar *avatar)
void FSPoserAnimator::flipEntirePose(LLVOAvatar* avatar)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -553,8 +551,7 @@ void FSPoserAnimator::flipEntirePose(LLVOAvatar *avatar)
}
// from the UI to the bone, the inverse translation, the un-swap, the backwards
LLQuaternion FSPoserAnimator::translateRotationToQuaternion(E_BoneAxisTranslation translation, S32 negation,
LLVector3 rotation)
LLQuaternion FSPoserAnimator::translateRotationToQuaternion(E_BoneAxisTranslation translation, S32 negation, LLVector3 rotation)
{
if (negation & NEGATE_ALL)
{
@ -608,7 +605,7 @@ LLQuaternion FSPoserAnimator::translateRotationToQuaternion(E_BoneAxisTranslatio
}
// from the bone to the UI; this is the 'forwards' use of the enum
LLVector3 FSPoserAnimator::translateRotationFromQuaternion(E_BoneAxisTranslation translation, S32 negation, LLQuaternion rotation)
LLVector3 FSPoserAnimator::translateRotationFromQuaternion(E_BoneAxisTranslation translation, S32 negation, const LLQuaternion& rotation) const
{
LLVector3 vec3;
@ -659,7 +656,7 @@ LLVector3 FSPoserAnimator::translateRotationFromQuaternion(E_BoneAxisTranslation
return vec3;
}
LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, FSPoserJoint joint, bool forRecapture)
LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture) const
{
LLVector3 scale;
if (!isAvatarSafeToUse(avatar))
@ -681,7 +678,7 @@ LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, FSPoserJoint joint,
return scale;
}
void FSPoserAnimator::setJointScale(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 scale, E_BoneDeflectionStyles style)
void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& scale, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -712,7 +709,7 @@ void FSPoserAnimator::setJointScale(LLVOAvatar *avatar, const FSPoserJoint *join
oppositeJointPose->setTargetScale(scale);
}
const FSPoserAnimator::FSPoserJoint* FSPoserAnimator::getPoserJointByName(std::string jointName)
const FSPoserAnimator::FSPoserJoint* FSPoserAnimator::getPoserJointByName(const std::string& jointName)
{
for (size_t index = 0; index != PoserJoints.size(); ++index)
{
@ -758,7 +755,7 @@ void FSPoserAnimator::stopPosingAvatar(LLVOAvatar *avatar)
avatar->stopMotion(posingMotion->motionId());
}
bool FSPoserAnimator::isPosingAvatar(LLVOAvatar* avatar)
bool FSPoserAnimator::isPosingAvatar(LLVOAvatar* avatar) const
{
if (!isAvatarSafeToUse(avatar))
return false;
@ -770,15 +767,15 @@ bool FSPoserAnimator::isPosingAvatar(LLVOAvatar* avatar)
return !posingMotion->isStopped();
}
FSPosingMotion* FSPoserAnimator::getPosingMotion(LLVOAvatar* avatar)
FSPosingMotion* FSPoserAnimator::getPosingMotion(LLVOAvatar* avatar) const
{
if (!isAvatarSafeToUse(avatar))
return nullptr;
if (_avatarIdToRegisteredAnimationId.find(avatar->getID()) == _avatarIdToRegisteredAnimationId.end())
if (sAvatarIdToRegisteredAnimationId.find(avatar->getID()) == sAvatarIdToRegisteredAnimationId.end())
return nullptr;
return dynamic_cast<FSPosingMotion*>(avatar->findMotion(_avatarIdToRegisteredAnimationId[avatar->getID()]));
return dynamic_cast<FSPosingMotion*>(avatar->findMotion(sAvatarIdToRegisteredAnimationId[avatar->getID()]));
}
FSPosingMotion* FSPoserAnimator::findOrCreatePosingMotion(LLVOAvatar* avatar)
@ -792,7 +789,7 @@ FSPosingMotion* FSPoserAnimator::findOrCreatePosingMotion(LLVOAvatar* avatar)
LLAssetID animationAssetId = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
if (avatar->registerMotion(animationAssetId, FSPosingMotion::create))
_avatarIdToRegisteredAnimationId[avatar->getID()] = animationAssetId;
sAvatarIdToRegisteredAnimationId[avatar->getID()] = animationAssetId;
return dynamic_cast<FSPosingMotion*>(avatar->createMotion(animationAssetId));
}
@ -800,7 +797,7 @@ FSPosingMotion* FSPoserAnimator::findOrCreatePosingMotion(LLVOAvatar* avatar)
return motion;
}
bool FSPoserAnimator::isAvatarSafeToUse(LLVOAvatar *avatar)
bool FSPoserAnimator::isAvatarSafeToUse(LLVOAvatar* avatar) const
{
if (!avatar)
return false;
@ -811,122 +808,3 @@ bool FSPoserAnimator::isAvatarSafeToUse(LLVOAvatar *avatar)
return true;
}
bool FSPoserAnimator::writePoseAsBvh(llofstream* fileStream, LLVOAvatar* avatar)
{
if (!fileStream || !avatar)
return false;
*fileStream << "HIERARCHY" << std::endl;
auto startingJoint = getPoserJointByName("mPelvis");
writeBvhFragment(fileStream, avatar, startingJoint, 0);
*fileStream << "MOTION" << std::endl;
*fileStream << "Frames: 1" << std::endl;
*fileStream << "Frame Time: 1" << std::endl;
writeBvhMotion(fileStream, avatar, startingJoint);
*fileStream << std::endl;
return true;
}
bool FSPoserAnimator::writeBvhFragment(llofstream* fileStream, LLVOAvatar* avatar, const FSPoserJoint* joint, int tabStops)
{
if (!joint)
return false;
auto position = getJointPosition(avatar, *joint);
switch (joint->boneType())
{
case WHOLEAVATAR:
*fileStream << "ROOT " + joint->jointName() << std::endl;
*fileStream << "{" << std::endl;
*fileStream << getTabs(tabStops + 1) + "OFFSET " + vec3ToXYZString(position) << std::endl;
*fileStream << getTabs(tabStops + 1) + "CHANNELS 6 Xposition Yposition Zposition Xrotation Yrotation Zrotation" << std::endl;
break;
default:
*fileStream << getTabs(tabStops) + "JOINT " + joint->jointName() << std::endl;
*fileStream << getTabs(tabStops) + "{" << std::endl;
*fileStream << getTabs(tabStops + 1) + "OFFSET " + vec3ToXYZString(position) << std::endl;
*fileStream << getTabs(tabStops + 1) + "CHANNELS 3 Xrotation Yrotation Zrotation" << std::endl;
break;
}
size_t numberOfBvhChildNodes = joint->bvhChildren().size();
if (numberOfBvhChildNodes > 0)
{
for (size_t index = 0; index != numberOfBvhChildNodes; ++index)
{
auto nextJoint = getPoserJointByName(joint->bvhChildren()[index]);
writeBvhFragment(fileStream, avatar, nextJoint, tabStops + 1);
}
}
else
{
*fileStream << getTabs(tabStops + 1) + "End Site" << std::endl;
*fileStream << getTabs(tabStops + 1) + "{" << std::endl;
*fileStream << getTabs(tabStops + 2) + "OFFSET " + vec3ToXYZString(position) << std::endl; // I don't understand this node
*fileStream << getTabs(tabStops + 1) + "}" << std::endl;
}
*fileStream << getTabs(tabStops) + "}" << std::endl;
return true;
}
bool FSPoserAnimator::writeBvhMotion(llofstream* fileStream, LLVOAvatar* avatar, const FSPoserJoint* joint)
{
if (!joint)
return false;
auto rotation = getJointRotation(avatar, *joint, SWAP_NOTHING, NEGATE_NOTHING, true);
auto position = getJointPosition(avatar, *joint, true);
switch (joint->boneType())
{
case WHOLEAVATAR:
*fileStream << vec3ToXYZString(position) + " " + rotationToYZXString(rotation);
break;
default:
*fileStream << " " + rotationToYZXString(rotation);
break;
}
size_t numberOfBvhChildNodes = joint->bvhChildren().size();
for (size_t index = 0; index != numberOfBvhChildNodes; ++index)
{
auto nextJoint = getPoserJointByName(joint->bvhChildren()[index]);
writeBvhMotion(fileStream, avatar, nextJoint);
}
return true;
}
std::string FSPoserAnimator::vec3ToXYZString(LLVector3 val)
{
return f32ToString(val[VX]) + " " + f32ToString(val[VY]) + " " + f32ToString(val[VZ]);
}
std::string FSPoserAnimator::rotationToYZXString(LLVector3 val)
{
return f32ToString(val[VY] * RAD_TO_DEG) + " " + f32ToString(val[VZ] * RAD_TO_DEG) + " " + f32ToString(val[VX] * RAD_TO_DEG);
}
std::string FSPoserAnimator::getTabs(int numOfTabstops)
{
std::string tabSpaces;
for (int i = 0; i < numOfTabstops; i++)
tabSpaces += "\t";
return tabSpaces;
}
std::string FSPoserAnimator::f32ToString(F32 val)
{
std::string str;
char buf[20];
snprintf(buf, 20, "%f", val);
str = buf;
return str;
}

View File

@ -88,9 +88,9 @@ typedef enum E_BoneAxisNegation
class FSPoserAnimator
{
public:
FSPoserAnimator();
FSPoserAnimator() = default;
virtual ~FSPoserAnimator();
virtual ~FSPoserAnimator() = default;
/// <summary>
/// A class encapsulating 'metadata' for a joint, such as its catagory and its opposite joint name.
@ -98,56 +98,57 @@ public:
/// </summary>
class FSPoserJoint
{
std::string _jointName; // expected to be a match to LLJoint.getName() for a joint implementation.
std::string _mirrorJointName;
E_BoneTypes _boneList;
std::vector<std::string> _bvhChildren;
bool _dontFlipOnMirror = false;
std::string mJointName; // expected to be a match to LLJoint.getName() for a joint implementation.
std::string mMirrorJointName;
E_BoneTypes mBoneList;
std::vector<std::string> mBvhChildren;
bool mDontFlipOnMirror = false;
public:
/// <summary>
/// Gets the name of the joint.
/// </summary>
std::string jointName() const { return _jointName; }
std::string jointName() const { return mJointName; }
/// <summary>
/// Gets the name of the mirror of this joint, or an empty string if there is no mirror.
/// </summary>
std::string mirrorJointName() const { return _mirrorJointName; }
std::string mirrorJointName() const { return mMirrorJointName; }
/// <summary>
/// Gets the E_BoneTypes of the joint.
/// </summary>
E_BoneTypes boneType() const { return _boneList; }
E_BoneTypes boneType() const { return mBoneList; }
/// <summary>
/// Gets whether when mirroring the entire body, should this joint flip its counterpart.
/// </summary>
bool dontFlipOnMirror() const { return _dontFlipOnMirror; }
bool dontFlipOnMirror() const { return mDontFlipOnMirror; }
/// <summary>
/// Gets the collection of child bvh joints for this.
/// </summary>
std::vector<std::string> bvhChildren() const { return _bvhChildren; }
std::vector<std::string> bvhChildren() const { return mBvhChildren; }
/// <summary>
/// Creates a new instance of a PoserJoint.
/// </summary>
/// <param name="a">
/// <param name="joint_name">
/// The joint name, should be one of the well known bones/joints/thingos.
/// An example for an LLJoints implementation would be what LLJoint.getName() returns, like 'mChest'.
/// Very likely case-sensitive.
/// </param>
/// <param name="b">The opposite joint name, if any. Also expected to be a well-known name.</param>
/// <param name="c">The type of bone, often determining with which other bones the new instance would appear with.</param>
/// <param name="d">The optional array of joints, needed for BVH saving, which are the direct decendent(s) of this joint.</param>
/// <param name="e">The option for whether this joint should rotation-flip it counterpart when mirroring the pose of the entire body.</param>
FSPoserJoint(std::string a, std::string b, E_BoneTypes c, std::vector<std::string> d = {}, bool e = false)
/// <param name="mirror_joint_name">The opposite joint name, if any. Also expected to be a well-known name.</param>
/// <param name="bone_list">The type of bone, often determining with which other bones the new instance would appear with.</param>
/// <param name="bhv_children">The optional array of joints, needed for BVH saving, which are the direct decendent(s) of this joint.</param>
/// <param name="dont_flip_on_mirror">The option for whether this joint should rotation-flip it counterpart when mirroring the pose of the entire body.</param>
FSPoserJoint(std::string joint_name, std::string mirror_joint_name, E_BoneTypes bone_list, std::vector<std::string> bhv_children = {}, bool dont_flip_on_mirror = false)
{
_jointName = a;
_mirrorJointName = b;
_boneList = c;
_bvhChildren = d;
_dontFlipOnMirror = e;
mJointName = joint_name;
mMirrorJointName = mirror_joint_name;
mBoneList = bone_list;
mBvhChildren = bhv_children;
mDontFlipOnMirror = dont_flip_on_mirror;
}
};
@ -159,56 +160,132 @@ public:
/// <remarks>
/// For an implementation of something other than LLJoints, different name(s) may be required.
/// </remarks>
const std::vector<FSPoserJoint> PoserJoints {
const std::vector<FSPoserJoint> PoserJoints{
// head, torso, legs
{"mHead", "", BODY}, {"mNeck", "", BODY, {"mHead"}}, {"mPelvis", "", WHOLEAVATAR, {"mTorso", "mHipLeft", "mHipRight"}}, {"mChest", "", BODY, {"mNeck", "mCollarLeft", "mCollarRight", "mWingsRoot"}}, {"mTorso", "", BODY, {"mChest"}},
{"mCollarLeft", "mCollarRight", BODY, {"mShoulderLeft"}}, {"mShoulderLeft", "mShoulderRight", BODY, {"mElbowLeft"}}, {"mElbowLeft", "mElbowRight", BODY, {"mWristLeft"}}, {"mWristLeft", "mWristRight", BODY},
{"mCollarRight", "mCollarLeft", BODY, {"mShoulderRight"}, true}, {"mShoulderRight", "mShoulderLeft", BODY, {"mElbowRight"}, true}, {"mElbowRight", "mElbowLeft", BODY, {"mWristRight"}, true}, {"mWristRight", "mWristLeft", BODY, {}, true},
{"mHipLeft", "mHipRight", BODY, {"mKneeLeft"}}, {"mKneeLeft", "mKneeRight", BODY, {"mAnkleLeft"}}, {"mAnkleLeft", "mAnkleRight", BODY},
{"mHipRight", "mHipLeft", BODY, {"mKneeRight"}, true}, {"mKneeRight", "mKneeLeft", BODY, {"mAnkleRight"}, true}, {"mAnkleRight", "mAnkleLeft", BODY, {}, true},
{ "mHead", "", BODY },
{ "mNeck", "", BODY, { "mHead" } },
{ "mPelvis", "", WHOLEAVATAR, { "mTorso", "mHipLeft", "mHipRight" } },
{ "mChest", "", BODY, { "mNeck", "mCollarLeft", "mCollarRight", "mWingsRoot" } },
{ "mTorso", "", BODY, { "mChest" } },
{ "mCollarLeft", "mCollarRight", BODY, { "mShoulderLeft" } },
{ "mShoulderLeft", "mShoulderRight", BODY, { "mElbowLeft" } },
{ "mElbowLeft", "mElbowRight", BODY, { "mWristLeft" } },
{ "mWristLeft", "mWristRight", BODY },
{ "mCollarRight", "mCollarLeft", BODY, { "mShoulderRight" }, true },
{ "mShoulderRight", "mShoulderLeft", BODY, { "mElbowRight" }, true },
{ "mElbowRight", "mElbowLeft", BODY, { "mWristRight" }, true },
{ "mWristRight", "mWristLeft", BODY, {}, true },
{ "mHipLeft", "mHipRight", BODY, { "mKneeLeft" } },
{ "mKneeLeft", "mKneeRight", BODY, { "mAnkleLeft" } },
{ "mAnkleLeft", "mAnkleRight", BODY },
{ "mHipRight", "mHipLeft", BODY, { "mKneeRight" }, true },
{ "mKneeRight", "mKneeLeft", BODY, { "mAnkleRight" }, true },
{ "mAnkleRight", "mAnkleLeft", BODY, {}, true },
// face
{"mFaceForeheadLeft", "mFaceForeheadRight", FACE}, {"mFaceForeheadCenter", "", FACE}, {"mFaceForeheadRight", "mFaceForeheadLeft", FACE, {}, true},
{"mFaceEyebrowOuterLeft", "mFaceEyebrowOuterRight", FACE}, {"mFaceEyebrowCenterLeft", "mFaceEyebrowCenterRight", FACE}, {"mFaceEyebrowInnerLeft", "mFaceEyebrowInnerRight", FACE},
{"mFaceEyebrowOuterRight", "mFaceEyebrowOuterLeft", FACE, {}, true}, {"mFaceEyebrowCenterRight", "mFaceEyebrowCenterLeft", FACE, {}, true}, {"mFaceEyebrowInnerRight", "mFaceEyebrowInnerLeft", FACE, {}, true},
{ "mFaceForeheadLeft", "mFaceForeheadRight", FACE },
{ "mFaceForeheadCenter", "", FACE },
{ "mFaceForeheadRight", "mFaceForeheadLeft", FACE, {}, true },
{ "mFaceEyebrowOuterLeft", "mFaceEyebrowOuterRight", FACE },
{ "mFaceEyebrowCenterLeft", "mFaceEyebrowCenterRight", FACE },
{ "mFaceEyebrowInnerLeft", "mFaceEyebrowInnerRight", FACE },
{ "mFaceEyebrowOuterRight", "mFaceEyebrowOuterLeft", FACE, {}, true },
{ "mFaceEyebrowCenterRight", "mFaceEyebrowCenterLeft", FACE, {}, true },
{ "mFaceEyebrowInnerRight", "mFaceEyebrowInnerLeft", FACE, {}, true },
{"mEyeLeft", "mEyeRight", FACE}, {"mEyeRight", "mEyeLeft", FACE, {}, true},
{"mFaceEyeLidUpperLeft", "mFaceEyeLidUpperRight", FACE}, {"mFaceEyeLidLowerLeft", "mFaceEyeLidLowerRight", FACE}, {"mFaceEyeLidUpperRight", "mFaceEyeLidUpperLeft", FACE, {}, true}, {"mFaceEyeLidLowerRight", "mFaceEyeLidLowerLeft", FACE, {}, true},
{ "mEyeLeft", "mEyeRight", FACE },
{ "mEyeRight", "mEyeLeft", FACE, {}, true },
{ "mFaceEyeLidUpperLeft", "mFaceEyeLidUpperRight", FACE },
{ "mFaceEyeLidLowerLeft", "mFaceEyeLidLowerRight", FACE },
{ "mFaceEyeLidUpperRight", "mFaceEyeLidUpperLeft", FACE, {}, true },
{ "mFaceEyeLidLowerRight", "mFaceEyeLidLowerLeft", FACE, {}, true },
{"mFaceCheekUpperLeft", "mFaceCheekUpperRight", FACE}, {"mFaceCheekLowerLeft", "mFaceCheekLowerRight", FACE}, {"mFaceCheekUpperRight", "mFaceCheekUpperLeft", FACE, {}, true}, {"mFaceCheekLowerRight", "mFaceCheekLowerLeft", FACE, {}, true},
{"mFaceLipUpperLeft", "mFaceLipUpperRight", FACE}, {"mFaceLipUpperCenter", "", FACE}, {"mFaceLipUpperRight", "mFaceLipUpperLeft", FACE, {}, true},
{"mFaceLipCornerLeft", "mFaceLipCornerRight", FACE}, {"mFaceLipCornerRight", "mFaceLipCornerLeft", FACE, {}, true},
{"mFaceTongueBase", "", FACE}, {"mFaceTongueTip", "", FACE, {}, true},
{"mFaceLipLowerLeft", "mFaceLipLowerRight", FACE}, {"mFaceLipLowerCenter", "", FACE}, {"mFaceLipLowerRight", "mFaceLipLowerLeft", FACE, {}, true},
{"mFaceJaw", "", FACE},
{ "mFaceCheekUpperLeft", "mFaceCheekUpperRight", FACE },
{ "mFaceCheekLowerLeft", "mFaceCheekLowerRight", FACE },
{ "mFaceCheekUpperRight", "mFaceCheekUpperLeft", FACE, {}, true },
{ "mFaceCheekLowerRight", "mFaceCheekLowerLeft", FACE, {}, true },
{ "mFaceLipUpperLeft", "mFaceLipUpperRight", FACE },
{ "mFaceLipUpperCenter", "", FACE },
{ "mFaceLipUpperRight", "mFaceLipUpperLeft", FACE, {}, true },
{ "mFaceLipCornerLeft", "mFaceLipCornerRight", FACE },
{ "mFaceLipCornerRight", "mFaceLipCornerLeft", FACE, {}, true },
{ "mFaceTongueBase", "", FACE },
{ "mFaceTongueTip", "", FACE, {}, true },
{ "mFaceLipLowerLeft", "mFaceLipLowerRight", FACE },
{ "mFaceLipLowerCenter", "", FACE },
{ "mFaceLipLowerRight", "mFaceLipLowerLeft", FACE, {}, true },
{ "mFaceJaw", "", FACE },
//left hand
{"mHandThumb1Left", "mHandThumb1Right", HANDS}, {"mHandThumb2Left", "mHandThumb2Right", HANDS}, {"mHandThumb3Left", "mHandThumb3Right", HANDS},
{"mHandIndex1Left", "mHandIndex1Right", HANDS}, {"mHandIndex2Left", "mHandIndex2Right", HANDS}, {"mHandIndex3Left", "mHandIndex3Right", HANDS},
{"mHandMiddle1Left", "mHandMiddle1Right", HANDS}, {"mHandMiddle2Left", "mHandMiddle2Right", HANDS}, {"mHandMiddle3Left", "mHandMiddle3Right", HANDS},
{"mHandRing1Left", "mHandRing1Right", HANDS}, {"mHandRing2Left", "mHandRing2Right", HANDS}, {"mHandRing3Left", "mHandRing3Right", HANDS},
{"mHandPinky1Left", "mHandPinky1Right", HANDS}, {"mHandPinky2Left", "mHandPinky2Right", HANDS}, {"mHandPinky3Left", "mHandPinky3Right", HANDS},
// left hand
{ "mHandThumb1Left", "mHandThumb1Right", HANDS },
{ "mHandThumb2Left", "mHandThumb2Right", HANDS },
{ "mHandThumb3Left", "mHandThumb3Right", HANDS },
{ "mHandIndex1Left", "mHandIndex1Right", HANDS },
{ "mHandIndex2Left", "mHandIndex2Right", HANDS },
{ "mHandIndex3Left", "mHandIndex3Right", HANDS },
{ "mHandMiddle1Left", "mHandMiddle1Right", HANDS },
{ "mHandMiddle2Left", "mHandMiddle2Right", HANDS },
{ "mHandMiddle3Left", "mHandMiddle3Right", HANDS },
{ "mHandRing1Left", "mHandRing1Right", HANDS },
{ "mHandRing2Left", "mHandRing2Right", HANDS },
{ "mHandRing3Left", "mHandRing3Right", HANDS },
{ "mHandPinky1Left", "mHandPinky1Right", HANDS },
{ "mHandPinky2Left", "mHandPinky2Right", HANDS },
{ "mHandPinky3Left", "mHandPinky3Right", HANDS },
// right hand
{"mHandThumb1Right", "mHandThumb1Left", HANDS, {}, true}, {"mHandThumb2Right", "mHandThumb2Left", HANDS, {}, true}, {"mHandThumb3Right", "mHandThumb3Left", HANDS, {}, true},
{"mHandIndex1Right", "mHandIndex1Left", HANDS, {}, true}, {"mHandIndex2Right", "mHandIndex2Left", HANDS, {}, true}, {"mHandIndex3Right", "mHandIndex3Left", HANDS, {}, true},
{"mHandMiddle1Right", "mHandMiddle1Left", HANDS, {}, true}, {"mHandMiddle2Right", "mHandMiddle2Left", HANDS, {}, true}, {"mHandMiddle3Right", "mHandMiddle3Left", HANDS, {}, true},
{"mHandRing1Right", "mHandRing1Left", HANDS, {}, true}, {"mHandRing2Right", "mHandRing2Left", HANDS, {}, true}, {"mHandRing3Right", "mHandRing3Left", HANDS, {}, true},
{"mHandPinky1Right", "mHandPinky1Left", HANDS, {}, true}, {"mHandPinky2Right", "mHandPinky2Left", HANDS, {}, true}, {"mHandPinky3Right", "mHandPinky3Left", HANDS, {}, true},
{ "mHandThumb1Right", "mHandThumb1Left", HANDS, {}, true },
{ "mHandThumb2Right", "mHandThumb2Left", HANDS, {}, true },
{ "mHandThumb3Right", "mHandThumb3Left", HANDS, {}, true },
{ "mHandIndex1Right", "mHandIndex1Left", HANDS, {}, true },
{ "mHandIndex2Right", "mHandIndex2Left", HANDS, {}, true },
{ "mHandIndex3Right", "mHandIndex3Left", HANDS, {}, true },
{ "mHandMiddle1Right", "mHandMiddle1Left", HANDS, {}, true },
{ "mHandMiddle2Right", "mHandMiddle2Left", HANDS, {}, true },
{ "mHandMiddle3Right", "mHandMiddle3Left", HANDS, {}, true },
{ "mHandRing1Right", "mHandRing1Left", HANDS, {}, true },
{ "mHandRing2Right", "mHandRing2Left", HANDS, {}, true },
{ "mHandRing3Right", "mHandRing3Left", HANDS, {}, true },
{ "mHandPinky1Right", "mHandPinky1Left", HANDS, {}, true },
{ "mHandPinky2Right", "mHandPinky2Left", HANDS, {}, true },
{ "mHandPinky3Right", "mHandPinky3Left", HANDS, {}, true },
// tail and hind limbs
{"mTail1", "", MISC}, {"mTail2", "", MISC}, {"mTail3", "", MISC}, {"mTail4", "", MISC}, {"mTail5", "", MISC}, {"mTail6", "", MISC}, {"mGroin", "", MISC},
{"mHindLimbsRoot", "", MISC},
{"mHindLimb1Left", "mHindLimb1Right", MISC}, {"mHindLimb2Left", "mHindLimb2Right", MISC}, {"mHindLimb3Left", "mHindLimb3Right", MISC}, {"mHindLimb4Left", "mHindLimb4Right", MISC},
{"mHindLimb1Right", "mHindLimb1Left", MISC, {}, true}, {"mHindLimb2Right", "mHindLimb2Left", MISC, {}, true}, {"mHindLimb3Right", "mHindLimb3Left", MISC, {}, true}, {"mHindLimb4Right", "mHindLimb4Left", MISC, {}, true},
{ "mTail1", "", MISC },
{ "mTail2", "", MISC },
{ "mTail3", "", MISC },
{ "mTail4", "", MISC },
{ "mTail5", "", MISC },
{ "mTail6", "", MISC },
{ "mGroin", "", MISC },
{ "mHindLimbsRoot", "", MISC },
{ "mHindLimb1Left", "mHindLimb1Right", MISC },
{ "mHindLimb2Left", "mHindLimb2Right", MISC },
{ "mHindLimb3Left", "mHindLimb3Right", MISC },
{ "mHindLimb4Left", "mHindLimb4Right", MISC },
{ "mHindLimb1Right", "mHindLimb1Left", MISC, {}, true },
{ "mHindLimb2Right", "mHindLimb2Left", MISC, {}, true },
{ "mHindLimb3Right", "mHindLimb3Left", MISC, {}, true },
{ "mHindLimb4Right", "mHindLimb4Left", MISC, {}, true },
// wings
{"mWingsRoot", "", MISC},
{"mWing1Left", "mWing1Right", MISC}, {"mWing2Left", "mWing2Right", MISC}, {"mWing3Left", "mWing3Right", MISC}, {"mWing4Left", "mWing4Right", MISC}, {"mWing4FanLeft", "mWing4FanRight", MISC},
{"mWing1Right", "mWing1Left", MISC, {}, true}, {"mWing2Right", "mWing2Left", MISC, {}, true}, {"mWing3Right", "mWing3Left", MISC, {}, true}, {"mWing4Right", "mWing4Left", MISC, {}, true}, {"mWing4FanRight", "mWing4FanLeft", MISC, {}, true},
{ "mWingsRoot", "", MISC },
{ "mWing1Left", "mWing1Right", MISC },
{ "mWing2Left", "mWing2Right", MISC },
{ "mWing3Left", "mWing3Right", MISC },
{ "mWing4Left", "mWing4Right", MISC },
{ "mWing4FanLeft", "mWing4FanRight", MISC },
{ "mWing1Right", "mWing1Left", MISC, {}, true },
{ "mWing2Right", "mWing2Left", MISC, {}, true },
{ "mWing3Right", "mWing3Left", MISC, {}, true },
{ "mWing4Right", "mWing4Left", MISC, {}, true },
{ "mWing4FanRight", "mWing4FanLeft", MISC, {}, true },
// Collision Volumes
{"LEFT_PEC", "RIGHT_PEC", COL_VOLUMES}, {"RIGHT_PEC", "LEFT_PEC", COL_VOLUMES, {}, true}, {"BELLY", "", COL_VOLUMES}, {"BUTT", "", COL_VOLUMES},
{ "LEFT_PEC", "RIGHT_PEC", COL_VOLUMES },
{ "RIGHT_PEC", "LEFT_PEC", COL_VOLUMES, {}, true },
{ "BELLY", "", COL_VOLUMES },
{ "BUTT", "", COL_VOLUMES },
};
public:
@ -217,27 +294,27 @@ public:
/// </summary>
/// <param name="jointName">The name of the joint to match.</param>
/// <returns>The matching joint if found, otherwise nullptr</returns>
const FSPoserJoint* getPoserJointByName(std::string jointName);
const FSPoserJoint* getPoserJointByName(const std::string& jointName);
/// <summary>
/// Tries to start posing the supplied avatar.
/// </summary>
/// <param name="avatar">The avatar to begin posing.</param>
/// <returns>True if the avatar was able to begin posing, otherwise false.</returns>
bool tryPosingAvatar(LLVOAvatar *avatar);
bool tryPosingAvatar(LLVOAvatar* avatar);
/// <summary>
/// Stops posing the supplied avatar.
/// </summary>
/// <param name="avatar">The avatar to stop posing.</param>
void stopPosingAvatar(LLVOAvatar *avatar);
void stopPosingAvatar(LLVOAvatar* avatar);
/// <summary>
/// Determines if the supplied avatar is being posed by this.
/// </summary>
/// <param name="avatar">The avatar to query posing status for.</param>
/// <returns>True if this is posing the supplied avatar, otherwise false.</returns>
bool isPosingAvatar(LLVOAvatar *avatar);
bool isPosingAvatar(LLVOAvatar* avatar) const;
/// <summary>
/// Determines whether the supplied PoserJoint for the supplied avatar is being posed.
@ -245,7 +322,7 @@ public:
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint being queried for.</param>
/// <returns>True if this is joint is being posed for the supplied avatar, otherwise false.</returns>
bool isPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint);
bool isPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint);
/// <summary>
/// Sets whether the supplied PoserJoint for the supplied avatar should be posed.
@ -256,49 +333,49 @@ public:
/// <remarks>
/// If this is not posing the joint, then it is free to be posed by other things.
/// </remarks>
void setPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint, bool shouldPose);
void setPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, bool shouldPose);
/// <summary>
/// Resets the supplied PoserJoint to its position/rotation/scale it was when poser was started.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint to be reset.</param>
void resetAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint);
void resetAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint);
/// <summary>
/// Undoes the last applied rotation to the supplied PoserJoint.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the rotation to undo.</param>
void undoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
void undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Undoes the last applied position to the supplied PoserJoint.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the position to undo.</param>
void undoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
void undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Undoes the last applied scale to the supplied PoserJoint.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the scale to undo.</param>
void undoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
void undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Resets the position of the supplied PoserJoint.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the position to reset.</param>
void resetJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
void resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Resets the scale of the supplied joint to initial values.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the scale to reset.</param>
void resetJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
void resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Determines if a redo action is currently permitted for the supplied joint.
@ -306,28 +383,28 @@ public:
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint to query.</param>
/// <returns>True if a redo action is available, otherwise false.</returns>
bool canRedoJointRotation(LLVOAvatar* avatar, FSPoserJoint joint);
bool canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint);
/// <summary>
/// Re-does the last undone rotation to the supplied PoserJoint.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the rotation to redo.</param>
void redoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
void redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Re-does the last undone position to the supplied PoserJoint.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the position to redo.</param>
void redoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
void redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Re-does the last undone scale to the supplied PoserJoint.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the scale to redo.</param>
void redoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
void redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Gets the position of a joint for the supplied avatar.
@ -335,7 +412,7 @@ public:
/// <param name="avatar">The avatar whose joint is being queried.</param>
/// <param name="joint">The joint to determine the position for.</param>
/// <returns>The position of the requested joint, if determinable, otherwise a default vector.</returns>
LLVector3 getJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, bool forRecapture = false);
LLVector3 getJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture = false) const;
/// <summary>
/// Sets the position of a joint for the supplied avatar.
@ -344,7 +421,7 @@ public:
/// <param name="joint">The joint to set.</param>
/// <param name="position">The position to set the joint to.</param>
/// <param name="style">Any ancilliary action to be taken with the change to be made.</param>
void setJointPosition(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 position, E_BoneDeflectionStyles style);
void setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& position, E_BoneDeflectionStyles style);
/// <summary>
/// Gets the rotation of a joint for the supplied avatar.
@ -355,8 +432,8 @@ public:
/// <param name="negation">The style of negation to apply to the set.</param>
/// <param name="forRecapture">Get the current non-poser rotation, for recapture opportunity.</param>
/// <returns>The rotation of the requested joint, if determinable, otherwise a default vector.</returns>
LLVector3 getJointRotation(LLVOAvatar *avatar, FSPoserJoint joint, E_BoneAxisTranslation translation, S32 negation,
bool forRecapture = false);
LLVector3 getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation,
bool forRecapture = false) const;
/// <summary>
/// Sets the rotation of a joint for the supplied avatar.
@ -366,7 +443,7 @@ public:
/// <param name="rotation">The rotation to set the joint to.</param>
/// <param name="style">Any ancilliary action to be taken with the change to be made.</param>
/// <param name="translation">The axial translation form the supplied joint.</param>
void setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, LLVector3 rotation, E_BoneDeflectionStyles style,
void setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& rotation, E_BoneDeflectionStyles style,
E_BoneAxisTranslation translation, S32 negation);
/// <summary>
@ -375,7 +452,7 @@ public:
/// <param name="avatar">The avatar whose joint is being queried.</param>
/// <param name="joint">The joint to determine the scale for.</param>
/// <returns>The scale of the requested joint, if determinable, otherwise a default vector.</returns>
LLVector3 getJointScale(LLVOAvatar* avatar, FSPoserJoint joint, bool forRecapture = false);
LLVector3 getJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture = false) const;
/// <summary>
/// Sets the scale of a joint for the supplied avatar.
@ -384,28 +461,20 @@ public:
/// <param name="joint">The joint to set.</param>
/// <param name="scale">The scale to set the joint to.</param>
/// <param name="style">Any ancilliary action to be taken with the change to be made.</param>
void setJointScale(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 scale, E_BoneDeflectionStyles style);
void setJointScale(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& scale, E_BoneDeflectionStyles style);
/// <summary>
/// Reflects the joint with its opposite if it has one, or just mirror the rotation of itself.
/// </summary>
/// <param name="avatar">The avatar whose joint should flip left-right.</param>
/// <param name="joint">The joint to mirror rotation for.</param>
void reflectJoint(LLVOAvatar *avatar, const FSPoserJoint *joint);
void reflectJoint(LLVOAvatar* avatar, const FSPoserJoint* joint);
/// <summary>
/// Reflects every joint of the supplied avatar with its opposite if it has one, or mirrors the rotation of the joint if it does not have an opposite.
/// </summary>
/// <param name="avatar">The avatar whose pose should flip left-right.</param>
void flipEntirePose(LLVOAvatar *avatar);
/// <summary>
/// Determines whether the supplied PoserJoint for the supplied avatar is being posed.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint being queried for.</param>
/// <returns>True if this is joint is being posed for the supplied avatar, otherwise false.</returns>
bool writePoseAsBvh(llofstream *fileStream, LLVOAvatar* avatar);
void flipEntirePose(LLVOAvatar* avatar);
private:
/// <summary>
@ -423,7 +492,7 @@ public:
/// <param name="translation">The axis translation to perform.</param>
/// <param name="rotation">The rotation to transform to matrix.</param>
/// <returns>The rotation vector.</returns>
LLVector3 translateRotationFromQuaternion(E_BoneAxisTranslation translation, S32 negation, LLQuaternion rotation);
LLVector3 translateRotationFromQuaternion(E_BoneAxisTranslation translation, S32 negation, const LLQuaternion& rotation) const;
/// <summary>
/// Creates a posing motion for the supplied avatar.
@ -441,54 +510,14 @@ public:
/// </summary>
/// <param name="avatar">The avatar to get the posing motion for.</param>
/// <returns>The posing motion if found, otherwise nullptr.</returns>
FSPosingMotion* getPosingMotion(LLVOAvatar* avatar);
FSPosingMotion* getPosingMotion(LLVOAvatar* avatar) const;
/// <summary>
/// Determines if the avatar can be used.
/// </summary>
/// <param name="avatar">The avatar to test if it is safe to animate.</param>
/// <returns>True if the avatar is safe to manipulate, otherwise false.</returns>
bool isAvatarSafeToUse(LLVOAvatar* avatar);
/// <summary>
/// Recursively writes a fragment of a BVH file format representation of the supplied joint, then that joints BVH child(ren).
/// </summary>
/// <param name="fileStream">The stream to write the fragment to.</param>
/// <param name="avatar">The avatar owning the supplied joint.</param>
/// <param name="joint">The joint whose fragment should be written, and whose child(ren) will also be written.</param>
/// <param name="tabStops">The number of tab-stops to include for formatting purpose.</param>
/// <returns>True if the fragment wrote successfully, otherwise false.</returns>
bool writeBvhFragment(llofstream* fileStream, LLVOAvatar* avatar, const FSPoserJoint* joint, int tabStops);
/// <summary>
/// Writes a fragment of the 'single line' representing an animation frame within the BVH file respresenting the positions and/or rotations.
/// </summary>
/// <param name="fileStream">The stream to write the position and/or rotation to.</param>
/// <param name="avatar">The avatar owning the supplied joint.</param>
/// <param name="joint">The joint whose position and/or rotation should be written.</param>
/// <returns></returns>
bool writeBvhMotion(llofstream* fileStream, LLVOAvatar* avatar, const FSPoserJoint* joint);
/// <summary>
/// Converts an F32 to a nice string.
/// </summary>
std::string static f32ToString(F32 val);
/// <summary>
/// Generates a string with the supplied number of tab-chars.
/// </summary>
std::string static getTabs(int numOfTabstops);
/// <summary>
/// Transforms a rotation such that llbvhloader.cpp can resolve it to something vaguely approximating the supplied angle.
/// When I say vague, I mean, it's numbers, buuuuut.
/// </summary>
std::string static rotationToYZXString(LLVector3 val);
/// <summary>
/// Transforms the supplied vector into a string of three numbers, format suiting to writing into a BVH file.
/// </summary>
std::string static vec3ToXYZString(LLVector3 val);
bool isAvatarSafeToUse(LLVOAvatar* avatar) const;
/// <summary>
/// Maps the avatar's ID to the animation registered to them.
@ -497,7 +526,7 @@ public:
/// An avatar's animation exists so long as their session does, and there is consideration for renewal (like if they relog/crash and their character is renewed).
/// Is static, so the animationId is not lost between sessions (such as when the UI floater is closed and reopened).
/// </summary>
static std::map<LLUUID, LLAssetID> _avatarIdToRegisteredAnimationId;
static std::map<LLUUID, LLAssetID> sAvatarIdToRegisteredAnimationId;
};
#endif // LL_FSPoserAnimator_H

View File

@ -32,7 +32,7 @@
FSPosingMotion::FSPosingMotion(const LLUUID &id) : LLMotion(id)
{
mName = "fs_poser_pose";
_motionID = id;
mMotionID = id;
}
LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character)
@ -40,7 +40,7 @@ LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character
if (!character)
return STATUS_FAILURE;
_jointPoses.clear();
mJointPoses.clear();
LLJoint* targetJoint;
for (S32 i = 0; (targetJoint = character->getCharacterJoint(i)); ++i)
@ -49,7 +49,7 @@ LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character
continue;
FSJointPose jointPose = FSJointPose(targetJoint);
_jointPoses.push_back(jointPose);
mJointPoses.push_back(jointPose);
addJointState(jointPose.getJointState());
}
@ -60,7 +60,7 @@ LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character
continue;
FSJointPose jointPose = FSJointPose(targetJoint, true);
_jointPoses.push_back(jointPose);
mJointPoses.push_back(jointPose);
addJointState(jointPose.getJointState());
}
@ -68,7 +68,10 @@ LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character
return STATUS_SUCCESS;
}
bool FSPosingMotion::onActivate() { return true; }
bool FSPosingMotion::onActivate()
{
return true;
}
bool FSPosingMotion::onUpdate(F32 time, U8* joint_mask)
{
@ -79,7 +82,7 @@ bool FSPosingMotion::onUpdate(F32 time, U8* joint_mask)
LLVector3 currentScale;
LLVector3 targetScale;
for (FSJointPose jointPose : _jointPoses)
for (FSJointPose jointPose : mJointPoses)
{
LLJoint* joint = jointPose.getJointState()->getJoint();
if (!joint)
@ -94,19 +97,19 @@ bool FSPosingMotion::onUpdate(F32 time, U8* joint_mask)
if (currentPosition != targetPosition)
{
currentPosition = lerp(currentPosition, targetPosition, _interpolationTime);
currentPosition = lerp(currentPosition, targetPosition, mInterpolationTime);
jointPose.getJointState()->setPosition(currentPosition);
}
if (currentRotation != targetRotation)
{
currentRotation = slerp(_interpolationTime, currentRotation, targetRotation);
currentRotation = slerp(mInterpolationTime, currentRotation, targetRotation);
jointPose.getJointState()->setRotation(currentRotation);
}
if (currentScale != targetScale)
{
currentScale = lerp(currentScale, targetScale, _interpolationTime);
currentScale = lerp(currentScale, targetScale, mInterpolationTime);
jointPose.getJointState()->setScale(currentScale);
}
}
@ -118,7 +121,7 @@ void FSPosingMotion::onDeactivate() { revertChangesToPositionsScalesAndCollision
void FSPosingMotion::revertChangesToPositionsScalesAndCollisionVolumes()
{
for (FSJointPose jointPose : _jointPoses)
for (FSJointPose jointPose : mJointPoses)
{
jointPose.revertJointScale();
jointPose.revertJointPosition();
@ -176,13 +179,19 @@ void FSPosingMotion::removeJointFromState(FSJointPose* joint)
setJointState(avJoint, 0);
}
void FSPosingMotion::addJointToState(LLJoint* joint) { setJointState(joint, POSER_JOINT_STATE); }
void FSPosingMotion::removeJointFromState(LLJoint *joint) { setJointState(joint, 0); }
void FSPosingMotion::setJointState(LLJoint *joint, U32 state)
void FSPosingMotion::addJointToState(LLJoint* joint)
{
if (_jointPoses.size() < 1)
setJointState(joint, POSER_JOINT_STATE);
}
void FSPosingMotion::removeJointFromState(LLJoint* joint)
{
setJointState(joint, 0);
}
void FSPosingMotion::setJointState(LLJoint* joint, U32 state)
{
if (mJointPoses.size() < 1)
return;
if (!joint)
return;
@ -204,13 +213,12 @@ void FSPosingMotion::setJointState(LLJoint *joint, U32 state)
addJointState(jointPose->getJointState());
}
FSPosingMotion::FSJointPose* FSPosingMotion::getJointPoseByJointName(std::string name)
FSPosingMotion::FSJointPose* FSPosingMotion::getJointPoseByJointName(const std::string& name)
{
if (_jointPoses.size() < 1)
if (mJointPoses.size() < 1)
return nullptr;
std::vector<FSPosingMotion::FSJointPose>::iterator poserJoint_iter;
for (poserJoint_iter = _jointPoses.begin(); poserJoint_iter != _jointPoses.end(); ++poserJoint_iter)
for (auto poserJoint_iter = mJointPoses.begin(); poserJoint_iter != mJointPoses.end(); ++poserJoint_iter)
{
if (!boost::iequals(poserJoint_iter->jointName(), name))
continue;
@ -223,7 +231,7 @@ FSPosingMotion::FSJointPose* FSPosingMotion::getJointPoseByJointName(std::string
bool FSPosingMotion::currentlyPosingJoint(LLJoint* joint)
{
if (_jointPoses.size() < 1)
if (mJointPoses.size() < 1)
return false;
if (!joint)
@ -240,3 +248,257 @@ bool FSPosingMotion::currentlyPosingJoint(LLJoint* joint)
U32 state = jointState->getUsage();
return (state & POSER_JOINT_STATE);
}
constexpr size_t MaximumUndoQueueLength = 20;
/// <summary>
/// The constant time interval, in seconds,
/// </summary>
constexpr std::chrono::duration<double> UndoUpdateInterval = std::chrono::duration<double>(0.3);
void FSPosingMotion::FSJointPose::addLastPositionToUndo()
{
if (mUndonePositionIndex > 0)
{
for (int i = 0; i < mUndonePositionIndex; i++)
mLastSetPositions.pop_front();
mUndonePositionIndex = 0;
}
mLastSetPositions.push_front(mTargetPosition);
while (mLastSetPositions.size() > MaximumUndoQueueLength)
mLastSetPositions.pop_back();
}
void FSPosingMotion::FSJointPose::addLastRotationToUndo()
{
if (mUndoneRotationIndex > 0)
{
for (int i = 0; i < mUndoneRotationIndex; i++)
mLastSetRotations.pop_front();
mUndoneRotationIndex = 0;
}
mLastSetRotations.push_front(mTargetRotation);
while (mLastSetRotations.size() > MaximumUndoQueueLength)
mLastSetRotations.pop_back();
}
void FSPosingMotion::FSJointPose::addLastScaleToUndo()
{
if (mUndoneScaleIndex > 0)
{
for (int i = 0; i < mUndoneScaleIndex; i++)
mLastSetScales.pop_front();
mUndoneScaleIndex = 0;
}
mLastSetScales.push_front(mTargetScale);
while (mLastSetScales.size() > MaximumUndoQueueLength)
mLastSetScales.pop_back();
}
LLVector3 FSPosingMotion::FSJointPose::getCurrentPosition()
{
LLVector3 vec3;
LLJoint* joint = mJointState->getJoint();
if (!joint)
return vec3;
vec3 = joint->getPosition();
return vec3;
}
void FSPosingMotion::FSJointPose::setTargetPosition(const LLVector3& pos)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - mTimeLastUpdatedPosition;
if (timeIntervalSinceLastRotationChange > UndoUpdateInterval)
addLastPositionToUndo();
mTimeLastUpdatedPosition = std::chrono::system_clock::now();
mTargetPosition.set(pos);
}
LLQuaternion FSPosingMotion::FSJointPose::getCurrentRotation()
{
LLQuaternion quat;
LLJoint* joint = mJointState->getJoint();
if (!joint)
return quat;
quat = joint->getRotation();
return quat;
}
void FSPosingMotion::FSJointPose::setTargetRotation(const LLQuaternion& rot)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - mTimeLastUpdatedRotation;
if (timeIntervalSinceLastRotationChange > UndoUpdateInterval)
addLastRotationToUndo();
mTimeLastUpdatedRotation = std::chrono::system_clock::now();
mTargetRotation.set(rot);
}
void FSPosingMotion::FSJointPose::applyDeltaRotation(const LLQuaternion& rot)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - mTimeLastUpdatedRotation;
if (timeIntervalSinceLastRotationChange > UndoUpdateInterval)
addLastRotationToUndo();
mTimeLastUpdatedRotation = std::chrono::system_clock::now();
mTargetRotation = mTargetRotation * rot;
}
LLVector3 FSPosingMotion::FSJointPose::getCurrentScale()
{
LLVector3 vec3;
LLJoint* joint = mJointState->getJoint();
if (!joint)
return vec3;
vec3 = joint->getScale();
return vec3;
}
void FSPosingMotion::FSJointPose::setTargetScale(LLVector3 scale)
{
auto timeIntervalSinceLastScaleChange = std::chrono::system_clock::now() - mTimeLastUpdatedScale;
if (timeIntervalSinceLastScaleChange > UndoUpdateInterval)
addLastScaleToUndo();
mTimeLastUpdatedScale = std::chrono::system_clock::now();
mTargetScale.set(scale);
}
void FSPosingMotion::FSJointPose::undoLastPositionSet()
{
if (mLastSetPositions.empty())
return;
if (mUndonePositionIndex == 0) // at the top of the queue add the current
addLastPositionToUndo();
mUndonePositionIndex++;
mUndonePositionIndex = llclamp(mUndonePositionIndex, 0, mLastSetPositions.size() - 1);
mTargetPosition.set(mLastSetPositions[mUndonePositionIndex]);
}
void FSPosingMotion::FSJointPose::redoLastPositionSet()
{
if (mLastSetPositions.empty())
return;
mUndonePositionIndex--;
mUndonePositionIndex = llclamp(mUndonePositionIndex, 0, mLastSetPositions.size() - 1);
mTargetPosition.set(mLastSetPositions[mUndonePositionIndex]);
if (mUndonePositionIndex == 0)
mLastSetPositions.pop_front();
}
void FSPosingMotion::FSJointPose::undoLastRotationSet()
{
if (mLastSetRotations.empty())
return;
if (mUndoneRotationIndex == 0) // at the top of the queue add the current
addLastRotationToUndo();
mUndoneRotationIndex++;
mUndoneRotationIndex = llclamp(mUndoneRotationIndex, 0, mLastSetRotations.size() - 1);
mTargetRotation.set(mLastSetRotations[mUndoneRotationIndex]);
}
void FSPosingMotion::FSJointPose::redoLastRotationSet()
{
if (mLastSetRotations.empty())
return;
mUndoneRotationIndex--;
mUndoneRotationIndex = llclamp(mUndoneRotationIndex, 0, mLastSetRotations.size() - 1);
mTargetRotation.set(mLastSetRotations[mUndoneRotationIndex]);
if (mUndoneRotationIndex == 0)
mLastSetRotations.pop_front();
}
void FSPosingMotion::FSJointPose::undoLastScaleSet()
{
if (mLastSetScales.empty())
return;
if (mUndoneScaleIndex == 0)
addLastScaleToUndo();
mUndoneScaleIndex++;
mUndoneScaleIndex = llclamp(mUndoneScaleIndex, 0, mLastSetScales.size() - 1);
mTargetScale.set(mLastSetScales[mUndoneScaleIndex]);
}
void FSPosingMotion::FSJointPose::redoLastScaleSet()
{
if (mLastSetScales.empty())
return;
mUndoneScaleIndex--;
mUndoneScaleIndex = llclamp(mUndoneScaleIndex, 0, mLastSetScales.size() - 1);
mTargetScale.set(mLastSetScales[mUndoneScaleIndex]);
if (mUndoneScaleIndex == 0)
mLastSetScales.pop_front();
}
void FSPosingMotion::FSJointPose::revertJointScale()
{
LLJoint* joint = mJointState->getJoint();
if (!joint)
return;
joint->setScale(mBeginningScale);
}
void FSPosingMotion::FSJointPose::revertJointPosition()
{
LLJoint* joint = mJointState->getJoint();
if (!joint)
return;
joint->setPosition(mBeginningPosition);
}
void FSPosingMotion::FSJointPose::revertCollisionVolume()
{
if (!mIsCollisionVolume)
return;
LLJoint* joint = mJointState->getJoint();
if (!joint)
return;
joint->setRotation(mBeginningRotation);
joint->setPosition(mBeginningPosition);
joint->setScale(mBeginningScale);
}
FSPosingMotion::FSJointPose::FSJointPose(LLJoint* joint, bool isCollisionVolume)
{
mJointState = new LLJointState;
mJointState->setJoint(joint);
mJointState->setUsage(POSER_JOINT_STATE);
mJointName = joint->getName();
mIsCollisionVolume = isCollisionVolume;
mBeginningRotation = mTargetRotation = joint->getRotation();
mBeginningPosition = mTargetPosition = joint->getPosition();
mBeginningScale = mTargetScale = joint->getScale();
}

View File

@ -52,398 +52,186 @@ public:
/// </summary>
class FSJointPose
{
const size_t MaximumUndoQueueLength = 20;
/// <summary>
/// The constant time interval, in seconds,
/// </summary>
std::chrono::duration<double> const _undoUpdateInterval = std::chrono::duration<double>(0.3);
std::string _jointName = ""; // expected to be a match to LLJoint.getName() for a joint implementation.
LLPointer<LLJointState> _jointState;
std::string mJointName = ""; // expected to be a match to LLJoint.getName() for a joint implementation.
LLPointer<LLJointState> mJointState{ nullptr };
/// <summary>
/// Collision Volumes require special treatment when we stop animating an avatar, as they do not revert to their original state natively.
/// </summary>
bool _isCollisionVolume = false;
bool mIsCollisionVolume{ false };
LLQuaternion _targetRotation;
LLQuaternion _beginningRotation;
std::deque<LLQuaternion> _lastSetRotations;
size_t _undoneRotationIndex = 0;
std::chrono::system_clock::time_point _timeLastUpdatedRotation = std::chrono::system_clock::now();
LLQuaternion mTargetRotation;
LLQuaternion mBeginningRotation;
std::deque<LLQuaternion> mLastSetRotations;
size_t mUndoneRotationIndex = 0;
std::chrono::system_clock::time_point mTimeLastUpdatedRotation = std::chrono::system_clock::now();
LLVector3 _targetPosition;
LLVector3 _beginningPosition;
std::deque<LLVector3> _lastSetPositions;
size_t _undonePositionIndex = 0;
std::chrono::system_clock::time_point _timeLastUpdatedPosition = std::chrono::system_clock::now();
LLVector3 mTargetPosition;
LLVector3 mBeginningPosition;
std::deque<LLVector3> mLastSetPositions;
size_t mUndonePositionIndex = 0;
std::chrono::system_clock::time_point mTimeLastUpdatedPosition = std::chrono::system_clock::now();
/// <summary>
/// Joint scales require special treatment, as they do not revert when we stop animating an avatar.
/// </summary>
LLVector3 _targetScale;
LLVector3 _beginningScale;
std::deque<LLVector3> _lastSetScales;
size_t _undoneScaleIndex = 0;
std::chrono::system_clock::time_point _timeLastUpdatedScale = std::chrono::system_clock::now();
LLVector3 mTargetScale;
LLVector3 mBeginningScale;
std::deque<LLVector3> mLastSetScales;
size_t mUndoneScaleIndex = 0;
std::chrono::system_clock::time_point mTimeLastUpdatedScale = std::chrono::system_clock::now();
/// <summary>
/// Adds a last position to the deque.
/// </summary>
void addLastPositionToUndo()
{
if (_undonePositionIndex > 0)
{
for (int i = 0; i < _undonePositionIndex; i++)
_lastSetPositions.pop_front();
_undonePositionIndex = 0;
}
_lastSetPositions.push_front(_targetPosition);
while (_lastSetPositions.size() > MaximumUndoQueueLength)
_lastSetPositions.pop_back();
}
void addLastPositionToUndo();
/// <summary>
/// Adds a last rotation to the deque.
/// </summary>
void addLastRotationToUndo()
{
if (_undoneRotationIndex > 0)
{
for (int i = 0; i < _undoneRotationIndex; i++)
_lastSetRotations.pop_front();
_undoneRotationIndex = 0;
}
_lastSetRotations.push_front(_targetRotation);
while (_lastSetRotations.size() > MaximumUndoQueueLength)
_lastSetRotations.pop_back();
}
void addLastRotationToUndo();
/// <summary>
/// Adds a last rotation to the deque.
/// </summary>
void addLastScaleToUndo()
{
if (_undoneScaleIndex > 0)
{
for (int i = 0; i < _undoneScaleIndex; i++)
_lastSetScales.pop_front();
_undoneScaleIndex = 0;
}
_lastSetScales.push_front(_targetScale);
while (_lastSetScales.size() > MaximumUndoQueueLength)
_lastSetScales.pop_back();
}
void addLastScaleToUndo();
public:
/// <summary>
/// Gets the name of the joint.
/// </summary>
std::string jointName() const { return _jointName; }
std::string jointName() const { return mJointName; }
/// <summary>
/// Gets whether this represents a collision volume.
/// </summary>
/// <returns></returns>
bool isCollisionVolume() const { return _isCollisionVolume; }
bool isCollisionVolume() const { return mIsCollisionVolume; }
/// <summary>
/// Gets whether a redo of this joints rotation may be performed.
/// </summary>
/// <returns></returns>
bool canRedoRotation() const { return _undoneRotationIndex > 0; }
bool canRedoRotation() const { return mUndoneRotationIndex > 0; }
/// <summary>
/// Gets the position the joint was in when the animation was initialized.
/// </summary>
LLVector3 getBeginningPosition() const { return _beginningPosition; }
LLVector3 getBeginningPosition() const { return mBeginningPosition; }
/// <summary>
/// Gets the position the animator wishes the joint to be in.
/// </summary>
LLVector3 getTargetPosition() const { return _targetPosition; }
LLVector3 getTargetPosition() const { return mTargetPosition; }
/// <summary>
/// Gets the position the animator wishes the joint to be in.
/// </summary>
LLVector3 getCurrentPosition()
{
LLVector3 vec3;
LLJoint* joint = _jointState->getJoint();
if (!joint)
return vec3;
vec3 = joint->getPosition();
return vec3;
}
LLVector3 getCurrentPosition();
/// <summary>
/// Sets the position the animator wishes the joint to be in.
/// </summary>
void setTargetPosition(const LLVector3& pos)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - _timeLastUpdatedPosition;
if (timeIntervalSinceLastRotationChange > _undoUpdateInterval)
addLastPositionToUndo();
_timeLastUpdatedPosition = std::chrono::system_clock::now();
_targetPosition.set(pos);
}
void setTargetPosition(const LLVector3& pos);
/// <summary>
/// Gets the rotation the joint was in when the animation was initialized.
/// </summary>
LLQuaternion getBeginningRotation() const { return _beginningRotation; }
LLQuaternion getBeginningRotation() const { return mBeginningRotation; }
/// <summary>
/// Gets the rotation the animator wishes the joint to be in.
/// </summary>
LLQuaternion getTargetRotation() const { return _targetRotation; }
LLQuaternion getTargetRotation() const { return mTargetRotation; }
/// <summary>
/// Gets the rotation of the joint.
/// </summary>
LLQuaternion getCurrentRotation()
{
LLQuaternion quat;
LLJoint* joint = _jointState->getJoint();
if (!joint)
return quat;
quat = joint->getRotation();
return quat;
}
LLQuaternion getCurrentRotation();
/// <summary>
/// Sets the rotation the animator wishes the joint to be in.
/// </summary>
void setTargetRotation(const LLQuaternion& rot)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - _timeLastUpdatedRotation;
if (timeIntervalSinceLastRotationChange > _undoUpdateInterval)
addLastRotationToUndo();
_timeLastUpdatedRotation = std::chrono::system_clock::now();
_targetRotation.set(rot);
}
void setTargetRotation(const LLQuaternion& rot);
/// <summary>
/// Applies a delta to the rotation the joint currently targets.
/// </summary>
void applyDeltaRotation(const LLQuaternion& rot)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - _timeLastUpdatedRotation;
if (timeIntervalSinceLastRotationChange > _undoUpdateInterval)
addLastRotationToUndo();
_timeLastUpdatedRotation = std::chrono::system_clock::now();
_targetRotation = _targetRotation * rot;
}
void applyDeltaRotation(const LLQuaternion& rot);
/// <summary>
/// Gets the scale the animator wishes the joint to have.
/// </summary>
LLVector3 getTargetScale() const { return _targetScale; }
LLVector3 getTargetScale() const { return mTargetScale; }
/// <summary>
/// Gets the scale the joint has.
/// </summary>
LLVector3 getCurrentScale()
{
LLVector3 vec3;
LLJoint* joint = _jointState->getJoint();
if (!joint)
return vec3;
vec3 = joint->getScale();
return vec3;
}
LLVector3 getCurrentScale();
/// <summary>
/// Gets the scale the joint had when the animation was initialized.
/// </summary>
LLVector3 getBeginningScale() const { return _beginningScale; }
LLVector3 getBeginningScale() const { return mBeginningScale; }
/// <summary>
/// Sets the scale the animator wishes the joint to have.
/// </summary>
void setTargetScale(LLVector3 scale)
{
auto timeIntervalSinceLastScaleChange = std::chrono::system_clock::now() - _timeLastUpdatedScale;
if (timeIntervalSinceLastScaleChange > _undoUpdateInterval)
addLastScaleToUndo();
_timeLastUpdatedScale = std::chrono::system_clock::now();
_targetScale.set(scale);
}
void setTargetScale(LLVector3 scale);
/// <summary>
/// Undoes the last position set, if any.
/// </summary>
void undoLastPositionSet()
{
if (_lastSetPositions.empty())
return;
if (_undonePositionIndex == 0) // at the top of the queue add the current
addLastPositionToUndo();
_undonePositionIndex++;
_undonePositionIndex = llclamp(_undonePositionIndex, 0, _lastSetPositions.size() - 1);
_targetPosition.set(_lastSetPositions[_undonePositionIndex]);
}
void undoLastPositionSet();
/// <summary>
/// Undoes the last position set, if any.
/// </summary>
void redoLastPositionSet()
{
if (_lastSetPositions.empty())
return;
_undonePositionIndex--;
_undonePositionIndex = llclamp(_undonePositionIndex, 0, _lastSetPositions.size() - 1);
_targetPosition.set(_lastSetPositions[_undonePositionIndex]);
if (_undonePositionIndex == 0)
_lastSetPositions.pop_front();
}
void redoLastPositionSet();
/// <summary>
/// Undoes the last rotation set, if any.
/// Ordinarily the queue does not contain the current rotation, because we rely on time to add, and not button-up.
/// When we undo, if we are at the top of the queue, we need to add the current rotation so we can redo back to it.
/// Thus when we start undoing, _undoneRotationIndex points at the current rotation.
/// Thus when we start undoing, mUndoneRotationIndex points at the current rotation.
/// </summary>
void undoLastRotationSet()
{
if (_lastSetRotations.empty())
return;
if (_undoneRotationIndex == 0) // at the top of the queue add the current
addLastRotationToUndo();
_undoneRotationIndex++;
_undoneRotationIndex = llclamp(_undoneRotationIndex, 0, _lastSetRotations.size() - 1);
_targetRotation.set(_lastSetRotations[_undoneRotationIndex]);
}
void undoLastRotationSet();
/// <summary>
/// Undoes the last rotation set, if any.
/// </summary>
void redoLastRotationSet()
{
if (_lastSetRotations.empty())
return;
void redoLastRotationSet();
_undoneRotationIndex--;
_undoneRotationIndex = llclamp(_undoneRotationIndex, 0, _lastSetRotations.size() - 1);
void undoLastScaleSet();
_targetRotation.set(_lastSetRotations[_undoneRotationIndex]);
if (_undoneRotationIndex == 0)
_lastSetRotations.pop_front();
}
void undoLastScaleSet()
{
if (_lastSetScales.empty())
return;
if (_undoneScaleIndex == 0)
addLastScaleToUndo();
_undoneScaleIndex++;
_undoneScaleIndex = llclamp(_undoneScaleIndex, 0, _lastSetScales.size() - 1);
_targetScale.set(_lastSetScales[_undoneScaleIndex]);
}
void redoLastScaleSet()
{
if (_lastSetScales.empty())
return;
_undoneScaleIndex--;
_undoneScaleIndex = llclamp(_undoneScaleIndex, 0, _lastSetScales.size() - 1);
_targetScale.set(_lastSetScales[_undoneScaleIndex]);
if (_undoneScaleIndex == 0)
_lastSetScales.pop_front();
}
void redoLastScaleSet();
/// <summary>
/// Restores the joint represented by this to the scale it had when this motion started.
/// </summary>
void revertJointScale()
{
LLJoint* joint = _jointState->getJoint();
if (!joint)
return;
joint->setScale(_beginningScale);
}
void revertJointScale();
/// <summary>
/// Restores the joint represented by this to the position it had when this motion started.
/// </summary>
void revertJointPosition()
{
LLJoint* joint = _jointState->getJoint();
if (!joint)
return;
joint->setPosition(_beginningPosition);
}
void revertJointPosition();
/// <summary>
/// Collision Volumes do not 'reset' their position/rotation when the animation stops.
/// This requires special treatment to revert changes we've made this animation session.
/// </summary>
void revertCollisionVolume()
{
if (!_isCollisionVolume)
return;
LLJoint* joint = _jointState->getJoint();
if (!joint)
return;
joint->setRotation(_beginningRotation);
joint->setPosition(_beginningPosition);
joint->setScale(_beginningScale);
}
void revertCollisionVolume();
/// <summary>
/// Gets the pointer to the jointstate for the joint this represents.
/// </summary>
LLPointer<LLJointState> getJointState() const { return _jointState; }
LLPointer<LLJointState> getJointState() const { return mJointState; }
FSJointPose(LLJoint* joint, bool isCollisionVolume = false)
{
_jointState = new LLJointState;
_jointState->setJoint(joint);
_jointState->setUsage(POSER_JOINT_STATE);
_jointName = joint->getName();
_isCollisionVolume = isCollisionVolume;
_beginningRotation = _targetRotation = joint->getRotation();
_beginningPosition = _targetPosition = joint->getPosition();
_beginningScale = _targetScale = joint->getScale();
}
FSJointPose(LLJoint* joint, bool isCollisionVolume = false);
};
public:
virtual bool getLoop() { return TRUE; }
virtual bool getLoop() { return true; }
virtual F32 getDuration() { return 0.0; }
@ -499,13 +287,13 @@ public:
/// </summary>
/// <param name="name">The name of the joint to get the pose for.</param>
/// <returns>The matching joint pose, if found, otherwise null.</returns>
FSJointPose* getJointPoseByJointName(std::string name);
FSJointPose* getJointPoseByJointName(const std::string& name);
/// <summary>
/// Gets the motion identity for this animation.
/// </summary>
/// <returns>The unique, per-session, per-character motion identity.</returns>
LLAssetID motionId() const { return _motionID; }
LLAssetID motionId() const { return mMotionID; }
private:
/// <summary>
@ -516,7 +304,7 @@ private:
/// <summary>
/// The unique identity of this motion.
/// </summary>
LLAssetID _motionID;
LLAssetID mMotionID;
/// <summary>
/// The amount of time, in seconds, we use for transitioning between one animation-state to another; this affects the 'fluidity'
@ -524,12 +312,12 @@ private:
/// Use caution making this larger than the subjective amount of time between adjusting a joint and then choosing to use 'undo' it.
/// Undo-function waits a similar amount of time after the last user-incited joint change to add a 'restore point'.
/// </summary>
const F32 _interpolationTime = 0.25f;
const F32 mInterpolationTime = 0.25f;
/// <summary>
/// The collection of joint poses this motion uses to pose the joints of the character this is animating.
/// </summary>
std::vector<FSJointPose> _jointPoses;
std::vector<FSJointPose> mJointPoses;
/// <summary>
/// Removes the current joint state for the supplied joint, and adds a new one.

View File

@ -54,18 +54,18 @@ FSVirtualTrackpad::FSVirtualTrackpad(const FSVirtualTrackpad::Params &p)
mImgSunBack(p.image_sun_back),
mImgSunFront(p.image_sun_front),
mImgSphere(p.image_sphere),
_allowPinchMode(p.pinch_mode),
_infiniteScrollMode(p.infinite_scroll_mode)
mAllowPinchMode(p.pinch_mode),
mInfiniteScrollMode(p.infinite_scroll_mode)
{
LLRect border_rect = getLocalRect();
_cursorValueX = _pinchCursorValueX = border_rect.getCenterX();
_cursorValueY = _pinchCursorValueY = border_rect.getCenterY();
_cursorValueZ = _pinchCursorValueZ = 0;
mCursorValueX = mPinchCursorValueX = border_rect.getCenterX();
mCursorValueY = mPinchCursorValueY = border_rect.getCenterY();
mCursorValueZ = mPinchCursorValueZ = 0;
_thumbClickOffsetX = _thumbClickOffsetY = _pinchThumbClickOffsetX = _pinchThumbClickOffsetY = 0;
_posXwhenCtrlDown = _posYwhenCtrlDown = 0;
_pinchValueDeltaX = _pinchValueDeltaY = _pinchValueDeltaZ = 0;
_valueDeltaX = _valueDeltaY = _valueDeltaZ = 0;
mThumbClickOffsetX = mThumbClickOffsetY = mPinchThumbClickOffsetX = mPinchThumbClickOffsetY = 0;
mPosXwhenCtrlDown = mPosYwhenCtrlDown = 0;
mPinchValueDeltaX = mPinchValueDeltaY = mPinchValueDeltaZ = 0;
mValueDeltaX = mValueDeltaY = mValueDeltaZ = 0;
LLViewBorder::Params border = p.border;
border.rect(border_rect);
@ -93,8 +93,8 @@ void FSVirtualTrackpad::drawThumb(bool isPinchThumb)
else
thumb = isPinchThumb ? mImgSunBack : mImgMoonBack;
S32 x = isPinchThumb ? _pinchCursorValueX : _cursorValueX;
S32 y = isPinchThumb ? _pinchCursorValueY : _cursorValueY;
S32 x = isPinchThumb ? mPinchCursorValueX : mCursorValueX;
S32 y = isPinchThumb ? mPinchCursorValueY : mCursorValueY;
wrapOrClipCursorPosition(&x, &y);
@ -122,11 +122,11 @@ void FSVirtualTrackpad::determineThumbClickError(S32 x, S32 y)
if (!mImgSunFront)
return;
_thumbClickOffsetX = 0;
_thumbClickOffsetY = 0;
mThumbClickOffsetX = 0;
mThumbClickOffsetY = 0;
S32 errorX = _cursorValueX;
S32 errorY = _cursorValueY;
S32 errorX = mCursorValueX;
S32 errorY = mCursorValueY;
wrapOrClipCursorPosition(&errorX, &errorY);
errorX -= x;
errorY -= y;
@ -136,37 +136,37 @@ void FSVirtualTrackpad::determineThumbClickError(S32 x, S32 y)
if (fabs(errorY) > mImgSunFront->getHeight() / 2.0)
return;
_thumbClickOffsetX = errorX;
_thumbClickOffsetY = errorY;
mThumbClickOffsetX = errorX;
mThumbClickOffsetY = errorY;
}
void FSVirtualTrackpad::updateClickErrorIfInfiniteScrolling()
{
if (!_infiniteScrollMode)
if (!mInfiniteScrollMode)
return;
S32 errorX = _cursorValueX;
S32 errorY = _cursorValueY;
S32 errorX = mCursorValueX;
S32 errorY = mCursorValueY;
LLRect rect = mTouchArea->getRect();
while (errorX > rect.mRight)
{
errorX -= rect.getWidth();
_thumbClickOffsetX += rect.getWidth();
mThumbClickOffsetX += rect.getWidth();
}
while (errorX < rect.mLeft)
{
errorX += rect.getWidth();
_thumbClickOffsetX -= rect.getWidth();
mThumbClickOffsetX -= rect.getWidth();
}
while (errorY > rect.mTop)
{
errorY -= rect.getHeight();
_thumbClickOffsetY += rect.getHeight();
mThumbClickOffsetY += rect.getHeight();
}
while (errorY < rect.mBottom)
{
errorY += rect.getHeight();
_thumbClickOffsetY -= rect.getHeight();
mThumbClickOffsetY -= rect.getHeight();
}
}
@ -177,11 +177,11 @@ void FSVirtualTrackpad::determineThumbClickErrorForPinch(S32 x, S32 y)
if (!mImgMoonFront)
return;
_pinchThumbClickOffsetX = 0;
_pinchThumbClickOffsetY = 0;
mPinchThumbClickOffsetX = 0;
mPinchThumbClickOffsetY = 0;
S32 errorX = _pinchCursorValueX;
S32 errorY = _pinchCursorValueY;
S32 errorX = mPinchCursorValueX;
S32 errorY = mPinchCursorValueY;
wrapOrClipCursorPosition(&errorX, &errorY);
errorX -= x;
errorY -= y;
@ -191,37 +191,37 @@ void FSVirtualTrackpad::determineThumbClickErrorForPinch(S32 x, S32 y)
if (fabs(errorY) > mImgMoonFront->getHeight() / 2.0)
return;
_pinchThumbClickOffsetX = errorX;
_pinchThumbClickOffsetY = errorY;
mPinchThumbClickOffsetX = errorX;
mPinchThumbClickOffsetY = errorY;
}
void FSVirtualTrackpad::updateClickErrorIfInfiniteScrollingForPinch()
{
if (!_infiniteScrollMode)
if (!mInfiniteScrollMode)
return;
S32 errorX = _cursorValueX;
S32 errorY = _cursorValueY;
S32 errorX = mCursorValueX;
S32 errorY = mCursorValueY;
LLRect rect = mTouchArea->getRect();
while (errorX > rect.mRight)
{
errorX -= rect.getWidth();
_pinchThumbClickOffsetX += rect.getWidth();
mPinchThumbClickOffsetX += rect.getWidth();
}
while (errorX < rect.mLeft)
{
errorX += rect.getWidth();
_pinchThumbClickOffsetX -= rect.getWidth();
mPinchThumbClickOffsetX -= rect.getWidth();
}
while (errorY > rect.mTop)
{
errorY -= rect.getHeight();
_pinchThumbClickOffsetY += rect.getHeight();
mPinchThumbClickOffsetY += rect.getHeight();
}
while (errorY < rect.mBottom)
{
errorY += rect.getHeight();
_pinchThumbClickOffsetY -= rect.getHeight();
mPinchThumbClickOffsetY -= rect.getHeight();
}
}
@ -229,7 +229,7 @@ void FSVirtualTrackpad::draw()
{
mImgSphere->draw(mTouchArea->getRect(), mTouchArea->isInEnabledChain() ? UI_VERTEX_COLOR : UI_VERTEX_COLOR % 0.5f);
if (_allowPinchMode)
if (mAllowPinchMode)
drawThumb(true);
drawThumb(false);
@ -258,25 +258,25 @@ void FSVirtualTrackpad::setValue(const LLSD& value)
void FSVirtualTrackpad::setValue(F32 x, F32 y, F32 z)
{
convertNormalizedToPixelPos(x, y, z, &_cursorValueX, &_cursorValueY, &_cursorValueZ);
_valueX = _cursorValueX;
_valueY = _cursorValueY;
_valueZ = _cursorValueZ;
convertNormalizedToPixelPos(x, y, z, &mCursorValueX, &mCursorValueY, &mCursorValueZ);
mValueX = mCursorValueX;
mValueY = mCursorValueY;
mValueZ = mCursorValueZ;
}
void FSVirtualTrackpad::setPinchValue(F32 x, F32 y, F32 z)
{
convertNormalizedToPixelPos(x, y, z, &_pinchCursorValueX, &_pinchCursorValueY, &_pinchCursorValueZ);
_pinchValueX = _pinchCursorValueX;
_pinchValueY = _pinchCursorValueY;
_pinchValueZ = _pinchCursorValueZ;
convertNormalizedToPixelPos(x, y, z, &mPinchCursorValueX, &mPinchCursorValueY, &mPinchCursorValueZ);
mPinchValueX = mPinchCursorValueX;
mPinchValueY = mPinchCursorValueY;
mPinchValueZ = mPinchCursorValueZ;
}
LLSD FSVirtualTrackpad::getValue() const { return normalizePixelPos(_valueX, _valueY, _valueZ).getValue(); }
LLSD FSVirtualTrackpad::getValueDelta() { return normalizeDelta(_valueDeltaX, _valueDeltaY, _valueDeltaZ).getValue(); }
LLSD FSVirtualTrackpad::getValue() const { return normalizePixelPos(mValueX, mValueY, mValueZ).getValue(); }
LLSD FSVirtualTrackpad::getValueDelta() { return normalizeDelta(mValueDeltaX, mValueDeltaY, mValueDeltaZ).getValue(); }
LLSD FSVirtualTrackpad::getPinchValue() { return normalizePixelPos(_pinchValueX, _pinchValueY, _pinchValueZ).getValue(); }
LLSD FSVirtualTrackpad::getPinchValueDelta() { return normalizeDelta(_pinchValueDeltaX, _pinchValueDeltaY, _pinchValueDeltaZ).getValue(); }
LLSD FSVirtualTrackpad::getPinchValue() { return normalizePixelPos(mPinchValueX, mPinchValueY, mPinchValueZ).getValue(); }
LLSD FSVirtualTrackpad::getPinchValueDelta() { return normalizeDelta(mPinchValueDeltaX, mPinchValueDeltaY, mPinchValueDeltaZ).getValue(); }
void FSVirtualTrackpad::wrapOrClipCursorPosition(S32* x, S32* y) const
{
@ -284,7 +284,7 @@ void FSVirtualTrackpad::wrapOrClipCursorPosition(S32* x, S32* y) const
return;
LLRect rect = mTouchArea->getRect();
if (_infiniteScrollMode)
if (mInfiniteScrollMode)
{
while (*x > rect.mRight)
*x -= rect.getWidth();
@ -323,152 +323,152 @@ void FSVirtualTrackpad::getHoverMovementDeltas(S32 x, S32 y, MASK mask, S32* del
return;
S32 fromX, fromY;
fromX = _doingPinchMode ? _pinchCursorValueX : _cursorValueX;
fromY = _doingPinchMode ? _pinchCursorValueY : _cursorValueY;
fromX = mDoingPinchMode ? mPinchCursorValueX : mCursorValueX;
fromY = mDoingPinchMode ? mPinchCursorValueY : mCursorValueY;
if (mask & MASK_CONTROL)
{
if (!_heldDownControlBefore)
if (!mHeldDownControlBefore)
{
_posXwhenCtrlDown = x;
_posYwhenCtrlDown = y;
_heldDownControlBefore = true;
mPosXwhenCtrlDown = x;
mPosYwhenCtrlDown = y;
mHeldDownControlBefore = true;
}
if (_doingPinchMode)
if (mDoingPinchMode)
{
*deltaX = _posXwhenCtrlDown - (_posXwhenCtrlDown - x) / 8 + _pinchThumbClickOffsetX - fromX;
*deltaY = _posYwhenCtrlDown - (_posYwhenCtrlDown - y) / 8 + _pinchThumbClickOffsetY - fromY;
*deltaX = mPosXwhenCtrlDown - (mPosXwhenCtrlDown - x) / 8 + mPinchThumbClickOffsetX - fromX;
*deltaY = mPosYwhenCtrlDown - (mPosYwhenCtrlDown - y) / 8 + mPinchThumbClickOffsetY - fromY;
}
else
{
*deltaX = _posXwhenCtrlDown - (_posXwhenCtrlDown - x) / 8 + _thumbClickOffsetX - fromX;
*deltaY = _posYwhenCtrlDown - (_posYwhenCtrlDown - y) / 8 + _thumbClickOffsetY - fromY;
*deltaX = mPosXwhenCtrlDown - (mPosXwhenCtrlDown - x) / 8 + mThumbClickOffsetX - fromX;
*deltaY = mPosYwhenCtrlDown - (mPosYwhenCtrlDown - y) / 8 + mThumbClickOffsetY - fromY;
}
}
else
{
if (_heldDownControlBefore)
if (mHeldDownControlBefore)
{
_thumbClickOffsetX = fromX - x;
_thumbClickOffsetY = fromY - y;
_heldDownControlBefore = false;
mThumbClickOffsetX = fromX - x;
mThumbClickOffsetY = fromY - y;
mHeldDownControlBefore = false;
}
if (_doingPinchMode)
if (mDoingPinchMode)
{
*deltaX = x + _pinchThumbClickOffsetX - fromX;
*deltaY = y + _pinchThumbClickOffsetY - fromY;
*deltaX = x + mPinchThumbClickOffsetX - fromX;
*deltaY = y + mPinchThumbClickOffsetY - fromY;
}
else
{
*deltaX = x + _thumbClickOffsetX - fromX;
*deltaY = y + _thumbClickOffsetY - fromY;
*deltaX = x + mThumbClickOffsetX - fromX;
*deltaY = y + mThumbClickOffsetY - fromY;
}
}
}
void FSVirtualTrackpad::applyHoverMovementDeltas(S32 deltaX, S32 deltaY, MASK mask)
{
if (_doingPinchMode)
if (mDoingPinchMode)
{
_pinchCursorValueX += deltaX;
_pinchCursorValueY += deltaY;
if (!_infiniteScrollMode) // then constrain the cursor within control area
wrapOrClipCursorPosition(&_pinchCursorValueX, &_pinchCursorValueY);
mPinchCursorValueX += deltaX;
mPinchCursorValueY += deltaY;
if (!mInfiniteScrollMode) // then constrain the cursor within control area
wrapOrClipCursorPosition(&mPinchCursorValueX, &mPinchCursorValueY);
}
else
{
_cursorValueX += deltaX;
_cursorValueY += deltaY;
mCursorValueX += deltaX;
mCursorValueY += deltaY;
if (!_infiniteScrollMode) // then constrain the cursor within control area
wrapOrClipCursorPosition(&_cursorValueX, &_cursorValueY);
if (!mInfiniteScrollMode) // then constrain the cursor within control area
wrapOrClipCursorPosition(&mCursorValueX, &mCursorValueY);
}
}
void FSVirtualTrackpad::applyDeltasToValues(S32 deltaX, S32 deltaY, MASK mask)
{
if (_doingPinchMode)
if (mDoingPinchMode)
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
{
_pinchValueY += deltaY;
_pinchValueZ += deltaX;
mPinchValueY += deltaY;
mPinchValueZ += deltaX;
}
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
{
_pinchValueX += deltaX;
_pinchValueZ += deltaY;
mPinchValueX += deltaX;
mPinchValueZ += deltaY;
}
else
{
_pinchValueX += deltaX;
_pinchValueY += deltaY;
mPinchValueX += deltaX;
mPinchValueY += deltaY;
}
}
else
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
{
_valueY += deltaY;
_valueZ += deltaX;
mValueY += deltaY;
mValueZ += deltaX;
}
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
{
_valueX += deltaX;
_valueZ += deltaY;
mValueX += deltaX;
mValueZ += deltaY;
}
else
{
_valueX += deltaX;
_valueY += deltaY;
mValueX += deltaX;
mValueY += deltaY;
}
}
}
void FSVirtualTrackpad::applyDeltasToDeltaValues(S32 deltaX, S32 deltaY, MASK mask)
{
if (_doingPinchMode)
if (mDoingPinchMode)
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
{
_pinchValueDeltaX = 0;
_pinchValueDeltaY = deltaY;
_pinchValueDeltaZ = deltaX;
mPinchValueDeltaX = 0;
mPinchValueDeltaY = deltaY;
mPinchValueDeltaZ = deltaX;
}
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
{
_pinchValueDeltaX = deltaX;
_pinchValueDeltaY = 0;
_pinchValueDeltaZ = deltaY;
mPinchValueDeltaX = deltaX;
mPinchValueDeltaY = 0;
mPinchValueDeltaZ = deltaY;
}
else
{
_pinchValueDeltaX = deltaX;
_pinchValueDeltaY = deltaY;
_pinchValueDeltaZ = 0;
mPinchValueDeltaX = deltaX;
mPinchValueDeltaY = deltaY;
mPinchValueDeltaZ = 0;
}
}
else
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
{
_valueDeltaX = 0;
_valueDeltaY = deltaY;
_valueDeltaZ = deltaX;
mValueDeltaX = 0;
mValueDeltaY = deltaY;
mValueDeltaZ = deltaX;
}
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
{
_valueDeltaX = deltaX;
_valueDeltaY = 0;
_valueDeltaZ = deltaY;
mValueDeltaX = deltaX;
mValueDeltaY = 0;
mValueDeltaZ = deltaY;
}
else
{
_valueDeltaX = deltaX;
_valueDeltaY = deltaY;
_valueDeltaZ = 0;
mValueDeltaX = deltaX;
mValueDeltaY = deltaY;
mValueDeltaZ = 0;
}
}
}
@ -520,7 +520,7 @@ void FSVirtualTrackpad::convertNormalizedToPixelPos(F32 x, F32 y, F32 z, S32 *va
S32 width = rect.getWidth();
S32 height = rect.getHeight();
if (_infiniteScrollMode)
if (mInfiniteScrollMode)
{
*valX = centerX + ll_round(x * width / 2);
*valY = centerY + ll_round(y * height / 2);
@ -539,7 +539,7 @@ bool FSVirtualTrackpad::handleMouseUp(S32 x, S32 y, MASK mask)
if (hasMouseCapture())
{
gFocusMgr.setMouseCapture(NULL);
_heldDownControlBefore = false;
mHeldDownControlBefore = false;
make_ui_sound("UISndClickRelease");
}
@ -563,7 +563,7 @@ bool FSVirtualTrackpad::handleRightMouseUp(S32 x, S32 y, MASK mask)
{
if (hasMouseCapture())
{
_doingPinchMode = false;
mDoingPinchMode = false;
gFocusMgr.setMouseCapture(NULL);
make_ui_sound("UISndClickRelease");
@ -575,14 +575,14 @@ bool FSVirtualTrackpad::handleRightMouseUp(S32 x, S32 y, MASK mask)
// move pinch cursor
bool FSVirtualTrackpad::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (!_allowPinchMode)
if (!mAllowPinchMode)
return LLView::handleRightMouseDown(x, y, mask);
if (isPointInTouchArea(x, y))
{
determineThumbClickErrorForPinch(x, y);
updateClickErrorIfInfiniteScrollingForPinch();
_doingPinchMode = true;
mDoingPinchMode = true;
gFocusMgr.setMouseCapture(this);
make_ui_sound("UISndClick");
@ -602,23 +602,23 @@ bool FSVirtualTrackpad::handleScrollWheel(S32 x, S32 y, S32 clicks)
if (mask & MASK_CONTROL)
changeAmount /= 5;
if (_doingPinchMode)
if (mDoingPinchMode)
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
_pinchValueX -= clicks * changeAmount;
mPinchValueX -= clicks * changeAmount;
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
_pinchValueY -= clicks * changeAmount;
mPinchValueY -= clicks * changeAmount;
else
_pinchValueZ -= clicks * changeAmount;
mPinchValueZ -= clicks * changeAmount;
}
else
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
_valueX -= clicks * changeAmount;
mValueX -= clicks * changeAmount;
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
_valueY -= clicks * changeAmount;
mValueY -= clicks * changeAmount;
else
_valueZ -= clicks * changeAmount;
mValueZ -= clicks * changeAmount;
}
if (!hasMouseCapture())

View File

@ -100,8 +100,8 @@ protected:
FSVirtualTrackpad(const Params&);
protected:
LLPanel* mTouchArea;
LLViewBorder* mBorder;
LLPanel* mTouchArea{ nullptr };
LLViewBorder* mBorder{ nullptr };
private:
const F32 ThirdAxisQuantization = 0.001f; // To avoid quantizing the third axis as we add integer wheel clicks, use this to preserve some precision as int.
@ -124,21 +124,21 @@ private:
void applyDeltasToValues(S32 deltaX, S32 deltaY, MASK mask);
void applyDeltasToDeltaValues(S32 deltaX, S32 deltaY, MASK mask);
LLUIImage* mImgMoonBack;
LLUIImage* mImgMoonFront;
LLUIImage* mImgSunBack;
LLUIImage* mImgSunFront;
LLUIImage* mImgSphere;
LLUIImage* mImgMoonBack{ nullptr };
LLUIImage* mImgMoonFront{ nullptr };
LLUIImage* mImgSunBack{ nullptr };
LLUIImage* mImgSunFront{ nullptr };
LLUIImage* mImgSphere{ nullptr };
/// <summary>
/// Whether we allow the second cursor to appear.
/// </summary>
bool _allowPinchMode = false;
bool mAllowPinchMode{ false };
/// <summary>
/// Whether we should be moving the pinch cursor now
/// </summary>
bool _doingPinchMode = false;
bool mDoingPinchMode{ false };
/// <summary>
/// Whether to allow the cursor(s) to 'wrap'.
@ -148,48 +148,48 @@ private:
/// When true, the cursor 'disappears' out the top, and starts from the bottom,
/// effectively allowing infinite scrolling.
/// </example>
bool _infiniteScrollMode = false;
bool mInfiniteScrollMode{ false };
bool _heldDownControlBefore = false;
bool mHeldDownControlBefore{ false };
/// <summary>
/// The values the owner will get and set.
/// </summary>
S32 _valueX;
S32 _valueY;
S32 _valueZ;
S32 _pinchValueX;
S32 _pinchValueY;
S32 _pinchValueZ;
S32 mValueX{ 0 };
S32 mValueY{ 0 };
S32 mValueZ{ 0 };
S32 mPinchValueX{ 0 };
S32 mPinchValueY{ 0 };
S32 mPinchValueZ{ 0 };
/// <summary>
/// The delta values the owner will get and set.
/// </summary>
S32 _valueDeltaX;
S32 _valueDeltaY;
S32 _valueDeltaZ;
S32 _pinchValueDeltaX;
S32 _pinchValueDeltaY;
S32 _pinchValueDeltaZ;
S32 mValueDeltaX{ 0 };
S32 mValueDeltaY{ 0 };
S32 mValueDeltaZ{ 0 };
S32 mPinchValueDeltaX{ 0 };
S32 mPinchValueDeltaY{ 0 };
S32 mPinchValueDeltaZ{ 0 };
/// <summary>
/// The various values placing the cursors and documenting behaviours.
/// Where relevant, all are scaled in pixels.
/// </summary>
S32 _cursorValueX;
S32 _cursorValueY;
S32 _cursorValueZ;
S32 _pinchCursorValueX;
S32 _pinchCursorValueY;
S32 _pinchCursorValueZ;
S32 mCursorValueX{ 0 };
S32 mCursorValueY{ 0 };
S32 mCursorValueZ{ 0 };
S32 mPinchCursorValueX{ 0 };
S32 mPinchCursorValueY{ 0 };
S32 mPinchCursorValueZ{ 0 };
// if one clicks on or about the thumb, we don't move it, instead we calculate the click-position error and factor it out
S32 _thumbClickOffsetX;
S32 _thumbClickOffsetY;
S32 _pinchThumbClickOffsetX;
S32 _pinchThumbClickOffsetY;
S32 _posXwhenCtrlDown;
S32 _posYwhenCtrlDown;
S32 mThumbClickOffsetX{ 0 };
S32 mThumbClickOffsetY{ 0 };
S32 mPinchThumbClickOffsetX{ 0 };
S32 mPinchThumbClickOffsetY{ 0 };
S32 mPosXwhenCtrlDown{ 0 };
S32 mPosYwhenCtrlDown{ 0 };
};
#endif

View File

@ -25,15 +25,15 @@
#include "llviewermenufile.h"
// Correction factors needed after porting from Phoenix
const S32 CORRECTION_X = 0;
const S32 CORRECTION_Y = -40;
constexpr S32 CORRECTION_X = 0;
constexpr S32 CORRECTION_Y = -40;
F32 convertXToHue(S32 place)
static F32 convertXToHue(S32 place)
{
return ((place - 6) / 396.0f) * 720.0f;
}
S32 convertHueToX(F32 place)
static S32 convertHueToX(F32 place)
{
return ll_round((place / 720.0f) * 396.0f) + 6;
}
@ -42,11 +42,10 @@ lggBeamColorMapFloater::lggBeamColorMapFloater(const LLSD& seed) : LLFloater(see
mContextConeOpacity(0.f),
mContextConeInAlpha(CONTEXT_CONE_IN_ALPHA),
mContextConeOutAlpha(CONTEXT_CONE_OUT_ALPHA),
mContextConeFadeTime(CONTEXT_CONE_FADE_TIME)
{
}
lggBeamColorMapFloater::~lggBeamColorMapFloater()
mContextConeFadeTime(CONTEXT_CONE_FADE_TIME),
mFSPanel(nullptr),
mColorSlider(nullptr),
mBeamColorPreview(nullptr)
{
}
@ -75,8 +74,11 @@ void lggBeamColorMapFloater::draw()
LLColor4 bColor = LLColor4(lggBeamMaps::beamColorFromData(mData));
mBeamColorPreview->set(bColor, true);
static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
drawConeToOwner(mContextConeOpacity, max_opacity, mFSPanel->getChild<LLButton>("BeamColor_new"), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
if (mFSPanel)
{
static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
drawConeToOwner(mContextConeOpacity, max_opacity, mFSPanel->getChild<LLButton>("BeamColor_new"), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
}
//Draw Base Stuff
LLFloater::draw();
@ -184,7 +186,7 @@ void lggBeamColorMapFloater::onClickSlider()
fixOrder();
}
F32 lggBeamColorMapFloater::getHueFromLocation(S32 x, S32 y)
F32 lggBeamColorMapFloater::getHueFromLocation(S32 x, S32 y) const
{
if (y > (201 + CORRECTION_Y) && y < (277 + CORRECTION_Y))
{
@ -225,7 +227,7 @@ void lggBeamColorMapFloater::setData(FSPanelPrefs* data)
}
}
LLSD lggBeamColorMapFloater::getDataSerialized()
LLSD lggBeamColorMapFloater::getDataSerialized() const
{
return mData.toLLSD();
}

View File

@ -28,7 +28,6 @@ class lggBeamColorMapFloater : public LLFloater
{
public:
lggBeamColorMapFloater(const LLSD& seed);
virtual ~lggBeamColorMapFloater();
bool postBuild() override;
bool handleMouseDown(S32 x, S32 y, MASK mask) override;
@ -47,9 +46,9 @@ protected:
void onSaveCallback(const std::vector<std::string>& filenames);
void onLoadCallback(const std::vector<std::string>& filenames);
F32 getHueFromLocation(S32 x, S32 y);
F32 getHueFromLocation(S32 x, S32 y) const;
void fixOrder();
LLSD getDataSerialized();
LLSD getDataSerialized() const;
F32 mContextConeOpacity;
F32 mContextConeInAlpha;

View File

@ -27,11 +27,9 @@ lggBeamMapFloater::lggBeamMapFloater(const LLSD& seed) : LLFloater(seed),
mContextConeOpacity(0.f),
mContextConeInAlpha(CONTEXT_CONE_IN_ALPHA),
mContextConeOutAlpha(CONTEXT_CONE_OUT_ALPHA),
mContextConeFadeTime(CONTEXT_CONE_FADE_TIME)
{
}
lggBeamMapFloater::~lggBeamMapFloater()
mContextConeFadeTime(CONTEXT_CONE_FADE_TIME),
mFSPanel(nullptr),
mBeamshapePanel(nullptr)
{
}
@ -52,11 +50,14 @@ bool lggBeamMapFloater::postBuild()
void lggBeamMapFloater::draw()
{
static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
drawConeToOwner(mContextConeOpacity, max_opacity, mFSPanel->getChild<LLButton>("custom_beam_btn"), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
if (mFSPanel)
{
static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
drawConeToOwner(mContextConeOpacity, max_opacity, mFSPanel->getChild<LLButton>("custom_beam_btn"), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
}
LLFloater::draw();
LLRect rec = mBeamshapePanel->getRect();
const LLRect& rec = mBeamshapePanel->getRect();
gGL.pushMatrix();
gGL.color4fv(LLColor4::white.mV);
@ -70,10 +71,8 @@ void lggBeamMapFloater::draw()
gGL.color4fv(LLColor4::white.mV);
gl_circle_2d((F32)rec.getCenterX(), (F32)rec.getCenterY(), 120.0f, 30, false);
for (std::vector<lggPoint>::iterator it = mDots.begin(); it != mDots.end(); ++it)
for (const auto& dot : mDots)
{
lggPoint dot = *it;
gGL.color4fv(LLColor4::white.mV);
gl_circle_2d((F32)dot.x, (F32)dot.y, 9.0f, 30, true);
@ -103,12 +102,11 @@ bool lggBeamMapFloater::handleMouseDown(S32 x, S32 y, MASK mask)
bool lggBeamMapFloater::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
std::vector<lggPoint> newDots;
for (std::vector<lggPoint>::iterator it = mDots.begin(); it != mDots.end(); ++it)
for (const auto& dot : mDots)
{
lggPoint dot = *it;
if (dist_vec(LLVector2((F32)x, (F32)y), LLVector2((F32)dot.x, (F32)dot.y)) >= 7)
{
newDots.push_back(dot);
newDots.emplace_back(dot);
}
}
@ -122,19 +120,19 @@ void lggBeamMapFloater::onBackgroundChange()
mBeamshapePanel->setBackgroundColor(getChild<LLColorSwatchCtrl>("back_color_swatch")->get());
}
LLSD lggBeamMapFloater::getDataSerialized()
LLSD lggBeamMapFloater::getDataSerialized() const
{
LLSD out;
LLRect r = mBeamshapePanel->getRect();
for (S32 i = 0; i < mDots.size(); ++i)
{
LLSD point;
lggPoint t = mDots[i];
LLVector3 vec = LLVector3(0.f, (F32)t.x, (F32)t.y);
const lggPoint& dot = mDots.at(i);
LLVector3 vec{ 0.f, (F32)dot.x, (F32)dot.y };
vec -= LLVector3(0.f, (F32)r.getCenterX(), (F32)r.getCenterY());
point["offset"] = vec.getValue();
point["color"] = t.c.getValue();
point["color"] = dot.c.getValue();
out[i] = point;
}
@ -192,7 +190,7 @@ void lggBeamMapFloater::onLoadCallback(const std::vector<std::string>& filenames
LLSD beam_data = *it;
lggPoint p;
LLVector3 vec = LLVector3(beam_data["offset"]);
LLVector3 vec{ beam_data["offset"] };
vec *= scale / (8.0f / rec.getWidth());
LLColor4 color = LLColor4(beam_data["color"]);
p.c = color;

View File

@ -19,12 +19,11 @@
class FSPanelPrefs;
class LLPanel;
class lggPoint
struct lggPoint
{
public:
S32 x;
S32 y;
LLColor4 c;
S32 x;
S32 y;
LLColor4 c;
};
////////////////////////////////////////////////////////////////////////////
@ -33,7 +32,6 @@ class lggBeamMapFloater : public LLFloater
{
public:
lggBeamMapFloater(const LLSD& seed);
virtual ~lggBeamMapFloater();
bool postBuild(void) override;
bool handleMouseDown(S32 x, S32 y, MASK mask) override;
@ -55,7 +53,7 @@ private:
void clearPoints();
LLSD getDataSerialized();
LLSD getDataSerialized() const;
std::vector<lggPoint> mDots;
F32 mContextConeOpacity;

View File

@ -88,7 +88,7 @@ void hslToRgb(F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F3
}
}
LLSD lggBeamMaps::getPic(const std::string& filename)
LLSD lggBeamMaps::getPic(const std::string& filename) const
{
LLSD data;
llifstream importer(filename.c_str());
@ -136,7 +136,7 @@ LLColor4U lggBeamMaps::beamColorFromData(const lggBeamsColors& data)
LLColor4U toReturn;
F32 difference = data.mEndHue - data.mStartHue;
F32 timeinc = difference != 0.f ? timer.getElapsedTimeF32() * 0.3f * (data.mRotateSpeed + 0.01f) * (360 / difference) : 0.f;
F32 timeinc = difference != 0.f ? timer.getElapsedTimeF32() * 0.3f * (data.mRotateSpeed + 0.01f) * (360.f / difference) : 0.f;
S32 rounded_difference = ll_round(difference);
if (rounded_difference == 360 || rounded_difference == 720)
@ -166,21 +166,21 @@ void lggBeamMaps::fireCurrentBeams(LLPointer<LLHUDEffectSpiral> mBeam, const LLC
static LLCachedControl<std::string> colorf(gSavedSettings, "FSBeamColorFile");
bool colorsDisabled = (colorf().empty());
for (std::vector<lggBeamData>::iterator it = mDots.begin(); it != mDots.end(); ++it)
for (const auto& dot : mDots)
{
LLColor4U myColor = rgb;
if (colorsDisabled)
{
myColor = (*it).c;
myColor = dot.c;
}
F32 distanceAdjust = (F32)dist_vec(mBeam->getPositionGlobal(), gAgent.getPositionGlobal());
F32 pulse = 0.75f + sinf(gFrameTimeSeconds * 1.0f) * 0.25f;
LLVector3d offset = (*it).p;
LLVector3d offset = dot.p;
offset.mdV[VY] *= -1.f;
offset *= pulse * mScale * distanceAdjust * 0.1f;
LLVector3 beamLine = LLVector3( mBeam->getPositionGlobal() - gAgent.getPositionGlobal());
LLVector3 beamLine = LLVector3(mBeam->getPositionGlobal() - gAgent.getPositionGlobal());
LLVector3 beamLineFlat = beamLine;
beamLineFlat.mV[VZ]= 0.0f;
@ -243,7 +243,7 @@ F32 lggBeamMaps::setUpAndGetDuration()
dot.p *= (FSBeamShapeScale * 2.0f);
LLColor4 color = LLColor4(beamData["color"]);
dot.c = LLColor4U(color);
mDots.push_back(dot);
mDots.push_back(std::move(dot));
}
static LLCachedControl<F32> FSMaxBeamsPerSecond(gSavedSettings, "FSMaxBeamsPerSecond");
@ -262,7 +262,7 @@ F32 lggBeamMaps::setUpAndGetDuration()
return mDuration;
}
string_vec_t lggBeamMaps::getFileNames()
string_vec_t lggBeamMaps::getFileNames() const
{
string_vec_t names;
std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "beams", ""));
@ -294,7 +294,7 @@ string_vec_t lggBeamMaps::getFileNames()
return names;
}
string_vec_t lggBeamMaps::getColorsFileNames()
string_vec_t lggBeamMaps::getColorsFileNames() const
{
string_vec_t names;
std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "beamsColors", ""));

View File

@ -21,9 +21,8 @@
F32 hueToRgb(F32 val1In, F32 val2In, F32 valHUeIn);
void hslToRgb(F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& bValOut);
class lggBeamData
struct lggBeamData
{
public:
LLVector3d p;
LLColor4U c;
};
@ -31,15 +30,6 @@ public:
class lggBeamMaps
{
public:
lggBeamMaps() :
mLastFileName(""),
mScale(0.0f),
mDuration(0.25f),
mPartsNow(false),
mBeamLastAt(LLVector3d::zero)
{}
~lggBeamMaps() {}
F32 setUpAndGetDuration();
void fireCurrentBeams(LLPointer<LLHUDEffectSpiral>, const LLColor4U& rgb);
void forceUpdate();
@ -47,19 +37,19 @@ public:
void updateBeamChat(const LLVector3d& currentPos);
static LLColor4U beamColorFromData(const lggBeamsColors& data);
LLColor4U getCurrentColor(const LLColor4U& agentColor);
string_vec_t getFileNames();
string_vec_t getColorsFileNames();
string_vec_t getFileNames() const;
string_vec_t getColorsFileNames() const;
private:
LLSD getPic(const std::string& filename);
LLSD getPic(const std::string& filename) const;
std::string mLastFileName;
std::string mLastColorFileName;
lggBeamsColors mLastColorsData;
F32 mDuration;
F32 mScale;
bool mPartsNow;
LLVector3d mBeamLastAt;
std::string mLastFileName{};
std::string mLastColorFileName{};
lggBeamsColors mLastColorsData{};
F32 mDuration{ 0.25f };
F32 mScale{ 0.0f };
bool mPartsNow{ false };
LLVector3d mBeamLastAt{ LLVector3d::zero };
std::vector<lggBeamData> mDots;
};

View File

@ -40,7 +40,7 @@ lggBeamsColors lggBeamsColors::fromLLSD(const LLSD& inputData)
return toReturn;
}
LLSD lggBeamsColors::toLLSD()
LLSD lggBeamsColors::toLLSD() const
{
LLSD out;
out["startHue"] = mStartHue;
@ -49,7 +49,7 @@ LLSD lggBeamsColors::toLLSD()
return out;
}
std::string lggBeamsColors::toString()
std::string lggBeamsColors::toString() const
{
return llformat("Start Hue %d\nEnd Hue is %d\nRotate Speed is %d", mStartHue, mEndHue, mRotateSpeed);
}
@ -60,14 +60,3 @@ lggBeamsColors::lggBeamsColors(F32 startHue, F32 endHue, F32 rotateSpeed) :
mRotateSpeed(rotateSpeed)
{
}
lggBeamsColors::lggBeamsColors():
mStartHue(0.0f),
mEndHue(360.0f),
mRotateSpeed(1.0f)
{
}
lggBeamsColors::~lggBeamsColors()
{
}

View File

@ -20,18 +20,16 @@ class lggBeamsColors
{
public:
lggBeamsColors(F32 startHue, F32 endHue, F32 rotateSpeed);
lggBeamsColors();
lggBeamsColors() = default;
~lggBeamsColors();
F32 mStartHue{ 0.0f };
F32 mEndHue{ 360.0f };
F32 mRotateSpeed{ 1.f };
F32 mStartHue;
F32 mEndHue;
F32 mRotateSpeed;
LLSD toLLSD();
LLSD toLLSD() const;
static lggBeamsColors fromLLSD(const LLSD& inputData);
std::string toString();
std::string toString() const;
// List sorted by name.
};

View File

@ -43,6 +43,7 @@ void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement
if (perform_autoreplace)
{
S32 word_end = cursor_pos - 1;
if (word_end < 0 ) { word_end = 0; }; // <FS:Beq/> FIRE-34765
bool at_space = (input_text[word_end] == ' ');
bool have_word = (LLWStringUtil::isPartOfWord(input_text[word_end]));

View File

@ -60,17 +60,17 @@ LLToolSelect::LLToolSelect( LLToolComposite* composite )
: LLTool( std::string("Select"), composite ),
mIgnoreGroup( false )
{
}
}
// True if you selected an object.
bool LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
{
// do immediate pick query
bool pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
bool pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects");
bool pick_reflection_probe = gSavedSettings.getBOOL("SelectReflectionProbes");
static LLCachedControl<bool> select_invisible_objects(gSavedSettings, "SelectInvisibleObjects");
static LLCachedControl<bool> select_reflection_probes(gSavedSettings, "SelectReflectionProbes");
mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged, false, true, pick_reflection_probe);
mPick = gViewerWindow->pickImmediate(x, y, select_invisible_objects, pick_rigged, false, true, select_reflection_probes);
// Pass mousedown to agent
LLTool::handleMouseDown(x, y, mask);
@ -78,7 +78,6 @@ bool LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
return mPick.getObject().notNull();
}
// static
LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, bool ignore_group, bool temp_select, bool select_root)
{

View File

@ -5362,15 +5362,15 @@ void LLViewerWindow::pickAsync( S32 x,
bool pick_unselectable,
bool pick_reflection_probes)
{
static LLCachedControl<bool> select_invisible_objects(gSavedSettings, "SelectInvisibleObjects");
// "Show Debug Alpha" means no object actually transparent
bool in_build_mode = LLFloaterReg::instanceVisible("build");
if (LLDrawPoolAlpha::sShowDebugAlpha
|| (in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")))
if (LLDrawPoolAlpha::sShowDebugAlpha || (in_build_mode && select_invisible_objects))
{
pick_transparent = true;
}
LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, false, pick_reflection_probes, pick_unselectable, true, callback);
LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, false, pick_reflection_probes, true, pick_unselectable, callback);
schedulePick(pick_info);
}
@ -5394,7 +5394,6 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info)
mWindow->delayInputProcessing();
}
void LLViewerWindow::performPick()
{
if (!mPicks.empty())
@ -5428,8 +5427,9 @@ void LLViewerWindow::returnEmptyPicks()
// Performs the GL object/land pick.
LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, bool pick_transparent, bool pick_rigged, bool pick_particle, bool pick_unselectable, bool pick_reflection_probe)
{
static LLCachedControl<bool> select_invisible_objects(gSavedSettings, "SelectInvisibleObjects");
bool in_build_mode = LLFloaterReg::instanceVisible("build");
if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha)
if ((in_build_mode && select_invisible_objects) || LLDrawPoolAlpha::sShowDebugAlpha)
{
// build mode allows interaction with all transparent objects
// "Show Debug Alpha" means no object actually transparent
@ -5437,7 +5437,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, bool pick_transp
}
// shortcut queueing in mPicks and just update mLastPick in place
MASK key_mask = gKeyboard->currentMask(true);
MASK key_mask = gKeyboard->currentMask(true);
mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, true, false, NULL);
mLastPick.fetchResults();
@ -7385,14 +7385,14 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
bool pick_rigged,
bool pick_particle,
bool pick_reflection_probe,
bool pick_uv_coords,
bool pick_surface_info,
bool pick_unselectable,
void (*pick_callback)(const LLPickInfo& pick_info))
: mMousePt(mouse_pos),
mKeyMask(keyboard_mask),
mPickCallback(pick_callback),
mPickType(PICK_INVALID),
mWantSurfaceInfo(pick_uv_coords),
mWantSurfaceInfo(pick_surface_info),
mObjectFace(-1),
mUVCoords(-1.f, -1.f),
mSTCoords(-1.f, -1.f),

View File

@ -277,7 +277,6 @@
</tab_container>
</panel>
<panel name="save_file_options">
<check_box name="also_save_bvh_checkbox" label="BVH beim Speichern schreiben" tool_tip="Wenn eine Pose gespeichert wird, zusätzlich eine BVH-Datei erstellen, die über das Bauen-Menü hochgeladen werden kann"/>
<slider label="Sensitivität" name="trackpad_sensitivity_slider" tool_tip="Passt die Sensitivität der Steuerkugel an"/>
</panel>
</layout_panel>

View File

@ -1463,15 +1463,6 @@ width="565">
name="save_file_options"
left_pad="2"
width="235">
<check_box
name="also_save_bvh_checkbox"
height="16"
label="Write BVH when saving"
follows="left|top"
left="0"
tool_tip="When you save your pose, also write a BVH file, which can be uploaded via the 'Build' menu to pose yourself or others in-world"
top_pad="5"
width="134" />
<slider
decimal_digits="2"
can_edit_text="true"

View File

@ -3,7 +3,7 @@
height="180"
layout="topleft"
name="floater_region_restart_schedule"
help_topic="Preferences_Graphics_Advanced"
help_topic="region_restart_schedule"
single_instance="true"
save_rect="true"
title="Region Restart Schedule"

View File

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="floater_poser" title="Pozer awatarów i animeszu">
<string name="header_mHead">Ciało</string>
<string name="header_mFaceForeheadLeft">Czoło/Brwi</string>
<string name="header_mEyeLeft">Oczy/Powieki</string>
<string name="header_mFaceCheekUpperLeft">Policzki/Usta</string>
<string name="header_mHandThumb1Left">Lewa ręka</string>
<string name="header_mCollarLeft">Lewe ramię</string>
<string name="header_mHandThumb1Right">Prawa ręka</string>
<string name="header_mCollarRight">Prawe ramię</string>
<string name="header_mHipLeft">Nogi</string>
<string name="header_mTail1">Ogon</string>
<string name="header_mHindLimbsRoot">Kończyny tylne</string>
<string name="header_mWingsRoot">Skrzydła</string>
<string name="title_mPelvis">Cały awatar</string>
<string name="title_mTorso">Tułów</string>
<string name="title_mChest">Klatka piersiowa</string>
<string name="title_mNeck">Szyja</string>
<string name="title_mHead">Głowa</string>
<string name="title_mEyeRight">Prawe oko</string>
<string name="title_mEyeLeft">Lewe oko</string>
<string name="title_mFaceForeheadLeft">Czoło, lewa strona</string>
<string name="title_mFaceForeheadRight">Czoło, prawa strona</string>
<string name="title_mFaceEyebrowOuterLeft">Brwi zewnętrzne lewe</string>
<string name="title_mFaceEyebrowCenterLeft">Brwi środkowe lewe</string>
<string name="title_mFaceEyebrowInnerLeft">Brwi wewnętrzne lewe</string>
<string name="title_mFaceEyebrowOuterRight">Brwi zewnętrzne prawe</string>
<string name="title_mFaceEyebrowCenterRight">Brwi środkowe prawe</string>
<string name="title_mFaceEyebrowInnerRight">Brwi wewnętrzne prawe</string>
<string name="title_mFaceEyeLidUpperLeft">Powieka górna lewa</string>
<string name="title_mFaceEyeLidLowerLeft">Powieka dolna lewa</string>
<string name="title_mFaceEyeLidUpperRight">Powieka górna prawa</string>
<string name="title_mFaceEyeLidLowerRight">Powieka dolna prawa</string>
<string name="title_mFaceEar1Left">Ucho górne lewe</string>
<string name="title_mFaceEar2Left">Ucho dolne lewe</string>
<string name="title_mFaceEar1Right">Ucho górne prawe</string>
<string name="title_mFaceEar2Right">Ucho dolne prawe</string>
<string name="title_mFaceNoseLeft">Nos lewy</string>
<string name="title_mFaceNoseCenter">Nos środkowy</string>
<string name="title_mFaceNoseRight">Nos prawy</string>
<string name="title_mFaceCheekLowerLeft">Policzek dolny lewy</string>
<string name="title_mFaceCheekUpperLeft">Policzek górny lewy</string>
<string name="title_mFaceCheekLowerRight">Policzek dolny prawy</string>
<string name="title_mFaceCheekUpperRight">Policzek górny prawy</string>
<string name="title_mFaceJaw">Szczęka</string>
<string name="title_mFaceTeethLower">Zęby dolne</string>
<string name="title_mFaceLipLowerLeft">Warga dolna lewa</string>
<string name="title_mFaceLipLowerRight">Warga dolna prawa</string>
<string name="title_mFaceLipLowerCenter">Warga dolna środkowa</string>
<string name="title_mFaceTongueBase">Podstawa języka</string>
<string name="title_mFaceTongueTip">Czubek języka</string>
<string name="title_mFaceJawShaper">Kształt szczęki</string>
<string name="title_mFaceForeheadCenter">Środek czoła</string>
<string name="title_mFaceNoseBase">Podstawa nosa</string>
<string name="title_mFaceTeethUpper">Teeth Upper</string>
<string name="title_mFaceLipUpperLeft">Warga górna lewa</string>
<string name="title_mFaceLipUpperRight">Warga górna prawa</string>
<string name="title_mFaceLipCornerLeft">Lewy kącik ust</string>
<string name="title_mFaceLipCornerRight">Prawy kącik ust</string>
<string name="title_mFaceLipUpperCenter">Warga górna środkowa</string>
<string name="title_mFaceEyecornerInnerLeft">Wewn. lewy kącik oka</string>
<string name="title_mFaceEyecornerInnerRight">Wewn. prawy kącik oka</string>
<string name="title_mFaceNoseBridge">Grzbiet nosa</string>
<string name="title_mCollarLeft">Kołnierz</string>
<string name="title_mShoulderLeft">Całe ramię</string>
<string name="title_mElbowLeft">Przedramię</string>
<string name="title_mWristLeft">Nadgarstek</string>
<string name="title_mHandMiddle1Left">Podstawa palca środkowego</string>
<string name="title_mHandMiddle2Left">Środek palca środkowego</string>
<string name="title_mHandMiddle3Left">Czubek palca środkowego</string>
<string name="title_mHandIndex1Left">Podstawa palca wskazującego</string>
<string name="title_mHandIndex2Left">Środek palca wskazującego</string>
<string name="title_mHandIndex3Left">Czubek palca wskazującego</string>
<string name="title_mHandRing1Left">Podstawa palca serdecznego</string>
<string name="title_mHandRing2Left">Środek palca serdecznego</string>
<string name="title_mHandRing3Left">Czubek palca serdecznego</string>
<string name="title_mHandPinky1Left">Podstawa palca małego</string>
<string name="title_mHandPinky2Left">Środek palca małego</string>
<string name="title_mHandPinky3Left">Czubek palca małego</string>
<string name="title_mHandThumb1Left">Podstawa kciuka</string>
<string name="title_mHandThumb2Left">Środek kciuka</string>
<string name="title_mHandThumb3Left">Czubek kciuka</string>
<string name="title_mCollarRight">Kołnierz</string>
<string name="title_mShoulderRight">Całe ramię</string>
<string name="title_mElbowRight">Przedramię</string>
<string name="title_mWristRight">Nadgarstek</string>
<string name="title_mHandMiddle1Right">Podstawa palca środkowego</string>
<string name="title_mHandMiddle2Right">Środek palca środkowego</string>
<string name="title_mHandMiddle3Right">Czubek palca środkowego</string>
<string name="title_mHandIndex1Right">Podstawa palca wskazującego</string>
<string name="title_mHandIndex2Right">Środek palca wskazującego</string>
<string name="title_mHandIndex3Right">Czubek palca wskazującego</string>
<string name="title_mHandRing1Right">Podstawa palca serdecznego</string>
<string name="title_mHandRing2Right">Środek palca serdecznego</string>
<string name="title_mHandRing3Right">Czubek palca serdecznego</string>
<string name="title_mHandPinky1Right">Podstawa palca małego</string>
<string name="title_mHandPinky2Right">Środek palca małego</string>
<string name="title_mHandPinky3Right">Czubek palca małego</string>
<string name="title_mHandThumb1Right">Podstawa kciuka</string>
<string name="title_mHandThumb2Right">Środek kciuka</string>
<string name="title_mHandThumb3Right">Czubek kciuka</string>
<string name="title_mWingsRoot">Skrzydła</string>
<string name="title_mWing1Left">Lewo 1</string>
<string name="title_mWing2Left">Lewo 2</string>
<string name="title_mWing3Left">Lewo 3</string>
<string name="title_mWing4Left">Lewo 4</string>
<string name="title_mWing4FanLeft">Lewy wachlarz</string>
<string name="title_mWing1Right">Prawo 1</string>
<string name="title_mWing2Right">Prawo 2</string>
<string name="title_mWing3Right">Prawo 3</string>
<string name="title_mWing4Right">Prawo 4</string>
<string name="title_mWing4FanRight">Prawy wachlarz</string>
<string name="title_mHipRight">Prawe biodro</string>
<string name="title_mKneeRight">Prawe kolano</string>
<string name="title_mAnkleRight">Prawa kostka</string>
<string name="title_mFootRight">Prawa stopa</string>
<string name="title_mToeRight">Prawy paluch</string>
<string name="title_mHipLeft">Lewe biodro</string>
<string name="title_mKneeLeft">Lewe kolano</string>
<string name="title_mAnkleLeft">Lewa kostka</string>
<string name="title_mFootLeft">Lewa stopa</string>
<string name="title_mToeLeft">Lewy paluch</string>
<string name="title_mTail1">Podstawa ogona</string>
<string name="title_mTail2">Ogon 2</string>
<string name="title_mTail3">Ogon 3</string>
<string name="title_mTail4">Ogon 4</string>
<string name="title_mTail5">Ogon 5</string>
<string name="title_mTail6">Czubek ogona</string>
<string name="title_mGroin">Krocze</string>
<string name="title_mHindLimbsRoot">Kończyny tylne</string>
<string name="title_mHindLimb1Left">Lewa podstawa</string>
<string name="title_mHindLimb2Left">Lewo 2</string>
<string name="title_mHindLimb3Left">Lewo 3</string>
<string name="title_mHindLimb4Left">Lewo 4</string>
<string name="title_mHindLimb1Right">Prawa podstawa</string>
<string name="title_mHindLimb2Right">Prawo 2</string>
<string name="title_mHindLimb3Right">Prawo 3</string>
<string name="title_mHindLimb4Right">Prawo 4</string>
<string name="title_BUTT">Pośladki</string>
<string name="title_BELLY">Brzuch</string>
<string name="title_LEFT_PEC">Lewa pierś</string>
<string name="title_RIGHT_PEC">Prawa pierś</string>
<layout_stack name="poser_stack">
<layout_panel name="regular_controls_layout">
<panel name="avatarSelection_panel">
<scroll_list tool_tip="Wybierz awatara lub animesz, który chcesz animować." name="avatarSelection_scroll">
<scroll_list.columns label="Wybierz kogoś..." name="name" />
</scroll_list>
</panel>
<panel name="joints_parent_panel">
<tab_container name="joints_tabs">
<panel title="Ruch" name="positionRotation_panel">
<panel name="title">
<text name="av_position_updown_label">
Góra/Dół:
</text>
<slider name="av_position_updown" tool_tip="Przesuń wybranego awatara w górę lub w dół" />
<text name="av_position_leftright_label">
Lewo/Prawo:
</text>
<slider name="av_position_leftright" tool_tip="Przesuń wybranego awatara w lewo lub w prawo" />
<text name="av_position_inout_label">
Przód/Tył:
</text>
<slider name="av_position_inout" tool_tip="Przesuń wybranego awatara w przód lub w tył" />
<scroll_list name="entireAv_joint_scroll">
<scroll_list.columns label="Część ciała" name="joint" />
</scroll_list>
</panel>
</panel>
<panel title="Ciało" name="body_joints_panel">
<scroll_list name="body_joints_scroll">
<scroll_list.columns label="Część ciała" name="joint" />
</scroll_list>
</panel>
<panel title="Twarz" name="face_joints_panel">
<scroll_list name="face_joints_scroll">
<scroll_list.columns label="Część ciała" name="joint" />
</scroll_list>
</panel>
<tab_container title="Dłonie" name="hands_tabs">
<panel title="Ustawienia" name="hands_presets_panel">
<scroll_list name="hand_presets_scroll">
<scroll_list.columns label="Ustawienie" name="name" />
</scroll_list>
<button label="Ustaw: Lewa" name="button_loadHandPoseLeft" tool_tip="Kliknij dwukrotnie, 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" />
</panel>
<panel title="Reguluj" name="hands_joints_panel">
<scroll_list name="hand_joints_scroll">
<scroll_list.columns label="Część ciała" name="joint" />
</scroll_list>
</panel>
</tab_container>
<panel title="Różne" name="misc_joints_panel">
<scroll_list name="misc_joints_scroll">
<scroll_list.columns label="Część ciała" name="joint" />
</scroll_list>
</panel>
<panel title="Fizyka" name="collision_volumes_panel">
<scroll_list name="collision_volumes_scroll">
<scroll_list.columns label="Fizyka" name="joint" />
</scroll_list>
</panel>
</tab_container>
</panel>
<panel name="trackball_panel">
<text name="rotation_label">
Obrót:
</text>
<fs_virtual_trackpad name="limb_rotation" tool_tip="Zmień obrót aktualnie wybranej części ciała. Przytrzymaj Ctrl, aby poruszać powoli. Obróć kółkiem, aby dostosować trzecią oś. Użyj Shift lub Alt, aby zamienić, które obroty się zmieniają" />
<panel name="trackball_button_panel">
<button name="undo_change" tool_tip="Cofnij ostatnią zmianę obrotu" />
<button name="button_redo_change" tool_tip="Ponów ostatnią cofniętą zmianę" />
<button name="refresh_avatars" 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="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." />
<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." />
</panel>
<text name="limb_pitch_label">
Góra/Dół:
</text>
<text name="limb_yaw_label">
Lewo/Prawo:
</text>
<text name="limb_roll_label">
Rolowanie:
</text>
</panel>
<panel name="poses_loadSave">
<scroll_list tool_tip="Załaduj pozę dla animowanej postaci." name="poses_scroll">
<scroll_list.columns label="Poza" name="name" />
</scroll_list>
<line_editor label="Nazwa pozy do zapisu..." name="pose_save_name" />
</panel>
</layout_panel>
<layout_panel name="button_controls_layout">
<panel name="button_controls_panel">
<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 name="toggleAdvancedPanel" tool_tip="Przełącz obszar ustawień zaawansowanych" />
<button name="FlipPose_avatar" tool_tip="Przerzuć całą pozę na lewo/prawo" />
<button name="FlipJoint_avatar" tool_tip="Odbij lustrzanie wybrane części ciała w lewo/prawo" />
<button label="Złap" name="button_RecaptureParts" tool_tip="Jeśli wybrane części ciała są WYŁĄCZONE, to ta opcja ponownie przechwytuje to, co te części ciała robią teraz" />
<button label="Wł/Wył część" name="toggle_PosingSelectedBones" tool_tip="Włącz lub wyłącz Pozer dla wybranych części ciała. Po wyłączeniu ta część ciała animuje się jak zwykle (jak z AO lub z kulką itp.)" />
<button label="Moje pozy" name="toggleLoadSavePanel" tool_tip="Wczytaj, zapisz i zarządzaj pozami, które tworzysz" />
<button tool_tip="Zarządzaj katalogiem poz" name="open_poseDir_button" />
<menu_button label="Wczytaj pozę" tool_tip="Wczytaj aktualnie wybraną pozę." name="load_poses_button" />
<button label="Zapisz pozę" tool_tip="Zapisz bieżącą pozę." name="save_poses_button" />
</panel>
</layout_panel>
<layout_panel name="advanced_controls_layout">
<panel name="advanced_parent_panel">
<tab_container name="modifier_tabs">
<panel title="Pozycja części ciała" name="position_panel">
<slider label="Pozycja X:" name="Advanced_Position_X" />
<slider label="Pozycja Y:" name="Advanced_Position_Y" />
<slider label="Pozycja Z:" name="Advanced_Position_Z" />
<button label="Cofnij zmianę pozycji" name="undo_position_change" tool_tip="Cofnij ostatnią zmianę pozycji" />
<button label="Ponów pozycję" name="redo_position_change" tool_tip="Ponownie wykonaj ostatnią zmianę pozycji" />
<button label="Reset pozycji" name="undo_position_change" tool_tip="Kliknij dwukrotnie, aby przywrócić pierwotną pozycję" />
</panel>
<panel title="Skala części ciała" name="scale_panel">
<slider label="Skala X:" name="Advanced_Scale_X" />
<slider label="Skala Y:" name="Advanced_Scale_Y" />
<slider label="Skala Z:" name="Advanced_Scale_Z" />
<button label="Cofnij zmianę skali" name="undo_position_change" tool_tip="Cofnij ostatnią zmianę skali" />
<button label="Ponów skalę" name="redo_scale_change" tool_tip="Ponownie wykonaj ostatnią zmianę skali" />
<button label="Reset skali" name="undo_scale_change" tool_tip="Kliknij dwukrotnie, aby przywrócić pierwotną skalę" />
</panel>
</tab_container>
</panel>
<panel name="save_file_options">
<slider label="Czułość" name="trackpad_sensitivity_slider" tool_tip="Dostosowuje czułość trackballa / kółka" />
</panel>
</layout_panel>
</layout_stack>
</floater>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<toggleable_menu name="Settings">
<menu_item_call label="Załaduj tylko obroty" name="rotations" />
<menu_item_call label="Załaduj tylko pozycje" name="positions" />
<menu_item_call label="Załaduj tylko rozmiary" name="scale" />
<menu_item_call label="Załaduj obroty i pozycje" name="rotations_positions" />
<menu_item_call label="Załaduj obroty i rozmiary" name="rotations_scales" />
<menu_item_call label="Załaduj pozycję i rozmiary" name="positions_scales" />
<menu_item_call label="Załaduj wszystko" name="load_all" />
</toggleable_menu>

View File

@ -99,6 +99,7 @@
<menu label="Świat" name="World">
<menu_item_call label="Synchronizuj animacje" name="Resync Animations"/>
<menu_item_call label="Osoby w pobliżu" name="Active Speakers"/>
<menu_item_check label="Pozer" name="Poser" />
<menu_item_check label="Radar" name="Radar"/>
<menu_item_call label="Historia teleportacji" name="Teleport History"/>
<menu_item_check label="Landmarki" name="Places"/>

View File

@ -5486,6 +5486,12 @@ Spróbuj załączyć ścieżkę do edytora w cytowaniu.
<string name="Command_Beacons_Label">
Emitery
</string>
<string name="Command_Poser_Label">
Pozer
</string>
<string name="Command_Poser_Tooltip">
Ustaw swojego awatara oraz animowane obiekty
</string>
<string name="Command_360_Capture_Tooltip">
Uchwyć równoprostokątny obraz 360°
</string>

View File

@ -0,0 +1,269 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="floater_poser" title="Позер для аватаров и анимешей">
<string name="header_mHead">Тело</string>
<string name="header_mFaceForeheadLeft">Лоб/Брови</string>
<string name="header_mEyeLeft">Глаза/Веки</string>
<string name="header_mFaceCheekUpperLeft">Щеки/Губы</string>
<string name="header_mHandThumb1Left">Левая Кисть</string>
<string name="header_mCollarLeft">Левая Рука</string>
<string name="header_mHandThumb1Right">Правая Кисть</string>
<string name="header_mCollarRight">Правая Рука</string>
<string name="header_mHipLeft">Ноги</string>
<string name="header_mTail1">Хвост</string>
<string name="header_mHindLimbsRoot">Задние конечности</string>
<string name="header_mWingsRoot">Крылья</string>
<string name="title_mPelvis">Весь аватар</string>
<string name="title_mTorso">Торс</string>
<string name="title_mChest">Грудь</string>
<string name="title_mNeck">Шея</string>
<string name="title_mHead">Голова</string>
<string name="title_mEyeRight">Глаз правый</string>
<string name="title_mEyeLeft">Глаз левый</string>
<string name="title_mFaceForeheadLeft">Лоб левая сторона</string>
<string name="title_mFaceForeheadRight">Лоб правая сторона</string>
<string name="title_mFaceEyebrowOuterLeft">Бровь левая внешняя </string>
<string name="title_mFaceEyebrowCenterLeft">Бровь левая середина</string>
<string name="title_mFaceEyebrowInnerLeft">Бровь левая внутренняя сторона </string>
<string name="title_mFaceEyebrowOuterRight">Бровь правая внешняя</string>
<string name="title_mFaceEyebrowCenterRight">Бровь правая середина</string>
<string name="title_mFaceEyebrowInnerRight">Бровь правая внутренняя</string>
<string name="title_mFaceEyeLidUpperLeft">Веко левое верхнее</string>
<string name="title_mFaceEyeLidLowerLeft">Веко левое нижнее</string>
<string name="title_mFaceEyeLidUpperRight">Веко правое верхнее</string>
<string name="title_mFaceEyeLidLowerRight">Веко правое нижнее</string>
<string name="title_mFaceEar1Left">Ухо левое верхнее</string>
<string name="title_mFaceEar2Left">Ухо левое нижнее</string>
<string name="title_mFaceEar1Right">Ухо правое верхнее</string>
<string name="title_mFaceEar2Right">Ухо правое нижнее</string>
<string name="title_mFaceNoseLeft">Нос слева</string>
<string name="title_mFaceNoseCenter">Нос центр</string>
<string name="title_mFaceNoseRight">Нос справа</string>
<string name="title_mFaceCheekLowerLeft">Щека левая нижняя</string>
<string name="title_mFaceCheekUpperLeft">Щека левая верхняя</string>
<string name="title_mFaceCheekLowerRight">Щека правая нижняя </string>
<string name="title_mFaceCheekUpperRight">Щека правая верхняя</string>
<string name="title_mFaceJaw">Челюсть</string>
<string name="title_mFaceTeethLower">Зубы нижние</string>
<string name="title_mFaceLipLowerLeft">Губа нижняя слева</string>
<string name="title_mFaceLipLowerRight">Губа нижняя справа</string>
<string name="title_mFaceLipLowerCenter">Губа нижняя середина</string>
<string name="title_mFaceTongueBase">Язык основание</string>
<string name="title_mFaceTongueTip">Язык кончик</string>
<string name="title_mFaceJawShaper">Челюсть форма</string>
<string name="title_mFaceForeheadCenter">Лоб середина</string>
<string name="title_mFaceNoseBase">Нос основание</string>
<string name="title_mFaceTeethUpper">Зубы верхние</string>
<string name="title_mFaceLipUpperLeft">Губа верхняя левая</string>
<string name="title_mFaceLipUpperRight">Губа верхняя правая</string>
<string name="title_mFaceLipCornerLeft">Губа уголок левая</string>
<string name="title_mFaceLipCornerRight">Губа уголок правая</string>
<string name="title_mFaceLipUpperCenter">Губа верхняя центр</string>
<string name="title_mFaceEyecornerInnerLeft">Глаз левый внутренний уголок</string>
<string name="title_mFaceEyecornerInnerRight">Глаз правый внутренний уголок</string>
<string name="title_mFaceNoseBridge">Переносица</string>
<string name="title_mCollarLeft">Ворот</string>
<string name="title_mShoulderLeft">Вся рука</string>
<string name="title_mElbowLeft">Предплечье</string>
<string name="title_mWristLeft">Запястье</string>
<string name="title_mHandMiddle1Left">Средний палец основа</string>
<string name="title_mHandMiddle2Left">Средний палец средина</string>
<string name="title_mHandMiddle3Left">Средний палец кончик</string>
<string name="title_mHandIndex1Left">Указат. палец основа</string>
<string name="title_mHandIndex2Left">Указат. палец средина</string>
<string name="title_mHandIndex3Left">Указат. палец кончик</string>
<string name="title_mHandRing1Left">Безым. палец основа</string>
<string name="title_mHandRing2Left">Безым. палец средина</string>
<string name="title_mHandRing3Left">Безым. палец кончик</string>
<string name="title_mHandPinky1Left">Мизинец основа</string>
<string name="title_mHandPinky2Left">Мизинец средина</string>
<string name="title_mHandPinky3Left">Мизинец кончик</string>
<string name="title_mHandThumb1Left">Большой палец основа</string>
<string name="title_mHandThumb2Left">Большой палец средина</string>
<string name="title_mHandThumb3Left">Большой палец кончик</string>
<string name="title_mCollarRight">Ворот</string>
<string name="title_mShoulderRight">Вся рука</string>
<string name="title_mElbowRight">Предплечье</string>
<string name="title_mWristRight">Запястье</string>
<string name="title_mHandMiddle1Right">Средний палец основа</string>
<string name="title_mHandMiddle2Right">Средний палец средина</string>
<string name="title_mHandMiddle3Right">Средний палец кончик</string>
<string name="title_mHandIndex1Right">Указат. палец основа</string>
<string name="title_mHandIndex2Right">Указат. палец средина</string>
<string name="title_mHandIndex3Right">Указат. палец кончик</string>
<string name="title_mHandRing1Right">Безым. палец основа</string>
<string name="title_mHandRing2Right">Безым. палец средина</string>
<string name="title_mHandRing3Right">Безым. палец кончик</string>
<string name="title_mHandPinky1Right">Мизинец основа</string>
<string name="title_mHandPinky2Right">Мизинец средина</string>
<string name="title_mHandPinky3Right">Мизинец кончик</string>
<string name="title_mHandThumb1Right">Большой палец основа</string>
<string name="title_mHandThumb2Right">Большой палец средина</string>
<string name="title_mHandThumb3Right">Большой палец кончик</string>
<string name="title_mWingsRoot">Корень</string>
<string name="title_mWing1Left">Левое 1</string>
<string name="title_mWing2Left">Левое 2</string>
<string name="title_mWing3Left">Левое 3</string>
<string name="title_mWing4Left">Левое 4</string>
<string name="title_mWing4FanLeft">Левое Перо</string>
<string name="title_mWing1Right">Правое 1</string>
<string name="title_mWing2Right">Правое 2</string>
<string name="title_mWing3Right">Правое 3</string>
<string name="title_mWing4Right">Правое 4</string>
<string name="title_mWing4FanRight">Правое Перо</string>
<string name="title_mHipRight">Правое Бедро</string>
<string name="title_mKneeRight">Правое Колено</string>
<string name="title_mAnkleRight">Правая Лодыжка</string>
<string name="title_mFootRight">Правая Ступня</string>
<string name="title_mToeRight">Правый Носок</string>
<string name="title_mHipLeft">Левое Бедро</string>
<string name="title_mKneeLeft">Левое Колено</string>
<string name="title_mAnkleLeft">Левая Лодыжка</string>
<string name="title_mFootLeft">Левая Ступня</string>
<string name="title_mToeLeft">Левая Носок</string>
<string name="title_mTail1">Хвост основа</string>
<string name="title_mTail2">Хвост 2</string>
<string name="title_mTail3">Хвост 3</string>
<string name="title_mTail4">Хвост 4</string>
<string name="title_mTail5">Хвост 5</string>
<string name="title_mTail6">Хвост Кончик</string>
<string name="title_mGroin">Пах</string>
<string name="title_mHindLimbsRoot">Корень</string>
<string name="title_mHindLimb1Left">Левая основа</string>
<string name="title_mHindLimb2Left">Левая 2</string>
<string name="title_mHindLimb3Left">Левая 3</string>
<string name="title_mHindLimb4Left">Левая 4</string>
<string name="title_mHindLimb1Right">Правая основа</string>
<string name="title_mHindLimb2Right">Правая 2</string>
<string name="title_mHindLimb3Right">Правая 3</string>
<string name="title_mHindLimb4Right">Правая 4</string>
<string name="title_BUTT">Ягодицы</string>
<string name="title_BELLY">Живот</string>
<string name="title_LEFT_PEC">Левая грудь</string>
<string name="title_RIGHT_PEC">Правая грудь</string>
<layout_stack name="poser_stack">
<layout_panel name="regular_controls_layout">
<panel name="avatarSelection_panel">
<avatar_list name="avatars_online"/>
<scroll_list name="avatarSelection_scroll" tool_tip="Выберите аватар или анимеш, который вы хотите анимировать.">
<scroll_list.columns label="Выберите кого-нибудь..." name="name"/>
<scroll_list.columns label="Сохранить имя файла" name="saveFileName"/>
</scroll_list>
</panel>
<panel name="joints_parent_panel">
<tab_container name="joints_tabs">
<panel title="Сдвиг" name="positionRotation_panel">
<panel name="title">
<text name="av_position_updown_label">Вверх/Вниз:</text>
<slider name="av_position_updown" tool_tip="Двигать выбранный аватар вверх или вниз"/>
<text name="av_position_leftright_label">Влево/Вправо:</text>
<slider name="av_position_leftright" tool_tip="Двигать выбранный аватар влево или вправо"/>
<text name="av_position_inout_label">Внутрь/Наружу:</text>
<slider name="av_position_inout" tool_tip="Двигать выбранный аватар внутрь или наружу"/>
<scroll_list name="entireAv_joint_scroll">
<scroll_list.columns label="Часть тела" name="joint"/>
</scroll_list>
</panel>
</panel>
<panel title="Тело" name="body_joints_panel">
<scroll_list name="body_joints_scroll">
<scroll_list.columns label="Часть тела" name="joint"/>
</scroll_list>
</panel>
<panel title="Лицо" name="face_joints_panel">
<scroll_list name="face_joints_scroll">
<scroll_list.columns label="Часть тела" name="joint"/>
</scroll_list>
</panel>
<tab_container title="Руки" name="hands_tabs">
<panel title="Пресеты" name="hands_presets_panel">
<scroll_list name="hand_presets_scroll">
<scroll_list.columns label="Имя пресета" name="name"/>
</scroll_list>
<button label="Уст. Левая" name="button_loadHandPoseLeft" tool_tip="Двойной клик чтобы настроить левую руку на выбранный пресет"/>
<button label="Уст. Правая" name="button_loadHandPoseRight" tool_tip="Двойной клик чтобы настроить правую руку на выбранный пресет"/>
</panel>
<panel title="Настроить" name="hands_joints_panel">
<scroll_list name="hand_joints_scroll">
<scroll_list.columns label="Часть тела" name="joint"/>
</scroll_list>
</panel>
</tab_container>
<panel title="Разное" name="misc_joints_panel">
<scroll_list name="misc_joints_scroll">
<scroll_list.columns label="Часть тела" name="joint"/>
</scroll_list>
</panel>
<panel title="Физика" name="collision_volumes_panel">
<scroll_list name="collision_volumes_scroll">
<scroll_list.columns label="Физика" name="joint"/>
</scroll_list>
</panel>
</tab_container>
</panel>
<panel name="trackball_panel">
<text name="rotation_label">Вращение:</text>
<fs_virtual_trackpad name="limb_rotation" tool_tip="Измените поворот выбранной в данный момент части(ей) тела. Удерживайте нажатой клавишу Ctrl для замедления перемещения. Поверните колесо, чтобы отрегулировать 3-ю ось. Используйте Shift или Alt, чтобы изменить направление вращения."/>
<panel name="trackball_button_panel">
<button name="undo_change" tool_tip="Отмените последнее изменение поворота"/>
<button name="button_redo_change" tool_tip="Повторить последнее отмененное изменение"/>
<button name="refresh_avatars" tool_tip="Двойной клик чтобы восстановить все выбранные части тела на тот момент, когда вы впервые начали изменения"/>
<button name="delta_mode_toggle" tool_tip="При изменении нескольких суставов каждый из них изменяется на одинаковую величину, а не все они получают одинаковое вращение."/>
<button label="Зерк." name="button_toggleMirrorRotation" tool_tip="Изменять положение противоположного сустава как в зеркале."/>
<button label="Симм." name="button_toggleSympatheticRotation" tool_tip="Изменять положение противоположного сустав таким же образом."/>
</panel>
<text name="limb_pitch_label">Вверх/Вниз:</text>
<text name="limb_yaw_label">Влево/Вправо:</text>
<text name="limb_roll_label">Крен:</text>
</panel>
<panel name="poses_loadSave">
<scroll_list name="poses_scroll" tool_tip="Загрузите позу для того, кого вы анимируете.">
<scroll_list.columns label="Имя Позы" name="name"/>
</scroll_list>
<line_editor label="Введите название для сохранения..." name="pose_save_name"/>
</panel>
</layout_panel>
<layout_panel name="button_controls_layout">
<panel name="button_controls_panel">
<button name="refresh_avatars" tool_tip="Обновить список аватаров и анимешей, которые она использует."/>
<button label="Начать" label_selected="Остановить" tool_tip="Начните позировать с выбранным аватаром или анимешем, если вам это разрешено" name="start_stop_posing_button"/>
<button name="toggleAdvancedPanel" tool_tip="Переключить область дополнительных настроек"/>
<button name="FlipPose_avatar" tool_tip="Перевернуть всю позу влево/вправо"/>
<button name="FlipJoint_avatar" tool_tip="Зеркально отобразить выбранные части тела влево/вправо"/>
<button label="Recap" name="button_RecaptureParts" tool_tip="Если выбранная часть тела включена/выключены, это возвращает то, что эти части тела делают прямо сейчас"/>
<button label="Части Вкл/Выкл" name="toggle_PosingSelectedBones" tool_tip="Включите или выключите Позер для выбранной части тела. Если выключено, эта часть тела анимируется как обычно (с вашим AO или pose-ball/и т.д.)"/>
<button label="Свои позы" name="toggleLoadSavePanel" tool_tip="Загружайте, сохраняйте и управляйте позами, которые вы создаете"/>
<button tool_tip="Управляйте своим каталогом поз" name="open_poseDir_button"/>
<menu_button label="Загрузить" tool_tip="Загрузить текущую выбранную позу." name="load_poses_button"/>
<button label="Сохранить" tool_tip="Сохранить текущую позу." name="save_poses_button"/>
</panel>
</layout_panel>
<layout_panel name="advanced_controls_layout">
<panel name="advanced_parent_panel">
<tab_container name="modifier_tabs">
<panel title="Часть тела Позиция" name="position_panel">
<slider label="Позиция X:" name="Advanced_Position_X"/>
<slider label="Позиция Y:" name="Advanced_Position_Y"/>
<slider label="Позиция Z:" name="Advanced_Position_Z"/>
<button label="Отмена" name="undo_position_change" tool_tip="Отменить последнее изменение позиции"/>
<button label="Повторить" name="redo_position_change" tool_tip="Повторить последнее изменение позиции"/>
<button label="Сброс" name="undo_position_change" tool_tip="Дважды щелкните, чтобы вернуть исходное положение."/>
</panel>
<panel title="Часть тела Размер" name="scale_panel">
<slider label="Размер X:" name="Advanced_Scale_X"/>
<slider label="Размер Y:" name="Advanced_Scale_Y"/>
<slider label="Размер Z:" name="Advanced_Scale_Z"/>
<button label="Отмена" name="undo_position_change" tool_tip="Отменить последнее изменение размера"/>
<button label="Повторить" name="redo_scale_change" tool_tip="Повторить последнее изменение размера"/>
<button label="Сброс" name="undo_scale_change" tool_tip="Дважды щелкните, чтобы сбросить размер до исходного."/>
</panel>
</tab_container>
</panel>
<panel name="save_file_options">
<slider label="Чувствительность" name="trackpad_sensitivity_slider" tool_tip="Регулирует чувствительность трекбола"/>
</panel>
</layout_panel>
</layout_stack>
</floater>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<toggleable_menu name="Settings">
<menu_item_call label="Загрузка только Вращений" name="rotations"/>
<menu_item_call label="Загрузка только Позиций" name="positions"/>
<menu_item_call label="Загрузка только Размеров" name="scale"/>
<menu_item_call label="Загрузка Вращений и Позиций" name="rotations_positions"/>
<menu_item_call label="Загрузка Вращений и Размеров" name="rotations_scales"/>
<menu_item_call label="Загрузка Позиций и Размеров" name="positions_scales"/>
<menu_item_call label="Загрузка Всего" name="load_all"/>
</toggleable_menu>

View File

@ -114,6 +114,7 @@
<menu_item_call label="Синхронизация анимации" name="Resync Animations"/>
<menu_item_call label="Ближайшие аватары" name="Active Speakers"/>
<menu_item_check label="Радар" name="Radar"/>
<menu_item_check label="Позер" name="Poser"/>
<menu_item_call label="История телепортаций" name="Teleport History"/>
<menu_item_check label="Места" name="Places"/>
<menu_item_call label="Пункты" name="Destinations"/>

View File

@ -5741,6 +5741,12 @@ https://www.firestormviewer.org/support за помощь в решении эт
<string name="Command_Beacons_Label">
Маяки
</string>
<string name="Command_Poser_Label">
Позер
</string>
<string name="Command_Poser_Tooltip">
Позы вашего аватара или анимированного объекта
</string>
<string name="Command_360_Capture_Tooltip">
Создание равнопрямоугольного изображения в формате 360°
</string>