diff --git a/.hgtags b/.hgtags
index c52a7b1806..6aef4978db 100755
--- a/.hgtags
+++ b/.hgtags
@@ -525,3 +525,4 @@ bcc2770e21c125e0bab59141c51db9145aec068d 3.7.17-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 01cc606db9..d8cebeb19f 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1742,9 +1742,9 @@
archive
name
linux
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 5eff4dd7e2..2daf0d2d43 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 92fa541422..b55c6a8844 100755
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -603,8 +603,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 );
@@ -696,6 +694,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 d81741da4a..87c47a24ae 100755
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -159,11 +159,17 @@ protected:
BOOL mIsBuilt; // state of deferred character building
typedef std::vector 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
+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);
+ 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);
+ 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);
}
-
-//--------------------------------------------------------------------
-// setPosition()
-//--------------------------------------------------------------------
-void LLJoint::setDefaultFromCurrentXform( void )
-{
- mDefaultXform = mXform;
-}
-
-//--------------------------------------------------------------------
-// storeCurrentXform()
-//--------------------------------------------------------------------
-void LLJoint::storeCurrentXform( const LLVector3& pos )
-{
- mOldXform = mXform;
- mResetAfterRestoreOldXform = true;
- setPosition( pos );
- touch(ALL_DIRTY);
-}
-
-//--------------------------------------------------------------------
-// storeScaleForReset()
-//--------------------------------------------------------------------
-void LLJoint::storeScaleForReset( const LLVector3& scale )
+void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info )
{
- mOldXform.setScale( scale );
+ 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;
}
+
//--------------------------------------------------------------------
-// restoreOldXform()
+// addAttachmentPosOverride()
//--------------------------------------------------------------------
-void LLJoint::restoreOldXform( void )
-{
- mXform = mDefaultXform;
- mResetAfterRestoreOldXform = false;
- mDirtyFlags = ALL_DIRTY;
+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);
}
+
+//--------------------------------------------------------------------
+// removeAttachmentPosOverride()
+//--------------------------------------------------------------------
+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);
+ }
+
+}
+
+//--------------------------------------------------------------------
+ // hasAttachmentPosOverride()
+ //--------------------------------------------------------------------
+bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const
+{
+ return m_attachmentOverrides.findActiveOverride(mesh_id,pos);
+}
+
+//--------------------------------------------------------------------
+// clearAttachmentPosOverrides()
+//--------------------------------------------------------------------
+void LLJoint::clearAttachmentPosOverrides()
+{
+ if (m_attachmentOverrides.count())
+ {
+ m_attachmentOverrides.clear();
+ setPosition(m_posBeforeOverrides);
+ setId( LLUUID::null );
+ }
+}
+
+//--------------------------------------------------------------------
+// updatePos()
+//--------------------------------------------------------------------
+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 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/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 73204e8b19..96599d3944 100755
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -180,18 +180,18 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& 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))
{
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& 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/llrender.cpp b/indra/llrender/llrender.cpp
index 9e2a5310e8..21bdbdde72 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/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index ace64311bf..b7c0413897 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -277,20 +277,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
-
+ if (filter_generation < 0)
+ {
+ filter_generation = getFolderViewModel()->getFilter().getFirstSuccessGeneration();
+ }
LLFolderViewModelItem* model = getViewModelItem();
- if (model->getLastFilterGeneration() < 0 && !getFolderViewModel()->getFilter().isModified())
+ BOOL visible = model->passedFilter(filter_generation);
+ if (model->getMarkedDirtyGeneration() >= filter_generation)
{
- return model->descendantsPassedFilter(filter_generation) || getVisible();
- }
- else
- {
- 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 efeaa50840..c548e78c3a 100755
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -203,11 +203,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;
@@ -251,6 +253,7 @@ public:
mFolderViewItem(NULL),
mLastFilterGeneration(-1),
mLastFolderFilterGeneration(-1),
+ mMarkedDirtyGeneration(-1),
mMostFilteredDescendantGeneration(-1),
mParent(NULL),
mRootViewModel(root_view_model)
@@ -264,8 +267,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;
@@ -275,6 +283,14 @@ public:
mParent->dirtyFilter();
}
}
+ void dirtyDescendantsFilter()
+ {
+ mMostFilteredDescendantGeneration = -1;
+ if (mParent)
+ {
+ mParent->dirtyDescendantsFilter();
+ }
+ }
bool hasFilterStringMatch();
std::string::size_type getFilterStringOffset();
std::string::size_type getFilterStringSize();
@@ -293,7 +309,7 @@ public:
return;
}
}
- mChildren.push_back(child);
+ mChildren.push_back(child);
child->setParent(this);
dirtyFilter();
requestSort();
@@ -301,7 +317,8 @@ public:
virtual void removeChild(LLFolderViewModelItem* child)
{
mChildren.remove(child);
- child->setParent(NULL);
+ child->setParent(NULL);
+ dirtyDescendantsFilter();
dirtyFilter();
}
@@ -311,6 +328,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();
}
@@ -324,6 +342,7 @@ public:
mLastFilterGeneration = filter_generation;
mStringMatchOffsetFilter = string_offset;
mStringFilterSize = string_size;
+ mMarkedDirtyGeneration = -1;
}
void setPassedFolderFilter(bool passed, S32 filter_generation)
@@ -372,7 +391,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 233c65dd12..7f88846f55 100755
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -528,11 +528,7 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLW
}
// Skip white space
-
- // use iswspace in case *cur > 0xFF
- // while( *cur && isspace(*cur) && (*cur != '\n') )
while( *cur && iswspace(*cur) && (*cur != '\n') )
- //
{
cur++;
}
@@ -575,11 +571,7 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLW
}
// Skip white space
-
- // use iswspace in case *cur > 0xFF
- // while( *cur && isspace(*cur) && (*cur != '\n') )
while( *cur && iswspace(*cur) && (*cur != '\n') )
- //
{
cur++;
}
@@ -687,9 +679,11 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLW
// check against words
llwchar prev = cur > base ? *(cur-1) : 0;
// NaCl - LSL Preprocessor
+ //if( !iswalnum( prev ) && (prev != '_') )
if( !iswalnum( prev ) && (prev != '_') && (prev != '#'))
{
const llwchar* p = cur;
+ //while( iswalnum( *p ) || (*p == '_') )
while( *p && ( iswalnum( *p ) || (*p == '_') || (*p == '#') ) )
// NaCl End
{
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 39b968ba02..e025365fd3 100755
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1281,7 +1281,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 )
@@ -3271,6 +3279,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/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 28d7d4e6c8..a29308f850 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 aa28cf5e69..7defdfc2df 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 0e12a4f7b0..4619b2b07a 100755
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -49,7 +49,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());
@@ -70,7 +71,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());
@@ -136,6 +138,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;
}
@@ -227,6 +234,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 mUrlEntry;
LLUrlEntryBase* mUrlEntryIcon;
+ LLUrlEntryBase* mUrlEntryHTTPLabel;
+ LLUrlEntryBase* mUrlEntrySLLabel;
};
#endif
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 6d2aad9784..0e9441c14c 100755
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -946,7 +946,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 a39740a82b..b3a9a666ae 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];
@@ -326,13 +344,6 @@ attributedStringInfo getSegments(NSAttributedString *str)
callRightMouseUp(mMousePos, [theEvent modifierFlags]);
}
-// Fix FIRE-14282/BUG-6875 with the solution provided in LL's jira.
-- (void) rightMouseDragged:(NSEvent *)theEvent
-{
- [self mouseDragged:theEvent];
-}
-//
-
- (void)mouseMoved:(NSEvent *)theEvent
{
float mouseDeltas[2] = {
@@ -379,9 +390,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
callMiddleMouseUp(mMousePos, [theEvent modifierFlags]);
}
+- (void) rightMouseDragged:(NSEvent *)theEvent
+{
+ [self mouseDragged:theEvent];
+}
+
- (void) otherMouseDragged:(NSEvent *)theEvent
{
- [self mouseDragged:theEvent]; // Fix FIRE-14282/BUG-6875 with the solution provided in LL's jira.
+ [self mouseDragged:theEvent];
}
- (void) scrollWheel:(NSEvent *)theEvent
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 359db30c83..658d8770d3 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -117,6 +117,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 cb7976c470..900ee8e52e 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -361,6 +361,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/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f189f974b7..868e5e50d6 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8486,7 +8486,7 @@
Type
F32
Value
- 30.0
+ 600.0
MemoryPrivatePoolEnabled