summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2014-12-22 10:06:45 -0500
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2014-12-22 10:06:45 -0500
commitd33bb1fe675a926a434539c3e59c13c35d425fe3 (patch)
tree64c2fe2e02d2dfd008bf2040616a614fc09f4835
parentf179fcd0006bdfd0ea99041d0d663049466ffd2a (diff)
parent4ec9bce3c2a715f53938e4568c95b7a2bdfc9e16 (diff)
merge
-rwxr-xr-x.hgtags2
-rwxr-xr-xautobuild.xml4
-rwxr-xr-xdoc/contributions.txt9
-rwxr-xr-xindra/llappearance/llavatarappearance.cpp38
-rwxr-xr-xindra/llappearance/llavatarappearance.h8
-rw-r--r--indra/llappearance/llpolyskeletaldistortion.cpp2
-rwxr-xr-xindra/llcharacter/lljoint.cpp190
-rwxr-xr-xindra/llcharacter/lljoint.h40
-rwxr-xr-xindra/llimage/llimagefilter.cpp2
-rwxr-xr-xindra/llmath/llquaternion.h18
-rwxr-xr-xindra/llprimitive/llmodel.cpp20
-rwxr-xr-xindra/llrender/llglslshader.cpp2066
-rwxr-xr-xindra/llrender/llrender.cpp2
-rwxr-xr-xindra/llrender/llvertexbuffer.cpp6
-rw-r--r--indra/llui/llfolderviewitem.cpp19
-rwxr-xr-xindra/llui/llfolderviewmodel.h26
-rwxr-xr-xindra/llui/llkeywords.cpp8
-rwxr-xr-xindra/llui/llmenugl.cpp15
-rwxr-xr-xindra/llui/llstatbar.cpp2
-rwxr-xr-xindra/llui/llurlentry.cpp6
-rwxr-xr-xindra/llui/llurlentry.h2
-rwxr-xr-xindra/llui/llurlregistry.cpp20
-rwxr-xr-xindra/llui/llurlregistry.h2
-rwxr-xr-xindra/llui/llview.cpp2
-rw-r--r--indra/llwindow/llopenglview-objc.mm25
-rwxr-xr-xindra/llwindow/llwindowmacosx-objc.h2
-rwxr-xr-xindra/llwindow/llwindowmacosx.cpp16
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rwxr-xr-xindra/newview/app_settings/settings.xml24
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/alphaV.glsl5
-rwxr-xr-xindra/newview/llagent.cpp17
-rwxr-xr-xindra/newview/llagentwearables.cpp31
-rwxr-xr-xindra/newview/llagentwearables.h5
-rwxr-xr-xindra/newview/llaisapi.cpp1
-rwxr-xr-x[-rw-r--r--]indra/newview/llappdelegate-objc.mm12
-rwxr-xr-xindra/newview/llappearancemgr.cpp88
-rwxr-xr-xindra/newview/llappviewer.cpp5
-rwxr-xr-xindra/newview/lldrawpool.cpp2
-rwxr-xr-xindra/newview/lldrawpool.h2
-rwxr-xr-xindra/newview/lldrawpoolavatar.cpp2
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp2
-rwxr-xr-xindra/newview/llfeaturemanager.cpp221
-rwxr-xr-xindra/newview/llfeaturemanager.h3
-rw-r--r--indra/newview/llflickrconnect.cpp2
-rw-r--r--indra/newview/llfloatergroupbulkban.cpp2
-rwxr-xr-xindra/newview/llfloaterimsessiontab.cpp2
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp10
-rwxr-xr-xindra/newview/llfloateropenobject.cpp23
-rwxr-xr-xindra/newview/llfloateropenobject.h7
-rwxr-xr-xindra/newview/llfloaterpay.cpp75
-rwxr-xr-xindra/newview/llfloaterwebcontent.cpp7
-rwxr-xr-xindra/newview/llfolderviewmodelinventory.cpp12
-rwxr-xr-xindra/newview/llglsandbox.cpp52
-rwxr-xr-xindra/newview/llinventorybridge.cpp84
-rwxr-xr-xindra/newview/llinventorybridge.h1
-rwxr-xr-xindra/newview/llinventoryfilter.cpp14
-rwxr-xr-xindra/newview/llinventorypanel.cpp29
-rwxr-xr-xindra/newview/lllogchat.cpp2
-rwxr-xr-xindra/newview/llpanelface.cpp2
-rw-r--r--indra/newview/llpanelgroupbulk.cpp2
-rwxr-xr-xindra/newview/llpanelgroupinvite.cpp2
-rwxr-xr-xindra/newview/llpanelmaininventory.cpp8
-rwxr-xr-xindra/newview/llpanelobjectinventory.cpp4
-rwxr-xr-xindra/newview/llpreviewscript.cpp26
-rwxr-xr-xindra/newview/llpreviewscript.h1
-rwxr-xr-xindra/newview/llspatialpartition.cpp2
-rwxr-xr-xindra/newview/llspeakers.cpp10
-rwxr-xr-xindra/newview/lltexturectrl.cpp15
-rwxr-xr-xindra/newview/lltooldraganddrop.cpp31
-rw-r--r--indra/newview/lltwitterconnect.cpp2
-rwxr-xr-xindra/newview/llviewerinventory.cpp16
-rwxr-xr-xindra/newview/llviewerinventory.h6
-rwxr-xr-xindra/newview/llviewerkeyboard.cpp37
-rwxr-xr-xindra/newview/llviewerobject.cpp36
-rwxr-xr-xindra/newview/llviewerobject.h4
-rwxr-xr-xindra/newview/llvoavatar.cpp285
-rwxr-xr-xindra/newview/llvoavatar.h14
-rwxr-xr-xindra/newview/llvoavatarself.cpp40
-rwxr-xr-xindra/newview/llvoavatarself.h5
-rwxr-xr-xindra/newview/llvoicechannel.cpp2
-rwxr-xr-xindra/newview/llvoiceclient.cpp7
-rwxr-xr-xindra/newview/llvoiceclient.h3
-rwxr-xr-xindra/newview/llvoicevivox.cpp95
-rwxr-xr-xindra/newview/llvoicevivox.h3
-rwxr-xr-xindra/newview/llvovolume.cpp74
-rwxr-xr-xindra/newview/llwearableitemslist.cpp10
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_joystick.xml2
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_openobject.xml71
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_pay.xml187
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_pay_object.xml194
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_inventory.xml2
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_viewer.xml12
-rwxr-xr-xindra/newview/skins/default/xui/en/notifications.xml13
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml8
94 files changed, 2643 insertions, 1884 deletions
diff --git a/.hgtags b/.hgtags
index 5fb06c3609..a9ab8061d3 100755
--- a/.hgtags
+++ b/.hgtags
@@ -494,3 +494,5 @@ bcc2770e21c125e0bab59141c51db9145aec068d 3.7.17-release
82973b38a6c9a457333e3519e4f2b16bb5eedf47 3.7.19-release
27094824773b907c2e559396e6f9ec3a963de52d 3.7.20-release
9ecab4b0c7d8614767724a3422d3c1dca6bd4e4f 3.7.21-release
+bc61801f614022c920cb5c3df1d7d67a9561ce1f 3.7.22-release
+3be800e1afad9615442159e388d6d137be7b951e 3.7.23-release
diff --git a/autobuild.xml b/autobuild.xml
index 2d7916e217..ccf08f8c94 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1314,9 +1314,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>54e46715e72b7805d9d3f84d45b6b1b7</string>
+ <string>0e15751836ac0492250001b80aea379f</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-source/rev/290120/arch/Linux/installer/llappearanceutility_source-0.1-linux-20140519.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-source/rev/293888/arch/Linux/installer/llappearanceutility_source-0.1-linux-20140908.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index ab5eddd92d..18acb18911 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1058,10 +1058,11 @@ Peekay Semyorka
VWR-49
VWR-79
Pell Smit
- STORM-2069
- STORM-2070
- STORM-2071
- STORM-2072
+ MAINT-4323
+ STORM-2069
+ STORM-2070
+ STORM-2071
+ STORM-2072
Peter Lameth
VWR-7331
PeterPunk Mooney
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 6fdf9e2e07..d1eb389013 100755
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -584,8 +584,6 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent
info->mRot.mV[VZ], LLQuaternion::XYZ));
joint->setScale(info->mScale);
- joint->setDefaultFromCurrentXform();
-
if (info->mIsJoint)
{
joint->setSkinOffset( info->mPivot );
@@ -677,6 +675,42 @@ void LLAvatarAppearance::clearSkeleton()
mSkeleton.clear();
}
+//------------------------------------------------------------------------
+// addPelvisFixup
+//------------------------------------------------------------------------
+void LLAvatarAppearance::addPelvisFixup( F32 fixup, const LLUUID& mesh_id )
+{
+ LLVector3 pos(0.0,0.0,fixup);
+ mPelvisFixups.add(mesh_id,pos);
+}
+
+//------------------------------------------------------------------------
+// addPelvisFixup
+//------------------------------------------------------------------------
+void LLAvatarAppearance::removePelvisFixup( const LLUUID& mesh_id )
+{
+ mPelvisFixups.remove(mesh_id);
+}
+
+//------------------------------------------------------------------------
+// hasPelvisFixup
+//------------------------------------------------------------------------
+bool LLAvatarAppearance::hasPelvisFixup( F32& fixup, LLUUID& mesh_id ) const
+{
+ LLVector3 pos;
+ if (mPelvisFixups.findActiveOverride(mesh_id,pos))
+ {
+ fixup = pos[2];
+ return true;
+ }
+ return false;
+}
+
+bool LLAvatarAppearance::hasPelvisFixup( F32& fixup ) const
+{
+ LLUUID mesh_id;
+ return hasPelvisFixup( fixup, mesh_id );
+}
//-----------------------------------------------------------------------------
// LLAvatarAppearance::buildCharacter()
// Deferred initialization and rebuild of the avatar.
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
index 1e898026c0..a0ef49b7cb 100755
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -152,11 +152,17 @@ protected:
BOOL mIsBuilt; // state of deferred character building
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
avatar_joint_list_t mSkeleton;
-
+ LLPosOverrideMap mPelvisFixups;
+
//--------------------------------------------------------------------
// Pelvis height adjustment members.
//--------------------------------------------------------------------
public:
+ void addPelvisFixup( F32 fixup, const LLUUID& mesh_id );
+ void removePelvisFixup( const LLUUID& mesh_id );
+ bool hasPelvisFixup( F32& fixup, LLUUID& mesh_id ) const;
+ bool hasPelvisFixup( F32& fixup ) const;
+
LLVector3 mBodySize;
LLVector3 mAvatarOffset;
protected:
diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp
index ea29cbd451..fbc312c426 100644
--- a/indra/llappearance/llpolyskeletaldistortion.cpp
+++ b/indra/llappearance/llpolyskeletaldistortion.cpp
@@ -213,7 +213,7 @@ void LLPolySkeletalDistortion::apply( ESex avatar_sex )
LLVector3 scaleDelta = iter->second;
newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
//An aspect of attached mesh objects (which contain joint offsets) that need to be cleaned up when detached
- joint->storeScaleForReset( newScale );
+ // needed? // joint->storeScaleForReset( newScale );
joint->setScale(newScale);
}
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index dbd6d48a95..6f22a7c6b7 100755
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -36,6 +36,64 @@
S32 LLJoint::sNumUpdates = 0;
S32 LLJoint::sNumTouches = 0;
+template <class T>
+bool attachment_map_iter_compare_key(const T& a, const T& b)
+{
+ return a.first < b.first;
+}
+
+bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const
+{
+ pos = LLVector3(0,0,0);
+ mesh_id = LLUUID();
+ bool found = false;
+
+ map_type::const_iterator it = std::max_element(m_map.begin(),
+ m_map.end(),
+ attachment_map_iter_compare_key<map_type::value_type>);
+ if (it != m_map.end())
+ {
+ found = true;
+ pos = it->second;
+ mesh_id = it->first;
+ }
+ return found;
+}
+
+void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const
+{
+ map_type::const_iterator max_it = std::max_element(m_map.begin(),
+ m_map.end(),
+ attachment_map_iter_compare_key<map_type::value_type>);
+ for (map_type::const_iterator it = m_map.begin();
+ it != m_map.end(); ++it)
+ {
+ const LLVector3& pos = it->second;
+ os << " " << "[" << it->first <<": " << pos << "]" << ((it==max_it) ? "*" : "");
+ }
+}
+
+U32 LLPosOverrideMap::count() const
+{
+ return m_map.size();
+}
+
+void LLPosOverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos)
+{
+ m_map[mesh_id] = pos;
+}
+
+bool LLPosOverrideMap::remove(const LLUUID& mesh_id)
+{
+ U32 remove_count = m_map.erase(mesh_id);
+ return (remove_count > 0);
+}
+
+void LLPosOverrideMap::clear()
+{
+ m_map.clear();
+}
+
//-----------------------------------------------------------------------------
// LLJoint()
// Class Constructor
@@ -48,11 +106,8 @@ void LLJoint::init()
mParent = NULL;
mXform.setScaleChildOffset(TRUE);
mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
- mOldXform.setScaleChildOffset(TRUE);
- mOldXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
mUpdateXform = TRUE;
- mResetAfterRestoreOldXform = false;
}
LLJoint::LLJoint() :
@@ -233,52 +288,123 @@ const LLVector3& LLJoint::getPosition()
return mXform.getPosition();
}
+bool do_debug_joint(const std::string& name)
+{
+ return true;
+}
//--------------------------------------------------------------------
// setPosition()
//--------------------------------------------------------------------
void LLJoint::setPosition( const LLVector3& pos )
{
+ if (pos != getPosition())
+ {
+ if (do_debug_joint(getName()))
+ {
+ LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL;
+ }
+ }
mXform.setPosition(pos);
touch(MATRIX_DIRTY | POSITION_DIRTY);
}
+void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info )
+{
+ std::ostringstream os;
+ os << joint.m_posBeforeOverrides;
+ joint.m_attachmentOverrides.showJointPosOverrides(os);
+ LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL;
+}
//--------------------------------------------------------------------
-// setPosition()
+// addAttachmentPosOverride()
//--------------------------------------------------------------------
-void LLJoint::setDefaultFromCurrentXform( void )
-{
- mDefaultXform = mXform;
+void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info )
+{
+ if (mesh_id.isNull())
+ {
+ return;
+ }
+ if (!m_attachmentOverrides.count())
+ {
+ if (do_debug_joint(getName()))
+ {
+ LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_posBeforeOverrides " << getPosition() << LL_ENDL;
+ }
+ m_posBeforeOverrides = getPosition();
+ }
+ m_attachmentOverrides.add(mesh_id,pos);
+ if (do_debug_joint(getName()))
+ {
+ LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL;
+ }
+ updatePos(av_info);
}
//--------------------------------------------------------------------
-// storeCurrentXform()
+// removeAttachmentPosOverride()
//--------------------------------------------------------------------
-void LLJoint::storeCurrentXform( const LLVector3& pos )
-{
- mOldXform = mXform;
- mResetAfterRestoreOldXform = true;
- setPosition( pos );
- touch(ALL_DIRTY);
+void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info )
+{
+ if (mesh_id.isNull())
+ {
+ return;
+ }
+ if (m_attachmentOverrides.remove(mesh_id))
+ {
+ if (do_debug_joint(getName()))
+ {
+ LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName()
+ << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL;
+ showJointPosOverrides(*this, "remove", av_info);
+ }
+ updatePos(av_info);
+ }
+
}
//--------------------------------------------------------------------
-// storeScaleForReset()
+ // hasAttachmentPosOverride()
+ //--------------------------------------------------------------------
+bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const
+{
+ return m_attachmentOverrides.findActiveOverride(mesh_id,pos);
+}
+
+//--------------------------------------------------------------------
+// clearAttachmentPosOverrides()
//--------------------------------------------------------------------
-void LLJoint::storeScaleForReset( const LLVector3& scale )
+void LLJoint::clearAttachmentPosOverrides()
{
- mOldXform.setScale( scale );
+ if (m_attachmentOverrides.count())
+ {
+ m_attachmentOverrides.clear();
+ setPosition(m_posBeforeOverrides);
+ setId( LLUUID::null );
+ }
}
+
//--------------------------------------------------------------------
-// restoreOldXform()
+// updatePos()
//--------------------------------------------------------------------
-void LLJoint::restoreOldXform( void )
-{
- mXform = mDefaultXform;
- mResetAfterRestoreOldXform = false;
- mDirtyFlags = ALL_DIRTY;
+void LLJoint::updatePos(const std::string& av_info)
+{
+ LLVector3 pos, found_pos;
+ LLUUID mesh_id;
+ if (m_attachmentOverrides.findActiveOverride(mesh_id,found_pos))
+ {
+ LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL;
+ pos = found_pos;
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL;
+ pos = m_posBeforeOverrides;
+ }
+ setPosition(pos);
}
+
//--------------------------------------------------------------------
// getWorldPosition()
//--------------------------------------------------------------------
@@ -325,7 +451,7 @@ void LLJoint::setWorldPosition( const LLVector3& pos )
//--------------------------------------------------------------------
-// mXform.getRotation()
+// getRotation()
//--------------------------------------------------------------------
const LLQuaternion& LLJoint::getRotation()
{
@@ -432,7 +558,7 @@ const LLMatrix4 &LLJoint::getWorldMatrix()
//--------------------------------------------------------------------
void LLJoint::setWorldMatrix( const LLMatrix4& mat )
{
-LL_INFOS() << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << LL_ENDL;
+ LL_INFOS() << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << LL_ENDL;
// extract global translation
LLVector3 trans( mat.mMatrix[VW][VX],
mat.mMatrix[VW][VY],
@@ -548,20 +674,6 @@ void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot)
break;
}
}
-
- // 2003.03.26 - This code was just using up cpu cycles. AB
-
-// LLVector3 old_axis = main_axis * old_rot;
-// LLVector3 new_axis = main_axis * new_rot;
-
-// for (S32 i = 0; i < mConstraintSilhouette.size() - 1; i++)
-// {
-// LLVector3 vert1 = mConstraintSilhouette[i];
-// LLVector3 vert2 = mConstraintSilhouette[i + 1];
-
- // figure out how to clamp rotation to line on 3-sphere
-
-// }
}
// End
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index b65d6979d4..2abe1d6db1 100755
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -46,6 +46,21 @@ const U32 LL_FACE_JOINT_NUM = 30;
const S32 LL_CHARACTER_MAX_PRIORITY = 7;
const F32 LL_MAX_PELVIS_OFFSET = 5.f;
+class LLPosOverrideMap
+{
+public:
+ LLPosOverrideMap() {}
+ bool findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const;
+ void showJointPosOverrides(std::ostringstream& os) const;
+ U32 count() const;
+ void add(const LLUUID& mesh_id, const LLVector3& pos);
+ bool remove(const LLUUID& mesh_id);
+ void clear();
+private:
+ typedef std::map<LLUUID,LLVector3> map_type;
+ map_type m_map;
+};
+
//-----------------------------------------------------------------------------
// class LLJoint
//-----------------------------------------------------------------------------
@@ -79,8 +94,6 @@ protected:
// explicit transformation members
LLXformMatrix mXform;
- LLXformMatrix mOldXform;
- LLXformMatrix mDefaultXform;
LLUUID mId;
@@ -88,8 +101,6 @@ public:
U32 mDirtyFlags;
BOOL mUpdateXform;
- BOOL mResetAfterRestoreOldXform;
-
// describes the skin binding pose
LLVector3 mSkinOffset;
@@ -103,6 +114,11 @@ public:
static S32 sNumTouches;
static S32 sNumUpdates;
+ LLPosOverrideMap m_attachmentOverrides;
+ LLVector3 m_posBeforeOverrides;
+
+ void updatePos(const std::string& av_info);
+
public:
LLJoint();
LLJoint(S32 joint_num);
@@ -160,7 +176,7 @@ public:
// get/set local scale
const LLVector3& getScale();
void setScale( const LLVector3& scale );
- void storeScaleForReset( const LLVector3& scale );
+
// get/set world matrix
const LLMatrix4 &getWorldMatrix();
void setWorldMatrix( const LLMatrix4& mat );
@@ -183,20 +199,16 @@ public:
virtual BOOL isAnimatable() const { return TRUE; }
S32 getJointNum() const { return mJointNum; }
-
- void restoreOldXform( void );
- void setDefaultFromCurrentXform( void );
- void storeCurrentXform( const LLVector3& pos );
+
+ void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info );
+ void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info );
+ bool hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const;
+ void clearAttachmentPosOverrides();
//Accessor for the joint id
LLUUID getId( void ) { return mId; }
//Setter for the joints id
void setId( const LLUUID& id ) { mId = id;}
-
- //If the old transform flag has been set, then the reset logic in avatar needs to be aware(test) of it
- const BOOL doesJointNeedToBeReset( void ) const { return mResetAfterRestoreOldXform; }
- void setJointResetFlag( bool val ) { mResetAfterRestoreOldXform = val; }
-
};
#endif // LL_LLJOINT_H
diff --git a/indra/llimage/llimagefilter.cpp b/indra/llimage/llimagefilter.cpp
index 3d0c488768..0b9d136910 100755
--- a/indra/llimage/llimagefilter.cpp
+++ b/indra/llimage/llimagefilter.cpp
@@ -266,7 +266,7 @@ void LLImageFilter::executeFilter(LLPointer<LLImageRaw> raw_image)
}
else
{
- llwarns << "Filter unknown, cannot execute filter command : " << filter_name << llendl;
+ LL_WARNS() << "Filter unknown, cannot execute filter command : " << filter_name << LL_ENDL;
}
}
}
diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h
index e56929ed0f..aa0b1752f4 100755
--- a/indra/llmath/llquaternion.h
+++ b/indra/llmath/llquaternion.h
@@ -71,6 +71,9 @@ public:
void quantize8(F32 lower, F32 upper); // changes the vector to reflect quatization
void loadIdentity(); // Loads the quaternion that represents the identity rotation
+ bool isEqualEps(const LLQuaternion &quat, F32 epsilon) const;
+ bool isNotEqualEps(const LLQuaternion &quat, F32 epsilon) const;
+
const LLQuaternion& set(F32 x, F32 y, F32 z, F32 w); // Sets Quaternion to normalize(x, y, z, w)
const LLQuaternion& set(const LLQuaternion &quat); // Copies Quaternion
const LLQuaternion& set(const F32 *q); // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW])
@@ -239,6 +242,21 @@ inline void LLQuaternion::loadIdentity()
mQ[VW] = 1.0f;
}
+inline bool LLQuaternion::isEqualEps(const LLQuaternion &quat, F32 epsilon) const
+{
+ return ( fabs(mQ[VX] - quat.mQ[VX]) < epsilon
+ && fabs(mQ[VY] - quat.mQ[VY]) < epsilon
+ && fabs(mQ[VZ] - quat.mQ[VZ]) < epsilon
+ && fabs(mQ[VS] - quat.mQ[VS]) < epsilon );
+}
+
+inline bool LLQuaternion::isNotEqualEps(const LLQuaternion &quat, F32 epsilon) const
+{
+ return ( fabs(mQ[VX] - quat.mQ[VX]) > epsilon
+ || fabs(mQ[VY] - quat.mQ[VY]) > epsilon
+ || fabs(mQ[VZ] - quat.mQ[VZ]) > epsilon
+ || fabs(mQ[VS] - quat.mQ[VS]) > epsilon );
+}
inline const LLQuaternion& LLQuaternion::set(F32 x, F32 y, F32 z, F32 w)
{
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index b4963225dc..aa8dd7697c 100755
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -172,7 +172,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
if (!pos_source)
{
- llwarns << "Unable to process mesh without position data; invalid model; invalid model." << llendl;
+ LL_WARNS() << "Unable to process mesh without position data; invalid model; invalid model." << LL_ENDL;
return LLModel::BAD_ELEMENT;
}
@@ -180,20 +180,20 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
domListOfUInts& idx = p->getValue();
domListOfFloats dummy ;
- domListOfFloats& v = pos_source ? pos_source->getFloat_array()->getValue() : dummy ;
- domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy ;
- domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy ;
+ domListOfFloats& v = (pos_source && pos_source->getFloat_array()) ? pos_source->getFloat_array()->getValue() : dummy ;
+ domListOfFloats& tc = (tc_source && tc_source->getFloat_array()) ? tc_source->getFloat_array()->getValue() : dummy ;
+ domListOfFloats& n = (norm_source && norm_source->getFloat_array()) ? norm_source->getFloat_array()->getValue() : dummy ;
LLVolumeFace::VertexMapData::PointMap point_map;
U32 index_count = idx.getCount();
- U32 vertex_count = pos_source ? v.getCount() : 0;
- U32 tc_count = tc_source ? tc.getCount() : 0;
- U32 norm_count = norm_source ? n.getCount() : 0;
+ U32 vertex_count = (pos_source && pos_source->getFloat_array()) ? v.getCount() : 0;
+ U32 tc_count = (tc_source && tc_source->getFloat_array()) ? tc.getCount() : 0;
+ U32 norm_count = (norm_source && norm_source->getFloat_array()) ? n.getCount(): 0;
- if ((vertex_count == 0) || (tc_count == 0))
+ if ((vertex_count == 0))
{
- llwarns << "Unable to process mesh with empty position array; invalid model." << llendl;
+ LL_WARNS() << "Unable to process mesh with empty position array; invalid model." << LL_ENDL;
return LLModel::BAD_ELEMENT;
}
@@ -229,7 +229,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
{
// guard against model data specifiying out of range indices or tcs
//
-
+
if (((i + tc_offset) > index_count)
|| ((idx[i+tc_offset]*2+1) > tc_count))
{
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index b81dd4c9a1..3ceed95248 100755
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -61,33 +61,33 @@ U64 LLGLSLShader::sTotalSamplesDrawn = 0;
U32 LLGLSLShader::sTotalDrawCalls = 0;
//UI shader -- declared here so llui_libtest will link properly
-LLGLSLShader gUIProgram;
-LLGLSLShader gSolidColorProgram;
+LLGLSLShader gUIProgram;
+LLGLSLShader gSolidColorProgram;
BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
{
- return v1 != v2;
+ return v1 != v2;
}
LLShaderFeatures::LLShaderFeatures()
- : atmosphericHelpers(false)
- , calculatesLighting(false)
- , calculatesAtmospherics(false)
- , hasLighting(false)
- , isAlphaLighting(false)
- , isShiny(false)
- , isFullbright(false)
- , isSpecular(false)
- , hasWaterFog(false)
- , hasTransport(false)
- , hasSkinning(false)
- , hasObjectSkinning(false)
- , hasAtmospherics(false)
- , hasGamma(false)
- , mIndexedTextureChannels(0)
- , disableTextureIndex(false)
- , hasAlphaMask(false)
- , attachNothing(false)
+ : atmosphericHelpers(false)
+ , calculatesLighting(false)
+ , calculatesAtmospherics(false)
+ , hasLighting(false)
+ , isAlphaLighting(false)
+ , isShiny(false)
+ , isFullbright(false)
+ , isSpecular(false)
+ , hasWaterFog(false)
+ , hasTransport(false)
+ , hasSkinning(false)
+ , hasObjectSkinning(false)
+ , hasAtmospherics(false)
+ , hasGamma(false)
+ , mIndexedTextureChannels(0)
+ , disableTextureIndex(false)
+ , hasAlphaMask(false)
+ , attachNothing(false)
{
}
@@ -98,225 +98,225 @@ LLShaderFeatures::LLShaderFeatures()
//static
void LLGLSLShader::initProfile()
{
- sProfileEnabled = true;
- sTotalTimeElapsed = 0;
- sTotalTrianglesDrawn = 0;
- sTotalSamplesDrawn = 0;
- sTotalDrawCalls = 0;
-
- for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
- {
- (*iter)->clearStats();
- }
+ sProfileEnabled = true;
+ sTotalTimeElapsed = 0;
+ sTotalTrianglesDrawn = 0;
+ sTotalSamplesDrawn = 0;
+ sTotalDrawCalls = 0;
+
+ for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
+ {
+ (*iter)->clearStats();
+ }
}
struct LLGLSLShaderCompareTimeElapsed
{
- bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs)
- {
- return lhs->mTimeElapsed < rhs->mTimeElapsed;
- }
+ bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs)
+ {
+ return lhs->mTimeElapsed < rhs->mTimeElapsed;
+ }
};
//static
void LLGLSLShader::finishProfile(bool emit_report)
{
- sProfileEnabled = false;
-
- if (emit_report)
- {
- std::vector<LLGLSLShader*> sorted;
-
- for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
- {
- sorted.push_back(*iter);
- }
-
- std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed());
-
- for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter)
- {
- (*iter)->dumpStats();
- }
-
- LL_INFOS() << "-----------------------------------" << LL_ENDL;
- LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << LL_ENDL;
- LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << LL_ENDL;
- LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << LL_ENDL;
- }
+ sProfileEnabled = false;
+
+ if (emit_report)
+ {
+ std::vector<LLGLSLShader*> sorted;
+
+ for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
+ {
+ sorted.push_back(*iter);
+ }
+
+ std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed());
+
+ for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter)
+ {
+ (*iter)->dumpStats();
+ }
+
+ LL_INFOS() << "-----------------------------------" << LL_ENDL;
+ LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << LL_ENDL;
+ LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << LL_ENDL;
+ LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << LL_ENDL;
+ }
}
void LLGLSLShader::clearStats()
{
- mTrianglesDrawn = 0;
- mTimeElapsed = 0;
- mSamplesDrawn = 0;
- mDrawCalls = 0;
- mTextureStateFetched = false;
- mTextureMagFilter.clear();
- mTextureMinFilter.clear();
+ mTrianglesDrawn = 0;
+ mTimeElapsed = 0;
+ mSamplesDrawn = 0;
+ mDrawCalls = 0;
+ mTextureStateFetched = false;
+ mTextureMagFilter.clear();
+ mTextureMinFilter.clear();
}
void LLGLSLShader::dumpStats()
{
- if (mDrawCalls > 0)
- {
- LL_INFOS() << "=============================================" << LL_ENDL;
- LL_INFOS() << mName << LL_ENDL;
- for (U32 i = 0; i < mShaderFiles.size(); ++i)
- {
- LL_INFOS() << mShaderFiles[i].first << LL_ENDL;
- }
- for (U32 i = 0; i < mTexture.size(); ++i)
- {
- GLint idx = mTexture[i];
-
- if (idx >= 0)
- {
- GLint uniform_idx = getUniformLocation(i);
- LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << LL_ENDL;
- }
- }
- LL_INFOS() << "=============================================" << LL_ENDL;
-
- F32 ms = mTimeElapsed/1000000.f;
- F32 seconds = ms/1000.f;
-
- F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f;
- F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0);
- tris_sec /= seconds;
-
- F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f;
- F32 samples_sec = (F32) mSamplesDrawn/1000000000.0;
- samples_sec /= seconds;
-
- F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f;
- U32 avg_batch = mTrianglesDrawn/mDrawCalls;
-
- LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << LL_ENDL;
- LL_INFOS() << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << LL_ENDL;
- LL_INFOS() << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << LL_ENDL;
- LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << LL_ENDL;
- }
+ if (mDrawCalls > 0)
+ {
+ LL_INFOS() << "=============================================" << LL_ENDL;
+ LL_INFOS() << mName << LL_ENDL;
+ for (U32 i = 0; i < mShaderFiles.size(); ++i)
+ {
+ LL_INFOS() << mShaderFiles[i].first << LL_ENDL;
+ }
+ for (U32 i = 0; i < mTexture.size(); ++i)
+ {
+ GLint idx = mTexture[i];
+
+ if (idx >= 0)
+ {
+ GLint uniform_idx = getUniformLocation(i);
+ LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << LL_ENDL;
+ }
+ }
+ LL_INFOS() << "=============================================" << LL_ENDL;
+
+ F32 ms = mTimeElapsed/1000000.f;
+ F32 seconds = ms/1000.f;
+
+ F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f;
+ F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0);
+ tris_sec /= seconds;
+
+ F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f;
+ F32 samples_sec = (F32) mSamplesDrawn/1000000000.0;
+ samples_sec /= seconds;
+
+ F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f;
+ U32 avg_batch = mTrianglesDrawn/mDrawCalls;
+
+ LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << LL_ENDL;
+ LL_INFOS() << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << LL_ENDL;
+ LL_INFOS() << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << LL_ENDL;
+ LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << LL_ENDL;
+ }
}
//static
void LLGLSLShader::startProfile()
{
- if (sProfileEnabled && sCurBoundShaderPtr)
- {
- sCurBoundShaderPtr->placeProfileQuery();
- }
+ if (sProfileEnabled && sCurBoundShaderPtr)
+ {
+ sCurBoundShaderPtr->placeProfileQuery();
+ }
}
//static
void LLGLSLShader::stopProfile(U32 count, U32 mode)
{
- if (sProfileEnabled)
- {
- sCurBoundShaderPtr->readProfileQuery(count, mode);
- }
+ if (sProfileEnabled && sCurBoundShaderPtr)
+ {
+ sCurBoundShaderPtr->readProfileQuery(count, mode);
+ }
}
void LLGLSLShader::placeProfileQuery()
{
#if !LL_DARWIN
- if (mTimerQuery == 0)
- {
- glGenQueriesARB(1, &mSamplesQuery);
- glGenQueriesARB(1, &mTimerQuery);
- }
+ if (mTimerQuery == 0)
+ {
+ glGenQueriesARB(1, &mSamplesQuery);
+ glGenQueriesARB(1, &mTimerQuery);
+ }
- if (!mTextureStateFetched)
- {
- mTextureStateFetched = true;
- mTextureMagFilter.resize(mTexture.size());
- mTextureMinFilter.resize(mTexture.size());
+ if (!mTextureStateFetched)
+ {
+ mTextureStateFetched = true;
+ mTextureMagFilter.resize(mTexture.size());
+ mTextureMinFilter.resize(mTexture.size());
- U32 cur_active = gGL.getCurrentTexUnitIndex();
+ U32 cur_active = gGL.getCurrentTexUnitIndex();
- for (U32 i = 0; i < mTexture.size(); ++i)
- {
- GLint idx = mTexture[i];
+ for (U32 i = 0; i < mTexture.size(); ++i)
+ {
+ GLint idx = mTexture[i];
- if (idx >= 0)
- {
- gGL.getTexUnit(idx)->activate();
+ if (idx >= 0)
+ {
+ gGL.getTexUnit(idx)->activate();
- U32 mag = 0xFFFFFFFF;
- U32 min = 0xFFFFFFFF;
+ U32 mag = 0xFFFFFFFF;
+ U32 min = 0xFFFFFFFF;
- U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
+ U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
- glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
- glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
+ glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
+ glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
- mTextureMagFilter[i] = mag;
- mTextureMinFilter[i] = min;
- }
- }
+ mTextureMagFilter[i] = mag;
+ mTextureMinFilter[i] = min;
+ }
+ }
- gGL.getTexUnit(cur_active)->activate();
- }
+ gGL.getTexUnit(cur_active)->activate();
+ }
- glBeginQueryARB(GL_SAMPLES_PASSED, mSamplesQuery);
- glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
+ glBeginQueryARB(GL_SAMPLES_PASSED, mSamplesQuery);
+ glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
#endif
}
void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
{
#if !LL_DARWIN
- glEndQueryARB(GL_TIME_ELAPSED);
- glEndQueryARB(GL_SAMPLES_PASSED);
-
- U64 time_elapsed = 0;
- glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
-
- U64 samples_passed = 0;
- glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
-
- sTotalTimeElapsed += time_elapsed;
- mTimeElapsed += time_elapsed;
-
- sTotalSamplesDrawn += samples_passed;
- mSamplesDrawn += samples_passed;
-
- U32 tri_count = 0;
- switch (mode)
- {
- case LLRender::TRIANGLES: tri_count = count/3; break;
- case LLRender::TRIANGLE_FAN: tri_count = count-2; break;
- case LLRender::TRIANGLE_STRIP: tri_count = count-2; break;
- default: tri_count = count; break; //points lines etc just use primitive count
- }
-
- mTrianglesDrawn += tri_count;
- sTotalTrianglesDrawn += tri_count;
-
- sTotalDrawCalls++;
- mDrawCalls++;
+ glEndQueryARB(GL_TIME_ELAPSED);
+ glEndQueryARB(GL_SAMPLES_PASSED);
+
+ U64 time_elapsed = 0;
+ glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
+
+ U64 samples_passed = 0;
+ glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
+
+ sTotalTimeElapsed += time_elapsed;
+ mTimeElapsed += time_elapsed;
+
+ sTotalSamplesDrawn += samples_passed;
+ mSamplesDrawn += samples_passed;
+
+ U32 tri_count = 0;
+ switch (mode)
+ {
+ case LLRender::TRIANGLES: tri_count = count/3; break;
+ case LLRender::TRIANGLE_FAN: tri_count = count-2; break;
+ case LLRender::TRIANGLE_STRIP: tri_count = count-2; break;
+ default: tri_count = count; break; //points lines etc just use primitive count
+ }
+
+ mTrianglesDrawn += tri_count;
+ sTotalTrianglesDrawn += tri_count;
+
+ sTotalDrawCalls++;
+ mDrawCalls++;
#endif
}
LLGLSLShader::LLGLSLShader()
- : mProgramObject(0),
- mAttributeMask(0),
- mTotalUniformSize(0),
- mActiveTextureChannels(0),
- mShaderLevel(0),
- mShaderGroup(SG_DEFAULT),
- mUniformsDirty(FALSE),
- mTimerQuery(0),
- mSamplesQuery(0)
+ : mProgramObject(0),
+ mAttributeMask(0),
+ mTotalUniformSize(0),
+ mActiveTextureChannels(0),
+ mShaderLevel(0),
+ mShaderGroup(SG_DEFAULT),
+ mUniformsDirty(FALSE),
+ mTimerQuery(0),
+ mSamplesQuery(0)
{
-
+
}
LLGLSLShader::~LLGLSLShader()
@@ -325,1077 +325,1077 @@ LLGLSLShader::~LLGLSLShader()
void LLGLSLShader::unload()
{
- sInstances.erase(this);
-
- stop_glerror();
- mAttribute.clear();
- mTexture.clear();
- mUniform.clear();
- mShaderFiles.clear();
- mDefines.clear();
-
- if (mProgramObject)
- {
- GLhandleARB obj[1024];
- GLsizei count;
-
- glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
- for (GLsizei i = 0; i < count; i++)
- {
+ sInstances.erase(this);
+
+ stop_glerror();
+ mAttribute.clear();
+ mTexture.clear();
+ mUniform.clear();
+ mShaderFiles.clear();
+ mDefines.clear();
+
+ if (mProgramObject)
+ {
+ GLhandleARB obj[1024];
+ GLsizei count;
+
+ glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
+ for (GLsizei i = 0; i < count; i++)
+ {
#if !LL_DARWIN
- if (glIsProgramARB(obj[i]))
+ if (glIsProgramARB(obj[i]))
#endif
- {
- glDeleteObjectARB(obj[i]);
- }
- }
-
- glDeleteObjectARB(mProgramObject);
-
- mProgramObject = 0;
- }
-
- if (mTimerQuery)
- {
- glDeleteQueriesARB(1, &mTimerQuery);
- mTimerQuery = 0;
- }
-
- if (mSamplesQuery)
- {
- glDeleteQueriesARB(1, &mSamplesQuery);
- mSamplesQuery = 0;
- }
-
- //hack to make apple not complain
- glGetError();
-
- stop_glerror();
+ {
+ glDeleteObjectARB(obj[i]);
+ }
+ }
+
+ glDeleteObjectARB(mProgramObject);
+
+ mProgramObject = 0;
+ }
+
+ if (mTimerQuery)
+ {
+ glDeleteQueriesARB(1, &mTimerQuery);
+ mTimerQuery = 0;
+ }
+
+ if (mSamplesQuery)
+ {
+ glDeleteQueriesARB(1, &mSamplesQuery);
+ mSamplesQuery = 0;
+ }
+
+ //hack to make apple not complain
+ glGetError();
+
+ stop_glerror();
}
BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
- std::vector<LLStaticHashedString> * uniforms,
- U32 varying_count,
- const char** varyings)
+ std::vector<LLStaticHashedString> * uniforms,
+ U32 varying_count,
+ const char** varyings)
{
- sInstances.insert(this);
+ sInstances.insert(this);
- //reloading, reset matrix hash values
- for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
- {
- mMatHash[i] = 0xFFFFFFFF;
- }
- mLightHash = 0xFFFFFFFF;
+ //reloading, reset matrix hash values
+ for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
+ {
+ mMatHash[i] = 0xFFFFFFFF;
+ }
+ mLightHash = 0xFFFFFFFF;
- llassert_always(!mShaderFiles.empty());
- BOOL success = TRUE;
+ llassert_always(!mShaderFiles.empty());
+ BOOL success = TRUE;
- // Create program
- mProgramObject = glCreateProgramObjectARB();
-
+ // Create program
+ mProgramObject = glCreateProgramObjectARB();
+
#if LL_DARWIN
// work-around missing mix(vec3,vec3,bvec3)
mDefines["OLD_SELECT"] = "1";
#endif
-
- //compile new source
- vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
- for ( ; fileIter != mShaderFiles.end(); fileIter++ )
- {
- GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
- LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
- if (shaderhandle > 0)
- {
- attachObject(shaderhandle);
- }
- else
- {
- success = FALSE;
- }
- }
-
- // Attach existing objects
- if (!LLShaderMgr::instance()->attachShaderFeatures(this))
- {
- return FALSE;
- }
-
- if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3)
- { //indexed texture rendering requires GLSL 1.3 or later
- //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
- mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
- }
+
+ //compile new source
+ vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
+ for ( ; fileIter != mShaderFiles.end(); fileIter++ )
+ {
+ GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
+ LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
+ if (shaderhandle > 0)
+ {
+ attachObject(shaderhandle);
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
+
+ // Attach existing objects
+ if (!LLShaderMgr::instance()->attachShaderFeatures(this))
+ {
+ return FALSE;
+ }
+
+ if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3)
+ { //indexed texture rendering requires GLSL 1.3 or later
+ //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
+ mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
+ }
#ifdef GL_INTERLEAVED_ATTRIBS
- if (varying_count > 0 && varyings)
- {
- glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
- }
+ if (varying_count > 0 && varyings)
+ {
+ glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
+ }
#endif
- // Map attributes and uniforms
- if (success)
- {
- success = mapAttributes(attributes);
- }
- if (success)
- {
- success = mapUniforms(uniforms);
- }
- if( !success )
- {
- LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
-
- // Try again using a lower shader level;
- if (mShaderLevel > 0)
- {
- LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
- mShaderLevel--;
- return createShader(attributes,uniforms);
- }
- }
- else if (mFeatures.mIndexedTextureChannels > 0)
- { //override texture channels for indexed texture rendering
- bind();
- S32 channel_count = mFeatures.mIndexedTextureChannels;
-
- for (S32 i = 0; i < channel_count; i++)
- {
- LLStaticHashedString uniName(llformat("tex%d", i));
- uniform1i(uniName, i);
- }
-
- S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
- for (U32 i = 0; i < mTexture.size(); i++)
- {
- if (mTexture[i] > -1 && mTexture[i] < channel_count)
- {
- llassert(cur_tex < gGLManager.mNumTextureImageUnits);
- uniform1i(i, cur_tex);
- mTexture[i] = cur_tex++;
- }
- }
- unbind();
- }
-
- return success;
+ // Map attributes and uniforms
+ if (success)
+ {
+ success = mapAttributes(attributes);
+ }
+ if (success)
+ {
+ success = mapUniforms(uniforms);
+ }
+ if( !success )
+ {
+ LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
+
+ // Try again using a lower shader level;
+ if (mShaderLevel > 0)
+ {
+ LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
+ mShaderLevel--;
+ return createShader(attributes,uniforms);
+ }
+ }
+ else if (mFeatures.mIndexedTextureChannels > 0)
+ { //override texture channels for indexed texture rendering
+ bind();
+ S32 channel_count = mFeatures.mIndexedTextureChannels;
+
+ for (S32 i = 0; i < channel_count; i++)
+ {
+ LLStaticHashedString uniName(llformat("tex%d", i));
+ uniform1i(uniName, i);
+ }
+
+ S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
+ for (U32 i = 0; i < mTexture.size(); i++)
+ {
+ if (mTexture[i] > -1 && mTexture[i] < channel_count)
+ {
+ llassert(cur_tex < gGLManager.mNumTextureImageUnits);
+ uniform1i(i, cur_tex);
+ mTexture[i] = cur_tex++;
+ }
+ }
+ unbind();
+ }
+
+ return success;
}
BOOL LLGLSLShader::attachObject(std::string object)
{
- if (LLShaderMgr::instance()->mShaderObjects.count(object) > 0)
- {
- stop_glerror();
- glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object]);
- stop_glerror();
- return TRUE;
- }
- else
- {
- LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
- return FALSE;
- }
+ if (LLShaderMgr::instance()->mShaderObjects.count(object) > 0)
+ {
+ stop_glerror();
+ glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object]);
+ stop_glerror();
+ return TRUE;
+ }
+ else
+ {
+ LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
+ return FALSE;
+ }
}
void LLGLSLShader::attachObject(GLhandleARB object)
{
- if (object != 0)
- {
- stop_glerror();
- glAttachObjectARB(mProgramObject, object);
- stop_glerror();
- }
- else
- {
- LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL;
- }
+ if (object != 0)
+ {
+ stop_glerror();
+ glAttachObjectARB(mProgramObject, object);
+ stop_glerror();
+ }
+ else
+ {
+ LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL;
+ }
}
void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
{
- for (S32 i = 0; i < count; i++)
- {
- attachObject(objects[i]);
- }
+ for (S32 i = 0; i < count; i++)
+ {
+ attachObject(objects[i]);
+ }
}
BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes)
{
- //before linking, make sure reserved attributes always have consistent locations
- for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
- {
- const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
- glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name);
- }
-
- //link the program
- BOOL res = link();
-
- mAttribute.clear();
- U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
- mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1);
-
- if (res)
- { //read back channel locations
-
- mAttributeMask = 0;
-
- //read back reserved channels first
- for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
- {
- const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
- S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name);
- if (index != -1)
- {
- mAttribute[i] = index;
- mAttributeMask |= 1 << i;
- LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
- }
- }
- if (attributes != NULL)
- {
- for (U32 i = 0; i < numAttributes; i++)
- {
- const char* name = (*attributes)[i].String().c_str();
- S32 index = glGetAttribLocationARB(mProgramObject, name);
- if (index != -1)
- {
- mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index;
- LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
- }
- }
- }
-
- return TRUE;
- }
-
- return FALSE;
+ //before linking, make sure reserved attributes always have consistent locations
+ for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
+ {
+ const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
+ glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name);
+ }
+
+ //link the program
+ BOOL res = link();
+
+ mAttribute.clear();
+ U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
+ mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1);
+
+ if (res)
+ { //read back channel locations
+
+ mAttributeMask = 0;
+
+ //read back reserved channels first
+ for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
+ {
+ const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
+ S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name);
+ if (index != -1)
+ {
+ mAttribute[i] = index;
+ mAttributeMask |= 1 << i;
+ LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
+ }
+ }
+ if (attributes != NULL)
+ {
+ for (U32 i = 0; i < numAttributes; i++)
+ {
+ const char* name = (*attributes)[i].String().c_str();
+ S32 index = glGetAttribLocationARB(mProgramObject, name);
+ if (index != -1)
+ {
+ mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index;
+ LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
+ }
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
}
void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms)
{
- if (index == -1)
- {
- return;
- }
+ if (index == -1)
+ {
+ return;
+ }
- GLenum type;
- GLsizei length;
- GLint size = -1;
- char name[1024]; /* Flawfinder: ignore */
- name[0] = 0;
+ GLenum type;
+ GLsizei length;
+ GLint size = -1;
+ char name[1024]; /* Flawfinder: ignore */
+ name[0] = 0;
- glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
+ glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
#if !LL_DARWIN
- if (size > 0)
- {
- switch(type)
- {
- case GL_FLOAT_VEC2: size *= 2; break;
- case GL_FLOAT_VEC3: size *= 3; break;
- case GL_FLOAT_VEC4: size *= 4; break;
- case GL_DOUBLE: size *= 2; break;
- case GL_DOUBLE_VEC2: size *= 2; break;
- case GL_DOUBLE_VEC3: size *= 6; break;
- case GL_DOUBLE_VEC4: size *= 8; break;
- case GL_INT_VEC2: size *= 2; break;
- case GL_INT_VEC3: size *= 3; break;
- case GL_INT_VEC4: size *= 4; break;
- case GL_UNSIGNED_INT_VEC2: size *= 2; break;
- case GL_UNSIGNED_INT_VEC3: size *= 3; break;
- case GL_UNSIGNED_INT_VEC4: size *= 4; break;
- case GL_BOOL_VEC2: size *= 2; break;
- case GL_BOOL_VEC3: size *= 3; break;
- case GL_BOOL_VEC4: size *= 4; break;
- case GL_FLOAT_MAT2: size *= 4; break;
- case GL_FLOAT_MAT3: size *= 9; break;
- case GL_FLOAT_MAT4: size *= 16; break;
- case GL_FLOAT_MAT2x3: size *= 6; break;
- case GL_FLOAT_MAT2x4: size *= 8; break;
- case GL_FLOAT_MAT3x2: size *= 6; break;
- case GL_FLOAT_MAT3x4: size *= 12; break;
- case GL_FLOAT_MAT4x2: size *= 8; break;
- case GL_FLOAT_MAT4x3: size *= 12; break;
- case GL_DOUBLE_MAT2: size *= 8; break;
- case GL_DOUBLE_MAT3: size *= 18; break;
- case GL_DOUBLE_MAT4: size *= 32; break;
- case GL_DOUBLE_MAT2x3: size *= 12; break;
- case GL_DOUBLE_MAT2x4: size *= 16; break;
- case GL_DOUBLE_MAT3x2: size *= 12; break;
- case GL_DOUBLE_MAT3x4: size *= 24; break;
- case GL_DOUBLE_MAT4x2: size *= 16; break;
- case GL_DOUBLE_MAT4x3: size *= 24; break;
- }
- mTotalUniformSize += size;
- }
+ if (size > 0)
+ {
+ switch(type)
+ {
+ case GL_FLOAT_VEC2: size *= 2; break;
+ case GL_FLOAT_VEC3: size *= 3; break;
+ case GL_FLOAT_VEC4: size *= 4; break;
+ case GL_DOUBLE: size *= 2; break;
+ case GL_DOUBLE_VEC2: size *= 2; break;
+ case GL_DOUBLE_VEC3: size *= 6; break;
+ case GL_DOUBLE_VEC4: size *= 8; break;
+ case GL_INT_VEC2: size *= 2; break;
+ case GL_INT_VEC3: size *= 3; break;
+ case GL_INT_VEC4: size *= 4; break;
+ case GL_UNSIGNED_INT_VEC2: size *= 2; break;
+ case GL_UNSIGNED_INT_VEC3: size *= 3; break;
+ case GL_UNSIGNED_INT_VEC4: size *= 4; break;
+ case GL_BOOL_VEC2: size *= 2; break;
+ case GL_BOOL_VEC3: size *= 3; break;
+ case GL_BOOL_VEC4: size *= 4; break;
+ case GL_FLOAT_MAT2: size *= 4; break;
+ case GL_FLOAT_MAT3: size *= 9; break;
+ case GL_FLOAT_MAT4: size *= 16; break;
+ case GL_FLOAT_MAT2x3: size *= 6; break;
+ case GL_FLOAT_MAT2x4: size *= 8; break;
+ case GL_FLOAT_MAT3x2: size *= 6; break;
+ case GL_FLOAT_MAT3x4: size *= 12; break;
+ case GL_FLOAT_MAT4x2: size *= 8; break;
+ case GL_FLOAT_MAT4x3: size *= 12; break;
+ case GL_DOUBLE_MAT2: size *= 8; break;
+ case GL_DOUBLE_MAT3: size *= 18; break;
+ case GL_DOUBLE_MAT4: size *= 32; break;
+ case GL_DOUBLE_MAT2x3: size *= 12; break;
+ case GL_DOUBLE_MAT2x4: size *= 16; break;
+ case GL_DOUBLE_MAT3x2: size *= 12; break;
+ case GL_DOUBLE_MAT3x4: size *= 24; break;
+ case GL_DOUBLE_MAT4x2: size *= 16; break;
+ case GL_DOUBLE_MAT4x3: size *= 24; break;
+ }
+ mTotalUniformSize += size;
+ }
#endif
- S32 location = glGetUniformLocationARB(mProgramObject, name);
- if (location != -1)
- {
- //chop off "[0]" so we can always access the first element
- //of an array by the array name
- char* is_array = strstr(name, "[0]");
- if (is_array)
- {
- is_array[0] = 0;
- }
-
- LLStaticHashedString hashedName(name);
- mUniformNameMap[location] = name;
- mUniformMap[hashedName] = location;
-
- LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
-
- //find the index of this uniform
- for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
- {
- if ( (mUniform[i] == -1)
- && (LLShaderMgr::instance()->mReservedUniforms[i] == name))
- {
- //found it
- mUniform[i] = location;
- mTexture[i] = mapUniformTextureChannel(location, type);
- return;
- }
- }
-
- if (uniforms != NULL)
- {
- for (U32 i = 0; i < uniforms->size(); i++)
- {
- if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
- && ((*uniforms)[i].String() == name))
- {
- //found it
- mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
- mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type);
- return;
- }
- }
- }
- }
+ S32 location = glGetUniformLocationARB(mProgramObject, name);
+ if (location != -1)
+ {
+ //chop off "[0]" so we can always access the first element
+ //of an array by the array name
+ char* is_array = strstr(name, "[0]");
+ if (is_array)
+ {
+ is_array[0] = 0;
+ }
+
+ LLStaticHashedString hashedName(name);
+ mUniformNameMap[location] = name;
+ mUniformMap[hashedName] = location;
+
+ LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
+
+ //find the index of this uniform
+ for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
+ {
+ if ( (mUniform[i] == -1)
+ && (LLShaderMgr::instance()->mReservedUniforms[i] == name))
+ {
+ //found it
+ mUniform[i] = location;
+ mTexture[i] = mapUniformTextureChannel(location, type);
+ return;
+ }
+ }
+
+ if (uniforms != NULL)
+ {
+ for (U32 i = 0; i < uniforms->size(); i++)
+ {
+ if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
+ && ((*uniforms)[i].String() == name))
+ {
+ //found it
+ mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
+ mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type);
+ return;
+ }
+ }
+ }
+ }
}
void LLGLSLShader::addPermutation(std::string name, std::string value)
{
- mDefines[name] = value;
+ mDefines[name] = value;
}
void LLGLSLShader::removePermutation(std::string name)
{
- mDefines[name].erase();
+ mDefines[name].erase();
}
GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
{
- if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
- type == GL_SAMPLER_2D_MULTISAMPLE)
- { //this here is a texture
- glUniform1iARB(location, mActiveTextureChannels);
- LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
- return mActiveTextureChannels++;
- }
- return -1;
+ if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
+ type == GL_SAMPLER_2D_MULTISAMPLE)
+ { //this here is a texture
+ glUniform1iARB(location, mActiveTextureChannels);
+ LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
+ return mActiveTextureChannels++;
+ }
+ return -1;
}
BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
{
- BOOL res = TRUE;
-
- mTotalUniformSize = 0;
- mActiveTextureChannels = 0;
- mUniform.clear();
- mUniformMap.clear();
- mUniformNameMap.clear();
- mTexture.clear();
- mValue.clear();
- //initialize arrays
- U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size();
- mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
- mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
-
- bind();
-
- //get the number of active uniforms
- GLint activeCount;
- glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
-
- for (S32 i = 0; i < activeCount; i++)
- {
- mapUniform(i, uniforms);
- }
-
- unbind();
-
- LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
- return res;
+ BOOL res = TRUE;
+
+ mTotalUniformSize = 0;
+ mActiveTextureChannels = 0;
+ mUniform.clear();
+ mUniformMap.clear();
+ mUniformNameMap.clear();
+ mTexture.clear();
+ mValue.clear();
+ //initialize arrays
+ U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size();
+ mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
+ mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
+
+ bind();
+
+ //get the number of active uniforms
+ GLint activeCount;
+ glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
+
+ for (S32 i = 0; i < activeCount; i++)
+ {
+ mapUniform(i, uniforms);
+ }
+
+ unbind();
+
+ LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
+ return res;
}
BOOL LLGLSLShader::link(BOOL suppress_errors)
{
- BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
+ BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
- if (!suppress_errors)
- {
+ if (!suppress_errors)
+ {
LLShaderMgr::instance()->dumpObjectLog(mProgramObject, !success, mName);
- }
+ }
- return success;
+ return success;
}
void LLGLSLShader::bind()
{
- gGL.flush();
- if (gGLManager.mHasShaderObjects)
- {
- LLVertexBuffer::unbind();
- glUseProgramObjectARB(mProgramObject);
- sCurBoundShader = mProgramObject;
- sCurBoundShaderPtr = this;
- if (mUniformsDirty)
- {
- LLShaderMgr::instance()->updateShaderUniforms(this);
- mUniformsDirty = FALSE;
- }
- }
+ gGL.flush();
+ if (gGLManager.mHasShaderObjects)
+ {
+ LLVertexBuffer::unbind();
+ glUseProgramObjectARB(mProgramObject);
+ sCurBoundShader = mProgramObject;
+ sCurBoundShaderPtr = this;
+ if (mUniformsDirty)
+ {
+ LLShaderMgr::instance()->updateShaderUniforms(this);
+ mUniformsDirty = FALSE;
+ }
+ }
}
void LLGLSLShader::unbind()
{
- gGL.flush();
- if (gGLManager.mHasShaderObjects)
- {
- stop_glerror();
- if (gGLManager.mIsNVIDIA)
- {
- for (U32 i = 0; i < mAttribute.size(); ++i)
- {
- vertexAttrib4f(i, 0,0,0,1);
- stop_glerror();
- }
- }
- LLVertexBuffer::unbind();
- glUseProgramObjectARB(0);
- sCurBoundShader = 0;
- sCurBoundShaderPtr = NULL;
- stop_glerror();
- }
+ gGL.flush();
+ if (gGLManager.mHasShaderObjects)
+ {
+ stop_glerror();
+ if (gGLManager.mIsNVIDIA)
+ {
+ for (U32 i = 0; i < mAttribute.size(); ++i)
+ {
+ vertexAttrib4f(i, 0,0,0,1);
+ stop_glerror();
+ }
+ }
+ LLVertexBuffer::unbind();
+ glUseProgramObjectARB(0);
+ sCurBoundShader = 0;
+ sCurBoundShaderPtr = NULL;
+ stop_glerror();
+ }
}
void LLGLSLShader::bindNoShader(void)
{
- LLVertexBuffer::unbind();
- if (gGLManager.mHasShaderObjects)
- {
- glUseProgramObjectARB(0);
- sCurBoundShader = 0;
- sCurBoundShaderPtr = NULL;
- }
+ LLVertexBuffer::unbind();
+ if (gGLManager.mHasShaderObjects)
+ {
+ glUseProgramObjectARB(0);
+ sCurBoundShader = 0;
+ sCurBoundShaderPtr = NULL;
+ }
}
S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
{
- S32 channel = 0;
- channel = getUniformLocation(uniform);
-
- return bindTexture(channel, texture, mode);
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return bindTexture(channel, texture, mode);
}
S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
{
- if (uniform < 0 || uniform >= (S32)mTexture.size())
- {
- UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
- return -1;
- }
-
- uniform = mTexture[uniform];
-
- if (uniform > -1)
- {
- gGL.getTexUnit(uniform)->bind(texture, mode);
- }
-
- return uniform;
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->bind(texture, mode);
+ }
+
+ return uniform;
}
S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode)
{
- S32 channel = 0;
- channel = getUniformLocation(uniform);
-
- return unbindTexture(channel);
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return unbindTexture(channel);
}
S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
- if (uniform < 0 || uniform >= (S32)mTexture.size())
- {
- UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
- return -1;
- }
-
- uniform = mTexture[uniform];
-
- if (uniform > -1)
- {
- gGL.getTexUnit(uniform)->unbind(mode);
- }
-
- return uniform;
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->unbind(mode);
+ }
+
+ return uniform;
}
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
- if (uniform < 0 || uniform >= (S32)mTexture.size())
- {
- UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
- return -1;
- }
- S32 index = mTexture[uniform];
- if (index != -1)
- {
- gGL.getTexUnit(index)->activate();
- gGL.getTexUnit(index)->enable(mode);
- }
- return index;
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+ S32 index = mTexture[uniform];
+ if (index != -1)
+ {
+ gGL.getTexUnit(index)->activate();
+ gGL.getTexUnit(index)->enable(mode);
+ }
+ return index;
}
S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
- if (uniform < 0 || uniform >= (S32)mTexture.size())
- {
- UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
- return -1;
- }
- S32 index = mTexture[uniform];
- if (index != -1 && gGL.getTexUnit(index)->getCurrType() != LLTexUnit::TT_NONE)
- {
- if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
- {
- if (gDebugSession)
- {
- gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl;
- ll_fail("LLGLSLShader::disableTexture failed");
- }
- else
- {
- LL_ERRS() << "Texture channel " << index << " texture type corrupted." << LL_ENDL;
- }
- }
- gGL.getTexUnit(index)->disable();
- }
- return index;
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+ S32 index = mTexture[uniform];
+ if (index != -1 && gGL.getTexUnit(index)->getCurrType() != LLTexUnit::TT_NONE)
+ {
+ if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
+ {
+ if (gDebugSession)
+ {
+ gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl;
+ ll_fail("LLGLSLShader::disableTexture failed");
+ }
+ else
+ {
+ LL_ERRS() << "Texture channel " << index << " texture type corrupted." << LL_ENDL;
+ }
+ }
+ gGL.getTexUnit(index)->disable();
+ }
+ return index;
}
void LLGLSLShader::uniform1i(U32 index, GLint x)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- if (iter == mValue.end() || iter->second.mV[0] != x)
- {
- glUniform1iARB(mUniform[index], x);
- mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ if (iter == mValue.end() || iter->second.mV[0] != x)
+ {
+ glUniform1iARB(mUniform[index], x);
+ mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
+ }
+ }
+ }
}
void LLGLSLShader::uniform1f(U32 index, GLfloat x)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- if (iter == mValue.end() || iter->second.mV[0] != x)
- {
- glUniform1fARB(mUniform[index], x);
- mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ if (iter == mValue.end() || iter->second.mV[0] != x)
+ {
+ glUniform1fARB(mUniform[index], x);
+ mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
+ }
+ }
+ }
}
void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- LLVector4 vec(x,y,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
- {
- glUniform2fARB(mUniform[index], x, y);
- mValue[mUniform[index]] = vec;
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ LLVector4 vec(x,y,0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec))
+ {
+ glUniform2fARB(mUniform[index], x, y);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
}
void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- LLVector4 vec(x,y,z,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
- {
- glUniform3fARB(mUniform[index], x, y, z);
- mValue[mUniform[index]] = vec;
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ LLVector4 vec(x,y,z,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec))
+ {
+ glUniform3fARB(mUniform[index], x, y, z);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
}
void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- LLVector4 vec(x,y,z,w);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
- {
- glUniform4fARB(mUniform[index], x, y, z, w);
- mValue[mUniform[index]] = vec;
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ LLVector4 vec(x,y,z,w);
+ if (iter == mValue.end() || shouldChange(iter->second,vec))
+ {
+ glUniform4fARB(mUniform[index], x, y, z, w);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
}
void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
- {
- glUniform1ivARB(mUniform[index], count, v);
- mValue[mUniform[index]] = vec;
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ LLVector4 vec(v[0],0.f,0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ {
+ glUniform1ivARB(mUniform[index], count, v);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
}
void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
- {
- glUniform1fvARB(mUniform[index], count, v);
- mValue[mUniform[index]] = vec;
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ LLVector4 vec(v[0],0.f,0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ {
+ glUniform1fvARB(mUniform[index], count, v);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
}
void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],v[1],0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
- {
- glUniform2fvARB(mUniform[index], count, v);
- mValue[mUniform[index]] = vec;
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ LLVector4 vec(v[0],v[1],0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ {
+ glUniform2fvARB(mUniform[index], count, v);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
}
void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],v[1],v[2],0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
- {
- glUniform3fvARB(mUniform[index], count, v);
- mValue[mUniform[index]] = vec;
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ LLVector4 vec(v[0],v[1],v[2],0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ {
+ glUniform3fvARB(mUniform[index], count, v);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
}
void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],v[1],v[2],v[3]);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
- {
- glUniform4fvARB(mUniform[index], count, v);
- mValue[mUniform[index]] = vec;
- }
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ LLVector4 vec(v[0],v[1],v[2],v[3]);
+ if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ {
+ glUniform4fvARB(mUniform[index], count, v);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
}
void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- glUniformMatrix2fvARB(mUniform[index], count, transpose, v);
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ glUniformMatrix2fvARB(mUniform[index], count, transpose, v);
+ }
+ }
}
void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- glUniformMatrix3fvARB(mUniform[index], count, transpose, v);
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ glUniformMatrix3fvARB(mUniform[index], count, transpose, v);
+ }
+ }
}
void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
{
- if (mProgramObject > 0)
- {
- if (mUniform.size() <= index)
- {
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
-
- if (mUniform[index] >= 0)
- {
- glUniformMatrix4fvARB(mUniform[index], count, transpose, v);
- }
- }
+ if (mProgramObject > 0)
+ {
+ if (mUniform.size() <= index)
+ {
+ UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ glUniformMatrix4fvARB(mUniform[index], count, transpose, v);
+ }
+ }
}
GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
{
- GLint ret = -1;
- if (mProgramObject > 0)
- {
- LLStaticStringTable<GLint>::iterator iter = mUniformMap.find(uniform);
- if (iter != mUniformMap.end())
- {
- if (gDebugGL)
- {
- stop_glerror();
- if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str()))
- {
- LL_ERRS() << "Uniform does not match." << LL_ENDL;
- }
- stop_glerror();
- }
- ret = iter->second;
- }
- }
-
- return ret;
+ GLint ret = -1;
+ if (mProgramObject > 0)
+ {
+ LLStaticStringTable<GLint>::iterator iter = mUniformMap.find(uniform);
+ if (iter != mUniformMap.end())
+ {
+ if (gDebugGL)
+ {
+ stop_glerror();
+ if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str()))
+ {
+ LL_ERRS() << "Uniform does not match." << LL_ENDL;
+ }
+ stop_glerror();
+ }
+ ret = iter->second;
+ }
+ }
+
+ return ret;
}
GLint LLGLSLShader::getUniformLocation(U32 index)
{
- GLint ret = -1;
- if (mProgramObject > 0)
- {
- llassert(index < mUniform.size());
- return mUniform[index];
- }
-
- return ret;
+ GLint ret = -1;
+ if (mProgramObject > 0)
+ {
+ llassert(index < mUniform.size());
+ return mUniform[index];
+ }
+
+ return ret;
}
GLint LLGLSLShader::getAttribLocation(U32 attrib)
{
- if (attrib < mAttribute.size())
- {
- return mAttribute[attrib];
- }
- else
- {
- return -1;
- }
+ if (attrib < mAttribute.size())
+ {
+ return mAttribute[attrib];
+ }
+ else
+ {
+ return -1;
+ }
}
void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(v,0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
- {
- glUniform1iARB(location, v);
- mValue[location] = vec;
- }
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ LLVector4 vec(v,0.f,0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec))
+ {
+ glUniform1iARB(location, v);
+ mValue[location] = vec;
+ }
+ }
}
void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(i,j,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
- {
- glUniform2iARB(location, i, j);
- mValue[location] = vec;
- }
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ LLVector4 vec(i,j,0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec))
+ {
+ glUniform2iARB(location, i, j);
+ mValue[location] = vec;
+ }
+ }
}
void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(v,0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
- {
- glUniform1fARB(location, v);
- mValue[location] = vec;
- }
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ LLVector4 vec(v,0.f,0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec))
+ {
+ glUniform1fARB(location, v);
+ mValue[location] = vec;
+ }
+ }
}
void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(x,y,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
- {
- glUniform2fARB(location, x,y);
- mValue[location] = vec;
- }
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ LLVector4 vec(x,y,0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec))
+ {
+ glUniform2fARB(location, x,y);
+ mValue[location] = vec;
+ }
+ }
}
void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(x,y,z,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
- {
- glUniform3fARB(location, x,y,z);
- mValue[location] = vec;
- }
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ LLVector4 vec(x,y,z,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec))
+ {
+ glUniform3fARB(location, x,y,z);
+ mValue[location] = vec;
+ }
+ }
}
void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(v[0],0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
- {
- glUniform1fvARB(location, count, v);
- mValue[location] = vec;
- }
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ LLVector4 vec(v[0],0.f,0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ {
+ glUniform1fvARB(location, count, v);
+ mValue[location] = vec;
+ }
+ }
}
void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(v[0],v[1],0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
- {
- glUniform2fvARB(location, count, v);
- mValue[location] = vec;
- }
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ LLVector4 vec(v[0],v[1],0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ {
+ glUniform2fvARB(location, count, v);
+ mValue[location] = vec;
+ }
+ }
}
void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(v[0],v[1],v[2],0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
- {
- glUniform3fvARB(location, count, v);
- mValue[location] = vec;
- }
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ LLVector4 vec(v[0],v[1],v[2],0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ {
+ glUniform3fvARB(location, count, v);
+ mValue[location] = vec;
+ }
+ }
}
void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- LLVector4 vec(v);
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
- {
- stop_glerror();
- glUniform4fvARB(location, count, v);
- stop_glerror();
- mValue[location] = vec;
- }
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ LLVector4 vec(v);
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ {
+ stop_glerror();
+ glUniform4fvARB(location, count, v);
+ stop_glerror();
+ mValue[location] = vec;
+ }
+ }
}
void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v)
{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- stop_glerror();
- glUniformMatrix4fvARB(location, count, transpose, v);
- stop_glerror();
- }
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ stop_glerror();
+ glUniformMatrix4fvARB(location, count, transpose, v);
+ stop_glerror();
+ }
}
void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
- if (mAttribute[index] > 0)
- {
- glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
- }
+ if (mAttribute[index] > 0)
+ {
+ glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
+ }
}
void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
{
- if (mAttribute[index] > 0)
- {
- glVertexAttrib4fvARB(mAttribute[index], v);
- }
+ if (mAttribute[index] > 0)
+ {
+ glVertexAttrib4fvARB(mAttribute[index], v);
+ }
}
void LLGLSLShader::setMinimumAlpha(F32 minimum)
{
- gGL.flush();
- uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum);
+ gGL.flush();
+ uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum);
}
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 388d3a4f1a..0af402efea 100755
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1168,7 +1168,7 @@ void LLRender::syncMatrices()
{
stop_glerror();
- U32 name[] =
+ static const U32 name[] =
{
LLShaderMgr::MODELVIEW_MATRIX,
LLShaderMgr::PROJECTION_MATRIX,
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index d06564df36..0fae600a90 100755
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -843,9 +843,11 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
LL_RECORD_BLOCK_TIME(FTM_GL_DRAW_ARRAYS);
stop_glerror();
- LLGLSLShader::startProfile();
+ LLGLSLShader::startProfile();
+ stop_glerror();
glDrawArrays(sGLMode[mode], first, count);
- LLGLSLShader::stopProfile(count, mode);
+ stop_glerror();
+ LLGLSLShader::stopProfile(count, mode);
}
stop_glerror();
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 7c88f8fb9b..6dd6f94d02 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -258,20 +258,19 @@ BOOL LLFolderViewItem::passedFilter(S32 filter_generation)
BOOL LLFolderViewItem::isPotentiallyVisible(S32 filter_generation)
{
- // Item should be visible if:
- // 1. item passed current filter
- // 2. item was updated (gen < 0) but has descendants that passed filter
- // 3. item was recently updated and was visible before update
-
- LLFolderViewModelItem* model = getViewModelItem();
- if (model->getLastFilterGeneration() < 0 && !getFolderViewModel()->getFilter().isModified())
+ if (filter_generation < 0)
{
- return model->descendantsPassedFilter(filter_generation) || getVisible();
+ filter_generation = getFolderViewModel()->getFilter().getFirstSuccessGeneration();
}
- else
+ LLFolderViewModelItem* model = getViewModelItem();
+ BOOL visible = model->passedFilter(filter_generation);
+ if (model->getMarkedDirtyGeneration() >= filter_generation)
{
- return model->passedFilter(filter_generation);
+ // unsure visibility state
+ // retaining previous visibility until item is updated or filter generation changes
+ visible |= getVisible();
}
+ return visible;
}
void LLFolderViewItem::refresh()
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 8d98363c5f..f6550eae42 100755
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -185,11 +185,13 @@ public:
virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) = 0;
virtual void setPassedFolderFilter(bool passed, S32 filter_generation) = 0;
virtual void dirtyFilter() = 0;
+ virtual void dirtyDescendantsFilter() = 0;
virtual bool hasFilterStringMatch() = 0;
virtual std::string::size_type getFilterStringOffset() = 0;
virtual std::string::size_type getFilterStringSize() = 0;
virtual S32 getLastFilterGeneration() const = 0;
+ virtual S32 getMarkedDirtyGeneration() const = 0;
virtual bool hasChildren() const = 0;
virtual void addChild(LLFolderViewModelItem* child) = 0;
@@ -230,6 +232,7 @@ public:
mFolderViewItem(NULL),
mLastFilterGeneration(-1),
mLastFolderFilterGeneration(-1),
+ mMarkedDirtyGeneration(-1),
mMostFilteredDescendantGeneration(-1),
mParent(NULL),
mRootViewModel(root_view_model)
@@ -243,8 +246,13 @@ public:
S32 getLastFilterGeneration() const { return mLastFilterGeneration; }
S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; }
+ S32 getMarkedDirtyGeneration() const { return mMarkedDirtyGeneration; }
void dirtyFilter()
{
+ if(mMarkedDirtyGeneration < 0)
+ {
+ mMarkedDirtyGeneration = mLastFilterGeneration;
+ }
mLastFilterGeneration = -1;
mLastFolderFilterGeneration = -1;
@@ -254,6 +262,14 @@ public:
mParent->dirtyFilter();
}
}
+ void dirtyDescendantsFilter()
+ {
+ mMostFilteredDescendantGeneration = -1;
+ if (mParent)
+ {
+ mParent->dirtyDescendantsFilter();
+ }
+ }
bool hasFilterStringMatch();
std::string::size_type getFilterStringOffset();
std::string::size_type getFilterStringSize();
@@ -272,7 +288,7 @@ public:
return;
}
}
- mChildren.push_back(child);
+ mChildren.push_back(child);
child->setParent(this);
dirtyFilter();
requestSort();
@@ -280,7 +296,8 @@ public:
virtual void removeChild(LLFolderViewModelItem* child)
{
mChildren.remove(child);
- child->setParent(NULL);
+ child->setParent(NULL);
+ dirtyDescendantsFilter();
dirtyFilter();
}
@@ -290,6 +307,7 @@ public:
// This is different and not equivalent to calling removeChild() on each child
std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
mChildren.clear();
+ dirtyDescendantsFilter();
dirtyFilter();
}
@@ -303,6 +321,7 @@ public:
mLastFilterGeneration = filter_generation;
mStringMatchOffsetFilter = string_offset;
mStringFilterSize = string_size;
+ mMarkedDirtyGeneration = -1;
}
void setPassedFolderFilter(bool passed, S32 filter_generation)
@@ -351,7 +370,8 @@ protected:
S32 mLastFilterGeneration,
mLastFolderFilterGeneration,
- mMostFilteredDescendantGeneration;
+ mMostFilteredDescendantGeneration,
+ mMarkedDirtyGeneration;
child_list_t mChildren;
LLFolderViewModelItem* mParent;
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index 75773d7dfd..6750ee482a 100755
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -505,7 +505,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
}
// Skip white space
- while( *cur && isspace(*cur) && (*cur != '\n') )
+ while( *cur && iswspace(*cur) && (*cur != '\n') )
{
cur++;
}
@@ -548,7 +548,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
}
// Skip white space
- while( *cur && isspace(*cur) && (*cur != '\n') )
+ while( *cur && iswspace(*cur) && (*cur != '\n') )
{
cur++;
}
@@ -655,10 +655,10 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
// check against words
llwchar prev = cur > base ? *(cur-1) : 0;
- if( !isalnum( prev ) && (prev != '_') )
+ if( !iswalnum( prev ) && (prev != '_') )
{
const llwchar* p = cur;
- while( isalnum( *p ) || (*p == '_') )
+ while( iswalnum( *p ) || (*p == '_') )
{
p++;
}
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 604dc92789..d3ed4a1286 100755
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1276,7 +1276,15 @@ void LLMenuItemBranchGL::openMenu()
{
// open upwards if menu extends past bottom
// adjust by the height of the menu item branch since it is a submenu
- delta_y = branch_rect.getHeight() - getRect().getHeight();
+ if (y + 2 * branch_rect.getHeight() - getRect().getHeight() > menu_region_rect.mTop)
+ {
+ // overlaps with top border, align with top
+ delta_y = menu_region_rect.mTop - y - branch_rect.getHeight();
+ }
+ else
+ {
+ delta_y = branch_rect.getHeight() - getRect().getHeight();
+ }
}
if( x + branch_rect.getWidth() > menu_region_rect.mRight )
@@ -3258,6 +3266,11 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect );
+ if (menu->getRect().mTop > menu_region_rect.mTop)
+ {
+ // not enough space: align with top, ignore exclusion
+ menu->translateIntoRect( menu_region_rect );
+ }
menu->getParent()->sendChildToFront(menu);
}
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index 1bd2bc06f4..303417c337 100755
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -638,7 +638,7 @@ void LLStatBar::drawLabelAndValue( F32 value, std::string &label, LLRect &bar_re
void LLStatBar::drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect )
{
- if (mAutoScaleMax || mAutoScaleMin)
+ if (!llisnan(min) && (mAutoScaleMax || mAutoScaleMin))
{
F32 u = LLSmoothInterpolation::getInterpolant(10.f);
mFloatingTargetMinBar = llmin(min, lerp(mFloatingTargetMinBar, min, u));
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 6f3122e7a1..be583c83d8 100755
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -178,6 +178,12 @@ bool LLUrlEntryBase::isLinkDisabled() const
return globally_disabled;
}
+bool LLUrlEntryBase::isWikiLinkCorrect(std::string url)
+{
+ std::string label = getLabelFromWikiLink(url);
+ return (LLUrlRegistry::instance().hasUrl(label)) ? false : true;
+}
+
static std::string getStringAfterToken(const std::string str, const std::string token)
{
size_t pos = str.find(token);
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index d4684e2e1e..ffcd45dfde 100755
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -100,6 +100,8 @@ public:
bool isLinkDisabled() const;
+ bool isWikiLinkCorrect(std::string url);
+
protected:
std::string getIDStringFromUrl(const std::string &url) const;
std::string escapeUrl(const std::string &url) const;
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index bccc646821..ef0789e0e4 100755
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -45,7 +45,8 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(mUrlEntryIcon);
registerUrl(new LLUrlEntrySLURL());
registerUrl(new LLUrlEntryHTTP());
- registerUrl(new LLUrlEntryHTTPLabel());
+ mUrlEntryHTTPLabel = new LLUrlEntryHTTPLabel();
+ registerUrl(mUrlEntryHTTPLabel);
registerUrl(new LLUrlEntryAgentCompleteName());
registerUrl(new LLUrlEntryAgentDisplayName());
registerUrl(new LLUrlEntryAgentUserName());
@@ -64,7 +65,8 @@ LLUrlRegistry::LLUrlRegistry()
//LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern,
//so it should be registered in the end of list
registerUrl(new LLUrlEntrySL());
- registerUrl(new LLUrlEntrySLLabel());
+ mUrlEntrySLLabel = new LLUrlEntrySLLabel();
+ registerUrl(mUrlEntrySLLabel);
// most common pattern is a URL without any protocol,
// e.g., "secondlife.com"
registerUrl(new LLUrlEntryHTTPNoProtocol());
@@ -128,6 +130,11 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en
end--;
}
+ else if (text[end] == ']' && std::string(text+start, end-start).find('[') == std::string::npos)
+ {
+ end--;
+ }
+
return true;
}
@@ -175,6 +182,15 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
// does this match occur in the string before any other match
if (start < match_start || match_entry == NULL)
{
+
+ if((mUrlEntryHTTPLabel == *it) || (mUrlEntrySLLabel == *it))
+ {
+ if(url_entry && !url_entry->isWikiLinkCorrect(text.substr(start, end - start + 1)))
+ {
+ continue;
+ }
+ }
+
match_start = start;
match_end = end;
match_entry = url_entry;
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index 6270df1bbb..1cb403dfc9 100755
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
@@ -94,6 +94,8 @@ private:
std::vector<LLUrlEntryBase *> mUrlEntry;
LLUrlEntryBase* mUrlEntryIcon;
+ LLUrlEntryBase* mUrlEntryHTTPLabel;
+ LLUrlEntryBase* mUrlEntrySLLabel;
};
#endif
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 77c8878f4b..9e6bebc93b 100755
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -885,7 +885,7 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
handled = handleKeyHere( key, mask );
if (handled)
{
- LL_WARNS() << "Key handled by " << getName() << LL_ENDL;
+ LL_DEBUGS() << "Key handled by " << getName() << LL_ENDL;
}
}
}
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index ff312945b6..24b8406098 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -124,6 +124,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowResized:) name:NSWindowDidResizeNotification
+ object:[self window]];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification
+ object:[self window]];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification
object:[self window]];
}
@@ -141,6 +149,16 @@ attributedStringInfo getSegments(NSAttributedString *str)
}
}
+- (void)windowWillMiniaturize:(NSNotification *)notification;
+{
+ callWindowHide();
+}
+
+- (void)windowDidDeminiaturize:(NSNotification *)notification;
+{
+ callWindowUnhide();
+}
+
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
@@ -349,9 +367,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
callMiddleMouseUp(mMousePos, [theEvent modifierFlags]);
}
+- (void) rightMouseDragged:(NSEvent *)theEvent
+{
+ [self mouseDragged:theEvent];
+}
+
- (void) otherMouseDragged:(NSEvent *)theEvent
{
-
+ [self mouseDragged:theEvent];
}
- (void) scrollWheel:(NSEvent *)theEvent
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index d64525fbdd..f02052ca6a 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -116,6 +116,8 @@ void callScrollMoved(float delta);
void callMouseExit();
void callWindowFocus();
void callWindowUnfocus();
+void callWindowHide();
+void callWindowUnhide();
void callDeltaUpdate(float *delta, unsigned int mask);
void callMiddleMouseDown(float *pos, unsigned int mask);
void callMiddleMouseUp(float *pos, unsigned int mask);
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index aca8bb6527..d7aa47f378 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -352,6 +352,22 @@ void callWindowUnfocus()
gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
}
+void callWindowHide()
+{
+ if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
+ {
+ gWindowImplementation->getCallbacks()->handleActivate(gWindowImplementation, false);
+ }
+}
+
+void callWindowUnhide()
+{
+ if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
+ {
+ gWindowImplementation->getCallbacks()->handleActivate(gWindowImplementation, true);
+ }
+}
+
void callDeltaUpdate(float *delta, MASK mask)
{
gWindowImplementation->updateMouseDeltas(delta);
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index b49c354524..f36181278b 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.7.22
+3.7.24
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ca74b759ff..138bdde9e9 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6186,7 +6186,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>30.0</real>
+ <real>600.0</real>
</map>
<key>MemoryPrivatePoolEnabled</key>
<map>
@@ -13569,6 +13569,28 @@
<key>Value</key>
<string>0</string>
</map>
+ <key>VivoxLogDirectory</key>
+ <map>
+ <key>Comment</key>
+ <string>Default log path is Application Support/SecondLife/logs specify alternate absolute path here.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string></string>
+ </map>
+ <key>VivoxShutdownTimeout</key>
+ <map>
+ <key>Comment</key>
+ <string>shutdown timeout in miliseconds. The amount of time to wait for the service to shutdown gracefully after the last disconnect</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>5</string>
+ </map>
<key>VivoxDebugSIPURIHostName</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
index b40785bbd7..506118d381 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
@@ -111,10 +111,9 @@ void main()
#ifdef USE_INDEXED_TEX
passTextureIndex();
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-#else
- vary_texcoord0 = texcoord0;
#endif
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vary_norm = norm;
vary_position = pos.xyz;
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index e5a90e8a28..5cb03cd2ae 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3808,6 +3808,10 @@ void LLAgent::restartFailedTeleportRequest()
void LLAgent::clearTeleportRequest()
{
+ if(LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->setHidden(FALSE);
+ }
mTeleportRequest.reset();
}
@@ -3826,6 +3830,10 @@ bool LLAgent::hasPendingTeleportRequest()
void LLAgent::startTeleportRequest()
{
+ if(LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->setHidden(TRUE);
+ }
if (hasPendingTeleportRequest())
{
if (!isMaturityPreferenceSyncedWithServer())
@@ -3871,6 +3879,11 @@ void LLAgent::handleTeleportFinished()
void LLAgent::handleTeleportFailed()
{
+ if(LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->setHidden(FALSE);
+ }
+
if (mTeleportRequest != NULL)
{
mTeleportRequest->setStatus(LLTeleportRequest::kFailed);
@@ -4116,8 +4129,8 @@ void LLAgent::stopCurrentAnimations()
anim_it != gAgentAvatarp->mPlayingAnimations.end();
anim_it++)
{
- if (anim_it->first ==
- ANIM_AGENT_SIT_GROUND_CONSTRAINED)
+ if ((anim_it->first == ANIM_AGENT_DO_NOT_DISTURB)||
+ (anim_it->first == ANIM_AGENT_SIT_GROUND_CONSTRAINED))
{
// don't cancel a ground-sit anim, as viewers
// use this animation's status in
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 49fedb8df8..f06ffb4fb3 100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1009,6 +1009,10 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
continue;
}
+ // Don't care about this case - ordering of wearables with the same asset id has no effect.
+ // Causes the two-alphas error case in MAINT-4158.
+ // We should actually disallow wearing two wearables with the same asset id.
+#if 0
if (curr_wearable->getName() != new_item->getName() ||
curr_wearable->getItemID() != new_item->getUUID())
{
@@ -1019,6 +1023,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
mismatched++;
continue;
}
+#endif
// If we got here, everything matches.
matched++;
}
@@ -1083,7 +1088,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (isAgentAvatarValid())
{
gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
- gAgentAvatarp->updateVisualParams();
// If we have not yet declouded, we may want to use
// baked texture UUIDs sent from the first objectUpdate message
@@ -1101,6 +1105,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
notifyLoadingFinished();
+ // Copy wearable params to avatar.
+ gAgentAvatarp->writeWearablesToAvatar();
+
+ // Then update the avatar based on the copied params.
+ gAgentAvatarp->updateVisualParams();
+
gAgentAvatarp->dumpAvatarTEs("setWearableOutfit");
LL_DEBUGS("Avatar") << "setWearableOutfit() end" << LL_ENDL;
@@ -1243,9 +1253,12 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty
}
}
-// Combines userRemoveMulipleAttachments() and userAttachMultipleAttachments() logic to
-// get attachments into desired state with minimal number of adds/removes.
-void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
+// Given a desired set of attachments, find what objects need to be
+// removed, and what additional inventory items need to be added.
+void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array,
+ llvo_vec_t& objects_to_remove,
+ llvo_vec_t& objects_to_retain,
+ LLInventoryModel::item_array_t& items_to_add)
{
// Possible cases:
// already wearing but not in request set -> take off.
@@ -1264,7 +1277,6 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
}
// Build up list of objects to be removed and items currently attached.
- llvo_vec_t objects_to_remove;
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
iter != gAgentAvatarp->mAttachmentPoints.end();)
{
@@ -1299,12 +1311,12 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
{
// LL_INFOS() << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL;
current_item_ids.insert(object_item_id);
+ objects_to_retain.push_back(objectp);
}
}
}
}
- LLInventoryModel::item_array_t items_to_add;
for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin();
it != obj_item_array.end();
++it)
@@ -1323,12 +1335,6 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
// S32 remove_count = objects_to_remove.size();
// S32 add_count = items_to_add.size();
// LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL;
-
- // Remove everything in objects_to_remove
- userRemoveMultipleAttachments(objects_to_remove);
-
- // Add everything in items_to_add
- userAttachMultipleAttachments(items_to_add);
}
void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove)
@@ -1348,6 +1354,7 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
++it)
{
LLViewerObject *objectp = *it;
+ //gAgentAvatarp->resetJointPositionsOnDetach(objectp);
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
}
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index cdb1bdbe05..1004482020 100755
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -178,7 +178,10 @@ public:
typedef std::vector<LLViewerObject*> llvo_vec_t;
- static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
+ static void findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array,
+ llvo_vec_t& objects_to_remove,
+ llvo_vec_t& objects_to_retain,
+ LLInventoryModel::item_array_t& items_to_add);
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index 96de15bf75..9d887a61f1 100755
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -34,6 +34,7 @@
#include "llsdutil.h"
#include "llviewerregion.h"
#include "llinventoryobserver.h"
+#include "llviewercontrol.h"
///----------------------------------------------------------------------------
/// Classes for AISv3 support.
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index aad5dbae7d..549df80fa1 100644..100755
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -84,7 +84,17 @@
callWindowUnfocus();
}
-- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender
+- (void) applicationDidHide:(NSNotification *)notification
+{
+ callWindowHide();
+}
+
+- (void) applicationDidUnhide:(NSNotification *)notification
+{
+ callWindowUnhide();
+}
+
+- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender
{
if (!runMainLoop())
{
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 29534a4382..d7ef5fcba7 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -807,15 +807,48 @@ void LLWearableHoldingPattern::onAllComplete()
}
}
- // Update wearables.
- LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with " << mResolved << " wearable items " << LL_ENDL;
- LLAppearanceMgr::instance().updateAgentWearables(this);
-
- // Update attachments to match those requested.
if (isAgentAvatarValid())
{
LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL;
- LLAgentWearables::userUpdateAttachments(mObjItems);
+ LLAgentWearables::llvo_vec_t objects_to_remove;
+ LLAgentWearables::llvo_vec_t objects_to_retain;
+ LLInventoryModel::item_array_t items_to_add;
+
+ LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems,
+ objects_to_remove,
+ objects_to_retain,
+ items_to_add);
+
+ LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size()
+ << " attachments" << LL_ENDL;
+
+ // Here we remove the attachment pos overrides for *all*
+ // attachments, even those that are not being removed. This is
+ // needed to get joint positions all slammed down to their
+ // pre-attachment states.
+ gAgentAvatarp->clearAttachmentPosOverrides();
+
+ // Take off the attachments that will no longer be in the outfit.
+ LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
+
+ // Update wearables.
+ LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with "
+ << mResolved << " wearable items " << LL_ENDL;
+ LLAppearanceMgr::instance().updateAgentWearables(this);
+
+ // Restore attachment pos overrides for the attachments that
+ // are remaining in the outfit.
+ for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin();
+ it != objects_to_retain.end();
+ ++it)
+ {
+ LLViewerObject *objectp = *it;
+ gAgentAvatarp->addAttachmentPosOverridesForObject(objectp);
+ }
+
+ // Add new attachments to match those requested.
+ LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
+ LLAgentWearables::userAttachMultipleAttachments(items_to_add);
}
if (isFetchCompleted() && isMissingCompleted())
@@ -2699,7 +2732,12 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInve
const LLInventoryItem* item = item_array.at(i).get();
if (item->getIsLinkType() && item->getLinkedUUID() == item_id)
{
- remove_inventory_item(item->getUUID(), cb);
+ bool immediate_delete = false;
+ if (item->getType() == LLAssetType::AT_OBJECT)
+ {
+ immediate_delete = true;
+ }
+ remove_inventory_item(item->getUUID(), cb, immediate_delete);
}
}
}
@@ -4056,17 +4094,33 @@ public:
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
- LLPointer<LLInventoryCategory> category = new LLInventoryCategory(query_map["folder_id"],
- LLUUID::null,
- LLFolderType::FT_CLOTHING,
- "Quick Appearance");
- LLSD::UUID folder_uuid = query_map["folder_id"].asUUID();
- if ( gInventory.getCategory( folder_uuid ) != NULL )
- {
- LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
+ LLSD::UUID folder_uuid;
- // *TODOw: This may not be necessary if initial outfit is chosen already -- josh
- gAgent.setOutfitChosen(TRUE);
+ if (folder_uuid.isNull() && query_map.has("folder_name"))
+ {
+ std::string outfit_folder_name = query_map["folder_name"];
+ folder_uuid = findDescendentCategoryIDByName(
+ gInventory.getLibraryRootFolderID(),
+ outfit_folder_name);
+ }
+ if (folder_uuid.isNull() && query_map.has("folder_id"))
+ {
+ folder_uuid = query_map["folder_id"].asUUID();
+ }
+
+ if (folder_uuid.notNull())
+ {
+ LLPointer<LLInventoryCategory> category = new LLInventoryCategory(folder_uuid,
+ LLUUID::null,
+ LLFolderType::FT_CLOTHING,
+ "Quick Appearance");
+ if ( gInventory.getCategory( folder_uuid ) != NULL )
+ {
+ LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
+
+ // *TODOw: This may not be necessary if initial outfit is chosen already -- josh
+ gAgent.setOutfitChosen(TRUE);
+ }
}
// release avatar picker keyboard focus
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3a5008507a..f6b6c71cfc 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -4896,7 +4896,10 @@ void LLAppViewer::idle()
// Handle the regular UI idle callbacks as well as
// hover callbacks
//
-
+
+#ifdef LL_DARWIN
+ if (!mQuitRequested) //MAINT-4243
+#endif
{
// LL_RECORD_BLOCK_TIME(FTM_IDLE_CB);
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 5b151bdcda..f74164aea6 100755
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -443,7 +443,7 @@ void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_
}
}
-void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
+void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
{
if (params.mModelMatrix != gGLLastMatrix)
{
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 3bde0d29be..bc299cc89f 100755
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -168,7 +168,7 @@ public:
BOOL isDead() { return FALSE; }
void resetDrawOrders() { }
- static void applyModelMatrix(LLDrawInfo& params);
+ static void applyModelMatrix(const LLDrawInfo& params);
virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index e7420f32f0..ab96201a63 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -375,7 +375,7 @@ void LLDrawPoolAvatar::endPostDeferredAlpha()
void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
{
- const S32 actual_pass[] =
+ static const S32 actual_pass[] =
{ //map post deferred pass numbers to what render() expects
2, //skinned
4, // rigged fullbright
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 514411aef5..f92320490a 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -96,7 +96,7 @@ void LLDrawPoolMaterials::endDeferredPass(S32 pass)
void LLDrawPoolMaterials::renderDeferred(S32 pass)
{
- U32 type_list[] =
+ static const U32 type_list[] =
{
LLRenderPass::PASS_MATERIAL,
//LLRenderPass::PASS_MATERIAL_ALPHA,
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 4db0422634..d89599cb45 100755
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -76,9 +76,6 @@ const char FEATURE_TABLE_FILENAME[] = "featuretable%s.txt";
const char FEATURE_TABLE_VER_FILENAME[] = "featuretable%s.%s.txt";
#endif
-const char GPU_TABLE_FILENAME[] = "gpu_table.txt";
-const char GPU_TABLE_VER_FILENAME[] = "gpu_table.%s.txt";
-
LLFeatureInfo::LLFeatureInfo(const std::string& name, const BOOL available, const F32 level)
: mValid(TRUE), mName(name), mAvailable(available), mRecommendedLevel(level)
{
@@ -428,6 +425,7 @@ bool LLFeatureManager::loadGPUClass()
{ //couldn't bench, use GLVersion
#if LL_DARWIN
//GLVersion is misleading on OSX, just default to class 3 if we can't bench
+ LL_WARNS() << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL;
mGPUClass = GPU_CLASS_3;
#else
if (gGLManager.mGLVersion < 2.f)
@@ -452,23 +450,31 @@ bool LLFeatureManager::loadGPUClass()
}
#endif
}
- else if (gbps < 5.f)
+ else if (gGLManager.mGLVersion <= 2.f)
+ {
+ mGPUClass = GPU_CLASS_0;
+ }
+ else if (gGLManager.mGLVersion <= 3.f)
+ {
+ mGPUClass = GPU_CLASS_1;
+ }
+ else if (gbps <= 5.f)
{
mGPUClass = GPU_CLASS_0;
}
- else if (gbps < 10.f)
+ else if (gbps <= 8.f)
{
mGPUClass = GPU_CLASS_1;
}
- else if (gbps < 20.f)
+ else if (gbps <= 16.f)
{
mGPUClass = GPU_CLASS_2;
}
- else if (gbps < 40.f)
+ else if (gbps <= 40.f)
{
mGPUClass = GPU_CLASS_3;
}
- else if (gbps < 80.f)
+ else if (gbps <= 80.f)
{
mGPUClass = GPU_CLASS_4;
}
@@ -476,195 +482,15 @@ bool LLFeatureManager::loadGPUClass()
{
mGPUClass = GPU_CLASS_5;
}
-
+
// defaults
mGPUString = gGLManager.getRawGLString();
mGPUSupported = TRUE;
-#if 0
- // first table is in the app dir
- std::string app_path = gDirUtilp->getAppRODataDir();
- app_path += gDirUtilp->getDirDelimiter();
- app_path += GPU_TABLE_FILENAME;
-
- // second table is downloaded with HTTP
- std::string http_filename = llformat(GPU_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
- std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
-
- // use HTTP table if it exists
- std::string path;
- bool parse_ok = false;
- if (gDirUtilp->fileExists(http_path))
- {
- parse_ok = parseGPUTable(http_path);
- if (!parse_ok)
- {
- // the HTTP table failed to parse, so delete it
- LLFile::remove(http_path);
- LL_WARNS("RenderInit") << "Removed invalid gpu table '" << http_path << "'" << LL_ENDL;
- }
- }
-
- if (!parse_ok)
- {
- parse_ok = parseGPUTable(app_path);
- }
-#endif
- return true; // indicates that the file parsed correctly, not that the gpu was recognized
+ return true; // indicates that a gpu value was established
}
-bool LLFeatureManager::parseGPUTable(std::string filename)
-{
- llifstream file;
-
- LL_INFOS("RenderInit") << "Attempting to parse GPU table from " << filename << LL_ENDL;
- file.open(filename);
-
- if (file)
- {
- const char recognizer[] = "//GPU_TABLE";
- char first_line[MAX_STRING];
- file.getline(first_line, MAX_STRING);
- if (0 != strncmp(first_line, recognizer, strlen(recognizer)))
- {
- LL_WARNS("RenderInit") << "Invalid GPU table: " << filename << "!" << LL_ENDL;
- return false;
- }
- }
- else
- {
- LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL;
- return false;
- }
-
- std::string rawRenderer = gGLManager.getRawGLString();
- std::string renderer = rawRenderer;
- for (std::string::iterator i = renderer.begin(); i != renderer.end(); ++i)
- {
- *i = tolower(*i);
- }
-
-#if LL_EXPORT_GPU_TABLE
- llofstream json;
- json.open("gpu_table.json");
-
- json << "var gpu_table = [" << std::endl;
-#endif
-
- bool gpuFound;
- U32 lineNumber;
- for (gpuFound = false, lineNumber = 0; !gpuFound && !file.eof(); lineNumber++)
- {
- char buffer[MAX_STRING]; /*Flawfinder: ignore*/
- buffer[0] = 0;
-
- file.getline(buffer, MAX_STRING);
-
- if (strlen(buffer) >= 2 && /*Flawfinder: ignore*/
- buffer[0] == '/' &&
- buffer[1] == '/')
- {
- // This is a comment.
- continue;
- }
-
- if (strlen(buffer) == 0) /*Flawfinder: ignore*/
- {
- // This is a blank line
- continue;
- }
-
- // setup the tokenizer
- std::string buf(buffer);
- std::string cls, label, expr, supported, stats_based, expected_gl_version;
- boost_tokenizer tokens(buf, boost::char_separator<char>("\t\n"));
- boost_tokenizer::iterator token_iter = tokens.begin();
-
- // grab the label, pseudo regular expression, and class
- if(token_iter != tokens.end())
- {
- label = *token_iter++;
- }
- if(token_iter != tokens.end())
- {
- expr = *token_iter++;
- }
- if(token_iter != tokens.end())
- {
- cls = *token_iter++;
- }
- if(token_iter != tokens.end())
- {
- supported = *token_iter++;
- }
- if (token_iter != tokens.end())
- {
- stats_based = *token_iter++;
- }
- if (token_iter != tokens.end())
- {
- expected_gl_version = *token_iter++;
- }
-
- if (label.empty() || expr.empty() || cls.empty() || supported.empty())
- {
- LL_WARNS("RenderInit") << "invald gpu_table.txt:" << lineNumber << ": '" << buffer << "'" << LL_ENDL;
- continue;
- }
-#if LL_EXPORT_GPU_TABLE
- json << "{'label' : '" << label << "',\n" <<
- "'regexp' : '" << expr << "',\n" <<
- "'class' : '" << cls << "',\n" <<
- "'supported' : '" << supported << "',\n" <<
- "'stats_based' : " << stats_based << ",\n" <<
- "'gl_version' : " << expected_gl_version << "\n},\n";
-#endif
-
- for (U32 i = 0; i < expr.length(); i++) /*Flawfinder: ignore*/
- {
- expr[i] = tolower(expr[i]);
- }
-
- // run the regular expression against the renderer
- boost::regex re(expr.c_str());
- if(boost::regex_search(renderer, re))
- {
- // if we found it, stop!
-#if !LL_EXPORT_GPU_TABLE
- gpuFound = true;
-#endif
- mGPUString = label;
- mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10);
- mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10);
- sscanf(expected_gl_version.c_str(), "%f", &mExpectedGLVersion);
- }
- }
-#if LL_EXPORT_GPU_TABLE
- json << "];\n\n";
- json.close();
-#endif
- file.close();
-
- if ( gpuFound )
- {
- LL_INFOS("RenderInit") << "GPU '" << rawRenderer << "' recognized as '" << mGPUString << "'" << LL_ENDL;
- if (!mGPUSupported)
- {
- LL_INFOS("RenderInit") << "GPU '" << mGPUString << "' is not supported." << LL_ENDL;
- }
- }
- else
- {
- LL_WARNS("RenderInit") << "GPU '" << rawRenderer << "' not recognized" << LL_ENDL;
- }
-
-#if LL_DARWIN // never go over "Mid" settings by default on OS X
- mGPUClass = llmin(mGPUClass, GPU_CLASS_2);
-#endif
- return true;
-}
-
// responder saves table into file
class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder
{
@@ -745,26 +571,11 @@ void fetch_feature_table(std::string table)
LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
}
-void fetch_gpu_table(std::string table)
-{
- const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
-
- const std::string filename = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
-
- const std::string url = base + "/" + filename;
-
- const std::string path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
-
- LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL;
-
- LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
-}
// fetch table(s) from a website (S3)
void LLFeatureManager::fetchHTTPTables()
{
fetch_feature_table(FEATURE_TABLE_VER_FILENAME);
- fetch_gpu_table(GPU_TABLE_VER_FILENAME);
}
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 95141b241d..69078ccc21 100755
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -162,9 +162,6 @@ protected:
bool parseFeatureTable(std::string filename);
///< @returns TRUE is file parsed correctly, FALSE if not
- bool parseGPUTable(std::string filename);
- ///< @returns true if file parsed correctly, false if not - does not reflect whether or not the gpu was recognized
-
void initBaseMask();
diff --git a/indra/newview/llflickrconnect.cpp b/indra/newview/llflickrconnect.cpp
index b715896264..b75660ea00 100644
--- a/indra/newview/llflickrconnect.cpp
+++ b/indra/newview/llflickrconnect.cpp
@@ -400,7 +400,7 @@ void LLFlickrConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std::
}
else
{
- llwarns << "Image to upload is not a PNG or JPEG" << llendl;
+ LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
return;
}
diff --git a/indra/newview/llfloatergroupbulkban.cpp b/indra/newview/llfloatergroupbulkban.cpp
index 54a2283b13..44074047a7 100644
--- a/indra/newview/llfloatergroupbulkban.cpp
+++ b/indra/newview/llfloatergroupbulkban.cpp
@@ -101,7 +101,7 @@ void LLFloaterGroupBulkBan::showForGroup(const LLUUID& group_id, uuid_vec_t* age
// Make sure group_id isn't null
if (group_id.isNull())
{
- llwarns << "LLFloaterGroupInvite::showForGroup with null group_id!" << llendl;
+ LL_WARNS() << "LLFloaterGroupInvite::showForGroup with null group_id!" << LL_ENDL;
return;
}
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index fbdaca0e6f..2864f018b2 100755
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -47,7 +47,7 @@
const F32 REFRESH_INTERVAL = 1.0f;
LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
-: LLTransientDockableFloater(NULL, true, session_id),
+: LLTransientDockableFloater(NULL, false, session_id),
mIsP2PChat(false),
mExpandCollapseBtn(NULL),
mTearOffBtn(NULL),
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index b17ce97a2e..0c81ab7e79 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1935,7 +1935,9 @@ bool LLModelLoader::doLoadModel()
LLJoint* pJoint = mPreview->getPreviewAvatar()->getJoint( lookingForJoint );
if ( pJoint )
{
- pJoint->storeCurrentXform( jointTransform.getTranslation() );
+ LLUUID fake_mesh_id;
+ fake_mesh_id.generate();
+ pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, gAgentAvatarp->avString());
}
else
{
@@ -3242,7 +3244,11 @@ U32 LLModelPreview::calcResourceCost()
if ( mFMP && mFMP->childGetValue("upload_joints").asBoolean() )
{
- getPreviewAvatar()->setPelvisOffset( mPelvisZOffset );
+ // FIXME if preview avatar ever gets reused, this fake mesh ID stuff will fail.
+ // see also call to addAttachmentPosOverride.
+ LLUUID fake_mesh_id;
+ fake_mesh_id.generate();
+ getPreviewAvatar()->addPelvisFixup( mPelvisZOffset, fake_mesh_id );
}
F32 streaming_cost = 0.f;
diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 9986bdbd7f..ef746d308d 100755
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -58,6 +58,8 @@ LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key)
{
mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this));
mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this));
+ mCommitCallbackRegistrar.add("OpenObject.ReplaceOutfit", boost::bind(&LLFloaterOpenObject::onClickReplace, this));
+ mCommitCallbackRegistrar.add("OpenObject.Cancel", boost::bind(&LLFloaterOpenObject::onClickCancel, this));
}
LLFloaterOpenObject::~LLFloaterOpenObject()
@@ -115,6 +117,7 @@ void LLFloaterOpenObject::refresh()
getChild<LLUICtrl>("object_name")->setTextArg("[DESC]", name);
getChildView("copy_to_inventory_button")->setEnabled(enabled);
getChildView("copy_and_wear_button")->setEnabled(enabled);
+ getChildView("copy_and_replace_button")->setEnabled(enabled);
}
@@ -135,7 +138,7 @@ void LLFloaterOpenObject::dirty()
-void LLFloaterOpenObject::moveToInventory(bool wear)
+void LLFloaterOpenObject::moveToInventory(bool wear, bool replace)
{
if (mObjectSelection->getRootObjectCount() != 1)
{
@@ -163,7 +166,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
parent_category_id = gInventory.getRootFolderID();
}
- inventory_func_type func = boost::bind(LLFloaterOpenObject::callbackCreateInventoryCategory,_1,object_id,wear);
+ inventory_func_type func = boost::bind(LLFloaterOpenObject::callbackCreateInventoryCategory,_1,object_id,wear,replace);
LLUUID category_id = gInventory.createNewCategory(parent_category_id,
LLFolderType::FT_NONE,
name,
@@ -177,6 +180,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
data->mCatID = category_id;
data->mWear = wear;
data->mFolderResponded = false;
+ data->mReplace = replace;
// Copy and/or move the items into the newly created folder.
// Ignore any "you're going to break this item" messages.
@@ -194,13 +198,14 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
}
// static
-void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear)
+void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace)
{
LLCatAndWear* wear_data = new LLCatAndWear;
wear_data->mCatID = category_id;
wear_data->mWear = wear;
wear_data->mFolderResponded = true;
+ wear_data->mReplace = replace;
// Copy and/or move the items into the newly created folder.
// Ignore any "you're going to break this item" messages.
@@ -241,7 +246,17 @@ void LLFloaterOpenObject::onClickMoveToInventory()
void LLFloaterOpenObject::onClickMoveAndWear()
{
- moveToInventory(true);
+ moveToInventory(true, false);
closeFloater();
}
+void LLFloaterOpenObject::onClickReplace()
+{
+ moveToInventory(true, true);
+ closeFloater();
+}
+
+void LLFloaterOpenObject::onClickCancel()
+{
+ closeFloater();
+}
diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h
index 8e472804a4..2e761f99bf 100755
--- a/indra/newview/llfloateropenobject.h
+++ b/indra/newview/llfloateropenobject.h
@@ -50,6 +50,7 @@ public:
LLUUID mCatID;
bool mWear;
bool mFolderResponded;
+ bool mReplace;
};
protected:
@@ -59,11 +60,13 @@ protected:
void draw();
virtual void onOpen(const LLSD& key);
- void moveToInventory(bool wear);
+ void moveToInventory(bool wear, bool replace = false);
void onClickMoveToInventory();
void onClickMoveAndWear();
- static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear);
+ void onClickReplace();
+ void onClickCancel();
+ static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace = false);
static void callbackMoveInventory(S32 result, void* data);
private:
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index f0c010b545..a4d13ce1d5 100755
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -40,8 +40,10 @@
#include "lltextbox.h"
#include "lllineeditor.h"
#include "llmutelist.h"
+#include "llnotificationsutil.h"
#include "llfloaterreporter.h"
#include "llslurl.h"
+#include "llstatusbar.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
@@ -90,6 +92,9 @@ public:
static void payDirectly(money_callback callback,
const LLUUID& target_id,
bool is_group);
+ static bool payConfirmationCallback(const LLSD& notification,
+ const LLSD& response,
+ LLGiveMoneyInfo* info);
private:
static void onCancel(void* data);
@@ -111,14 +116,12 @@ protected:
LLGiveMoneyInfo* mQuickPayInfo[MAX_PAY_BUTTONS];
LLSafeHandle<LLObjectSelection> mObjectSelection;
-
- static S32 sLastAmount;
};
-S32 LLFloaterPay::sLastAmount = 0;
const S32 MAX_AMOUNT_LENGTH = 10;
const S32 FASTPAY_BUTTON_WIDTH = 80;
+const S32 PAY_AMOUNT_NOTIFICATION = 200;
LLFloaterPay::LLFloaterPay(const LLSD& key)
: LLFloater(key),
@@ -188,17 +191,9 @@ BOOL LLFloaterPay::postBuild()
getChildView("amount text")->setVisible(FALSE);
-
- std::string last_amount;
- if(sLastAmount > 0)
- {
- last_amount = llformat("%d", sLastAmount);
- }
-
getChildView("amount")->setVisible(FALSE);
getChild<LLLineEditor>("amount")->setKeystrokeCallback(&LLFloaterPay::onKeystroke, this);
- getChild<LLUICtrl>("amount")->setValue(last_amount);
getChild<LLLineEditor>("amount")->setPrevalidate(LLTextValidate::validateNonNegativeS32);
info = new LLGiveMoneyInfo(this, 0);
@@ -207,7 +202,7 @@ BOOL LLFloaterPay::postBuild()
childSetAction("pay btn",&LLFloaterPay::onGive,info);
setDefaultBtn("pay btn");
getChildView("pay btn")->setVisible(FALSE);
- getChildView("pay btn")->setEnabled((sLastAmount > 0));
+ getChildView("pay btn")->setEnabled(FALSE);
childSetAction("cancel btn",&LLFloaterPay::onCancel,this);
@@ -419,7 +414,24 @@ void LLFloaterPay::payDirectly(money_callback callback,
floater->finishPayUI(target_id, is_group);
}
-
+
+bool LLFloaterPay::payConfirmationCallback(const LLSD& notification, const LLSD& response, LLGiveMoneyInfo* info)
+{
+ if (!info || !info->mFloater)
+ {
+ return false;
+ }
+
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ info->mFloater->give(info->mAmount);
+ info->mFloater->closeFloater();
+ }
+
+ return false;
+}
+
void LLFloaterPay::finishPayUI(const LLUUID& target_id, BOOL is_group)
{
std::string slurl;
@@ -470,10 +482,40 @@ void LLFloaterPay::onKeystroke(LLLineEditor*, void* data)
void LLFloaterPay::onGive(void* data)
{
LLGiveMoneyInfo* info = reinterpret_cast<LLGiveMoneyInfo*>(data);
- if(info && info->mFloater)
+ LLFloaterPay* floater = info->mFloater;
+ if(info && floater)
{
- info->mFloater->give(info->mAmount);
- info->mFloater->closeFloater();
+ S32 amount = info->mAmount;
+ if(amount == 0)
+ {
+ amount = atoi(floater->getChild<LLUICtrl>("amount")->getValue().asString().c_str());
+ }
+ if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount)
+ {
+ LLUUID payee_id;
+ BOOL is_group;
+ if (floater->mObjectSelection.notNull())
+ {
+ LLSelectNode* node = floater->mObjectSelection->getFirstRootNode();
+ node->mPermissions->getOwnership(payee_id, is_group);
+ }
+ else
+ {
+ is_group = floater->mTargetIsGroup;
+ payee_id = floater->mTargetUUID;
+ }
+
+ LLSD args;
+ args["TARGET"] = LLSLURL( is_group ? "group" : "agent", payee_id, "completename").getSLURLString();
+ args["AMOUNT"] = amount;
+
+ LLNotificationsUtil::add("PayConfirmation", args, LLSD(), boost::bind(&LLFloaterPay::payConfirmationCallback, _1, _2, info));
+ }
+ else
+ {
+ floater->give(amount);
+ floater->closeFloater();
+ }
}
}
@@ -487,7 +529,6 @@ void LLFloaterPay::give(S32 amount)
{
amount = atoi(getChild<LLUICtrl>("amount")->getValue().asString().c_str());
}
- sLastAmount = amount;
// Try to pay an object.
if (mObjectSelection.notNull())
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index 3f3d87b564..024e315632 100755
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -293,6 +293,7 @@ void LLFloaterWebContent::onOpen(const LLSD& key)
void LLFloaterWebContent::onClose(bool app_quitting)
{
// If we close the web browsing window showing the facebook login, we need to signal to this object that the connection will not happen
+ // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
LLFloater* fbc_web = LLFloaterReg::findInstance("fbc_web");
if (fbc_web == this)
{
@@ -302,7 +303,8 @@ void LLFloaterWebContent::onClose(bool app_quitting)
}
}
// Same with Flickr
- LLFloater* flickr_web = LLFloaterReg::getInstance("flickr_web");
+ // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
+ LLFloater* flickr_web = LLFloaterReg::findInstance("flickr_web");
if (flickr_web == this)
{
if (!LLFlickrConnect::instance().isConnected())
@@ -311,7 +313,8 @@ void LLFloaterWebContent::onClose(bool app_quitting)
}
}
// And Twitter
- LLFloater* twitter_web = LLFloaterReg::getInstance("twitter_web");
+ // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
+ LLFloater* twitter_web = LLFloaterReg::findInstance("twitter_web");
if (twitter_web == this)
{
if (!LLTwitterConnect::instance().isConnected())
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index 7615c12043..3271a40ea0 100755
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -129,13 +129,18 @@ void LLFolderViewModelItemInventory::requestSort()
void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size)
{
+ bool generation_skip = mMarkedDirtyGeneration >= 0
+ && mPrevPassedAllFilters
+ && mMarkedDirtyGeneration < mRootViewModel.getFilter().getFirstSuccessGeneration();
LLFolderViewModelItemCommon::setPassedFilter(passed, filter_generation, string_offset, string_size);
bool before = mPrevPassedAllFilters;
mPrevPassedAllFilters = passedFilter(filter_generation);
- if (before != mPrevPassedAllFilters)
+ if (before != mPrevPassedAllFilters || generation_skip)
{
- // Need to rearrange the folder if the filtered state of the item changed
+ // Need to rearrange the folder if the filtered state of the item changed,
+ // previously passed item skipped filter generation changes while being dirty
+ // or previously passed not yet filtered item was marked dirty
LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder();
if (parent_folder)
{
@@ -144,6 +149,9 @@ void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_gen
}
}
+
+
+
bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
{
S32 filter_generation = filter.getCurrentGeneration();
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 4b8ac2b3cf..64f796e1fd 100755
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -881,13 +881,14 @@ void LLViewerObjectList::renderObjectBeacons()
F32 gpu_benchmark()
{
- if (!gGLManager.mHasShaderObjects)
- { //don't bother benchmarking the fixed function
+ if (!gGLManager.mHasShaderObjects || !gGLManager.mHasTimerQuery)
+ { // don't bother benchmarking the fixed function
+ // or venerable drivers which don't support accurate timing anyway
+ // and are likely to be correctly identified by the GPU table already.
return -1.f;
}
-
- if (gBenchmarkProgram.mProgramObject == 0)
+ if (gBenchmarkProgram.mProgramObject == 0)
{
LLViewerShaderMgr::instance()->initAttribsAndUniforms();
@@ -920,7 +921,10 @@ F32 gpu_benchmark()
//number of samples to take
const S32 samples = 64;
- LLGLSLShader::initProfile();
+ if (gGLManager.mHasTimerQuery)
+ {
+ LLGLSLShader::initProfile();
+ }
LLRenderTarget dest[count];
U32 source[count];
@@ -964,16 +968,16 @@ F32 gpu_benchmark()
v[0].set(-1,1,0);
v[1].set(-1,-3,0);
v[2].set(3,1,0);
+
buff->flush();
gBenchmarkProgram.bind();
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- //wait for any previoius GL commands to finish
- glFinish();
bool busted_finish = false;
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ glFinish();
+
for (S32 c = -1; c < samples; ++c)
{
LLTimer timer;
@@ -1013,6 +1017,7 @@ F32 gpu_benchmark()
if (!gGLManager.mHasTimerQuery && !busted_finish && gbps > 128.f)
{ //unrealistically high bandwidth for a card without timer queries, glFinish is probably ignored
busted_finish = true;
+ LL_WARNS() << "GPU Benchmark detected GL driver with broken glFinish implementation." << LL_ENDL;
}
else
{
@@ -1023,10 +1028,12 @@ F32 gpu_benchmark()
gBenchmarkProgram.unbind();
- LLGLSLShader::finishProfile(false);
-
- LLImageGL::deleteTextures(count, source);
+ if (gGLManager.mHasTimerQuery)
+ {
+ LLGLSLShader::finishProfile(false);
+ }
+ LLImageGL::deleteTextures(count, source);
std::sort(results.begin(), results.end());
@@ -1037,27 +1044,20 @@ F32 gpu_benchmark()
#if LL_DARWIN
if (gbps > 512.f)
{
- LL_INFOS() << "Memory bandwidth is improbably high and likely incorrect." << LL_ENDL;
+ LL_WARNS() << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL;
//OSX is probably lying, discard result
gbps = -1.f;
}
#endif
- if (gGLManager.mHasTimerQuery)
- {
- F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
- F32 seconds = ms/1000.f;
+ F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
+ F32 seconds = ms/1000.f;
- F64 samples_drawn = res*res*count*samples;
- F32 samples_sec = (samples_drawn/1000000000.0)/seconds;
- gbps = samples_sec*8;
+ F64 samples_drawn = res*res*count*samples;
+ F32 samples_sec = (samples_drawn/1000000000.0)/seconds;
+ gbps = samples_sec*8;
- LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "ARB_timer_query unavailable." << LL_ENDL;
- }
+ LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL;
return gbps;
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 33e557cddd..1910656066 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -87,6 +87,8 @@ void copy_slurl_to_clipboard_callback_inv(const std::string& slurl);
typedef std::pair<LLUUID, LLUUID> two_uuids_t;
typedef std::list<two_uuids_t> two_uuids_list_t;
+const F32 SOUND_GAIN = 1.0f;
+
struct LLMoveInv
{
LLUUID mObjectID;
@@ -2785,8 +2787,8 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
class LLInventoryCopyAndWearObserver : public LLInventoryObserver
{
public:
- LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count, bool folder_added=false) :
- mCatID(cat_id), mContentsCount(count), mFolderAdded(folder_added) {}
+ LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count, bool folder_added=false, bool replace=false) :
+ mCatID(cat_id), mContentsCount(count), mFolderAdded(folder_added), mReplace(replace){}
virtual ~LLInventoryCopyAndWearObserver() {}
virtual void changed(U32 mask);
@@ -2794,6 +2796,7 @@ protected:
LLUUID mCatID;
int mContentsCount;
bool mFolderAdded;
+ bool mReplace;
};
@@ -2832,7 +2835,7 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask)
mContentsCount)
{
gInventory.removeObserver(this);
- LLAppearanceMgr::instance().wearInventoryCategory(category, FALSE, TRUE);
+ LLAppearanceMgr::instance().wearInventoryCategory(category, FALSE, !mReplace);
delete this;
}
}
@@ -3779,24 +3782,21 @@ void LLFolderBridge::modifyOutfit(BOOL append)
// checking amount of items to wear
U32 max_items = gSavedSettings.getU32("WearFolderLimit");
- if (cat->getDescendentCount() > max_items)
- {
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
- gInventory.collectDescendentsIf(cat->getUUID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- not_worn);
-
- if (items.size() > max_items)
- {
- LLSD args;
- args["AMOUNT"] = llformat("%d", max_items);
- LLNotificationsUtil::add("TooManyWearables", args);
- return;
- }
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
+ gInventory.collectDescendentsIf(cat->getUUID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ not_worn);
+
+ if (items.size() > max_items)
+ {
+ LLSD args;
+ args["AMOUNT"] = llformat("%d", max_items);
+ LLNotificationsUtil::add("TooManyWearables", args);
+ return;
}
LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append );
@@ -3816,7 +3816,8 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
LLInventoryObject::object_list_t inventory_objects;
object->getInventoryContents(inventory_objects);
int contents_count = inventory_objects.size()-1; //subtract one for containing folder
- LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded);
+ LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded,
+ cat_and_wear->mReplace);
gInventory.addObserver(inventoryObserver);
}
@@ -4526,6 +4527,23 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
hide_context_entries(menu, items, disabled_items);
}
+void LLSoundBridge::performAction(LLInventoryModel* model, std::string action)
+{
+ if ("sound_play" == action)
+ {
+ LLViewerInventoryItem* item = getItem();
+ if(item)
+ {
+ send_sound_trigger(item->getAssetUUID(), SOUND_GAIN);
+ }
+ }
+ else if ("open" == action)
+ {
+ openSoundPreview((void*)this);
+ }
+ else LLItemBridge::performAction(model, action);
+}
+
// +=================================================+
// | LLLandmarkBridge |
// +=================================================+
@@ -5326,16 +5344,20 @@ std::string LLObjectBridge::getLabelSuffix() const
{
return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn");
}
- std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID);
- if (attachment_point_name == LLStringUtil::null) // Error condition, invalid attach point
+ std::string attachment_point_name;
+ if (gAgentAvatarp->getAttachedPointName(mUUID, attachment_point_name))
{
- attachment_point_name = "Invalid Attachment";
- }
- // e.g. "(worn on ...)" / "(attached to ...)"
- LLStringUtil::format_map_t args;
- args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name);
+ LLStringUtil::format_map_t args;
+ args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name);
- return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args);
+ return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args);
+ }
+ else
+ {
+ LLStringUtil::format_map_t args;
+ args["[ATTACHMENT_ERROR]"] = LLTrans::getString(attachment_point_name);
+ return LLItemBridge::getLabelSuffix() + LLTrans::getString("AttachmentErrorMessage", args);
+ }
}
return LLItemBridge::getLabelSuffix();
}
@@ -6138,7 +6160,7 @@ public:
LLViewerInventoryItem* item = getItem();
if (item)
{
- LLFloaterReg::showInstance("preview_sound", LLSD(mUUID), TAKE_FOCUS_YES);
+ send_sound_trigger(item->getAssetUUID(), SOUND_GAIN);
}
LLInvFVBridgeAction::doIt();
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 833fbbadbb..e8d5db4437 100755
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -389,6 +389,7 @@ public:
LLItemBridge(inventory, root, uuid) {}
virtual void openItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+ virtual void performAction(LLInventoryModel* model, std::string action);
static void openSoundPreview(void*);
};
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index f211acedf0..dc8b15a5bf 100755
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -126,13 +126,6 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
{
- // when applying a filter, matching folders get their contents downloaded first
- if (isNotDefault()
- && !gInventory.isCategoryComplete(folder_id))
- {
- LLInventoryModelBackgroundFetch::instance().start(folder_id);
- }
-
// Always check against the clipboard
const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
@@ -142,6 +135,13 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
return passed_clipboard;
}
+ // when applying a filter, matching folders get their contents downloaded first
+ if (mFilterSubString.size()
+ && !gInventory.isCategoryComplete(folder_id))
+ {
+ LLInventoryModelBackgroundFetch::instance().start(folder_id);
+ }
+
// show folder links
LLViewerInventoryItem* item = gInventory.getItem(folder_id);
if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER)
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index e18ecd2e2a..3546317471 100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -542,12 +542,13 @@ void LLInventoryPanel::modelChanged(U32 mask)
// This item already exists in both memory and UI. It was probably reparented.
else if (model_item && view_item)
{
+ LLFolderViewFolder* old_parent = view_item->getParentFolder();
// Don't process the item if it is the root
- if (view_item->getParentFolder())
+ if (old_parent)
{
LLFolderViewFolder* new_parent = (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());
// Item has been moved.
- if (view_item->getParentFolder() != new_parent)
+ if (old_parent != new_parent)
{
if (new_parent != NULL)
{
@@ -573,6 +574,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
// doesn't include trash). Just remove the item's UI.
view_item->destroyView();
}
+ old_parent->getViewModelItem()->dirtyDescendantsFilter();
}
}
}
@@ -583,27 +585,16 @@ void LLInventoryPanel::modelChanged(U32 mask)
else if (!model_item && view_item && viewmodel_item)
{
// Remove the item's UI.
- removeItemID(viewmodel_item->getUUID());
+ LLFolderViewFolder* parent = view_item->getParentFolder();
+ removeItemID(viewmodel_item->getUUID());
view_item->destroyView();
+ if(parent)
+ {
+ parent->getViewModelItem()->dirtyDescendantsFilter();
+ }
}
}
}
-
- if (mask & (LLInventoryObserver::STRUCTURE | LLInventoryObserver::REMOVE))
- {
- // STRUCTURE and REMOVE model changes usually fail to update (clean)
- // mMostFilteredDescendantGeneration of parent folder and dirtyFilter()
- // is not sufficient for successful filter update, so we need to check
- // all already passed element over again to remove obsolete elements.
- // New items or moved items should be sufficiently covered by
- // dirtyFilter().
- LLInventoryFilter& filter = getFilter();
- if (filter.getFilterTypes() & LLInventoryFilter::FILTERTYPE_DATE
- || filter.isNotDefault())
- {
- filter.setModified(LLFolderViewFilter::FILTER_MORE_RESTRICTIVE);
- }
- }
}
LLUUID LLInventoryPanel::getRootFolderID()
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 06e517a861..cadbc16f1e 100755
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -1022,7 +1022,7 @@ void LLLoadHistoryThread::run()
{
loadHistory(mFileName, mMessages, mLoadParams);
int count = mMessages->size();
- llinfos << "mMessages->size(): " << count << llendl;
+ LL_INFOS() << "mMessages->size(): " << count << LL_ENDL;
setFinished();
}
}
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index e3be1312e4..02e05d3d9a 100755
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1848,6 +1848,8 @@ void LLPanelFace::onCancelNormalTexture(const LLSD& data)
U8 bumpy = 0;
bool identical_bumpy = false;
LLSelectedTE::getBumpmap(bumpy, identical_bumpy);
+ LLUUID spec_map_id = getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID();
+ bumpy = spec_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
sendBump(bumpy);
}
diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp
index 1eafc5bd64..76792cc6fd 100644
--- a/indra/newview/llpanelgroupbulk.cpp
+++ b/indra/newview/llpanelgroupbulk.cpp
@@ -387,7 +387,7 @@ void LLPanelGroupBulk::addUsers(uuid_vec_t& agent_ids)
}
else
{
- llwarns << "llPanelGroupBulk: Selected avatar has no name: " << dest->getID() << llendl;
+ LL_WARNS() << "llPanelGroupBulk: Selected avatar has no name: " << dest->getID() << LL_ENDL;
names.push_back("(Unknown)");
}
}
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 236ad861a5..e662a05dfc 100755
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -492,7 +492,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
}
else
{
- llwarns << "llPanelGroupInvite: Selected avatar has no name: " << dest->getID() << llendl;
+ LL_WARNS() << "llPanelGroupInvite: Selected avatar has no name: " << dest->getID() << LL_ENDL;
names.push_back("(Unknown)");
}
}
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index a7c9dbdf7b..eb037577be 100755
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -153,7 +153,9 @@ BOOL LLPanelMainInventory::postBuild()
recent_items_panel->setSinceLogoff(TRUE);
recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- recent_items_panel->getFilter().markDefault();
+ LLInventoryFilter& recent_filter = recent_items_panel->getFilter();
+ recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY));
+ recent_filter.markDefault();
recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
}
@@ -853,9 +855,9 @@ void LLFloaterInventoryFinder::draw()
filtered_by_all_types = FALSE;
}
- if (!filtered_by_all_types)
+ if (!filtered_by_all_types || (mPanelMainInventory->getPanel()->getFilter().getFilterTypes() & LLInventoryFilter::FILTERTYPE_DATE))
{
- // don't include folders in filter, unless I've selected everything
+ // don't include folders in filter, unless I've selected everything or filtering by date
filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
}
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 6b74d90708..6354b5a02b 100755
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -698,6 +698,10 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
if(isItemRenameable())
{
items.push_back(std::string("Task Rename"));
+ if ((flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Task Rename"));
+ }
}
if(isItemRemovable())
{
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 8eea5ea73e..a41986373e 100755
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -663,12 +663,13 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
LLTextSegmentPtr segment = NULL;
std::vector<LLTextSegmentPtr> selected_segments;
mEditor->getSelectedSegments(selected_segments);
-
+ LLKeywordToken* token;
// try segments in selection range first
std::vector<LLTextSegmentPtr>::iterator segment_iter;
for (segment_iter = selected_segments.begin(); segment_iter != selected_segments.end(); ++segment_iter)
{
- if((*segment_iter)->getToken() && (*segment_iter)->getToken()->getType() == LLKeywordToken::TT_WORD)
+ token = (*segment_iter)->getToken();
+ if(token && isKeyword(token))
{
segment = *segment_iter;
break;
@@ -679,7 +680,8 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
if (!segment)
{
const LLTextSegmentPtr test_segment = mEditor->getPreviousSegment();
- if(test_segment->getToken() && test_segment->getToken()->getType() == LLKeywordToken::TT_WORD)
+ token = test_segment->getToken();
+ if(token && isKeyword(token))
{
segment = test_segment;
}
@@ -708,6 +710,24 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
}
}
+bool LLScriptEdCore::isKeyword(LLKeywordToken* token)
+{
+ switch(token->getType())
+ {
+ case LLKeywordToken::TT_CONSTANT:
+ case LLKeywordToken::TT_CONTROL:
+ case LLKeywordToken::TT_EVENT:
+ case LLKeywordToken::TT_FUNCTION:
+ case LLKeywordToken::TT_SECTION:
+ case LLKeywordToken::TT_TYPE:
+ case LLKeywordToken::TT_WORD:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
void LLScriptEdCore::setHelpPage(const std::string& help_string)
{
LLFloater* help_floater = mLiveHelpHandle.get();
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 515f277c4a..66727bceee 100755
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -133,6 +133,7 @@ protected:
void deleteBridges();
void setHelpPage(const std::string& help_string);
void updateDynamicHelp(BOOL immediate = FALSE);
+ bool isKeyword(LLKeywordToken* token);
void addHelpItemToHistory(const std::string& help_string);
static void onErrorList(LLUICtrl*, void* user_data);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 0a8257f42b..5e342099d7 100755
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1632,7 +1632,7 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
{
LLDrawInfo* params = NULL;
- LLColor4 colors[] = {
+ static const LLColor4 colors[] = {
LLColor4::green,
LLColor4::green1,
LLColor4::green2,
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 89302c3c64..e80756e4de 100755
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -544,10 +544,18 @@ void LLSpeakerMgr::updateSpeakerList()
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
if (session->isGroupSessionType() && (mSpeakers.size() <= 1))
{
- const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout");
// For groups, we need to hit the group manager.
// Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail.
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id);
+ F32 large_group_delay = 0.f;
+ if (gdatap)
+ {
+ //This is a viewer-side bandaid for maint-4414 it does not fix the core issue.
+ large_group_delay = (F32)(gdatap->mMemberCount / 5000);
+ }
+
+ const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout") + large_group_delay;
+
if (!gdatap && (mGetListTime.getElapsedTimeF32() >= load_group_timeout))
{
// Request the data the first time around
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index c12753acb0..a426669b5e 100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -118,7 +118,7 @@ public:
/*virtual*/ void onClose(bool app_settings);
// New functions
- void setImageID( const LLUUID& image_asset_id);
+ void setImageID( const LLUUID& image_asset_id, bool set_selection = true);
void updateImageStats();
const LLUUID& getAssetID() { return mImageAssetID; }
const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only);
@@ -232,7 +232,7 @@ LLFloaterTexturePicker::~LLFloaterTexturePicker()
{
}
-void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
+void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selection /*=true*/)
{
if( mImageAssetID != image_id && mActive)
{
@@ -253,6 +253,10 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
mNoCopyTextureSelected = TRUE;
}
+ }
+
+ if (set_selection)
+ {
mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
}
}
@@ -461,7 +465,10 @@ BOOL LLFloaterTexturePicker::postBuild()
// don't put keyboard focus on selected item, because the selection callback
// will assume that this was user input
- mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
+ if(!mImageAssetID.isNull())
+ {
+ mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
+ }
}
mModeSelector = getChild<LLRadioGroup>("mode_selection");
@@ -820,7 +827,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
{
mNoCopyTextureSelected = TRUE;
}
- setImageID(itemp->getAssetUUID());
+ setImageID(itemp->getAssetUUID(),false);
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
if (user_action && mCanPreview)
{
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 575e5c5c52..8561d265de 100755
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -2173,23 +2173,20 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
}
U32 max_items = gSavedSettings.getU32("WearFolderLimit");
- if (category->getDescendentCount()>max_items)
- {
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
- gInventory.collectDescendentsIf(category->getUUID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- not_worn);
- if (items.size() > max_items)
- {
- LLStringUtil::format_map_t args;
- args["AMOUNT"] = llformat("%d", max_items);
- mCustomMsg = LLTrans::getString("TooltipTooManyWearables",args);
- return ACCEPT_NO_CUSTOM;
- }
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
+ gInventory.collectDescendentsIf(category->getUUID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ not_worn);
+ if (items.size() > max_items)
+ {
+ LLStringUtil::format_map_t args;
+ args["AMOUNT"] = llformat("%d", max_items);
+ mCustomMsg = LLTrans::getString("TooltipTooManyWearables",args);
+ return ACCEPT_NO_CUSTOM;
}
if(mSource == SOURCE_AGENT)
diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp
index 7088558b83..e983bc883f 100644
--- a/indra/newview/lltwitterconnect.cpp
+++ b/indra/newview/lltwitterconnect.cpp
@@ -397,7 +397,7 @@ void LLTwitterConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std:
}
else
{
- llwarns << "Image to upload is not a PNG or JPEG" << llendl;
+ LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
return;
}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index d364fce45a..d6c8ba10f6 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1456,7 +1456,8 @@ void update_inventory_category(
void remove_inventory_items(
LLInventoryObject::object_list_t& items_to_kill,
- LLPointer<LLInventoryCallback> cb)
+ LLPointer<LLInventoryCallback> cb
+ )
{
for (LLInventoryObject::object_list_t::iterator it = items_to_kill.begin();
it != items_to_kill.end();
@@ -1468,12 +1469,13 @@ void remove_inventory_items(
void remove_inventory_item(
const LLUUID& item_id,
- LLPointer<LLInventoryCallback> cb)
+ LLPointer<LLInventoryCallback> cb,
+ bool immediate_delete)
{
LLPointer<LLInventoryObject> obj = gInventory.getItem(item_id);
if (obj)
{
- remove_inventory_item(obj, cb);
+ remove_inventory_item(obj, cb, immediate_delete);
}
else
{
@@ -1483,7 +1485,8 @@ void remove_inventory_item(
void remove_inventory_item(
LLPointer<LLInventoryObject> obj,
- LLPointer<LLInventoryCallback> cb)
+ LLPointer<LLInventoryCallback> cb,
+ bool immediate_delete)
{
if(obj)
{
@@ -1493,6 +1496,11 @@ void remove_inventory_item(
{
LLPointer<AISCommand> cmd_ptr = new RemoveItemCommand(item_id, cb);
cmd_ptr->run_command();
+
+ if (immediate_delete)
+ {
+ gInventory.onObjectDeletedFromServer(item_id);
+ }
}
else // no cap
{
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index d345c49cfb..ca92565600 100755
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -394,11 +394,13 @@ void remove_inventory_items(
void remove_inventory_item(
LLPointer<LLInventoryObject> obj,
- LLPointer<LLInventoryCallback> cb);
+ LLPointer<LLInventoryCallback> cb,
+ bool immediate_delete = false);
void remove_inventory_item(
const LLUUID& item_id,
- LLPointer<LLInventoryCallback> cb);
+ LLPointer<LLInventoryCallback> cb,
+ bool immediate_delete = false);
void remove_inventory_category(
const LLUUID& cat_id,
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index b0f4802e20..a4a05587d3 100755
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -88,18 +88,25 @@ void agent_push_down( EKeystate s )
gAgent.moveUp(-1);
}
+static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode)
+{
+ if (gAgent.mDoubleTapRunMode == mode &&
+ gAgent.getRunning() &&
+ !gAgent.getAlwaysRun())
+ {
+ // Turn off temporary running.
+ gAgent.clearRunning();
+ gAgent.sendWalkRun(gAgent.getRunning());
+ }
+}
+
static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode)
{
if (KEYSTATE_UP == s)
{
- if (gAgent.mDoubleTapRunMode == mode &&
- gAgent.getRunning() &&
- !gAgent.getAlwaysRun())
- {
- // Turn off temporary running.
- gAgent.clearRunning();
- gAgent.sendWalkRun(gAgent.getRunning());
- }
+ // Note: in case shift is already released, slide left/right run
+ // will be released in agent_turn_left()/agent_turn_right()
+ agent_check_temporary_run(mode);
}
else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") &&
KEYSTATE_DOWN == s &&
@@ -218,7 +225,12 @@ void agent_turn_left( EKeystate s )
}
else
{
- if (KEYSTATE_UP == s) return;
+ if (KEYSTATE_UP == s)
+ {
+ // Check temporary running. In case user released 'left' key with shift already released.
+ agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT);
+ return;
+ }
F32 time = gKeyboard->getCurKeyElapsedTime();
gAgent.moveYaw( LLFloaterMove::getYawRate( time ) );
}
@@ -241,7 +253,12 @@ void agent_turn_right( EKeystate s )
}
else
{
- if (KEYSTATE_UP == s) return;
+ if (KEYSTATE_UP == s)
+ {
+ // Check temporary running. In case user released 'right' key with shift already released.
+ agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT);
+ return;
+ }
F32 time = gKeyboard->getCurKeyElapsedTime();
gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) );
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 4f992fc184..820249e181 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -359,10 +359,17 @@ void LLViewerObject::markDead()
//LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;
// Root object of this hierarchy unlinks itself.
+ LLVOAvatar *av = getAvatarAncestor();
if (getParent())
{
((LLViewerObject *)getParent())->removeChild(this);
}
+ LLUUID mesh_id;
+ if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id))
+ {
+ // This case is needed for indirectly attached mesh objects.
+ av->resetJointPositionsOnDetach(mesh_id);
+ }
// Mark itself as dead
mDead = TRUE;
@@ -2274,7 +2281,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
}
- if ((new_rot != getRotation())
+ if ((new_rot.isNotEqualEps(getRotation(), F_ALMOST_ZERO))
|| (new_angv != old_angv))
{
if (new_rot != mPreviousRotation)
@@ -5006,6 +5013,22 @@ LLVOAvatar* LLViewerObject::asAvatar()
return NULL;
}
+// If this object is directly or indirectly parented by an avatar, return it.
+LLVOAvatar* LLViewerObject::getAvatarAncestor()
+{
+ LLViewerObject *pobj = (LLViewerObject*) getParent();
+ while (pobj)
+ {
+ LLVOAvatar *av = pobj->asAvatar();
+ if (av)
+ {
+ return av;
+ }
+ pobj = (LLViewerObject*) pobj->getParent();
+ }
+ return NULL;
+}
+
BOOL LLViewerObject::isParticleSource() const
{
return !mPartSourcep.isNull() && !mPartSourcep->isDead();
@@ -6193,6 +6216,17 @@ const LLUUID &LLViewerObject::extractAttachmentItemID()
return getAttachmentItemID();
}
+const std::string& LLViewerObject::getAttachmentItemName()
+{
+ static std::string empty;
+ LLInventoryItem *item = gInventory.getItem(getAttachmentItemID());
+ if (isAttachment() && item)
+ {
+ return item->getName();
+ }
+ return empty;
+}
+
//virtual
LLVOAvatar* LLViewerObject::getAvatar() const
{
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index bab107cc57..05c87c153b 100755
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -135,6 +135,8 @@ public:
virtual LLVOAvatar* asAvatar();
+ LLVOAvatar* getAvatarAncestor();
+
static void initVOClasses();
static void cleanupVOClasses();
@@ -170,6 +172,8 @@ public:
void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; }
virtual BOOL isAttachment() const { return FALSE; }
+ const std::string& getAttachmentItemName();
+
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
virtual BOOL isHUDAttachment() const { return FALSE; }
virtual BOOL isTempAttachment() const;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 25c7120a19..da0e72a6ee 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -713,7 +713,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mVisualComplexity(0),
mVisualComplexityStale(TRUE),
mLoadedCallbacksPaused(FALSE),
- mHasPelvisOffset( FALSE ),
mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),
mLastRezzedStatus(-1),
mIsEditingAppearance(FALSE),
@@ -777,10 +776,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mRuthDebugTimer.reset();
mDebugExistenceTimer.reset();
mLastAppearanceMessageTimer.reset();
- mPelvisOffset = LLVector3(0.0f,0.0f,0.0f);
- mLastPelvisToFoot = 0.0f;
- mPelvisFixup = 0.0f;
- mLastPelvisFixup = 0.0f;
if(LLSceneMonitor::getInstance()->isEnabled())
{
@@ -1266,17 +1261,18 @@ const LLVector3 LLVOAvatar::getRenderPosition() const
}
else if (isRoot())
{
- if ( !mHasPelvisOffset )
- {
- return mDrawable->getPositionAgent();
- }
- else
+ F32 fixup;
+ if ( hasPelvisFixup( fixup) )
{
//Apply a pelvis fixup (as defined by the avs skin)
LLVector3 pos = mDrawable->getPositionAgent();
- pos[VZ] += mPelvisFixup;
+ pos[VZ] += fixup;
return pos;
}
+ else
+ {
+ return mDrawable->getPositionAgent();
+ }
}
else
{
@@ -3220,6 +3216,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
{
debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
}
+ debug_line += llformat(" bsz-z: %f avofs-z: %f", mBodySize[2], mAvatarOffset[2]);
if (mHoverOffset[2] != 0.0)
{
debug_line += llformat(" hov_z: %f", mHoverOffset[2]);
@@ -3745,21 +3742,6 @@ void LLVOAvatar::updateHeadOffset()
}
}
//------------------------------------------------------------------------
-// setPelvisOffset
-//------------------------------------------------------------------------
-void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount, F32 pelvisFixup )
-{
- mHasPelvisOffset = hasOffset;
- if ( mHasPelvisOffset )
- {
- //Store off last pelvis to foot value
- mLastPelvisToFoot = mPelvisToFoot;
- mPelvisOffset = offsetAmount;
- mLastPelvisFixup = mPelvisFixup;
- mPelvisFixup = pelvisFixup;
- }
-}
-//------------------------------------------------------------------------
// postPelvisSetRecalc
//------------------------------------------------------------------------
void LLVOAvatar::postPelvisSetRecalc( void )
@@ -3769,15 +3751,6 @@ void LLVOAvatar::postPelvisSetRecalc( void )
dirtyMesh(2);
}
//------------------------------------------------------------------------
-// setPelvisOffset
-//------------------------------------------------------------------------
-void LLVOAvatar::setPelvisOffset( F32 pelvisFixupAmount )
-{
- mHasPelvisOffset = true;
- mLastPelvisFixup = mPelvisFixup;
- mPelvisFixup = pelvisFixupAmount;
-}
-//------------------------------------------------------------------------
// updateVisibility()
//------------------------------------------------------------------------
void LLVOAvatar::updateVisibility()
@@ -4906,6 +4879,12 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
{
sitDown(FALSE);
}
+ if ((anim_id == ANIM_AGENT_DO_NOT_DISTURB) && gAgent.isDoNotDisturb())
+ {
+ // re-assert DND tag animation
+ gAgent.sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, ANIM_REQUEST_START);
+ return result;
+ }
stopMotion(anim_id);
result = TRUE;
}
@@ -5079,10 +5058,162 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
return jointp;
}
+
+//-----------------------------------------------------------------------------
+// getRiggedMeshID
+//
+// If viewer object is a rigged mesh, set the mesh id and return true.
+// Otherwise, null out the id and return false.
+//-----------------------------------------------------------------------------
+// static
+bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id)
+{
+ mesh_id.setNull();
+
+ //If a VO has a skin that we'll reset the joint positions to their default
+ if ( pVO && pVO->mDrawable )
+ {
+ LLVOVolume* pVObj = pVO->mDrawable->getVOVolume();
+ if ( pVObj )
+ {
+ const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
+ if (pSkinData
+ && pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig
+ && pSkinData->mAlternateBindMatrix.size() > 0 )
+ {
+ mesh_id = pSkinData->mMeshID;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void LLVOAvatar::clearAttachmentPosOverrides()
+{
+ //Subsequent joints are relative to pelvis
+ avatar_joint_list_t::iterator iter = mSkeleton.begin();
+ avatar_joint_list_t::iterator end = mSkeleton.end();
+
+ for (; iter != end; ++iter)
+ {
+ LLJoint* pJoint = (*iter);
+ pJoint->clearAttachmentPosOverrides();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// addAttachmentPosOverridesForObject
+//-----------------------------------------------------------------------------
+void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)
+{
+ LLVOAvatar *av = vo->getAvatarAncestor();
+ if (!av || (av != this))
+ {
+ LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
+ }
+
+ // Process all children
+ LLViewerObject::const_child_list_t& children = vo->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
+ it != children.end(); ++it)
+ {
+ LLViewerObject *childp = *it;
+ addAttachmentPosOverridesForObject(childp);
+ }
+
+ LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo);
+ bool pelvisGotSet = false;
+
+ if (!vobj)
+ {
+ return;
+ }
+ if (vobj->isMesh() &&
+ ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
+ {
+ return;
+ }
+ LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
+ const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
+
+ if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData )
+ {
+ const int bindCnt = pSkinData->mAlternateBindMatrix.size();
+ if ( bindCnt > 0 )
+ {
+ const int jointCnt = pSkinData->mJointNames.size();
+ const F32 pelvisZOffset = pSkinData->mPelvisOffset;
+ const LLUUID& mesh_id = pSkinData->mMeshID;
+ bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
+ if ( fullRig )
+ {
+ for ( int i=0; i<jointCnt; ++i )
+ {
+ std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
+ LLJoint* pJoint = getJoint( lookingForJoint );
+ if ( pJoint && pJoint->getId() != currentId )
+ {
+ pJoint->setId( currentId );
+ const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
+ //Set the joint position
+ pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString() );
+
+ //If joint is a pelvis then handle old/new pelvis to foot values
+ if ( lookingForJoint == "mPelvis" )
+ {
+ pelvisGotSet = true;
+ }
+ }
+ }
+ if (pelvisZOffset != 0.0F)
+ {
+ addPelvisFixup( pelvisZOffset, mesh_id );
+ pelvisGotSet = true;
+ }
+ }
+ }
+ }
+
+ //Rebuild body data if we altered joints/pelvis
+ if ( pelvisGotSet )
+ {
+ postPelvisSetRecalc();
+ }
+}
+
//-----------------------------------------------------------------------------
-// resetJointPositionsToDefault
+// resetJointPositionsOnDetach
//-----------------------------------------------------------------------------
-void LLVOAvatar::resetJointPositionsToDefault( void )
+void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo)
+{
+ LLVOAvatar *av = vo->getAvatarAncestor();
+ if (!av || (av != this))
+ {
+ LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
+ }
+
+ // Process all children
+ LLViewerObject::const_child_list_t& children = vo->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
+ it != children.end(); ++it)
+ {
+ LLViewerObject *childp = *it;
+ resetJointPositionsOnDetach(childp);
+ }
+
+ // Process self.
+ LLUUID mesh_id;
+ if (getRiggedMeshID(vo,mesh_id))
+ {
+ resetJointPositionsOnDetach(mesh_id);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// resetJointPositionsOnDetach
+//-----------------------------------------------------------------------------
+void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id)
{
//Subsequent joints are relative to pelvis
avatar_joint_list_t::iterator iter = mSkeleton.begin();
@@ -5094,23 +5225,18 @@ void LLVOAvatar::resetJointPositionsToDefault( void )
{
LLJoint* pJoint = (*iter);
//Reset joints except for pelvis
- if ( pJoint && pJoint != pJointPelvis && pJoint->doesJointNeedToBeReset() )
+ if ( pJoint )
{
pJoint->setId( LLUUID::null );
- pJoint->restoreOldXform();
+ pJoint->removeAttachmentPosOverride(mesh_id, avString());
}
- else
- if ( pJoint && pJoint == pJointPelvis && pJoint->doesJointNeedToBeReset() )
+ if ( pJoint && pJoint == pJointPelvis)
{
- pJoint->setId( LLUUID::null );
+ removePelvisFixup( mesh_id );
pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) );
- pJoint->setJointResetFlag( false );
}
}
- //make sure we don't apply the joint offset
- mHasPelvisOffset = false;
- mPelvisFixup = mLastPelvisFixup;
postPelvisSetRecalc();
}
//-----------------------------------------------------------------------------
@@ -5647,7 +5773,7 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
}
//-----------------------------------------------------------------------------
-// attachObject()
+// getNumAttachments()
//-----------------------------------------------------------------------------
U32 LLVOAvatar::getNumAttachments() const
{
@@ -5757,30 +5883,18 @@ void LLVOAvatar::rebuildRiggedAttachments( void )
//-----------------------------------------------------------------------------
void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
{
- //If a VO has a skin that we'll reset the joint positions to their default
- if ( pVO && pVO->mDrawable )
+ LLUUID mesh_id;
+ if (getRiggedMeshID(pVO, mesh_id))
{
- LLVOVolume* pVObj = pVO->mDrawable->getVOVolume();
- if ( pVObj )
+ resetJointPositionsOnDetach(mesh_id);
+ if ( gAgentCamera.cameraCustomizeAvatar() )
{
- const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
- if (pSkinData
- && pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig
- && pSkinData->mAlternateBindMatrix.size() > 0 )
- {
- LLVOAvatar::resetJointPositionsToDefault();
- //Need to handle the repositioning of the cam, updating rig data etc during outfit editing
- //This handles the case where we detach a replacement rig.
- if ( gAgentCamera.cameraCustomizeAvatar() )
- {
- gAgent.unpauseAnimation();
- //Still want to refocus on head bone
- gAgentCamera.changeCameraToCustomizeAvatar();
- }
- }
- }
- }
+ gAgent.unpauseAnimation();
+ //Still want to refocus on head bone
+ gAgentCamera.changeCameraToCustomizeAvatar();
}
+ }
+}
//-----------------------------------------------------------------------------
// detachObject()
@@ -7716,6 +7830,39 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
}
}
}
+
+ avatar_joint_list_t::iterator iter = mSkeleton.begin();
+ avatar_joint_list_t::iterator end = mSkeleton.end();
+ for (; iter != end; ++iter)
+ {
+ LLJoint* pJoint = (*iter);
+ const LLVector3& pos = pJoint->getPosition();
+ const LLVector3& scale = pJoint->getScale();
+ apr_file_printf( file, "\t\t<joint name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
+ }
+
+ for (iter = mSkeleton.begin(); iter != end; ++iter)
+ {
+ LLJoint* pJoint = (*iter);
+
+ LLVector3 pos;
+ LLUUID mesh_id;
+
+ if (pJoint->hasAttachmentPosOverride(pos,mesh_id))
+ {
+ apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str());
+ }
+ }
+ F32 pelvis_fixup;
+ LLUUID mesh_id;
+ if (hasPelvisFixup(pelvis_fixup, mesh_id))
+ {
+ apr_file_printf( file, "\t\t<pelvis_fixup z=\"%f\" mesh_id=\"%s\"/>\n",
+ pelvis_fixup, mesh_id.asString().c_str());
+ }
+
apr_file_printf( file, "\t</archetype>\n" );
apr_file_printf( file, "\n</linden_genepool>\n" );
@@ -7725,8 +7872,8 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
// show the cloned params inside the wearables as well.
gAgentAvatarp->dumpWearableInfo(outfile);
}
- outfile.close();
}
+ // File will close when handle goes out of scope
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 8135c3d4d8..a3f599e2d7 100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -199,7 +199,10 @@ public:
virtual LLJoint* getJoint(const std::string &name);
- void resetJointPositionsToDefault( void );
+ void addAttachmentPosOverridesForObject(LLViewerObject *vo);
+ void resetJointPositionsOnDetach(const LLUUID& mesh_id);
+ void resetJointPositionsOnDetach(LLViewerObject *vo);
+ void clearAttachmentPosOverrides();
/*virtual*/ const LLUUID& getID() const;
/*virtual*/ void addDebugText(const std::string& text);
@@ -357,19 +360,11 @@ protected:
/*virtual*/ LLAvatarJointMesh* createAvatarJointMesh(); // Returns LLViewerJointMesh
public:
void updateHeadOffset();
- void setPelvisOffset( bool hasOffset, const LLVector3& translation, F32 offset ) ;
- bool hasPelvisOffset( void ) { return mHasPelvisOffset; }
void postPelvisSetRecalc( void );
- void setPelvisOffset( F32 pelvixFixupAmount );
/*virtual*/ BOOL loadSkeletonNode();
/*virtual*/ void buildCharacter();
- bool mHasPelvisOffset;
- LLVector3 mPelvisOffset;
- F32 mLastPelvisToFoot;
- F32 mPelvisFixup;
- F32 mLastPelvisFixup;
LLVector3 mCurRootToHeadOffset;
LLVector3 mTargetRootToHeadOffset;
@@ -720,6 +715,7 @@ public:
void clampAttachmentPositions();
virtual const LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object);
virtual BOOL detachObject(LLViewerObject *viewer_object);
+ static bool getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id );
void cleanupAttachedMesh( LLViewerObject* pVO );
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index a5379f24ba..3d82a6dab6 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -283,7 +283,7 @@ void LLVOAvatarSelf::markDead()
{
BOOL success = LLVOAvatar::loadAvatar();
- // set all parameters sotred directly in the avatar to have
+ // set all parameters stored directly in the avatar to have
// the isSelfParam to be TRUE - this is used to prevent
// them from being animated or trigger accidental rebakes
// when we copy params from the wearable to the base avatar.
@@ -739,13 +739,8 @@ void LLVOAvatarSelf::updateVisualParams()
LLVOAvatar::updateVisualParams();
}
-/*virtual*/
-void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
+void LLVOAvatarSelf::writeWearablesToAvatar()
{
- // Animate all top-level wearable visual parameters
- gAgentWearables.animateAllWearableParams(calcMorphAmount());
-
- // apply wearable visual params to avatar
for (U32 type = 0; type < LLWearableType::WT_COUNT; type++)
{
LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);
@@ -755,6 +750,17 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
}
}
+}
+
+/*virtual*/
+void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
+{
+ // Animate all top-level wearable visual parameters
+ gAgentWearables.animateAllWearableParams(calcMorphAmount());
+
+ // Apply wearable visual params to avatar
+ writeWearablesToAvatar();
+
//allow avatar to process updates
LLVOAvatar::idleUpdateAppearanceAnimation();
@@ -1114,9 +1120,19 @@ LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id)
return NULL;
}
-const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id) const
+bool LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const
{
+ if (!gInventory.getItem(inv_item_id))
+ {
+ name = "ATTACHMENT_MISSING_ITEM";
+ return false;
+ }
const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id);
+ if (!gInventory.getItem(base_inv_item_id))
+ {
+ name = "ATTACHMENT_MISSING_BASE_ITEM";
+ return false;
+ }
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -1124,11 +1140,13 @@ const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id
const LLViewerJointAttachment* attachment = iter->second;
if (attachment->getAttachedObject(base_inv_item_id))
{
- return attachment->getName();
+ name = attachment->getName();
+ return true;
}
}
- return LLStringUtil::null;
+ name = "ATTACHMENT_NOT_ATTACHED";
+ return false;
}
//virtual
@@ -1163,8 +1181,6 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
const LLUUID attachment_id = viewer_object->getAttachmentItemID();
if ( LLVOAvatar::detachObject(viewer_object) )
{
- LLVOAvatar::cleanupAttachedMesh( viewer_object );
-
// the simulator should automatically handle permission revocation
stopMotionFromSource(attachment_id);
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 7b932abd44..a47b6c3463 100755
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -86,12 +86,11 @@ public:
/*virtual*/ void requestStopMotion(LLMotion* motion);
/*virtual*/ LLJoint* getJoint(const std::string &name);
- void resetJointPositions( void );
-
/*virtual*/ BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight);
/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight);
/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight);
/*virtual*/ void updateVisualParams();
+ void writeWearablesToAvatar();
/*virtual*/ void idleUpdateAppearanceAnimation();
private:
@@ -293,7 +292,7 @@ public:
void addAttachmentRequest(const LLUUID& inv_item_id);
void removeAttachmentRequest(const LLUUID& inv_item_id);
LLViewerObject* getWornAttachment(const LLUUID& inv_item_id);
- const std::string getAttachedPointName(const LLUUID& inv_item_id) const;
+ bool getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const;
/*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
/*virtual*/ BOOL detachObject(LLViewerObject *viewer_object);
static BOOL detachAttachmentIntoInventory(const LLUUID& item_id);
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 9a84cae403..426ca332e4 100755
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -725,6 +725,8 @@ void LLVoiceChannelProximal::handleStatusChange(EStatusType status)
// do not notify user when leaving proximal channel
return;
case STATUS_VOICE_DISABLED:
+ LLVoiceClient::getInstance()->setUserPTTState(false);
+ gAgent.setVoiceConnected(false);
//skip showing "Voice not available at your current location" when agent voice is disabled (EXT-4749)
if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking())
{
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 0bf373f478..962cdf0268 100755
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -161,6 +161,13 @@ void LLVoiceClient::userAuthorized(const std::string& user_id, const LLUUID &age
mVoiceModule->userAuthorized(user_id, agentID);
}
+void LLVoiceClient::setHidden(bool hidden)
+{
+ if (mVoiceModule)
+ {
+ mVoiceModule->setHidden(hidden);
+ }
+}
void LLVoiceClient::terminate()
{
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 1e20a814a0..fb387301be 100755
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -105,6 +105,8 @@ public:
virtual void updateSettings()=0; // call after loading settings and whenever they change
virtual bool isVoiceWorking() const = 0; // connected to a voice server and voice channel
+
+ virtual void setHidden(bool hidden)=0; // Hides the user from voice.
virtual const LLVoiceVersionInfo& getVersion()=0;
@@ -342,6 +344,7 @@ public:
void setCaptureDevice(const std::string& name);
void setRenderDevice(const std::string& name);
+ void setHidden(bool hidden);
const LLVoiceDeviceList& getCaptureDevices();
const LLVoiceDeviceList& getRenderDevices();
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 54b4119331..b6aecb4aaa 100755
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -70,6 +70,7 @@
#include "apr_base64.h"
#define USE_SESSION_GROUPS 0
+#define VX_NULL_POSITION -2147483648.0 /*The Silence*/
extern LLMenuBarGL* gMenuBarView;
extern void handle_voice_morphing_subscribe();
@@ -322,6 +323,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
mCaptureBufferRecording(false),
mCaptureBufferRecorded(false),
mCaptureBufferPlaying(false),
+ mShutdownComplete(true),
mPlayRequestCount(0),
mAvatarNameCacheConnection()
@@ -376,7 +378,16 @@ void LLVivoxVoiceClient::terminate()
if(mConnected)
{
logout();
- connectorShutdown();
+ connectorShutdown();
+#ifdef LL_WINDOWS
+ int count=0;
+ while (!mShutdownComplete && 10 > count++)
+ {
+ stateMachine();
+ _sleep(1000);
+ }
+
+#endif
closeSocket(); // Need to do this now -- bad things happen if the destructor does it later.
cleanUp();
}
@@ -476,10 +487,9 @@ void LLVivoxVoiceClient::connectorCreate()
std::string savedLogLevel = gSavedSettings.getString("VivoxDebugLevel");
- if(savedLogLevel != "-0")
+ if(savedLogLevel != "0")
{
LL_DEBUGS("Voice") << "creating connector with logging enabled" << LL_ENDL;
- loglevel = "0";
}
stream
@@ -488,13 +498,14 @@ void LLVivoxVoiceClient::connectorCreate()
<< "<AccountManagementServer>" << mVoiceAccountServerURI << "</AccountManagementServer>"
<< "<Mode>Normal</Mode>"
<< "<Logging>"
- << "<Folder>" << logpath << "</Folder>"
- << "<FileNamePrefix>Connector</FileNamePrefix>"
- << "<FileNameSuffix>.log</FileNameSuffix>"
- << "<LogLevel>" << loglevel << "</LogLevel>"
+ << "<Folder>" << logpath << "</Folder>"
+ << "<FileNamePrefix>Connector</FileNamePrefix>"
+ << "<FileNameSuffix>.log</FileNameSuffix>"
+ << "<LogLevel>" << loglevel << "</LogLevel>"
<< "</Logging>"
- << "<Application>SecondLifeViewer.1</Application>"
- << "</Request>\n\n\n";
+ << "<Application></Application>" //Name can cause problems per vivox.
+ << "<MaxCalls>12</MaxCalls>"
+ << "</Request>\n\n\n";
writeString(stream.str());
}
@@ -512,6 +523,7 @@ void LLVivoxVoiceClient::connectorShutdown()
<< "</Request>"
<< "\n\n\n";
+ mShutdownComplete = false;
mConnectorHandle.clear();
writeString(stream.str());
@@ -788,15 +800,32 @@ void LLVivoxVoiceClient::stateMachine()
// vivox executable exists. Build the command line and launch the daemon.
LLProcess::Params params;
params.executable = exe_path;
- // SLIM SDK: these arguments are no longer necessary.
-// std::string args = " -p tcp -h -c";
+
std::string loglevel = gSavedSettings.getString("VivoxDebugLevel");
+ std::string shutdown_timeout = gSavedSettings.getString("VivoxShutdownTimeout");
if(loglevel.empty())
{
loglevel = "0"; // turn logging off completely
}
+
params.args.add("-ll");
params.args.add(loglevel);
+
+ std::string log_folder = gSavedSettings.getString("VivoxLogDirectory");
+
+ if (log_folder.empty())
+ {
+ log_folder = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
+ }
+
+ params.args.add("-lf");
+ params.args.add(log_folder);
+
+ if(!shutdown_timeout.empty())
+ {
+ params.args.add("-st");
+ params.args.add(shutdown_timeout);
+ }
params.cwd = gDirUtilp->getAppRODataDir();
sGatewayPtr = LLProcess::create(params);
@@ -1334,7 +1363,7 @@ void LLVivoxVoiceClient::stateMachine()
{
// Connect to a session by URI
sessionCreateSendMessage(mAudioSession, true, false);
- }
+ }
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING);
setState(stateJoiningSession);
@@ -1510,7 +1539,7 @@ void LLVivoxVoiceClient::stateMachine()
// Always reset the terminate request flag when we get here.
mSessionTerminateRequested = false;
- if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested)
+ if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !LLApp::isExiting())
{
// Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state).
setState(stateNoChannel);
@@ -1553,6 +1582,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateConnectorStopping
case stateConnectorStopping: // waiting for connector stop
// The handler for the Connector.InitiateShutdown response will transition from here to stateConnectorStopped.
+ mShutdownComplete = true;
break;
//MARK: stateConnectorStopped
@@ -2318,6 +2348,14 @@ static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVe
#endif
}
+void LLVivoxVoiceClient::setHidden(bool hidden)
+{
+ mHidden = hidden;
+
+ sendPositionalUpdate();
+ return;
+}
+
void LLVivoxVoiceClient::sendPositionalUpdate(void)
{
std::ostringstream stream;
@@ -2339,14 +2377,23 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void)
l = mAvatarRot.getLeftRow();
u = mAvatarRot.getUpRow();
a = mAvatarRot.getFwdRow();
- pos = mAvatarPosition;
+
+ pos = mAvatarPosition;
vel = mAvatarVelocity;
// SLIM SDK: the old SDK was doing a transform on the passed coordinates that the new one doesn't do anymore.
// The old transform is replicated by this function.
oldSDKTransform(l, u, a, pos, vel);
+
+ if (mHidden)
+ {
+ for (int i=0;i<3;++i)
+ {
+ pos.mdV[i] = VX_NULL_POSITION;
+ }
+ }
- stream
+ stream
<< "<Position>"
<< "<X>" << pos.mdV[VX] << "</X>"
<< "<Y>" << pos.mdV[VY] << "</Y>"
@@ -2406,14 +2453,23 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void)
l = earRot.getLeftRow();
u = earRot.getUpRow();
a = earRot.getFwdRow();
- pos = earPosition;
+
+ pos = earPosition;
vel = earVelocity;
// LL_DEBUGS("Voice") << "Sending listener position " << earPosition << LL_ENDL;
oldSDKTransform(l, u, a, pos, vel);
- stream
+ if (mHidden)
+ {
+ for (int i=0;i<3;++i)
+ {
+ pos.mdV[i] = VX_NULL_POSITION;
+ }
+ }
+
+ stream
<< "<Position>"
<< "<X>" << pos.mdV[VX] << "</X>"
<< "<Y>" << pos.mdV[VY] << "</Y>"
@@ -3169,7 +3225,7 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent(
session->mErrorStatusCode = statusCode;
break;
}
-
+
switch(state)
{
case streamStateIdle:
@@ -5433,7 +5489,8 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta
// skipped to avoid speak button blinking
if ( status != LLVoiceClientStatusObserver::STATUS_JOINING
- && status != LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL)
+ && status != LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL
+ && status != LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED)
{
bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 5e876fa2ef..a4ec9f2a69 100755
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -723,6 +723,7 @@ private:
bool mRenderDeviceDirty;
bool mIsInitialized;
+ bool mShutdownComplete;
bool checkParcelChanged(bool update = false);
@@ -747,6 +748,7 @@ private:
std::string getAudioSessionURI();
std::string getAudioSessionHandle();
+ void setHidden(bool hidden); //virtual
void sendPositionalUpdate(void);
void buildSetCaptureDevice(std::ostringstream &stream);
@@ -775,6 +777,7 @@ private:
bool mMuteMic;
bool mMuteMicDirty;
+ bool mHidden; //Set to true during teleport to hide the agent's position.
// Set to true when the friends list is known to have changed.
bool mFriendsListDirty;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index a83e2e020e..66ee386874 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2040,7 +2040,18 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
- S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
+ S32 res = 0;
+
+ if (pMaterialParams && getTEImage(te) && 3 == getTEImage(te)->getComponents() && pMaterialParams->getDiffuseAlphaMode())
+ {
+ LLViewerObject::setTEMaterialID(te, LLMaterialID::null);
+ res = LLViewerObject::setTEMaterialParams(te, NULL);
+ }
+ else
+ {
+ res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
+ }
+
LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
<< LL_ENDL;
@@ -4328,7 +4339,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mBump = bump;
draw_info->mShiny = shiny;
- float alpha[4] =
+ static const float alpha[4] =
{
0.00f,
0.25f,
@@ -4517,7 +4528,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//Determine if we've received skininfo that contains an
//alternate bind matrix - if it does then apply the translational component
//to the joints of the avatar.
+#if 0
bool pelvisGotSet = false;
+#endif
{
LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_FACE_LIST);
@@ -4602,53 +4615,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//get drawpool of avatar with rigged face
LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
+ // FIXME should this be inside the face loop?
+ // doesn't seem to depend on any per-face state.
if ( pAvatarVO )
{
- LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
- const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
- if ( pSkinData )
- {
- const int bindCnt = pSkinData->mAlternateBindMatrix.size();
- if ( bindCnt > 0 )
- {
- const int jointCnt = pSkinData->mJointNames.size();
- const F32 pelvisZOffset = pSkinData->mPelvisOffset;
- bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
- if ( fullRig )
- {
- for ( int i=0; i<jointCnt; ++i )
- {
- std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
- LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
- if ( pJoint && pJoint->getId() != currentId )
- {
- pJoint->setId( currentId );
- const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
-
- //Set the joint position
- pJoint->storeCurrentXform( jointPos );
-
- //If joint is a pelvis then handle old/new pelvis to foot values
- if ( lookingForJoint == "mPelvis" )
- {
- if ( !pAvatarVO->hasPelvisOffset() )
- {
- pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
- pelvisGotSet = true;
- }
- }
- }
- }
- }
- }
- }
+ pAvatarVO->addAttachmentPosOverridesForObject(vobj);
}
-
- //Rebuild body data if we altered joints/pelvis
- if ( pelvisGotSet && pAvatarVO )
- {
- pAvatarVO->postPelvisSetRecalc();
- }
if (pool)
{
@@ -5006,14 +4978,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
-
-
-
-
-
-
-
-
}
group->mBufferUsage = useage;
@@ -5652,7 +5616,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
if (material_pass)
{
- U32 pass[] =
+ static const U32 pass[] =
{
LLRenderPass::PASS_MATERIAL,
LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA,
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index ca60b79f9d..fac0fd63ee 100755
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -364,8 +364,14 @@ void LLPanelAttachmentListItem::updateItem(const std::string& name,
LLViewerInventoryItem* inv_item = getItem();
if (inv_item && isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(inv_item->getLinkedUUID()))
{
- std::string joint = LLTrans::getString(gAgentAvatarp->getAttachedPointName(inv_item->getLinkedUUID()));
- title_joint = title_joint + " (" + joint + ")";
+ std::string found_name;
+ bool found = gAgentAvatarp->getAttachedPointName(inv_item->getLinkedUUID(),found_name);
+ std::string trans_name = LLTrans::getString(found_name);
+ if (!found)
+ {
+ LL_WARNS() << "invalid attachment joint, err " << found_name << LL_ENDL;
+ }
+ title_joint = title_joint + " (" + trans_name + ")";
}
LLPanelInventoryListItemBase::updateItem(title_joint, item_state);
diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml
index 259acccb68..3dfdf8e1a5 100755
--- a/indra/newview/skins/default/xui/en/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/en/floater_joystick.xml
@@ -4,7 +4,7 @@
height="500"
layout="topleft"
name="Joystick"
- help_topic="joystick"
+ help_topic="Viewerhelp:Joystick_Configuration"
title="JOYSTICK CONFIGURATION"
width="569">
<floater.string
diff --git a/indra/newview/skins/default/xui/en/floater_openobject.xml b/indra/newview/skins/default/xui/en/floater_openobject.xml
index bf6e0c4917..912db80bcc 100755
--- a/indra/newview/skins/default/xui/en/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/en/floater_openobject.xml
@@ -3,10 +3,10 @@
legacy_header_height="18"
can_resize="true"
default_tab_group="1"
- height="350"
+ height="370"
layout="topleft"
- min_height="160"
- min_width="280"
+ min_height="190"
+ min_width="285"
name="objectcontents"
help_topic="objectcontents"
save_rect="true"
@@ -31,36 +31,81 @@
background_visible="false"
draw_border="false"
follows="all"
- height="276"
+ height="240"
layout="topleft"
left="10"
name="object_contents"
top_pad="0"
width="284" />
+ <view_border
+ bevel_style="none"
+ follows="bottom|left"
+ height="50"
+ highlight_light_color="0.6 0.6 0.6"
+ layout="topleft"
+ left="10"
+ name="border"
+ top_pad="5"
+ width="270"/>
+ <text
+ follows="bottom|left"
+ height="15"
+ layout="topleft"
+ left="15"
+ name="border_note"
+ text_color="White"
+ top_delta="5">
+ Copy to inventory and wear
+ </text>
+ <button
+ follows="bottom|left"
+ height="23"
+ label="Add to outfit"
+ label_selected="Add to outfit"
+ layout="topleft"
+ left="15"
+ name="copy_and_wear_button"
+ top_pad="3"
+ width="135">
+ <button.commit_callback
+ function="OpenObject.MoveAndWear" />
+ </button>
+ <button
+ follows="bottom|left"
+ height="23"
+ label="Replace outfit"
+ label_selected="Replace outfit"
+ layout="topleft"
+ left_pad="5"
+ name="copy_and_replace_button"
+ width="120">
+ <button.commit_callback
+ function="OpenObject.ReplaceOutfit" />
+ </button>
<button
follows="bottom|left"
height="23"
- label="Copy to inventory"
- label_selected="Copy to inventory"
+ label="Only copy to inventory"
+ label_selected="Only copy to inventory"
layout="topleft"
left="15"
name="copy_to_inventory_button"
tab_group="1"
- top_pad="5"
- width="120">
+ top_pad="9"
+ width="135">
<button.commit_callback
function="OpenObject.MoveToInventory" />
</button>
<button
follows="bottom|left"
height="23"
- label="Copy and add to outfit"
- label_selected="Copy and add to outfit"
+ label="Cancel"
+ label_selected="Cancel"
layout="topleft"
left_pad="5"
- name="copy_and_wear_button"
- width="135">
+ name="cancel_button"
+ width="120">
<button.commit_callback
- function="OpenObject.MoveAndWear" />
+ function="OpenObject.Cancel" />
</button>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml
index 41a7134b1d..9d91f801a6 100755
--- a/indra/newview/skins/default/xui/en/floater_pay.xml
+++ b/indra/newview/skins/default/xui/en/floater_pay.xml
@@ -2,12 +2,12 @@
<floater
legacy_header_height="18"
can_minimize="false"
- height="200"
+ height="186"
layout="topleft"
name="Give Money"
help_topic="give_money"
save_rect="true"
- width="250">
+ width="261">
<string
name="payee_group">
Pay Group
@@ -21,88 +21,129 @@
type="string"
length="1"
follows="left|top"
- font="SansSerifSmall"
height="16"
layout="topleft"
left="10"
- name="payee_name"
- top="25"
- use_ellipses="true"
- width="230">
- Test Name That Is Extremely Long To Check Clipping
+ top="24"
+ name="paying_text"
+ width="180">
+ You are paying:
</text>
- <button
- height="23"
- label="L$1"
- label_selected="L$1"
- layout="topleft"
- left="35"
- name="fastpay 1"
- top_pad="8"
- width="80" />
- <button
- height="23"
- label="L$5"
- label_selected="L$5"
- layout="topleft"
- left_pad="15"
- name="fastpay 5"
- width="80" />
- <button
- height="23"
- label="L$10"
- label_selected="L$10"
- layout="topleft"
- left="35"
- name="fastpay 10"
- top_pad="8"
- width="80" />
- <button
- height="23"
- label="L$20"
- label_selected="L$20"
- layout="topleft"
- left_pad="15"
- name="fastpay 20"
- width="80" />
<text
type="string"
length="1"
follows="left|top"
- height="18"
+ font="SansSerifSmall"
+ height="16"
layout="topleft"
- left="35"
- name="amount text"
- top_pad="8"
+ left="10"
+ top_pad="5"
+ name="payee_name"
+ use_ellipses="true"
width="180">
- Or, choose amount:
+ Test Name That Is Extremely Long To Check Clipping
</text>
- <line_editor
- border_style="line"
- follows="left|top|right"
- height="19"
- top_pad="0"
- layout="topleft"
- left="130"
- max_length_bytes="9"
- name="amount"
- width="80" />
- <button
- enabled="false"
- height="23"
- label="Pay"
- label_selected="Pay"
- layout="topleft"
- left="20"
- name="pay btn"
- top_pad="15"
- width="100" />
- <button
- height="23"
- label="Cancel"
- label_selected="Cancel"
+ <panel
+ border_thickness="0"
+ height="104"
+ label="Search"
layout="topleft"
+ left="0"
+ top_pad="10"
+ help_topic="avatarpicker"
+ name="PatternsPanel"
+ width="120">
+ <button
+ height="23"
+ label="Pay L$ 1"
+ label_selected="Pay L$ 1"
+ layout="topleft"
+ left="10"
+ top="0"
+ name="fastpay 1"
+ width="110" />
+ <button
+ height="23"
+ label="Pay L$ 5"
+ label_selected="Pay L$ 5"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ name="fastpay 5"
+ width="110" />
+ <button
+ height="23"
+ label="Pay L$ 10"
+ label_selected="Pay L$ 10"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ name="fastpay 10"
+ width="110" />
+ <button
+ height="23"
+ label="Pay L$ 20"
+ label_selected="Pay L$ 20"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ name="fastpay 20"
+ width="110" />
+ </panel>
+ <view_border
+ bevel_style="in"
+ width="1"
+ height="104"
left_pad="10"
- name="cancel btn"
- width="100" />
+ layout="topleft" />
+ <panel
+ border_thickness="0"
+ height="104"
+ label="Search"
+ layout="topleft"
+ left_pad="0"
+ name="InputPanel"
+ width="120">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="18"
+ layout="topleft"
+ left="10"
+ top="0"
+ name="amount text"
+ width="110">
+ Other amount:
+ </text>
+ <line_editor
+ border_style="line"
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left="10"
+ top_pad="0"
+ max_length_bytes="9"
+ name="amount"
+ width="90" />
+ <button
+ enabled="false"
+ height="23"
+ label="Pay"
+ label_selected="Pay"
+ layout="topleft"
+ left="10"
+ top_pad="17"
+ name="pay btn"
+ width="110" />
+ <button
+ height="23"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ name="cancel btn"
+ width="110" />
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml
index d3a35c2051..f1e27b918e 100755
--- a/indra/newview/skins/default/xui/en/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml
@@ -2,12 +2,12 @@
<floater
legacy_header_height="18"
can_minimize="false"
- height="225"
+ height="228"
layout="topleft"
name="Give Money"
help_topic="give_money"
save_rect="true"
- width="250">
+ width="261">
<string
name="payee_group">
Pay Group
@@ -16,12 +16,25 @@
name="payee_resident">
Pay Resident
</string>
+
<text
+ type="string"
+ length="1"
follows="left|top"
height="16"
layout="topleft"
left="10"
- top_pad="24"
+ top="24"
+ name="paying_text"
+ width="180">
+ You are paying:
+ </text>
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ top_pad="5"
name="payee_name"
use_ellipses="true"
width="225">
@@ -40,7 +53,7 @@
width="180">
Via object:
</text>
- <icon
+ <icon
height="16"
width="16"
image_name="Inv_Object"
@@ -64,78 +77,107 @@
width="188">
My awesome object with a really damn long name
</text>
- <button
- height="23"
- label="L$1"
- label_selected="L$1"
- layout="topleft"
- left="25"
- name="fastpay 1"
- top_pad="8"
- width="80" />
- <button
- height="23"
- label="L$5"
- label_selected="L$5"
- layout="topleft"
- left_pad="15"
- name="fastpay 5"
- width="80" />
- <button
- height="23"
- label="L$10"
- label_selected="L$10"
- layout="topleft"
- left="25"
- name="fastpay 10"
- top_pad="8"
- width="80" />
- <button
- height="23"
- label="L$20"
- label_selected="L$20"
+ <panel
+ border_thickness="0"
+ height="104"
+ label="Search"
layout="topleft"
- left_pad="15"
- name="fastpay 20"
- width="80" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="14"
- layout="topleft"
- left="25"
- name="amount text"
- top_pad="8"
- width="180">
- Or, choose amount:
- </text>
- <line_editor
- border_style="line"
- follows="left|top|right"
- height="21"
- top_pad="0"
- layout="topleft"
- left="120"
- max_length_bytes="9"
- name="amount"
- width="80" />
- <button
- enabled="false"
- height="23"
- label="Pay"
- label_selected="Pay"
- layout="topleft"
- left="10"
- name="pay btn"
- top_pad="5"
- width="100" />
- <button
- height="23"
- label="Cancel"
- label_selected="Cancel"
+ left="0"
+ top_pad="10"
+ help_topic="avatarpicker"
+ name="PatternsPanel"
+ width="120">
+ <button
+ height="23"
+ label="Pay L$ 1"
+ label_selected="Pay L$ 1"
+ layout="topleft"
+ left="10"
+ top="0"
+ name="fastpay 1"
+ width="110" />
+ <button
+ height="23"
+ label="Pay L$ 5"
+ label_selected="Pay L$ 5"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ name="fastpay 5"
+ width="110" />
+ <button
+ height="23"
+ label="Pay L$ 10"
+ label_selected="Pay L$ 10"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ name="fastpay 10"
+ width="110" />
+ <button
+ height="23"
+ label="Pay L$ 20"
+ label_selected="Pay L$ 20"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ name="fastpay 20"
+ width="110" />
+ </panel>
+ <view_border
+ bevel_style="in"
+ width="1"
+ height="104"
+ left_pad="10"
+ layout="topleft" />
+ <panel
+ border_thickness="0"
+ height="104"
+ label="Search"
layout="topleft"
- left_pad="5"
- name="cancel btn"
- width="100" />
+ left_pad="0"
+ name="InputPanel"
+ width="120">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="18"
+ layout="topleft"
+ left="10"
+ top="0"
+ name="amount text"
+ width="180">
+ Other amount:
+ </text>
+ <line_editor
+ border_style="line"
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left="10"
+ top_pad="0"
+ max_length_bytes="9"
+ name="amount"
+ width="90" />
+ <button
+ enabled="false"
+ height="23"
+ label="Pay"
+ label_selected="Pay"
+ layout="topleft"
+ left="10"
+ top_pad="17"
+ name="pay btn"
+ width="110" />
+ <button
+ height="23"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ name="cancel btn"
+ width="110" />
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 6fa45d7d66..7099db63ab 100755
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -531,7 +531,7 @@
name="Sound Play">
<menu_item_call.on_click
function="Inventory.DoToSelected"
- parameter="open" />
+ parameter="sound_play" />
</menu_item_call>
<menu_item_separator
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index de441983d0..560f81a6fd 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2105,6 +2105,18 @@
parameter="notifications_console" />
</menu_item_call>
<menu_item_check
+ label="Region Debug Console"
+ name="Region Debug Console"
+ shortcut="control|shift|`"
+ use_mac_ctrl="true">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="region_debug_console" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="region_debug_console" />
+ </menu_item_check>
+ <menu_item_check
label="Fast Timers"
name="Fast Timers"
shortcut="control|shift|9"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f1d34a1449..ea1bc66236 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5246,6 +5246,19 @@ Warning: The &apos;Pay object&apos; click action has been set, but it will only
<notification
icon="alertmodal.tga"
+ name="PayConfirmation"
+ type="alertmodal">
+ Confirm that you want to pay L$[AMOUNT] to [TARGET].
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm before paying (sums over L$200)"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Pay"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="OpenObjectCannotCopy"
type="alertmodal">
There are no items in this object that you are allowed to copy.
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 5dcb8e2cdf..945a77c071 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2307,6 +2307,7 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
<string name="LoadingContents">Loading contents...</string>
<string name="NoContents">No contents</string>
<string name="WornOnAttachmentPoint" value=" (worn on [ATTACHMENT_POINT])" />
+ <string name="AttachmentErrorMessage" value=" ([ATTACHMENT_ERROR])" />
<string name="ActiveGesture" value="[GESLABEL] (active)"/>
<!-- Inventory permissions -->
<string name="PermYes">Yes</string>
@@ -2433,9 +2434,12 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
<string name="Stomach">Stomach</string>
<string name="Left Pec">Left Pec</string>
<string name="Right Pec">Right Pec</string>
- <string name="Neck">Neck</string>
- <string name="Avatar Center">Avatar Center</string>
+ <string name="Neck">Neck</string>
+ <string name="Avatar Center">Avatar Center</string>
<string name="Invalid Attachment">Invalid Attachment Point</string>
+ <string name="ATTACHMENT_MISSING_ITEM">Error: missing item</string>
+ <string name="ATTACHMENT_MISSING_BASE_ITEM">Error: missing base item</string>
+ <string name="ATTACHMENT_NOT_ATTACHED">Error: object is in current outfit but not attached</string>
<!-- Avatar age computation, see LLDateUtil::ageFromDate -->
<string name="YearsMonthsOld">[AGEYEARS] [AGEMONTHS] old</string>