diff --git a/indra/cmake/CopyWinLibs.cmake b/indra/cmake/CopyWinLibs.cmake index afd4d31f7..17d5eab02 100644 --- a/indra/cmake/CopyWinLibs.cmake +++ b/indra/cmake/CopyWinLibs.cmake @@ -16,11 +16,14 @@ endif(WORD_SIZE EQUAL 32) set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-win32") set(vivox_files - SLVoice.exe - alut.dll - vivoxsdk.dll + ca-bundle.crt + libsndfile-1.dll ortp.dll - wrap_oal.dll + SLVoice.exe + vivoxoal.dll + vivoxplatform.dll + vivoxsdk.dll + zlib1.dll ) copy_if_different( ${vivox_src_dir} diff --git a/indra/cwdebug/debug.h b/indra/cwdebug/debug.h index 3c59db690..58e0c6ac9 100644 --- a/indra/cwdebug/debug.h +++ b/indra/cwdebug/debug.h @@ -392,6 +392,40 @@ void InstanceTracker::dump(void) } // namespace debug +template +class AIDebugInstanceCounter +{ + public: + static int sInstanceCount; + + protected: + static void print_count(char const* name, int count, bool destruction); + + AIDebugInstanceCounter() + { + print_count(typeid(T).name(), ++sInstanceCount, false); + } + AIDebugInstanceCounter(AIDebugInstanceCounter const&) + { + print_count(typeid(T).name(), ++sInstanceCount, false); + } + ~AIDebugInstanceCounter() + { + print_count(typeid(T).name(), --sInstanceCount, true); + } +}; + +//static +template +int AIDebugInstanceCounter::sInstanceCount; + +//static +template +void AIDebugInstanceCounter::print_count(char const* name, int count, bool destruction) +{ + Dout(dc::notice, (destruction ? "Destructed " : "Constructing ") << name << ", now " << count << " instance" << ((count == 1) ? "." : "s.")); +} + //! Debugging macro. // // Print "Entering " << \a data to channel \a cntrl and increment diff --git a/indra/libhacd/hacdHACD.h b/indra/libhacd/hacdHACD.h index 2ca9a4ae7..fd9fd4301 100644 --- a/indra/libhacd/hacdHACD.h +++ b/indra/libhacd/hacdHACD.h @@ -317,7 +317,7 @@ namespace HACD bool m_addFacesPoints; //>! specifies whether to add faces points or not bool m_addExtraDistPoints; //>! specifies whether to add extra points for concave shapes or not - friend HACD * const CreateHACD(HeapManager * heapManager = 0); + friend HACD * const CreateHACD(HeapManager * heapManager); friend void DestroyHACD(HACD * const hacd); }; inline HACD * const CreateHACD(HeapManager * heapManager) diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h index 917511daa..3ff894dba 100644 --- a/indra/llaudio/llaudiodecodemgr.h +++ b/indra/llaudio/llaudiodecodemgr.h @@ -24,7 +24,7 @@ */ #ifndef LL_LLAUDIODECODEMGR_H -#define LL_LLAUDIODECODEMG_H +#define LL_LLAUDIODECODEMGR_H #include "stdtypes.h" diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index 6652333ef..8dda476d9 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -29,7 +29,6 @@ set(llcharacter_SOURCE_FILES lljointsolverrp3.cpp llkeyframefallmotion.cpp llkeyframemotion.cpp - llkeyframemotionparam.cpp llkeyframestandmotion.cpp llkeyframewalkmotion.cpp llmotion.cpp @@ -57,7 +56,6 @@ set(llcharacter_HEADER_FILES lljointstate.h llkeyframefallmotion.h llkeyframemotion.h - llkeyframemotionparam.h llkeyframestandmotion.h llkeyframewalkmotion.h llmotion.h diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 888c20cd4..12960ac01 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -136,7 +136,6 @@ LLMotion* LLCharacter::findMotion( const LLUUID &id ) //----------------------------------------------------------------------------- // createMotion() -// NOTE: Always assign the result to a LLPointer! //----------------------------------------------------------------------------- LLMotion* LLCharacter::createMotion( const LLUUID &id ) { @@ -195,11 +194,26 @@ void LLCharacter::updateMotions(e_update_t update_type) { if (update_type == HIDDEN_UPDATE) { + // + // Keep updating avatars that have at least one motion that is synchronized with a still running motion. + // This call tells the other controllers that we are in principle hidden. + // It returns false if we need to keep updating anyway. + if (!mMotionController.hidden(true)) + { + mMotionController.updateMotions(LLCharacter::NORMAL_UPDATE); + return; + } + // LLFastTimer t(FTM_UPDATE_HIDDEN_ANIMATION); mMotionController.updateMotionsMinimal(); } else { + // + // This call tells the other controllers that we are visible and that they need + // to keep updating if they are synchronized with us, even if they are hidden. + mMotionController.hidden(false); + // LLFastTimer t(FTM_UPDATE_ANIMATION); // unpause if the number of outstanding pause requests has dropped to the initial one if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1) @@ -529,3 +543,17 @@ LLAnimPauseRequest LLCharacter::requestPause() return mPauseRequest; } +void LLCharacter::requestPause(std::vector& avatar_pause_handles) +{ + mMotionController.pauseAllMotions(); + avatar_pause_handles.push_back(mPauseRequest); +} + +void LLCharacter::pauseAllSyncedCharacters(std::vector& avatar_pause_handles) +{ + // Pause this avatar. + requestPause(avatar_pause_handles); + // Also pause all avatars with synchronized motions. + mMotionController.pauseAllSyncedCharacters(avatar_pause_handles); +} + diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 2b872effa..f618b446f 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -146,6 +146,7 @@ public: // is this motion active? BOOL isMotionActive( const LLUUID& id ); + bool isMotionActive(U32 bit) const { return mMotionController.isactive(bit); } // Event handler for motion deactivation. // Called when a motion has completely stopped and has been deactivated. @@ -158,6 +159,8 @@ public: void updateMotions(e_update_t update_type); LLAnimPauseRequest requestPause(); + void requestPause(std::vector& avatar_pause_handles); + void pauseAllSyncedCharacters(std::vector& avatar_pause_handles); BOOL areAnimationsPaused() const { return mMotionController.isPaused(); } void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); } void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); } diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index c2a87d80a..d07f37779 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -49,7 +49,7 @@ S32 LLEditingMotion::sHandPosePriority = 3; // LLEditingMotion() // Class Constructor //----------------------------------------------------------------------------- -LLEditingMotion::LLEditingMotion( const LLUUID &id) : LLMotion(id) +LLEditingMotion::LLEditingMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_EDITING) { mCharacter = NULL; @@ -155,7 +155,7 @@ BOOL LLEditingMotion::onActivate() mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); - return TRUE; + return AIMaskedMotion::onActivate(); } //----------------------------------------------------------------------------- @@ -256,12 +256,4 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) return result; } -//----------------------------------------------------------------------------- -// LLEditingMotion::onDeactivate() -//----------------------------------------------------------------------------- -void LLEditingMotion::onDeactivate() -{ -} - - // End diff --git a/indra/llcharacter/lleditingmotion.h b/indra/llcharacter/lleditingmotion.h index 4a83d4b9f..bc95ff682 100644 --- a/indra/llcharacter/lleditingmotion.h +++ b/indra/llcharacter/lleditingmotion.h @@ -49,11 +49,11 @@ // class LLEditingMotion //----------------------------------------------------------------------------- class LLEditingMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLEditingMotion(const LLUUID &id); + LLEditingMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLEditingMotion(); @@ -65,7 +65,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLEditingMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLEditingMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -107,9 +107,6 @@ public: // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - public: //------------------------------------------------------------------------- // joint states to be animated diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp index 696dba0d9..be6dbb050 100644 --- a/indra/llcharacter/llhandmotion.cpp +++ b/indra/llcharacter/llhandmotion.cpp @@ -61,7 +61,7 @@ const F32 HAND_MORPH_BLEND_TIME = 0.2f; // LLHandMotion() // Class Constructor //----------------------------------------------------------------------------- -LLHandMotion::LLHandMotion(const LLUUID &id) : LLMotion(id) +LLHandMotion::LLHandMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_HAND_MOTION) { mCharacter = NULL; mLastTime = 0.f; @@ -112,7 +112,7 @@ BOOL LLHandMotion::onActivate() mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); mCharacter->updateVisualParams(); } - return TRUE; + return AIMaskedMotion::onActivate(); } @@ -235,14 +235,6 @@ BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask) return TRUE; } - -//----------------------------------------------------------------------------- -// LLHandMotion::onDeactivate() -//----------------------------------------------------------------------------- -void LLHandMotion::onDeactivate() -{ -} - //----------------------------------------------------------------------------- // LLHandMotion::getHandPoseName() //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llhandmotion.h b/indra/llcharacter/llhandmotion.h index dcf169662..012c3c6be 100644 --- a/indra/llcharacter/llhandmotion.h +++ b/indra/llcharacter/llhandmotion.h @@ -45,7 +45,7 @@ // class LLHandMotion //----------------------------------------------------------------------------- class LLHandMotion : - public LLMotion + public AIMaskedMotion { public: typedef enum e_hand_pose @@ -68,7 +68,7 @@ public: } eHandPose; // Constructor - LLHandMotion(const LLUUID &id); + LLHandMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLHandMotion(); @@ -80,7 +80,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLHandMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLHandMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -122,9 +122,6 @@ public: // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - virtual BOOL canDeprecate() { return FALSE; } static std::string getHandPoseName(eHandPose pose); diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 0ee378f3b..79912f9d5 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -76,8 +76,8 @@ const F32 EYE_BLINK_TIME_DELTA = 0.005f; // time between one eye starting a blin // LLHeadRotMotion() // Class Constructor //----------------------------------------------------------------------------- -LLHeadRotMotion::LLHeadRotMotion(const LLUUID &id) : - LLMotion(id), +LLHeadRotMotion::LLHeadRotMotion(LLUUID const& id, LLMotionController* controller) : + AIMaskedMotion(id, controller, ANIM_AGENT_HEAD_ROT), mCharacter(NULL), mTorsoJoint(NULL), mHeadJoint(NULL) @@ -104,7 +104,10 @@ LLHeadRotMotion::~LLHeadRotMotion() LLMotion::LLMotionInitStatus LLHeadRotMotion::onInitialize(LLCharacter *character) { if (!character) + { + llwarns << "character is NULL." << llendl; return STATUS_FAILURE; + } mCharacter = character; mPelvisJoint = character->getJoint("mPelvis"); @@ -169,16 +172,6 @@ LLMotion::LLMotionInitStatus LLHeadRotMotion::onInitialize(LLCharacter *characte return STATUS_SUCCESS; } - -//----------------------------------------------------------------------------- -// LLHeadRotMotion::onActivate() -//----------------------------------------------------------------------------- -BOOL LLHeadRotMotion::onActivate() -{ - return TRUE; -} - - //----------------------------------------------------------------------------- // LLHeadRotMotion::onUpdate() //----------------------------------------------------------------------------- @@ -263,19 +256,11 @@ BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask) } -//----------------------------------------------------------------------------- -// LLHeadRotMotion::onDeactivate() -//----------------------------------------------------------------------------- -void LLHeadRotMotion::onDeactivate() -{ -} - - //----------------------------------------------------------------------------- // LLEyeMotion() // Class Constructor //----------------------------------------------------------------------------- -LLEyeMotion::LLEyeMotion(const LLUUID &id) : LLMotion(id) +LLEyeMotion::LLEyeMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_EYE) { mCharacter = NULL; mEyeJitterTime = 0.f; @@ -343,16 +328,6 @@ LLMotion::LLMotionInitStatus LLEyeMotion::onInitialize(LLCharacter *character) return STATUS_SUCCESS; } - -//----------------------------------------------------------------------------- -// LLEyeMotion::onActivate() -//----------------------------------------------------------------------------- -BOOL LLEyeMotion::onActivate() -{ - return TRUE; -} - - //----------------------------------------------------------------------------- // LLEyeMotion::onUpdate() //----------------------------------------------------------------------------- @@ -533,6 +508,8 @@ void LLEyeMotion::onDeactivate() { joint->setRotation(LLQuaternion::DEFAULT); } + + AIMaskedMotion::onDeactivate(); } // End diff --git a/indra/llcharacter/llheadrotmotion.h b/indra/llcharacter/llheadrotmotion.h index 97e61eac1..5fa4610bf 100644 --- a/indra/llcharacter/llheadrotmotion.h +++ b/indra/llcharacter/llheadrotmotion.h @@ -46,11 +46,11 @@ // class LLHeadRotMotion //----------------------------------------------------------------------------- class LLHeadRotMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLHeadRotMotion(const LLUUID &id); + LLHeadRotMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLHeadRotMotion(); @@ -62,7 +62,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLHeadRotMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLHeadRotMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -94,19 +94,11 @@ public: // must return true to indicate success and be available for activation virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - public: //------------------------------------------------------------------------- // joint states to be animated @@ -129,11 +121,11 @@ public: // class LLEyeMotion //----------------------------------------------------------------------------- class LLEyeMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLEyeMotion(const LLUUID &id); + LLEyeMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLEyeMotion(); @@ -145,7 +137,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create( const LLUUID &id) { return new LLEyeMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLEyeMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -177,11 +169,6 @@ public: // must return true to indicate success and be available for activation virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index fe14c1e44..cb55e6ca7 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -41,7 +41,7 @@ #include "lldarray.h" const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15; -const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 4! +const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 16! const U32 LL_HAND_JOINT_NUM = 31; const U32 LL_FACE_JOINT_NUM = 30; const S32 LL_CHARACTER_MAX_PRIORITY = 7; diff --git a/indra/llcharacter/llkeyframefallmotion.cpp b/indra/llcharacter/llkeyframefallmotion.cpp index 15ad1b9e9..336d79e65 100644 --- a/indra/llcharacter/llkeyframefallmotion.cpp +++ b/indra/llcharacter/llkeyframefallmotion.cpp @@ -49,7 +49,7 @@ // LLKeyframeFallMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeFallMotion::LLKeyframeFallMotion(const LLUUID &id) : LLKeyframeMotion(id) +LLKeyframeFallMotion::LLKeyframeFallMotion(LLUUID const& id, LLMotionController* controller) : LLKeyframeMotion(id, controller) { mVelocityZ = 0.f; mCharacter = NULL; diff --git a/indra/llcharacter/llkeyframefallmotion.h b/indra/llcharacter/llkeyframefallmotion.h index 495be977f..0d2553ce3 100644 --- a/indra/llcharacter/llkeyframefallmotion.h +++ b/indra/llcharacter/llkeyframefallmotion.h @@ -47,7 +47,7 @@ class LLKeyframeFallMotion : { public: // Constructor - LLKeyframeFallMotion(const LLUUID &id); + LLKeyframeFallMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLKeyframeFallMotion(); @@ -59,7 +59,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeFallMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLKeyframeFallMotion(id, controller); } public: //------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 98906d3d4..711ac21e5 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -84,38 +84,55 @@ LLKeyframeMotion::JointMotionList::~JointMotionList() for_each(mJointMotionArray.begin(), mJointMotionArray.end(), DeletePointer()); } -U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo() +//Singu: add parameter 'silent'. +U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo(bool silent) const { S32 total_size = sizeof(JointMotionList); for (U32 i = 0; i < getNumJointMotions(); i++) { - LLKeyframeMotion::JointMotion* joint_motion_p = mJointMotionArray[i]; + LLKeyframeMotion::JointMotion const* joint_motion_p = mJointMotionArray[i]; - llinfos << "\tJoint " << joint_motion_p->mJointName << llendl; + if (!silent) + { + llinfos << "\tJoint " << joint_motion_p->mJointName << llendl; + } if (joint_motion_p->mUsage & LLJointState::SCALE) { - llinfos << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at " - << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << llendl; - + if (!silent) + { + llinfos << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at " + << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << llendl; + } total_size += joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey); } if (joint_motion_p->mUsage & LLJointState::ROT) { - llinfos << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at " - << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << llendl; - + if (!silent) + { + llinfos << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at " + << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << llendl; + } total_size += joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey); } if (joint_motion_p->mUsage & LLJointState::POS) { - llinfos << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at " - << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << llendl; - + if (!silent) + { + llinfos << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at " + << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << llendl; + } total_size += joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey); } } - llinfos << "Size: " << total_size << " bytes" << llendl; + //Singu: Also add memory used by the constraints. + S32 constraints_size = mConstraints.size() * sizeof(constraint_list_t::value_type); + total_size += constraints_size; + if (!silent) + { + llinfos << "\t" << mConstraints.size() << " constraints at " << constraints_size << " bytes" << llendl; + llinfos << "Size: " << total_size << " bytes" << llendl; + } return total_size; } @@ -427,9 +444,8 @@ void LLKeyframeMotion::JointMotion::update(LLJointState* joint_state, F32 time, // LLKeyframeMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id) - : LLMotion(id), - mJointMotionList(NULL), +LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id, LLMotionController* controller) + : LLMotion(id, controller), mPelvisp(NULL), mLastSkeletonSerialNum(0), mLastUpdateTime(0.f), @@ -452,9 +468,9 @@ LLKeyframeMotion::~LLKeyframeMotion() //----------------------------------------------------------------------------- // create() //----------------------------------------------------------------------------- -LLMotion *LLKeyframeMotion::create(const LLUUID &id) +LLMotion* LLKeyframeMotion::create(LLUUID const& id, LLMotionController* controller) { - return new LLKeyframeMotion(id); + return new LLKeyframeMotion(id, controller); } //----------------------------------------------------------------------------- @@ -517,6 +533,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact case ASSET_FETCHED: return STATUS_HOLD; case ASSET_FETCH_FAILED: + llwarns << "Trying to initialize a motion that failed to be fetched." << llendl; return STATUS_FAILURE; case ASSET_LOADED: return STATUS_SUCCESS; @@ -526,7 +543,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact break; } - LLKeyframeMotion::JointMotionList* joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID()); + LLKeyframeMotion::JointMotionListPtr joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID()); if(joint_motion_list) { @@ -801,7 +818,44 @@ void LLKeyframeMotion::onDeactivate() //----------------------------------------------------------------------------- // setStopTime() //----------------------------------------------------------------------------- -// time is in seconds since character creation +// +// Consider a looping animation of 20 frames, where the loop in point is at 3 frames +// and the loop out point at 16 frames: +// +// The first 3 frames of the animation would be the "loop in" animation. +// The last 4 frames of the animation would be the "loop out" animation. +// Frames 4 through 15 would be the looping animation frames. +// +// If the animation would not be looping, all frames would just be played once sequentially: +// +// mActivationTimestamp -. +// v +// 0 3 15 16 20 +// | | \| | +// --------------------- +// <--> <-- mLoopInPoint (relative to mActivationTimestamp) +// <--------------> <-- mLoopOutPoint (relative to mActivationTimestamp) +// <----mDuration------> +// +// When looping the animation would repeat frames 3 to 16 (loop) a few times, for example: +// +// 0 3 15 3 15 3 15 3 15 16 20 +// | | loop 1 \| loop 2 \| loop 3 \| loop 4 \| | +// ------------------------------------------------------------ +//LOOP^ ^ LOOP +// IN | <----->| OUT +// start_loop_time loop_fraction_time-' time +// +// The time at which the animation is started corresponds to frame 0 and is stored +// in mActivationTimestamp (in seconds since character creation). +// +// If setStopTime() is called with a time somewhere inside loop 4, +// then 'loop_fraction_time' is the time from the beginning of +// loop 4 till 'time'. Thus 'time - loop_fraction_time' is the first +// frame of loop 4, and '(time - loop_fraction_time) + +// (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint)' +// would correspond to frame 20. +// void LLKeyframeMotion::setStopTime(F32 time) { LLMotion::setStopTime(time); @@ -819,6 +873,8 @@ void LLKeyframeMotion::setStopTime(F32 time) loop_fraction_time = fmod(time - start_loop_time, mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint); } + // This sets mStopTimestamp to the time that corresponds to the end of the animation (ie, frame 20 in the above example) + // minus the ease out duration, so that the animation eases out during the loop out and finishes exactly at the end. mStopTimestamp = llmax(time, (time - loop_fraction_time) + (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint) - getEaseOutDuration()); } @@ -1227,13 +1283,42 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 } } +// Helper class. +template +struct AIAutoDestruct +{ + T* mPtr; + AIAutoDestruct() : mPtr(NULL) { } + ~AIAutoDestruct() { delete mPtr; } + void add(T* ptr) { mPtr = ptr; } +}; + //----------------------------------------------------------------------------- // deserialize() //----------------------------------------------------------------------------- BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) { BOOL old_version = FALSE; - mJointMotionList = new LLKeyframeMotion::JointMotionList; + + // + + // First add a new LLKeyframeMotion::JointMotionList to the cache, then assign a pointer + // to that to mJointMotionList. In LLs code the cache is never deleted again. Now it is + // is deleted when the last mJointMotionList pointer is destructed. + // + // It is possible that we get here for an already added animation, because animations can + // be requested multiple times (we get here from LLKeyframeMotion::onLoadComplete) when + // the animation was still downloading from a previous request for another LLMotionController + // object (avatar). In that case we just overwrite the old data while decoding it again. + mJointMotionList = LLKeyframeDataCache::getKeyframeData(getID()); + bool singu_new_joint_motion_list = !mJointMotionList; + if (singu_new_joint_motion_list) + { + // Create a new JointMotionList. + mJointMotionList = LLKeyframeDataCache::createKeyframeData(getID()); + } + + // //------------------------------------------------------------------------- // get base priority @@ -1396,8 +1481,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } - mJointMotionList->mJointMotionArray.clear(); - mJointMotionList->mJointMotionArray.reserve(num_motions); + if (singu_new_joint_motion_list) + { + mJointMotionList->mJointMotionArray.reserve(num_motions); + } mJointStates.clear(); mJointStates.reserve(num_motions); @@ -1407,8 +1494,19 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) for(U32 i=0; i watcher; + JointMotion* joint_motion = new JointMotion; - mJointMotionList->mJointMotionArray.push_back(joint_motion); + if (singu_new_joint_motion_list) + { + // Pass ownership to mJointMotionList. + mJointMotionList->mJointMotionArray.push_back(joint_motion); + } + else + { + // Just delete this at the end. + watcher.add(joint_motion); + } std::string joint_name; if (!dp.unpackString(joint_name, "joint_name")) @@ -1836,7 +1934,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } - mJointMotionList->mConstraints.push_front(constraintp); + AIAutoDestruct watcher; + if (singu_new_joint_motion_list) + { + mJointMotionList->mConstraints.push_front(constraintp); + } + else + { + watcher.add(constraintp); + } constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte @@ -1876,15 +1982,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (constraintp->mJointStateIndices[i] < 0 ) { llwarns << "No joint index for constraint " << i << llendl; - delete constraintp; return FALSE; } } } } - // *FIX: support cleanup of old keyframe data - LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList); mAssetStatus = ASSET_LOADED; setupPose(); @@ -2226,16 +2329,24 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, //-------------------------------------------------------------------- // LLKeyframeDataCache::dumpDiagInfo() //-------------------------------------------------------------------- -void LLKeyframeDataCache::dumpDiagInfo() +// +// quiet = 0 : print everything in detail. +// 1 : print the UUIDs of all animations in the cache and the total memory usage. +// 2 : only print the total memory usage. +// +void LLKeyframeDataCache::dumpDiagInfo(int quiet) { // keep track of totals U32 total_size = 0; char buf[1024]; /* Flawfinder: ignore */ - llinfos << "-----------------------------------------------------" << llendl; - llinfos << " Global Motion Table (DEBUG only)" << llendl; - llinfos << "-----------------------------------------------------" << llendl; + if (quiet < 2) + { + llinfos << "-----------------------------------------------------" << llendl; + llinfos << " Global Motion Table" << llendl; + llinfos << "-----------------------------------------------------" << llendl; + } // print each loaded mesh, and it's memory usage for (keyframe_data_map_t::iterator map_it = sKeyframeDataMap.begin(); @@ -2243,30 +2354,46 @@ void LLKeyframeDataCache::dumpDiagInfo() { U32 joint_motion_kb; - LLKeyframeMotion::JointMotionList *motion_list_p = map_it->second; + LLKeyframeMotion::JointMotionList const* motion_list_p = map_it->get(); - llinfos << "Motion: " << map_it->first << llendl; + if (quiet < 2) + { + llinfos << "Motion: " << map_it->key() << llendl; + } - joint_motion_kb = motion_list_p->dumpDiagInfo(); - - total_size += joint_motion_kb; + if (motion_list_p) + { + joint_motion_kb = motion_list_p->dumpDiagInfo(quiet); + total_size += joint_motion_kb; + } } - llinfos << "-----------------------------------------------------" << llendl; + if (quiet < 2) + { + llinfos << "-----------------------------------------------------" << llendl; + } llinfos << "Motions\tTotal Size" << llendl; snprintf(buf, sizeof(buf), "%d\t\t%d bytes", (S32)sKeyframeDataMap.size(), total_size ); /* Flawfinder: ignore */ llinfos << buf << llendl; - llinfos << "-----------------------------------------------------" << llendl; + if (quiet < 2) + { + llinfos << "-----------------------------------------------------" << llendl; + } } //-------------------------------------------------------------------- -// LLKeyframeDataCache::addKeyframeData() +// LLKeyframeDataCache::createKeyframeData() //-------------------------------------------------------------------- -void LLKeyframeDataCache::addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList* joint_motion_listp) +// This function replaces LLKeyframeDataCache::addKeyframeData and was rewritten to fix a memory leak (aka, the usage of AICachedPointer). +LLKeyframeMotion::JointMotionListPtr LLKeyframeDataCache::createKeyframeData(LLUUID const& id) { - sKeyframeDataMap[id] = joint_motion_listp; + std::pair result = + sKeyframeDataMap.insert(AICachedPointer(id, new LLKeyframeMotion::JointMotionList, &sKeyframeDataMap)); + llassert(result.second); // id may not already exist in the cache. + return &*result.first; // Construct and return a JointMotionListPt from a pointer to the actually inserted AICachedPointer. } +// //-------------------------------------------------------------------- // LLKeyframeDataCache::removeKeyframeData() @@ -2276,7 +2403,6 @@ void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id) keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id); if (found_data != sKeyframeDataMap.end()) { - delete found_data->second; sKeyframeDataMap.erase(found_data); } } @@ -2284,14 +2410,14 @@ void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id) //-------------------------------------------------------------------- // LLKeyframeDataCache::getKeyframeData() //-------------------------------------------------------------------- -LLKeyframeMotion::JointMotionList* LLKeyframeDataCache::getKeyframeData(const LLUUID& id) +LLKeyframeMotion::JointMotionListPtr LLKeyframeDataCache::getKeyframeData(const LLUUID& id) { keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id); if (found_data == sKeyframeDataMap.end()) { return NULL; } - return found_data->second; + return &*found_data; // Construct and return a JointMotionListPt from a pointer to the found AICachedPointer. } //-------------------------------------------------------------------- @@ -2307,7 +2433,6 @@ LLKeyframeDataCache::~LLKeyframeDataCache() //----------------------------------------------------------------------------- void LLKeyframeDataCache::clear() { - for_each(sKeyframeDataMap.begin(), sKeyframeDataMap.end(), DeletePairedPointer()); sKeyframeDataMap.clear(); } diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 50d9d0504..4c54d5500 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -5,6 +5,7 @@ * $LicenseInfo:firstyear=2001&license=viewergpl$ * * Copyright (c) 2001-2009, Linden Research, Inc. + * AICachedPointer and AICachedPointPtr copyright (c) 2013, Aleric Inglewood. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -48,10 +49,12 @@ #include "v3dmath.h" #include "v3math.h" #include "llbvhconsts.h" +#include class LLKeyframeDataCache; class LLVFS; class LLDataPacker; +class LLMotionController; #define MIN_REQUIRED_PIXEL_AREA_KEYFRAME (40.f) #define MAX_CHAIN_LENGTH (4) @@ -59,6 +62,112 @@ class LLDataPacker; const S32 KEYFRAME_MOTION_VERSION = 1; const S32 KEYFRAME_MOTION_SUBVERSION = 0; +//----------------------------------------------------------------------------- +// + +template +class AICachedPointer; + +template +void intrusive_ptr_add_ref(AICachedPointer const* p); + +template +void intrusive_ptr_release(AICachedPointer const* p); + +template +class AICachedPointer +{ + public: + typedef std::set > container_type; + + private: + KEY mKey; // The unique key. + LLPointer mData; // The actual data pointer. + container_type* mCache; // Pointer to the underlaying cache. + mutable int mRefCount; // Number of AICachedPointerPtr's pointing to this object. + + public: + // Construct a NULL pointer. This is needed when adding a new entry to a std::set, it is always first default constructed. + AICachedPointer(void) : mCache(NULL) { } + + // Copy constructor. This is needed to replace the std::set inserted instance with its actual value. + AICachedPointer(AICachedPointer const& cptr) : mKey(cptr.mKey), mData(cptr.mData), mCache(cptr.mCache), mRefCount(0) { } + + // Construct a AICachedPointer that points to 'ptr' with key 'key'. + AICachedPointer(KEY const& key, T* ptr, container_type* cache) : mKey(key), mData(ptr), mCache(cache), mRefCount(-1) { } + + // Construct a temporary NULL pointer that can be used in a search for a key. + AICachedPointer(KEY const& key) : mKey(key), mCache(NULL) { } + + // Accessors for key and data. + KEY const& key(void) const { return mKey; } + T const* get(void) const { return mData.get(); } + T* get(void) { return mData.get(); } + + // Order only by key. + friend bool operator<(AICachedPointer const& cp1, AICachedPointer const& cp2) { return cp1.mKey < cp2.mKey; } + + private: + friend void intrusive_ptr_add_ref<>(AICachedPointer const* p); + friend void intrusive_ptr_release<>(AICachedPointer const* p); + + private: + AICachedPointer& operator=(AICachedPointer const&); +}; + +template +void intrusive_ptr_add_ref(AICachedPointer const* p) +{ + llassert(p->mCache); + if (p->mCache) + { + p->mRefCount++; + } +} + +template +void intrusive_ptr_release(AICachedPointer const* p) +{ + llassert(p->mCache); + if (p->mCache) + { + if (--p->mRefCount == 0) + { + p->mCache->erase(p->mKey); + } + } +} + +template +class AICachedPointerPtr +{ + private: + boost::intrusive_ptr const> mPtr; + static int sCnt; + + public: + AICachedPointerPtr(void) { ++sCnt; } + AICachedPointerPtr(AICachedPointerPtr const& cpp) : mPtr(cpp.mPtr) { ++sCnt; } + AICachedPointerPtr(AICachedPointer const* cp) : mPtr(cp) { ++sCnt; } + ~AICachedPointerPtr() { --sCnt; } + + typedef boost::intrusive_ptr const> const AICachedPointerPtr::* const bool_type; + operator bool_type() const { return mPtr ? &AICachedPointerPtr::mPtr : NULL; } + + T const* operator->() const { return mPtr->get(); } + T* operator->() { return const_cast&>(*mPtr).get(); } + T const& operator*() const { return *mPtr->get(); } + T& operator*() { return *const_cast&>(*mPtr).get(); } + + AICachedPointerPtr& operator=(AICachedPointerPtr const& cpp) { mPtr = cpp.mPtr; return *this; } +}; + +template +int AICachedPointerPtr::sCnt; + +// +//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // class LLKeyframeMotion //----------------------------------------------------------------------------- @@ -68,7 +177,7 @@ class LLKeyframeMotion : friend class LLKeyframeDataCache; public: // Constructor - LLKeyframeMotion(const LLUUID &id); + LLKeyframeMotion(const LLUUID &id, LLMotionController* controller); // Destructor virtual ~LLKeyframeMotion(); @@ -85,7 +194,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID& id); + static LLMotion* create(LLUUID const& id, LLMotionController* controller); public: //------------------------------------------------------------------------- @@ -158,7 +267,7 @@ public: U32 getFileSize(); BOOL serialize(LLDataPacker& dp) const; BOOL deserialize(LLDataPacker& dp); - BOOL isLoaded() { return mJointMotionList != NULL; } + BOOL isLoaded() { return !!mJointMotionList; } // setters for modifying a keyframe animation @@ -393,7 +502,7 @@ public: //------------------------------------------------------------------------- // JointMotionList //------------------------------------------------------------------------- - class JointMotionList + class JointMotionList : public LLRefCount { public: std::vector mJointMotionArray; @@ -416,19 +525,22 @@ public: public: JointMotionList(); ~JointMotionList(); - U32 dumpDiagInfo(); + U32 dumpDiagInfo(bool silent = false) const; JointMotion* getJointMotion(U32 index) const { llassert(index < mJointMotionArray.size()); return mJointMotionArray[index]; } U32 getNumJointMotions() const { return mJointMotionArray.size(); } }; + // Singu: Type of a pointer to the cached pointer (in LLKeyframeDataCache::sKeyframeDataMap) to a JointMotionList object. + typedef AICachedPointerPtr JointMotionListPtr; + protected: static LLVFS* sVFS; //------------------------------------------------------------------------- // Member Data //------------------------------------------------------------------------- - JointMotionList* mJointMotionList; + JointMotionListPtr mJointMotionList; // singu: automatically clean up cache entry when destructed. std::vector > mJointStates; LLJoint* mPelvisp; LLCharacter* mCharacter; @@ -442,21 +554,24 @@ protected: class LLKeyframeDataCache { -public: - // *FIX: implement this as an actual singleton member of LLKeyframeMotion +private: + friend class LLKeyframeMotion; LLKeyframeDataCache(){}; ~LLKeyframeDataCache(); - typedef std::map keyframe_data_map_t; +public: + typedef AICachedPointer::container_type keyframe_data_map_t; // singu: add automatic cache cleanup. static keyframe_data_map_t sKeyframeDataMap; - static void addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList*); - static LLKeyframeMotion::JointMotionList* getKeyframeData(const LLUUID& id); + // + static LLKeyframeMotion::JointMotionListPtr createKeyframeData(LLUUID const& id); // id may not exist. + static LLKeyframeMotion::JointMotionListPtr getKeyframeData(LLUUID const& id); // id may or may not exists. Returns a NULL pointer when it doesn't exist. + // static void removeKeyframeData(const LLUUID& id); //print out diagnostic info - static void dumpDiagInfo(); + static void dumpDiagInfo(int quiet = 0); // singu: added param 'quiet'. static void clear(); }; diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp deleted file mode 100644 index 4df1ef46b..000000000 --- a/indra/llcharacter/llkeyframemotionparam.cpp +++ /dev/null @@ -1,456 +0,0 @@ -/** - * @file llkeyframemotionparam.cpp - * @brief Implementation of LLKeyframeMotion class. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -//----------------------------------------------------------------------------- -// Header Files -//----------------------------------------------------------------------------- -#include "linden_common.h" - -#include "llkeyframemotionparam.h" -#include "llcharacter.h" -#include "llmath.h" -#include "m3math.h" -#include "lldir.h" -#include "llanimationstates.h" - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam class -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam() -// Class Constructor -//----------------------------------------------------------------------------- -LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id) -{ - mDefaultKeyframeMotion = NULL; - mCharacter = NULL; - - mEaseInDuration = 0.f; - mEaseOutDuration = 0.f; - mDuration = 0.f; - mPriority = LLJoint::LOW_PRIORITY; -} - - -//----------------------------------------------------------------------------- -// ~LLKeyframeMotionParam() -// Class Destructor -//----------------------------------------------------------------------------- -LLKeyframeMotionParam::~LLKeyframeMotionParam() -{ - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - delete paramMotion.mMotion; - } - motionList.clear(); - } - mParameterizedMotions.clear(); -} - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::onInitialize(LLCharacter *character) -//----------------------------------------------------------------------------- -LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character) -{ - mCharacter = character; - - if (!loadMotions()) - { - return STATUS_FAILURE; - } - - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - LLMotion* motion = paramMotion.mMotion; - motion->onInitialize(character); - - if (motion->getDuration() > mEaseInDuration) - { - mEaseInDuration = motion->getEaseInDuration(); - } - - if (motion->getEaseOutDuration() > mEaseOutDuration) - { - mEaseOutDuration = motion->getEaseOutDuration(); - } - - if (motion->getDuration() > mDuration) - { - mDuration = motion->getDuration(); - } - - if (motion->getPriority() > mPriority) - { - mPriority = motion->getPriority(); - } - - LLPose *pose = motion->getPose(); - - mPoseBlender.addMotion(motion); - for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) - { - LLPose *blendedPose = mPoseBlender.getBlendedPose(); - blendedPose->addJointState(jsp); - } - } - } - - return STATUS_SUCCESS; -} - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::onActivate() -//----------------------------------------------------------------------------- -BOOL LLKeyframeMotionParam::onActivate() -{ - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - paramMotion.mMotion->activate(mActivationTimestamp); - } - } - return TRUE; -} - - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::onUpdate() -//----------------------------------------------------------------------------- -BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) -{ - F32 weightFactor = 1.f / (F32)mParameterizedMotions.size(); - - // zero out all pose weights - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; -// llinfos << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << llendl; - paramMotion.mMotion->getPose()->setWeight(0.f); - } - } - - - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - const std::string& paramName = iter->first; - F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName); - if (NULL == paramValue) // unexpected, but... - { - llwarns << "paramValue == NULL" << llendl; - continue; - } - - // DANGER! Do not modify mParameterizedMotions while using these pointers! - const ParameterizedMotion* firstMotion = NULL; - const ParameterizedMotion* secondMotion = NULL; - - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - paramMotion.mMotion->onUpdate(time, joint_mask); - - F32 distToParam = paramMotion.mParam - *paramValue; - - if ( distToParam <= 0.f) - { - // keep track of the motion closest to the parameter value - firstMotion = ¶mMotion; - } - else - { - // we've passed the parameter value - // so store the first motion we find as the second one we want to blend... - if (firstMotion && !secondMotion ) - { - secondMotion = ¶mMotion; - } - //...or, if we've seen no other motion so far, make sure we blend to this only - else if (!firstMotion) - { - firstMotion = ¶mMotion; - secondMotion = ¶mMotion; - } - } - } - - LLPose *firstPose; - LLPose *secondPose; - - if (firstMotion) - firstPose = firstMotion->mMotion->getPose(); - else - firstPose = NULL; - - if (secondMotion) - secondPose = secondMotion->mMotion->getPose(); - else - secondPose = NULL; - - // now modify weight of the subanim (only if we are blending between two motions) - if (firstMotion && secondMotion) - { - if (firstMotion == secondMotion) - { - firstPose->setWeight(weightFactor); - } - else if (firstMotion->mParam == secondMotion->mParam) - { - firstPose->setWeight(0.5f * weightFactor); - secondPose->setWeight(0.5f * weightFactor); - } - else - { - F32 first_weight = 1.f - - ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) / - (secondMotion->mParam - firstMotion->mParam)); - first_weight = llclamp(first_weight, 0.f, 1.f); - - F32 second_weight = 1.f - first_weight; - - firstPose->setWeight(first_weight * weightFactor); - secondPose->setWeight(second_weight * weightFactor); - -// llinfos << "Parameter " << *paramName << ": " << *paramValue << llendl; -// llinfos << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << llendl; - } - } - else if (firstMotion && !secondMotion) - { - firstPose->setWeight(weightFactor); - } - } - - // blend poses - mPoseBlender.blendAndApply(); - - llinfos << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << llendl; - - return TRUE; -} - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::onDeactivate() -//----------------------------------------------------------------------------- -void LLKeyframeMotionParam::onDeactivate() -{ - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - paramMotion.mMotion->onDeactivate(); - } - } -} - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::addKeyframeMotion() -//----------------------------------------------------------------------------- -BOOL LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value) -{ - LLMotion *newMotion = mCharacter->createMotion( id ); - - if (!newMotion) - { - return FALSE; - } - - newMotion->setName(name); - - // now add motion to this list - mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value)); - - return TRUE; -} - - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::setDefaultKeyframeMotion() -//----------------------------------------------------------------------------- -void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name) -{ - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - if (paramMotion.mMotion->getName() == name) - { - mDefaultKeyframeMotion = paramMotion.mMotion; - } - } - } -} - -//----------------------------------------------------------------------------- -// loadMotions() -//----------------------------------------------------------------------------- -BOOL LLKeyframeMotionParam::loadMotions() -{ - //------------------------------------------------------------------------- - // Load named file by concatenating the character prefix with the motion name. - // Load data into a buffer to be parsed. - //------------------------------------------------------------------------- - //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix()) - // + "_" + getName() + ".llp"; - //RN: deprecated unused reference to "motion" directory - std::string path; - - - //------------------------------------------------------------------------- - // open the file - //------------------------------------------------------------------------- - S32 fileSize = 0; - LLAPRFile infile(path, LL_APR_R, &fileSize); - apr_file_t* fp = infile.getFileHandle() ; - if (!fp || fileSize == 0) - { - llinfos << "ERROR: can't open: " << path << llendl; - return FALSE; - } - - // allocate a text buffer - try - { - std::vector text(fileSize+1); - - //------------------------------------------------------------------------- - // load data from file into buffer - //------------------------------------------------------------------------- - bool error = false; - char *p = &text[0]; - while ( 1 ) - { - if (apr_file_eof(fp) == APR_EOF) - { - break; - } - if (apr_file_gets(p, 1024, fp) != APR_SUCCESS) - { - error = true; - break; - } - while ( *(++p) ) - ; - } - - //------------------------------------------------------------------------- - // close the file - //------------------------------------------------------------------------- - infile.close(); - - //------------------------------------------------------------------------- - // check for error - //------------------------------------------------------------------------- - llassert( p <= (&text[0] + fileSize) ); - - if ( error ) - { - llinfos << "ERROR: error while reading from " << path << llendl; - return FALSE; - } - - llinfos << "Loading parametric keyframe data for: " << getName() << llendl; - - //------------------------------------------------------------------------- - // parse the text and build keyframe data structures - //------------------------------------------------------------------------- - p = &text[0]; - S32 num; - char strA[80]; /* Flawfinder: ignore */ - char strB[80]; /* Flawfinder: ignore */ - F32 floatA = 0.0f; - - - //------------------------------------------------------------------------- - // get priority - //------------------------------------------------------------------------- - BOOL isFirstMotion = TRUE; - num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */ - - while(1) - { - if (num == 0 || num == EOF) break; - if ((num != 3)) - { - llinfos << "WARNING: can't read parametric motion" << llendl; - return FALSE; - } - - addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA); - if (isFirstMotion) - { - isFirstMotion = FALSE; - setDefaultKeyframeMotion(strA); - } - - p = strstr(p, "\n"); - if (!p) - { - break; - } - - p++; - num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */ - } - - return TRUE; - } - catch(std::bad_alloc) - { - llinfos << "ERROR: Unable to allocate keyframe text buffer." << llendl; - return FALSE; - } -} - -// End diff --git a/indra/llcharacter/llkeyframemotionparam.h b/indra/llcharacter/llkeyframemotionparam.h deleted file mode 100644 index f74aea276..000000000 --- a/indra/llcharacter/llkeyframemotionparam.h +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @file llkeyframemotionparam.h - * @brief Implementation of LLKeframeMotionParam class. - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLKEYFRAMEMOTIONPARAM_H -#define LL_LLKEYFRAMEMOTIONPARAM_H - -//----------------------------------------------------------------------------- -// Header files -//----------------------------------------------------------------------------- - -#include - -#include "llmotion.h" -#include "lljointstate.h" -#include "v3math.h" -#include "llquaternion.h" -#include "linked_lists.h" -#include "llkeyframemotion.h" - -//----------------------------------------------------------------------------- -// class LLKeyframeMotionParam -//----------------------------------------------------------------------------- -class LLKeyframeMotionParam : - public LLMotion -{ -public: - // Constructor - LLKeyframeMotionParam(const LLUUID &id); - - // Destructor - virtual ~LLKeyframeMotionParam(); - -public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- - - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeMotionParam(id); } - -public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- - - // motions must specify whether or not they loop - virtual BOOL getLoop() { - return TRUE; - } - - // motions must report their total duration - virtual F32 getDuration() { - return mDuration; - } - - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { - return mEaseInDuration; - } - - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { - return mEaseOutDuration; - } - - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { - return mPriority; - } - - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; } - - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character); - - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask); - - // called when a motion is deactivated - virtual void onDeactivate(); - - virtual LLPose* getPose() { return mPoseBlender.getBlendedPose();} - -protected: - //------------------------------------------------------------------------- - // new functions defined by this subclass - //------------------------------------------------------------------------- - struct ParameterizedMotion - { - ParameterizedMotion(LLMotion* motion, F32 param) : mMotion(motion), mParam(param) {} - LLMotion* mMotion; - F32 mParam; - }; - - // add a motion and associated parameter triplet - BOOL addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value); - - // set default motion for LOD and retrieving blend constants - void setDefaultKeyframeMotion(char *); - - BOOL loadMotions(); - -protected: - //------------------------------------------------------------------------- - // Member Data - //------------------------------------------------------------------------- - - struct compare_motions - { - bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const - { - if (a.mParam != b.mParam) - return (a.mParam < b.mParam); - else - return a.mMotion < b.mMotion; - } - }; - - typedef std::set < ParameterizedMotion, compare_motions > motion_list_t; - typedef std::map motion_map_t; - motion_map_t mParameterizedMotions; - LLMotion* mDefaultKeyframeMotion; - LLCharacter* mCharacter; - LLPoseBlender mPoseBlender; - - F32 mEaseInDuration; - F32 mEaseOutDuration; - F32 mDuration; - LLJoint::JointPriority mPriority; - - LLUUID mTransactionID; -}; - -#endif // LL_LLKEYFRAMEMOTIONPARAM_H diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index 1ae0ddeea..bccc714f1 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -50,7 +50,7 @@ const F32 POSITION_THRESHOLD = 0.1f; // LLKeyframeStandMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeStandMotion::LLKeyframeStandMotion(const LLUUID &id) : LLKeyframeMotion(id) +LLKeyframeStandMotion::LLKeyframeStandMotion(LLUUID const& id, LLMotionController* controller) : LLKeyframeMotion(id, controller) { mFlipFeet = FALSE; mCharacter = NULL; diff --git a/indra/llcharacter/llkeyframestandmotion.h b/indra/llcharacter/llkeyframestandmotion.h index b0500dc8e..346df97f0 100644 --- a/indra/llcharacter/llkeyframestandmotion.h +++ b/indra/llcharacter/llkeyframestandmotion.h @@ -48,7 +48,7 @@ class LLKeyframeStandMotion : { public: // Constructor - LLKeyframeStandMotion(const LLUUID &id); + LLKeyframeStandMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLKeyframeStandMotion(); @@ -60,7 +60,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeStandMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLKeyframeStandMotion(id, controller); } public: //------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp index f9c2e4766..21d6fce30 100644 --- a/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/indra/llcharacter/llkeyframewalkmotion.cpp @@ -55,8 +55,8 @@ const F32 SPEED_ADJUST_TIME_CONSTANT = 0.1f; // time constant for speed adjustm // LLKeyframeWalkMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeWalkMotion::LLKeyframeWalkMotion(const LLUUID &id) -: LLKeyframeMotion(id), +LLKeyframeWalkMotion::LLKeyframeWalkMotion(LLUUID const& id, LLMotionController* controller) +: LLKeyframeMotion(id, controller), mCharacter(NULL), mCyclePhase(0.0f), mRealTimeLast(0.0f), @@ -138,8 +138,8 @@ BOOL LLKeyframeWalkMotion::onUpdate(F32 time, U8* joint_mask) // LLWalkAdjustMotion() // Class Constructor //----------------------------------------------------------------------------- -LLWalkAdjustMotion::LLWalkAdjustMotion(const LLUUID &id) : - LLMotion(id), +LLWalkAdjustMotion::LLWalkAdjustMotion(LLUUID const& id, LLMotionController* controller) : + AIMaskedMotion(id, controller, ANIM_AGENT_WALK_ADJUST), mLastTime(0.f), mAnimSpeed(0.f), mAdjustedSpeed(0.f), @@ -193,7 +193,7 @@ BOOL LLWalkAdjustMotion::onActivate() F32 rightAnkleOffset = (mRightAnkleJoint->getWorldPosition() - mCharacter->getCharacterPosition()).magVec(); mAnkleOffset = llmax(leftAnkleOffset, rightAnkleOffset); - return TRUE; + return AIMaskedMotion::onActivate(); } //----------------------------------------------------------------------------- @@ -325,13 +325,14 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask) void LLWalkAdjustMotion::onDeactivate() { mCharacter->removeAnimationData("Walk Speed"); + AIMaskedMotion::onDeactivate(); } //----------------------------------------------------------------------------- // LLFlyAdjustMotion::LLFlyAdjustMotion() //----------------------------------------------------------------------------- -LLFlyAdjustMotion::LLFlyAdjustMotion(const LLUUID &id) - : LLMotion(id), +LLFlyAdjustMotion::LLFlyAdjustMotion(LLUUID const& id, LLMotionController* controller) + : AIMaskedMotion(id, controller, ANIM_AGENT_FLY_ADJUST), mRoll(0.f) { mName = "fly_adjust"; @@ -368,7 +369,7 @@ BOOL LLFlyAdjustMotion::onActivate() mPelvisState->setPosition(LLVector3::zero); mPelvisState->setRotation(LLQuaternion::DEFAULT); mRoll = 0.f; - return TRUE; + return AIMaskedMotion::onActivate(); } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframewalkmotion.h b/indra/llcharacter/llkeyframewalkmotion.h index b507e9423..653c2b539 100644 --- a/indra/llcharacter/llkeyframewalkmotion.h +++ b/indra/llcharacter/llkeyframewalkmotion.h @@ -52,7 +52,7 @@ class LLKeyframeWalkMotion : friend class LLWalkAdjustMotion; public: // Constructor - LLKeyframeWalkMotion(const LLUUID &id); + LLKeyframeWalkMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLKeyframeWalkMotion(); @@ -64,7 +64,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeWalkMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLKeyframeWalkMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -86,11 +86,11 @@ public: S32 mDownFoot; }; -class LLWalkAdjustMotion : public LLMotion +class LLWalkAdjustMotion : public AIMaskedMotion { public: // Constructor - LLWalkAdjustMotion(const LLUUID &id); + LLWalkAdjustMotion(LLUUID const& id, LLMotionController* controller); public: //------------------------------------------------------------------------- @@ -99,7 +99,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLWalkAdjustMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLWalkAdjustMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -136,11 +136,11 @@ public: F32 mAnkleOffset; }; -class LLFlyAdjustMotion : public LLMotion +class LLFlyAdjustMotion : public AIMaskedMotion { public: // Constructor - LLFlyAdjustMotion(const LLUUID &id); + LLFlyAdjustMotion(LLUUID const& id, LLMotionController* controller); public: //------------------------------------------------------------------------- @@ -149,7 +149,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLFlyAdjustMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLFlyAdjustMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -157,7 +157,6 @@ public: //------------------------------------------------------------------------- virtual LLMotionInitStatus onInitialize(LLCharacter *character); virtual BOOL onActivate(); - virtual void onDeactivate() {}; virtual BOOL onUpdate(F32 time, U8* joint_mask); virtual LLJoint::JointPriority getPriority(){return LLJoint::HIGHER_PRIORITY;} virtual BOOL getLoop() { return TRUE; } diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp index ce926a38a..526341d20 100644 --- a/indra/llcharacter/llmotion.cpp +++ b/indra/llcharacter/llmotion.cpp @@ -37,6 +37,125 @@ #include "llmotion.h" #include "llcriticaldamp.h" +#include "llmotioncontroller.h" + +// +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// AISyncClientMotion class +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +AISyncKey* AISyncClientMotion::createSyncKey(AISyncKey const* from_key) const +{ + // The const cast is needed because getDuration() is non-const while it should have been. + AISyncClientMotion* self = const_cast(this); + // Only synchronize motions with the same duration and loop value. + return new AISyncKeyMotion(from_key, self->getDuration(), self->getLoop()); +} + +void AISyncClientMotion::aisync_loading(void) +{ + // Register the motion for (possible) synchronization: this marks the time at which is should have started. + unregister_client(); // In case it is already registered. Getting here means we are being (re)started now, we need to synchronize with other motions that start now. + register_client(); +} + +void AISyncClientMotion::aisync_loaded(void) +{ + AISyncServer* server = this->server(); + if (!server) + { + // Already expired without being synchronized (no other motion was started at the same time). + return; + } + AISyncKey const& key = server->key(); // The allocation of this is owned by server. + // There is no need to resync if there was not another motion started at the same time and the key already expired. + bool need_resync = !(server->never_synced() && key.expired()); + AISyncKey* new_key = NULL; + if (need_resync) + { + // Create a new key using the old start time. + new_key = createSyncKey(&key); + } + server->remove(this); // This resets mServer and might even delete server. + if (need_resync) + { + // Add the client to another server (based on the new key). This takes ownership of the key allocation. + AISyncServerMap::instance().register_client(this, new_key); + } +} + +F32 LLMotion::getRuntime(void) const +{ + llassert(mActive); + return mController->getAnimTime() - mActivationTimestamp; +} + +F32 LLMotion::getAnimTime(void) const +{ + return mController->getAnimTime(); +} + +F32 LLMotion::syncActivationTime(F32 time) +{ + AISyncServer* server = this->server(); + if (!server) + { + register_client(); + server = this->server(); + } + AISyncServer::client_list_t const& clients = server->getClients(); + if (clients.size() > 1) + { + // Look for the client with the smallest runtime. + AISyncClientMotion* motion_with_smallest_runtime = NULL; + F32 runtime = 1e10; + // Run over all motions in this to be synchronized group. + for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) + { + if ((client->mReadyEvents & 2)) // Is this motion active? Motions that aren't loaded yet are not active. + { + // Currently, if event 2 is set then this is an LLMotion. + llassert(dynamic_cast(client->mClientPtr)); + AISyncClientMotion* motion = static_cast(client->mClientPtr); + // Deactivated motions should have been deregistered, certainly not have event 2 set. + llassert(static_cast(motion)->isActive()); + if (motion->getRuntime() < runtime) + { + // This is a bit fuzzy since theoretically the runtime of all active motions in the list should be the same. + // Just use the smallest value to get rid of some randomness. We might even synchronizing with ourselves + // in which case 'time' would be set to a value such that mActivationTimestamp won't change. + // In practise however, this list will contain only two clients: this, being inactive, and our partner. + runtime = motion->getRuntime(); + motion_with_smallest_runtime = motion; + } + } + } + //----------------------------------------------------------------------------------------- + // Here is where the actual synchronization takes place. + // Current we only synchronize looped motions. + if (getLoop()) + { + if (motion_with_smallest_runtime) + { + // Pretend the motion was started in the past at the same time as the other motion(s). + time = getAnimTime() - runtime; + } + } + //----------------------------------------------------------------------------------------- + } + + return time; +} + +void AISyncClientMotion::deregistered(void) +{ +#ifdef SHOW_ASSERT + mReadyEvents = 0; +#endif +} +// //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -48,10 +167,11 @@ // LLMotion() // Class Constructor //----------------------------------------------------------------------------- -LLMotion::LLMotion( const LLUUID &id ) : +LLMotion::LLMotion(LLUUID const& id, LLMotionController* controller) : mStopped(TRUE), mActive(FALSE), mID(id), + mController(controller), mActivationTimestamp(0.f), mStopTimestamp(0.f), mSendStopTimestamp(F32_MAX), @@ -147,6 +267,19 @@ void LLMotion::activate(F32 time) { mActivationTimestamp = time; mStopped = FALSE; + // + if (mController && !mController->syncing_disabled()) // Avoid being registered when syncing is disabled for this motion. + { + if (mActive) + { + // If the motion is already active then we are being restarted. + // Unregister it first (if it is registered) so that the call to ready will cause it to be registered + // and be synchronized with other motions that are started at this moment. + unregister_client(); + } + ready(6, 2 | (mController->isHidden() ? 0 : 4)); // Signal that mActivationTimestamp is set/valid (2), and that this server has a visible motion (4) (or not). + } + // mActive = TRUE; onActivate(); } @@ -159,6 +292,14 @@ void LLMotion::deactivate() mActive = FALSE; mPose.setWeight(0.f); + // + if (server()) // Only when this motion is already registered. + { + ready(6, 0); // Signal that mActivationTimestamp is no longer valid. + unregister_client(); // No longer running, so no longer a part of this sync group. + } + // + if (mDeactivateCallback) { (*mDeactivateCallback)(mDeactivateCallbackUserData); @@ -174,4 +315,19 @@ BOOL LLMotion::canDeprecate() return TRUE; } +//----------------------------------------------------------------------------- +// AIMaskedMotion +//----------------------------------------------------------------------------- + +BOOL AIMaskedMotion::onActivate() +{ + mController->activated(mMaskBit); + return TRUE; +} + +void AIMaskedMotion::onDeactivate() +{ + mController->deactivated(mMaskBit); +} + // End diff --git a/indra/llcharacter/llmotion.h b/indra/llcharacter/llmotion.h index d6628fd99..a246b08c7 100644 --- a/indra/llcharacter/llmotion.h +++ b/indra/llcharacter/llmotion.h @@ -38,16 +38,85 @@ //----------------------------------------------------------------------------- #include +#include "aisyncclient.h" #include "llerror.h" #include "llpose.h" #include "lluuid.h" class LLCharacter; +class LLMotionController; + +//----------------------------------------------------------------------------- +// class AISync* stuff +//----------------------------------------------------------------------------- + +class AISyncKeyMotion : public AISyncKey +{ + private: + F32 mDuration; + bool mLoop; + + public: + AISyncKeyMotion(AISyncKey const* from_key, F32 duration, bool loop) : AISyncKey(from_key), mDuration(duration), mLoop(loop) { } + + // Virtual functions of AISyncKey. + public: + /*virtual*/ synckeytype_t getkeytype(void) const + { + // Return a unique identifier for this class, where the low 8 bits represent the syncgroup. + return synckeytype_motion; + } + + /*virtual*/ bool equals(AISyncKey const& key) const + { + switch (key.getkeytype()) + { + case synckeytype_motion: + { + // The other key is of the same type. + AISyncKeyMotion const& motion_key = static_cast(key); + return mLoop == motion_key.mLoop && is_approx_equal(mDuration, motion_key.mDuration); + } + default: + // The keys must be in the same syncgroup. + break; + } + return false; + } +}; + +class AISyncClientMotion : public AISyncClient +{ + protected: + // Make sure that clients that are destroyed are first unregistered. + // This is needed, for example, when loading fails or when excess motions are being purged. + /*virtual*/ ~AISyncClientMotion() { unregister_client(); } + + // AISyncClient events. + /*virtual*/ AISyncKey* createSyncKey(AISyncKey const* from_key = NULL) const; + /*virtual*/ void event1_ready(void) { } + /*virtual*/ void event1_not_ready(void) { } + /*virtual*/ void deregistered(void); + + protected: + // This is called when the server sent us a message that it wants us to play this animation, but we can't because it isn't fully downloaded yet. + void aisync_loading(void); + // This is called when that motion is successfully loaded and it has to be re-registered because now the duration etc is known. + void aisync_loaded(void); + + public: + // Virtual functions of AISyncClientMotion. + // These are defined by classes derived from LLMotion (which is derived from this class). + virtual BOOL getLoop() = 0; + virtual F32 getDuration() = 0; + virtual F32 getAnimTime(void) const = 0; + virtual F32 getRuntime(void) const = 0; +}; //----------------------------------------------------------------------------- // class LLMotion //----------------------------------------------------------------------------- -class LLMotion +class LLMotion : public AISyncClientMotion { friend class LLMotionController; @@ -66,7 +135,7 @@ public: }; // Constructor - LLMotion(const LLUUID &id); + LLMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLMotion(); @@ -114,7 +183,22 @@ protected: BOOL isActive() { return mActive; } public: void activate(F32 time); - + + // + // Returns the time that this motion has been running. + virtual F32 getRuntime(void) const; + + // Return the current time (in seconds since creation of the controller). + virtual F32 getAnimTime(void) const; + + // This is called when a motion is to be activated, but might need synchronization. + // It adjusts the start time to match that of other motions in the same synchronization group that were already started. + F32 syncActivationTime(F32 time); + + // Accessor. + LLMotionController* getController(void) const { return mController; } + // + public: //------------------------------------------------------------------------- // animation callbacks to be implemented by subclasses @@ -181,6 +265,9 @@ protected: //------------------------------------------------------------------------- std::string mName; // instance name assigned by motion controller LLUUID mID; + // + LLMotionController* mController; + // F32 mActivationTimestamp; // time when motion was activated F32 mStopTimestamp; // time when motion was told to stop @@ -199,9 +286,9 @@ protected: class LLTestMotion : public LLMotion { public: - LLTestMotion(const LLUUID &id) : LLMotion(id){} + LLTestMotion(LLUUID const& id, LLMotionController* controller) : LLMotion(id, controller){} ~LLTestMotion() {} - static LLMotion *create(const LLUUID& id) { return new LLTestMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLTestMotion(id, controller); } BOOL getLoop() { return FALSE; } F32 getDuration() { return 0.0f; } F32 getEaseInDuration() { return 0.0f; } @@ -223,9 +310,9 @@ public: class LLNullMotion : public LLMotion { public: - LLNullMotion(const LLUUID &id) : LLMotion(id) {} + LLNullMotion(LLUUID const& id, LLMotionController* controller) : LLMotion(id, controller) {} ~LLNullMotion() {} - static LLMotion *create(const LLUUID &id) { return new LLNullMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLNullMotion(id, controller); } // motions must specify whether or not they loop /*virtual*/ BOOL getLoop() { return TRUE; } @@ -266,5 +353,41 @@ public: // called when a motion is deactivated /*virtual*/ void onDeactivate() {} }; + + +//----------------------------------------------------------------------------- +// AIMaskedMotion +//----------------------------------------------------------------------------- + +// These motions have a bit assigned in LLMotionController::mActiveMask +// that is set and uset upon activation/deactivation. + +// This must be in the same order as ANIM_AGENT_BODY_NOISE_ID through ANIM_AGENT_WALK_ADJUST_ID in llvoavatar.cpp. +U32 const ANIM_AGENT_BODY_NOISE = 0x001; +U32 const ANIM_AGENT_BREATHE_ROT = 0x002; +U32 const ANIM_AGENT_PHYSICS_MOTION = 0x004; +U32 const ANIM_AGENT_EDITING = 0x008; +U32 const ANIM_AGENT_EYE = 0x010; +U32 const ANIM_AGENT_FLY_ADJUST = 0x020; +U32 const ANIM_AGENT_HAND_MOTION = 0x040; +U32 const ANIM_AGENT_HEAD_ROT = 0x080; +U32 const ANIM_AGENT_PELVIS_FIX = 0x100; +U32 const ANIM_AGENT_TARGET = 0x200; +U32 const ANIM_AGENT_WALK_ADJUST = 0x400; + +class AIMaskedMotion : public LLMotion +{ +private: + U32 mMaskBit; + +public: + AIMaskedMotion(LLUUID const& id, LLMotionController* controller, U32 mask_bit) : LLMotion(id, controller), mMaskBit(mask_bit) { } + + /*virtual*/ BOOL onActivate(); + /*virtual*/ void onDeactivate(); + + U32 getMaskBit(void) const { return mMaskBit; } +}; + #endif // LL_LLMOTION_H diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 35dcc1057..d12b3ddb6 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -97,7 +97,7 @@ void LLMotionRegistry::markBad( const LLUUID& id ) //----------------------------------------------------------------------------- // createMotion() //----------------------------------------------------------------------------- -LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) +LLMotion* LLMotionRegistry::createMotion(LLUUID const& id, LLMotionController* controller) { LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL)); LLMotion* motion = NULL; @@ -105,11 +105,11 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) if ( constructor == NULL ) { // *FIX: need to replace with a better default scheme. RN - motion = LLKeyframeMotion::create(id); + motion = LLKeyframeMotion::create(id, controller); } else { - motion = constructor(id); + motion = constructor(id, controller); } return motion; @@ -126,18 +126,22 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) // Class Constructor //----------------------------------------------------------------------------- LLMotionController::LLMotionController() - : mTimeFactor(sCurrentTimeFactor), + : mIsSelf(FALSE), + mTimeFactor(sCurrentTimeFactor), mCharacter(NULL), - mAnimTime(0.f), + mActiveMask(0), + mDisableSyncing(0), + mHidden(false), + mHaveVisibleSyncedMotions(false), mPrevTimerElapsed(0.f), + mAnimTime(0.f), mLastTime(0.0f), mHasRunOnce(FALSE), mPaused(FALSE), mPauseTime(0.f), mTimeStep(0.f), mTimeStepCount(0), - mLastInterp(0.f), - mIsSelf(FALSE) + mLastInterp(0.f) { } @@ -168,7 +172,15 @@ void LLMotionController::deleteAllMotions() mLoadingMotions.clear(); mLoadedMotions.clear(); mActiveMotions.clear(); - + // + mActiveMask = 0; + for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer()); + mDeprecatedMotions.clear(); + for (motion_map_t::iterator iter = mAllMotions.begin(); iter != mAllMotions.end(); ++iter) + { + iter->second->unregister_client(); + } + // for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer()); mAllMotions.clear(); } @@ -178,26 +190,19 @@ void LLMotionController::deleteAllMotions() //----------------------------------------------------------------------------- void LLMotionController::purgeExcessMotions() { - if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) + // + // The old code attempted to remove non-active motions from mDeprecatedMotions, + // but that is nonsense: there are no motions in mDeprecatedMotions that are not active. + if (mLoadedMotions.size() <= MAX_MOTION_INSTANCES) { - // clean up deprecated motions - for (motion_set_t::iterator deprecated_motion_it = mDeprecatedMotions.begin(); - deprecated_motion_it != mDeprecatedMotions.end(); ) - { - motion_set_t::iterator cur_iter = deprecated_motion_it++; - LLMotion* cur_motionp = *cur_iter; - if (!isMotionActive(cur_motionp)) - { - // Motion is deprecated so we know it's not cannonical, - // we can safely remove the instance - removeMotionInstance(cur_motionp); // modifies mDeprecatedMotions - mDeprecatedMotions.erase(cur_iter); - } - } + // Speed up, no need to create motions_to_kill. + return; } + // std::set motions_to_kill; - if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) + + if (1) // Singu: leave indentation alone... { // too many motions active this frame, kill all blenders mPoseBlender.clearBlenders(); @@ -308,24 +313,44 @@ BOOL LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor c void LLMotionController::removeMotion( const LLUUID& id) { LLMotion* motionp = findMotion(id); - mAllMotions.erase(id); - removeMotionInstance(motionp); + // + // If a motion is erased from mAllMotions, it must be deleted. + if (motionp) + { + mAllMotions.erase(id); + removeMotionInstance(motionp); + delete motionp; + } + // } // removes instance of a motion from all runtime structures, but does // not erase entry by ID, as this could be a duplicate instance -// use removeMotion(id) to remove all references to a given motion by id. +// use removeMotion(id) to remove a reference to a given motion by id +// (that will not remove (active) deprecated motions). void LLMotionController::removeMotionInstance(LLMotion* motionp) { if (motionp) { llassert(findMotion(motionp->getID()) != motionp); - if (motionp->isActive()) - motionp->deactivate(); mLoadingMotions.erase(motionp); mLoadedMotions.erase(motionp); mActiveMotions.remove(motionp); - delete motionp; + // + // Deactivation moved here. Only delete motionp when it is being removed from mDeprecatedMotions. + if (motionp->isActive()) + { + motionp->deactivate(); + // If a motion is deactivated, it must be removed from mDeprecatedMotions if there. + motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp); + if (found_it != mDeprecatedMotions.end()) + { + mDeprecatedMotions.erase(found_it); + // If a motion is erased from mDeprecatedMotions, it must be deleted. + delete motionp; + } + } + // } } @@ -341,7 +366,7 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id ) if (!motion) { // look up constructor and create it - motion = sRegistry.createMotion(id); + motion = sRegistry.createMotion(id, this); if (!motion) { return NULL; @@ -393,6 +418,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) if (motion && !mPaused && motion->canDeprecate() + && motion->isActive() // singu: do not deprecate motions that are not active. && motion->getFadeWeight() > 0.01f // not LOD-ed out && (motion->isBlending() || motion->getStopTime() != 0.f)) { @@ -418,7 +444,19 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) } // llinfos << "Starting motion " << name << llendl; - return activateMotionInstance(motion, mAnimTime - start_offset); + // + F32 start_time = mAnimTime - start_offset; + if (!mDisableSyncing) + { + start_time = motion->syncActivationTime(start_time); + } + ++mDisableSyncing; + // + BOOL res = activateMotionInstance(motion, start_time); + // + --mDisableSyncing; + // + return res; } @@ -774,7 +812,19 @@ void LLMotionController::updateLoadingMotions() // this motion should be playing if (!motionp->isStopped()) { - activateMotionInstance(motionp, mAnimTime); + // + F32 start_time = mAnimTime; + if (!mDisableSyncing) + { + motionp->aisync_loaded(); + start_time = motionp->syncActivationTime(start_time); + } + ++mDisableSyncing; + // + activateMotionInstance(motionp, start_time); + // + --mDisableSyncing; + // } } else if (status == LLMotion::STATUS_FAILURE) @@ -782,12 +832,15 @@ void LLMotionController::updateLoadingMotions() llinfos << "Motion " << motionp->getID() << " init failed." << llendl; sRegistry.markBad(motionp->getID()); mLoadingMotions.erase(curiter); - motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp); - if (found_it != mDeprecatedMotions.end()) - { - mDeprecatedMotions.erase(found_it); - } + // Singu note: a motion in mLoadingMotions will not be in mActiveMotions + // and therefore not be in mDeprecatedMotions. So, we don't have to + // check for it's existence there. + llassert(mDeprecatedMotions.find(motionp) == mDeprecatedMotions.end()); mAllMotions.erase(motionp->getID()); + // + // Make sure we're not registered anymore. + motionp->unregister_client(); + // delete motionp; } } @@ -821,8 +874,15 @@ void LLMotionController::updateMotions(bool force_update) { F32 time_interval = fmodf(update_time, mTimeStep); - // always animate *ahead* of actual time - S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1; + // + // This old code is nonsense. + //S32 quantum_count = llmax(0, llround((update_time - time_interval) / mTimeStep)) + 1; + // (update_time - time_interval) / mTimeStep is an integer! We need llround to get rid of floating point errors, not llfloor. + // Moreover, just rounding off to the nearest integer with llround(update_time / mTimeStep) makes a lot more sense: + // it is the best we can do to get as close to what we should draw as possible. + // However, mAnimTime may only be incremented; therefore make sure of that with the llmax. + S32 quantum_count = llmax(llround(update_time / mTimeStep), llceil(mAnimTime / mTimeStep)); + // if (quantum_count == mTimeStepCount) { // we're still in same time quantum as before, so just interpolate and exit @@ -848,7 +908,8 @@ void LLMotionController::updateMotions(bool force_update) } else { - mAnimTime = update_time; + // Singu note: mAnimTime may never be set back in time. + mAnimTime = llmax(mAnimTime, update_time); } } @@ -915,6 +976,12 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) if (mLoadingMotions.find(motion) != mLoadingMotions.end()) { + // + if (!syncing_disabled()) + { + motion->aisync_loading(); + } + // // we want to start this motion, but we can't yet, so flag it as started motion->setStopped(FALSE); // report pending animations as activated @@ -970,18 +1037,16 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) //----------------------------------------------------------------------------- BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion) { - motion->deactivate(); - motion_set_t::iterator found_it = mDeprecatedMotions.find(motion); if (found_it != mDeprecatedMotions.end()) { // deprecated motions need to be completely excised - removeMotionInstance(motion); - mDeprecatedMotions.erase(found_it); + removeMotionInstance(motion); // singu note: this deactivates motion and removes it from mDeprecatedMotions. } else { // for motions that we are keeping, simply remove from active queue + motion->deactivate(); // singu note: moved here from the top of the function. mActiveMotions.remove(motion); } @@ -1049,11 +1114,26 @@ void LLMotionController::dumpMotions() state_string += std::string("L"); if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end()) state_string += std::string("A"); - if (mDeprecatedMotions.find(motion) != mDeprecatedMotions.end()) - state_string += std::string("D"); + llassert(mDeprecatedMotions.find(motion) == mDeprecatedMotions.end()); // singu: it's impossible that a motion is in mAllMotions and mDeprecatedMotions at the same time. llinfos << gAnimLibrary.animationName(id) << " " << state_string << llendl; - } + // + // Also dump the deprecated motions. + for (motion_set_t::iterator iter = mDeprecatedMotions.begin(); + iter != mDeprecatedMotions.end(); ++iter) + { + std::string state_string; + LLMotion* motion = *iter; + LLUUID id = motion->getID(); + llassert(mLoadingMotions.find(motion) == mLoadingMotions.end()); + if (mLoadedMotions.find(motion) != mLoadedMotions.end()) + state_string += std::string("L"); + if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end()) + state_string += std::string("A"); + state_string += "D"; + llinfos << gAnimLibrary.animationName(id) << " " << state_string << llendl; + } + // } //----------------------------------------------------------------------------- @@ -1061,11 +1141,11 @@ void LLMotionController::dumpMotions() //----------------------------------------------------------------------------- void LLMotionController::deactivateAllMotions() { - for (motion_map_t::iterator iter = mAllMotions.begin(); - iter != mAllMotions.end(); iter++) + // Singu note: this must run over mActiveMotions: other motions are not active, + // and running over mAllMotions will miss the ones in mDeprecatedMotions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end();) { - LLMotion* motionp = iter->second; - deactivateMotionInstance(motionp); + deactivateMotionInstance(*iter++); // This might invalidate iter by erasing it from mActiveMotions. } } @@ -1086,8 +1166,7 @@ void LLMotionController::flushAllMotions() active_motions.push_back(std::make_pair(motionp->getID(),dtime)); motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it } - mActiveMotions.clear(); - + // delete all motion instances deleteAllMotions(); @@ -1096,13 +1175,136 @@ void LLMotionController::flushAllMotions() mCharacter->removeAnimationData("Hand Pose"); // restart motions + // + // Because we called motionp->deactivate() above, instead of deactivateMotionInstance(), + // prevent calling AISyncClientMotion::activateInstance in startMotion below. + disable_syncing(); + // for (std::vector >::iterator iter = active_motions.begin(); iter != active_motions.end(); ++iter) { startMotion(iter->first, iter->second); } + // + enable_syncing(); + // } +// +//----------------------------------------------------------------------------- +// toggle_hidden() +//----------------------------------------------------------------------------- +void LLMotionController::toggle_hidden(void) +{ + mHaveVisibleSyncedMotions = mHidden; // Default is false if we just became invisible (otherwise this value isn't used). + mHidden = !mHidden; + synceventset_t const visible = mHidden ? 0 : 4; + + // Run over all motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + AISyncServer* server = motionp->server(); + if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. + { + bool visible_before = server->events_with_at_least_one_client_ready() & 4; + server->ready(4, visible, motionp); // Mark that now we are visible or no longer visible. + bool visible_after = server->events_with_at_least_one_client_ready() & 4; + if (visible_after) // Are there any synchronized motions (left) that ARE visible? + { + mHaveVisibleSyncedMotions = true; + } + if (visible_before != visible_after) + { + // The group as a whole now might need to change whether or not it is animated. + AISyncServer::client_list_t const& clients = server->getClients(); + for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) + { + LLMotion* motion = dynamic_cast(client->mClientPtr); + if (!motion) + { + continue; + } + LLMotionController* controller = motion->getController(); + if (controller == this) + { + continue; + } + if (visible_after) + { + // Us becoming visible means that all synchronized avatars need to be animated again too. + controller->setHaveVisibleSyncedMotions(); + } + else + { + // Us becoming hidden means that all synchronized avatars might stop animating. + controller->refresh_hidden(); // It is extremely unlikely, but harmless, to call this twice on the same controller. + } + } + } + } + } +} + +void LLMotionController::refresh_hidden(void) +{ + mHaveVisibleSyncedMotions = !mHidden; + + // Run over all motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + AISyncServer* server = motionp->server(); + if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. + { + bool visible_after = server->events_with_at_least_one_client_ready() & 4; + if (visible_after) // Are there any synchronized motions (left) that ARE visible? + { + mHaveVisibleSyncedMotions = true; + } + } + } +} + +void LLMotionController::pauseAllSyncedCharacters(std::vector& avatar_pause_handles) +{ + // Run over all motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + AISyncServer* server = motionp->server(); + if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. + { + // Run over all clients of the found servers. + AISyncServer::client_list_t const& clients = server->getClients(); + for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) + { + LLMotion* motion = dynamic_cast(client->mClientPtr); + if (!motion) + { + continue; + } + LLMotionController* controller = motion->getController(); + if (controller == this) + { + continue; + } + controller->requestPause(avatar_pause_handles); + } + } + } +} + +void LLMotionController::requestPause(std::vector& avatar_pause_handles) +{ + if (mCharacter) + { + mCharacter->requestPause(avatar_pause_handles); + } +} + +// + //----------------------------------------------------------------------------- // pause() //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index 2de13aa36..054f1c2f9 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -51,11 +51,14 @@ // This is necessary because llcharacter.h includes this file. //----------------------------------------------------------------------------- class LLCharacter; +class LLMotionController; +class LLPauseRequestHandle; +typedef LLPointer LLAnimPauseRequest; //----------------------------------------------------------------------------- // LLMotionRegistry //----------------------------------------------------------------------------- -typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id); +typedef LLMotion* (*LLMotionConstructor)(LLUUID const& id, LLMotionController*); class LLMotionRegistry { @@ -72,7 +75,7 @@ public: // creates a new instance of a named motion // returns NULL motion is not registered - LLMotion *createMotion( const LLUUID &id ); + LLMotion* createMotion(LLUUID const& id, LLMotionController* controller); // initialization of motion failed, don't try to create this motion again void markBad( const LLUUID& id ); @@ -115,7 +118,6 @@ public: // unregisters a motion with the controller // (actually just forwards call to motion registry) - // returns true if successfull void removeMotion( const LLUUID& id ); // start motion @@ -150,10 +152,20 @@ public: //Flush is a liar. void deactivateAllMotions(); + // + void activated(U32 bit) { mActiveMask |= bit; } + void deactivated(U32 bit) { mActiveMask &= ~bit; } + bool isactive(U32 bit) const { return (mActiveMask & bit) != 0; } + // + // pause and continue all motions void pauseAllMotions(); void unpauseAllMotions(); BOOL isPaused() const { return mPaused; } + // + void requestPause(std::vector& avatar_pause_handles); + void pauseAllSyncedCharacters(std::vector& avatar_pause_handles); + // void setTimeStep(F32 step); @@ -180,7 +192,10 @@ protected: // internal operations act on motion instances directly // as there can be duplicate motions per id during blending overlap void deleteAllMotions(); + // singu: LLMotion needs access to activateMotionInstance. +public: BOOL activateMotionInstance(LLMotion *motion, F32 time); +protected: BOOL deactivateMotionInstance(LLMotion *motion); void deprecateMotionInstance(LLMotion* motion); BOOL stopMotionInstance(LLMotion *motion, BOOL stop_imemdiate); @@ -205,10 +220,13 @@ protected: // Life cycle of an animation: // // Animations are instantiated and immediately put in the mAllMotions map for their entire lifetime. +// Singu note: that is not true, they are moved to mDeprecatedMotions (often) for the last part of their lifetime. // If the animations depend on any asset data, the appropriate data is fetched from the data server, // and the animation is put on the mLoadingMotions list. // Once an animations is loaded, it will be initialized and put on the mLoadedMotions list. // Any animation that is currently playing also sits in the mActiveMotions list. +// Singu note: animations are only put in mDeprecatedMotions if and while they are playing, +// therefore animations in mDeprecatedMotions will be (must be) active and in mActiveMotions. typedef std::map motion_map_t; motion_map_t mAllMotions; @@ -217,7 +235,13 @@ protected: motion_set_t mLoadedMotions; motion_list_t mActiveMotions; motion_set_t mDeprecatedMotions; - + + // + U32 mActiveMask; + int mDisableSyncing; // Set while LLMotion::onActivate (and onDeactivate) are called for this controller. + bool mHidden; // The value of the last call to hidden(). + bool mHaveVisibleSyncedMotions; // Set when we are synchronized with one or more motions of a controller that is not hidden. + // LLFrameTimer mTimer; F32 mPrevTimerElapsed; F32 mAnimTime; @@ -230,6 +254,26 @@ protected: F32 mLastInterp; U8 mJointSignature[2][LL_CHARACTER_MAX_JOINTS]; + + // +public: + // Internal administration for AISync. + void disable_syncing(void) { mDisableSyncing += 100; } + void enable_syncing(void) { mDisableSyncing -= 100; } + bool syncing_disabled(void) const { return mDisableSyncing >= 100; } + + // Accessors needed for synchronization. + F32 getAnimTime(void) const { return mAnimTime; } + bool isHidden(void) const { return mHidden; } + + // Called often. Should return false if we still need to keep updating our motions even if we're not visible. + bool hidden(bool not_visible) { if (mHidden != not_visible) toggle_hidden(); return !mHaveVisibleSyncedMotions; } + +private: + void toggle_hidden(void); + void refresh_hidden(void); + void setHaveVisibleSyncedMotions(void) { mHaveVisibleSyncedMotions = true; } + // }; //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp index a330b2265..05b0fdfe8 100644 --- a/indra/llcharacter/lltargetingmotion.cpp +++ b/indra/llcharacter/lltargetingmotion.cpp @@ -52,7 +52,7 @@ const F32 TORSO_ROT_FRACTION = 0.5f; // LLTargetingMotion() // Class Constructor //----------------------------------------------------------------------------- -LLTargetingMotion::LLTargetingMotion(const LLUUID &id) : LLMotion(id) +LLTargetingMotion::LLTargetingMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_TARGET) { mCharacter = NULL; mName = "targeting"; @@ -99,14 +99,6 @@ LLMotion::LLMotionInitStatus LLTargetingMotion::onInitialize(LLCharacter *charac return STATUS_SUCCESS; } -//----------------------------------------------------------------------------- -// LLTargetingMotion::onActivate() -//----------------------------------------------------------------------------- -BOOL LLTargetingMotion::onActivate() -{ - return TRUE; -} - //----------------------------------------------------------------------------- // LLTargetingMotion::onUpdate() //----------------------------------------------------------------------------- @@ -166,12 +158,4 @@ BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask) return result; } -//----------------------------------------------------------------------------- -// LLTargetingMotion::onDeactivate() -//----------------------------------------------------------------------------- -void LLTargetingMotion::onDeactivate() -{ -} - - // End diff --git a/indra/llcharacter/lltargetingmotion.h b/indra/llcharacter/lltargetingmotion.h index 1ec9f80d6..f7b08ee69 100644 --- a/indra/llcharacter/lltargetingmotion.h +++ b/indra/llcharacter/lltargetingmotion.h @@ -48,11 +48,11 @@ // class LLTargetingMotion //----------------------------------------------------------------------------- class LLTargetingMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLTargetingMotion(const LLUUID &id); + LLTargetingMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLTargetingMotion(); @@ -64,7 +64,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLTargetingMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLTargetingMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -96,19 +96,11 @@ public: // must return true to indicate success and be available for activation virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - public: LLCharacter *mCharacter; diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index be045f100..fd0e8208c 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -20,6 +20,7 @@ set(llcommon_SOURCE_FILES aialert.cpp aifile.cpp aiframetimer.cpp + aisyncclient.cpp aithreadid.cpp imageids.cpp indra_constants.cpp @@ -112,11 +113,13 @@ set(llcommon_HEADER_FILES aifile.h aiframetimer.h airecursive.h + aisyncclient.h aithreadid.h aithreadsafe.h bitpack.h ctype_workaround.h doublelinkedlist.h + fix_macros.h imageids.h indra_constants.h linden_common.h diff --git a/indra/llcommon/aisyncclient.cpp b/indra/llcommon/aisyncclient.cpp new file mode 100644 index 000000000..c62d88efb --- /dev/null +++ b/indra/llcommon/aisyncclient.cpp @@ -0,0 +1,698 @@ +/** + * @file aisyncclient.cpp + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 13/12/2013 + * - Initial version, written by Aleric Inglewood @ SL + */ + +/* + * AISyncClient : the base class of a client object (LLMotion) that needs to be informed + * of the state of other such objects and/or to poll a server object about the state of + * other such objects, in order to be and stay synchronized with those other objects. + * In the case of an LLMotion (animation), all clients would be started and stopped at + * the same time, as long as they are part of the same synchronization group (AISyncServer). + * + * AISyncKey: object that determines what synchronization group a client belongs to. + * When a new client is created, a new AISyncKey is created too, using information from + * the client, the current frame number and the current frame time. If two AISyncKey + * compare equal, using operator==(AISyncKey const& key1, AISyncKey const& key2), + * then the clients that created them need to be synchronized. + * + * AISyncServer: object that represents a group of clients that need to be synchronized: + * it's a wrapper around a std::list with pointers to all the clients + * that need to be synchronized. It also stores the AISyncKey of the first (oldest) client + * that was added. Clients with keys that compare equal to that will be added. + * If a client is added with a synckeytype_t that is larger then it always replaces + * the existing key however. + * + * AISyncServerMap: A wrapper around std::list > + * that stores pointers to all currently existing AISyncServer objects. New entries + * are added at the end, so the oldest key is at the front. + * + * AISyncServerMap list + - - - - - - + - - - - - - + ... The AISyncServerMap is + * | | | a list with refcounted + * V V V pointers to AISyncServers. + * AISyncClient +--> AISyncServer + * | <--- list key ---> AISyncKey Each AISyncServer is a + * DerivedClient . list of normal pointers + * . AISyncClients and one + * <--- . pointer to a AISyncKey. + * Each AISyncClient is the + * base class of a DerivedClient + * and pointers back to the + * server with a refcounted + * pointer. + * + * A new client is passed to the AISyncServerMap to be stored in a new or existing AISyncServer + * object, using the key that the client produces. A boost::intrusive_ptr member + * of the client is set to point to this server. + * + * The lifetime of the server objects is determined by the intrusive_ptr objects that + * point to it: all the clients (which have an externally determined lifetime) and one + * pointer in the AISyncServerMap. However, regularly a check is done on all servers in + * the list to find expired servers: objects with keys older than two frames and older + * than 0.1 seconds; if such a server is found and it has zero or one client, then the + * client is unregistered and the pointer (and thus the server) removed from the + * AISyncServerMap. If it has two or more clients then the entry is kept until both + * clients are removed, which therefore can only be detected in intrusive_ptr_release + * which only has access to the server object. The server then is removed from the list + * by searching through it for the pointer to the server. + */ + +#include "sys.h" +#include "aisyncclient.h" +#include +#include +#include "debug.h" + +bool operator==(AISyncKey const& key1, AISyncKey const& key2) +{ + // Test if these keys match based on time. + if (std::abs((S32)(key1.mStartFrameCount - key2.mStartFrameCount)) > 1 && + std::abs(key1.mFrameTimer.getStartTime() - key2.mFrameTimer.getStartTime()) >= sSyncKeyExpirationTime) + { + return false; + } + // Time matches, let the derived classes determine if they also match otherwise. + return key1.equals(key2); +} + +#ifdef CWDEBUG +struct SyncEventSet { + synceventset_t mBits; + SyncEventSet(synceventset_t bits) : mBits(bits) { } +}; + +std::ostream& operator<<(std::ostream& os, SyncEventSet const& ses) +{ + for (int b = sizeof(ses.mBits) * 8 - 1; b >= 0; --b) + { + int m = 1 << b; + os << ((ses.mBits & m) ? '1' : '0'); + } + return os; +} + +void print_clients(AISyncServer const* server, AISyncServer::client_list_t const& client_list) +{ + Dout(dc::notice, "Clients of server " << server << ": "); + for (AISyncServer::client_list_t::const_iterator iter = client_list.begin(); iter != client_list.end(); ++ iter) + { + llassert(iter->mClientPtr->mReadyEvents == iter->mReadyEvents); + Dout(dc::notice, "-> " << iter->mClientPtr << " : " << SyncEventSet(iter->mReadyEvents)); + } +} +#endif + +void AISyncServerMap::register_client(AISyncClient* client, AISyncKey* new_key) +{ + // client must always be a new client that has to be stored somewhere. + llassert(client->server() == NULL); + // Obviously the client can't be ready for anything when it isn't registered yet. + llassert(!client->mReadyEvents); + + // Find if a server with this key already exists. + AISyncServer* server = NULL; + for (server_list_t::iterator iter = mServers.begin(); iter != mServers.end();) + { + boost::intrusive_ptr& server_ptr = *iter++; // Immediately increment iter because the call to unregister_last_client will erase it. + AISyncKey const& server_key(server_ptr->key()); + if (server_key.is_older_than(*new_key)) // This means that the server key is expired: a new key will never match. + { + if (server_ptr->never_synced()) // This means that it contains one or zero clients and will never contain more. + { + // Get rid of this server. + server_ptr->unregister_last_client(); // This will cause the server to be deleted, and erased from mServers. + } + continue; + } + if (*new_key == server_key) + { + server = server_ptr.get(); + // mServers stores new servers in strict order of the creation time of the keys, + // so once we find a server with a key that is equal, none of the remaining servers + // will have expired if they were never synced and we're done with the loop. + // Servers that synced might have been added later, but we don't unregister + // clients from those anyway because their sync partner might still show up. + break; + } + } + + if (server) + { + // A server already exists. + // Keep the oldest key, unless this new key has a synckeytype_t that is larger! + if (new_key->getkeytype() > server->key().getkeytype()) + { + server->swapkey(new_key); + } + delete new_key; + } + else + { + // Create a new server for this client. Transfers the ownership of the key allocation to the server. + server = new AISyncServer(new_key); + // Add it to mServers, before the last server that is younger then the new key. + server_list_t::iterator where = mServers.end(); // Insert the new server before 'where', + server_list_t::iterator new_where = where; + while (where != mServers.begin()) // unless there exists a server before that + { + --new_where; + if (new_key->getCreationTime() > (*new_where)->key().getCreationTime()) // and the new key is not younger then that, + { + break; + } + where = new_where; // then insert it before that element (etc). + } + // This method causes a single call to intrusive_ptr_add_ref and none to intrusive_ptr_release. + server_ptr_t server_ptr = server; + mServers.insert(where, server_ptr_t())->swap(server_ptr); + } + + // Add the client to the server. + server->add(client); +} + +#ifdef SYNC_TESTSUITE +void AISyncServer::sanity_check(void) const +{ + synceventset_t ready_events = (synceventset_t)-1; // All clients are ready. + client_list_t::const_iterator client_iter = mClients.begin(); + while (client_iter != mClients.end()) + { + ready_events &= client_iter->mReadyEvents; + ++client_iter; + } + synceventset_t pending_events = 0; // At least one client is ready. + client_iter = mClients.begin(); + while (client_iter != mClients.end()) + { + pending_events |= client_iter->mReadyEvents; + ++client_iter; + } + llassert(ready_events == mReadyEvents); + llassert(pending_events == mPendingEvents); +} +#endif + +void AISyncServer::add(AISyncClient* client) +{ +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif + + // The client can't already be ready when it isn't even added to a server yet. + llassert(!client->mReadyEvents); + synceventset_t old_ready_events = mReadyEvents; + // A new client is not ready for anything. + mReadyEvents = 0; + // Set mSynchronized if after adding client we'll have more than 1 client (that prevents the + // server from being deleted unless all clients are actually destructed or explicitly unregistered). + if (!mSynchronized && mClients.size() > 0) + { + mSynchronized = true; + } + // Trigger the existing clients to be not-ready anymore (if we were before). + trigger(old_ready_events); + // Only then add the new client (so that it didn't get not-ready trigger). + mClients.push_back(client); + client->mServer = this; + +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif +} + +void AISyncServer::remove(AISyncClient* client) +{ +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif + + client_list_t::iterator client_iter = mClients.begin(); + synceventset_t remaining_ready_events = (synceventset_t)-1; // All clients are ready. + synceventset_t remaining_pending_events = 0; // At least one client is ready (waiting for the other clients thus). + client_list_t::iterator found_client = mClients.end(); + while (client_iter != mClients.end()) + { + if (client_iter->mClientPtr == client) + { + found_client = client_iter; + } + else + { + remaining_ready_events &= client_iter->mReadyEvents; + remaining_pending_events |= client_iter->mReadyEvents; + } + ++client_iter; + } + llassert(found_client != mClients.end()); + // This must be the same as client->mReadyEvents. + llassert(found_client->mReadyEvents == client->mReadyEvents); + mClients.erase(found_client); + synceventset_t old_ready_events = mReadyEvents; + mReadyEvents = remaining_ready_events; + mPendingEvents = remaining_pending_events; + trigger(old_ready_events); + client->mServer.reset(); + client->deregistered(); + +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif +} + +void AISyncServer::unregister_last_client(void) +{ +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif + + // This function may only be called for servers with exactly one client that was never (potentially) synchronized. + llassert(!mSynchronized && mClients.size() == 1); + AISyncClient* client = mClients.begin()->mClientPtr; + mClients.clear(); + client->mServer.reset(); + llassert(mReadyEvents == client->mReadyEvents); + llassert(mPendingEvents == mReadyEvents); + // No need to update mReadyEvents/mPendingEvents because the server is going to be deleted, + // but inform the client that is no longer has a server. + client->deregistered(); + +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif +} + +void AISyncServer::trigger(synceventset_t old_ready_events) +{ + // If event 1 changed, informat all clients about it. + if (((old_ready_events ^ mReadyEvents) & 1)) + { + for (client_list_t::iterator client_iter = mClients.begin(); client_iter != mClients.end(); ++client_iter) + { + if ((mReadyEvents & 1)) + { + client_iter->mClientPtr->event1_ready(); + } + else + { + client_iter->mClientPtr->event1_not_ready(); + } + } + } +} + +void AISyncServer::ready(synceventset_t events, synceventset_t yesno, AISyncClient* client) +{ +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif + + synceventset_t added_events = events & yesno; + synceventset_t removed_events = events & ~yesno; + + // Run over all clients to find the client and calculate the current state. + synceventset_t remaining_ready_events = (synceventset_t)-1; // All clients are ready. + synceventset_t remaining_pending_events = 0; // At least one client is ready (waiting for the other clients thus). + client_list_t::iterator found_client = mClients.end(); + for (client_list_t::iterator client_iter = mClients.begin(); client_iter != mClients.end(); ++client_iter) + { + if (client_iter->mClientPtr == client) + { + found_client = client_iter; + } + else + { + remaining_ready_events &= client_iter->mReadyEvents; + remaining_pending_events |= client_iter->mReadyEvents; + } + } + + llassert(mReadyEvents == (remaining_ready_events & found_client->mReadyEvents)); + llassert(mPendingEvents == (remaining_pending_events | found_client->mReadyEvents)); + + found_client->mReadyEvents &= ~removed_events; + found_client->mReadyEvents |= added_events; +#ifdef SHOW_ASSERT + client->mReadyEvents = found_client->mReadyEvents; +#endif + + synceventset_t old_ready_events = mReadyEvents; + + mReadyEvents = remaining_ready_events & found_client->mReadyEvents; + mPendingEvents = remaining_pending_events | found_client->mReadyEvents; + + trigger(old_ready_events); + +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif +} + +void intrusive_ptr_add_ref(AISyncServer* server) +{ + server->mRefCount++; +} + +void intrusive_ptr_release(AISyncServer* server) +{ + llassert(server->mRefCount > 0); + server->mRefCount--; + if (server->mRefCount == 0) + { + delete server; + } + else if (server->mRefCount == 1) + { + // If the the last pointer to this server is in the the AISyncServerMap, then delete that too. + AISyncServerMap::instance().remove_server(server); + } +} + +void AISyncServerMap::remove_server(AISyncServer* server) +{ + for (server_list_t::iterator iter = mServers.begin(); iter != mServers.end(); ++iter) + { + if (server == iter->get()) + { + mServers.erase(iter); // This causes server to be deleted too. + return; + } + } + // The server must be found: this function is only called from intrusive_ptr_release for servers + // with just a single server_ptr_t left, which must be the one in mServers (otherwise it wasn't + // even registered properly!) + llassert(false); +} + + +//============================================================================= +// SYNC_TESTSUITE +//============================================================================= + +#ifdef SYNC_TESTSUITE +#include +#include +#include +#include + +//static +U32 LLFrameTimer::sFrameCount; + +double innerloop_count = 0; + +double LLFrameTimer::getCurrentTime() +{ + return innerloop_count * 0.001; +} + +template +class TestsuiteKey : public AISyncKey +{ + private: + int mIndex; + + public: + TestsuiteKey(int index) : mIndex(index) { } + + int getIndex(void) const { return mIndex; } + + // Virtual functions of AISyncKey. + public: + /*virtual*/ synckeytype_t getkeytype(void) const + { + // Return a unique identifier for this class, where the low 8 bits represent the syncgroup. + return synckeytype; + } + + /*virtual*/ bool equals(AISyncKey const& key) const + { + synckeytype_t const theotherkey = (synckeytype_t)(synckeytype ^ 0x100); + switch (key.getkeytype()) + { + case synckeytype: + { + // The other key is of the same type. + TestsuiteKey const& test_key = static_cast const&>(key); + return (mIndex & 1) == (test_key.mIndex & 1); + } + case theotherkey: + { + TestsuiteKey const& test_key = static_cast const&>(key); + return (mIndex & 2) == (test_key.getIndex() & 2); + } + default: + // The keys must be in the same syncgroup. + break; + } + return false; + } +}; + +template +class TestsuiteClient : public AISyncClient +{ + // AISyncClient events. + protected: + /*virtual*/ AISyncKey* createSyncKey(void) const + { + return new TestsuiteKey(mIndex); + } + + private: + int mIndex; + bool mRequestedRegistered; + synceventset_t mRequestedReady; + bool mActualReady1; + + public: + TestsuiteClient() : mIndex(-1), mRequestedRegistered(false), mRequestedReady(0), mActualReady1(false) { } + ~TestsuiteClient() { if (is_registered()) this->ready(mRequestedReady, (synceventset_t)0); } + + void setIndex(int index) { mIndex = index; } + + protected: + /*virtual*/ void event1_ready(void) + { +#ifdef DEBUG_SYNCOUTPUT + Dout(dc::notice, "Calling TestsuiteClient<" << synckeytype << ">::event1_ready() (mIndex = " << mIndex << ") of client " << this); +#endif + llassert(!mActualReady1); + mActualReady1 = true; + } + + /*virtual*/ void event1_not_ready(void) + { +#ifdef DEBUG_SYNCOUTPUT + Dout(dc::notice, "Calling TestsuiteClient<" << synckeytype << ">::event1_not_ready() (mIndex = " << mIndex << ") of client " << this); +#endif + llassert(mActualReady1); + mActualReady1 = false; + } + + // This is called when the server expired and we're the only client on it. + /*virtual*/ void deregistered(void) + { +#ifdef DEBUG_SYNCOUTPUT + DoutEntering(dc::notice, "TestsuiteClient<" << synckeytype << ">::deregistered(), with this = " << this); +#endif + mRequestedRegistered = false; + mRequestedReady = 0; + mActualReady1 = false; + this->mReadyEvents = 0; + } + + private: + bool is_registered(void) const { return this->server(); } + + public: + void change_state(unsigned long r); + bool getRequestedRegistered(void) const { return mRequestedRegistered; } + synceventset_t getRequestedReady(void) const { return mRequestedReady; } +}; + +TestsuiteClient* client1ap; +TestsuiteClient* client1bp; +TestsuiteClient* client2ap; +TestsuiteClient* client2bp; + +int const number_of_clients_per_syncgroup = 8; + +template +void TestsuiteClient::change_state(unsigned long r) +{ + bool change_registered = r & 1; + r >>= 1; + synceventset_t toggle_events = r & 15; + r >>= 4; + if (change_registered) + { + if (mRequestedRegistered && !mRequestedReady) + { + mRequestedRegistered = false; + this->unregister_client(); + } + } + else if (toggle_events) + { + mRequestedReady ^= toggle_events; + mRequestedRegistered = true; + this->ready(toggle_events, mRequestedReady & toggle_events); + } + llassert(mRequestedRegistered == is_registered()); + AISyncServer* server = this->server(); + if (mRequestedRegistered) + { + synceventset_t all_ready = synceventset_t(-1); + synceventset_t any_ready = 0; + int nr = 0; + for (int cl = 0; cl < number_of_clients_per_syncgroup; ++cl) + { + switch ((synckeytype & 0xff)) + { + case syncgroup_test1: + { + if (client1ap[cl].server() == server) + { + if (client1ap[cl].getRequestedRegistered()) + { + ++nr; + all_ready &= client1ap[cl].getRequestedReady(); + any_ready |= client1ap[cl].getRequestedReady(); + } + } + if (client1bp[cl].server() == server) + { + if (client1bp[cl].getRequestedRegistered()) + { + ++nr; + all_ready &= client1bp[cl].getRequestedReady(); + any_ready |= client1bp[cl].getRequestedReady(); + } + } + break; + } + case syncgroup_test2: + { + if (client2ap[cl].server() == server) + { + if (client2ap[cl].getRequestedRegistered()) + { + ++nr; + all_ready &= client2ap[cl].getRequestedReady(); + any_ready |= client2ap[cl].getRequestedReady(); + } + } + if (client2bp[cl].server() == server) + { + if (client2bp[cl].getRequestedRegistered()) + { + ++nr; + all_ready &= client2bp[cl].getRequestedReady(); + any_ready |= client2bp[cl].getRequestedReady(); + } + } + break; + } + } + } + llassert(nr == server->getClients().size()); + llassert(!!(all_ready & 1) == mActualReady1); + llassert(this->server()->events_with_all_clients_ready() == all_ready); + llassert(this->server()->events_with_at_least_one_client_ready() == any_ready); + llassert(nr == 0 || (any_ready & all_ready) == all_ready); + } + llassert(mRequestedReady == this->mReadyEvents); +} + +int main() +{ + Debug(libcw_do.on()); + Debug(dc::notice.on()); + Debug(libcw_do.set_ostream(&std::cout)); + Debug(list_channels_on(libcw_do)); + + unsigned short seed16v[3] = { 0x1234, 0xfedc, 0x7091 }; + + for (int k = 0;; ++k) + { + std::cout << "Loop: " << k << "; SEED: " << std::hex << seed16v[0] << ", " << seed16v[1] << ", " << seed16v[2] << std::dec << std::endl; + ++LLFrameTimer::sFrameCount; + + seed48(seed16v); + seed16v[0] = lrand48() & 0xffff; + seed16v[1] = lrand48() & 0xffff; + seed16v[2] = lrand48() & 0xffff; + + TestsuiteClient client1a[number_of_clients_per_syncgroup]; + TestsuiteClient client1b[number_of_clients_per_syncgroup]; + TestsuiteClient client2a[number_of_clients_per_syncgroup]; + TestsuiteClient client2b[number_of_clients_per_syncgroup]; + client1ap = client1a; + client1bp = client1b; + client2ap = client2a; + client2bp = client2b; + + for (int i = 0; i < number_of_clients_per_syncgroup; ++i) + { + client1a[i].setIndex(i); + client1b[i].setIndex(i); + client2a[i].setIndex(i); + client2b[i].setIndex(i); + } + + for (int j = 0; j < 1000000; ++j) + { + innerloop_count += 1; + +#ifdef DEBUG_SYNCOUTPUT + Dout(dc::notice, "Innerloop: " << j); +#endif + unsigned long r = lrand48(); + synckeytype_t keytype = (r & 1) ? ((r & 2) ? synckeytype_test1a : synckeytype_test1b) : ((r & 2) ? synckeytype_test2a : synckeytype_test2b); + r >>= 2; + int cl = (r & 255) % number_of_clients_per_syncgroup; + r >>= 8; + switch (keytype) + { + case synckeytype_test1a: + client1a[cl].change_state(r); + break; + case synckeytype_test1b: + client1b[cl].change_state(r); + break; + case synckeytype_test2a: + client2a[cl].change_state(r); + break; + case synckeytype_test2b: + client2b[cl].change_state(r); + break; + } + } + } +} + +#endif diff --git a/indra/llcommon/aisyncclient.h b/indra/llcommon/aisyncclient.h new file mode 100644 index 000000000..0f5237f99 --- /dev/null +++ b/indra/llcommon/aisyncclient.h @@ -0,0 +1,304 @@ +/** + * @file aisyncclient.h + * @brief Declaration of AISyncClient. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 12/12/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AI_SYNC_CLIENT_H +#define AI_SYNC_CLIENT_H + +#ifdef SYNC_TESTSUITE +/* + * To compile the testsuite, run: + * + * cd indra/llcommon + * g++ -O3 -DCWDEBUG -DSYNC_TESTSUITE -I. -I../cwdebug aisyncclient.cpp -lcwd + */ + +#include +#include +typedef uint32_t U32; +typedef int32_t S32; +typedef uint64_t U64; +typedef float F32; +typedef double F64; +#define LL_COMMON_API +#define SHOW_ASSERT +#define ASSERT_ONLY_COMMA(...) , __VA_ARGS__ +#define llassert assert + +struct LLFrameTimer +{ + double mStartTime; + double mExpiry; + static double getCurrentTime(void); + static U32 sFrameCount; + static U32 getFrameCount() { return sFrameCount; } + F64 getStartTime() const { return mStartTime; } + void reset(double expiration) { mStartTime = getCurrentTime(); mExpiry = mStartTime + expiration; } + bool hasExpired(void) const { return getCurrentTime() > mExpiry; } +}; + +template +struct LLSingleton +{ + static T sInstance; + static T& instance(void) { return sInstance; } +}; + +template +T LLSingleton::sInstance; + +#else // !SYNC_TESTSUITE +#include "llsingleton.h" +#include "llframetimer.h" +#endif +#include +#include + +//--------------------------------------------------------------------------------------------------------------------- +// Keys with a different syncgroup are never equal (so they are never synchronized). +enum syncgroups +{ +#ifdef SYNC_TESTSUITE + syncgroup_test1, + syncgroup_test2, +#else + syncgroup_motions, // Syncgroup used for animations. +#endif + syncgroup_size +}; + +// Each key type must return a unique identifier that exists of its syncgroup (the least significant 8 bit) plus a few bit to make it unique (bit 9 and higher). +enum synckeytype_t +{ +#ifdef SYNC_TESTSUITE + synckeytype_test1a = 0x000 + syncgroup_test1, + synckeytype_test1b = 0x100 + syncgroup_test1, + synckeytype_test2a = 0x000 + syncgroup_test2, + synckeytype_test2b = 0x100 + syncgroup_test2, +#else + synckeytype_motion = syncgroup_motions // There is currently only one key type in the syncgroup_motions group: AISyncKeyMotion. +#endif +}; + +typedef U32 synceventset_t; // A mask where each bit represents a ready state. + +static F32 const sSyncKeyExpirationTime = 0.25; // In seconds. + +class LL_COMMON_API AISyncKey +{ + private: + LLFrameTimer mFrameTimer; // This timer is started at the moment the sync key is created. + U32 mStartFrameCount; // The frame count at which the timer was started. + + public: + // Constructor. + AISyncKey(AISyncKey const* from_key) : mStartFrameCount(from_key ? from_key->mStartFrameCount : LLFrameTimer::getFrameCount()) + { + if (from_key) + { + mFrameTimer.copy(from_key->mFrameTimer); + } + else + { + mFrameTimer.reset(sSyncKeyExpirationTime); + } + } + + // Destructor. + virtual ~AISyncKey() { } + + // Return true if this key expired. + bool expired(void) const + { + // The key has expired when sSyncKeyExpirationTime seconds have elapsed AND at least two frames have passed. + return mFrameTimer.getFrameCount() > mStartFrameCount + 1 && mFrameTimer.hasExpired(); + } + + // Returns true if this object and key would not compare equal based on time because this object is too old. + bool is_older_than(AISyncKey const& key) const + { + return key.mStartFrameCount > mStartFrameCount + 1 && key.mFrameTimer.getStartTime() > mFrameTimer.getStartTime() + sSyncKeyExpirationTime; + } + + // Return the creation time of this key (in number of seconds since application start). + F64 getCreationTime(void) const { return mFrameTimer.getStartTime(); } + + // Returns true if the two keys match, meaning that they should be synchronized. + friend bool operator==(AISyncKey const& key1, AISyncKey const& key2); + + // Returns an ID that uniquely identifies the derived type. + // Currently the only derived type is AISyncKeyMotion with ID synckeytype_motion. + virtual synckeytype_t getkeytype(void) const = 0; + + // Returns true if the data in the derived objects match, meaning that they should be synchronized. + virtual bool equals(AISyncKey const& key) const = 0; +}; + +// Forward declaration. +class AISyncClient; +class AISyncServer; +LL_COMMON_API extern void intrusive_ptr_add_ref(AISyncServer* server); +LL_COMMON_API extern void intrusive_ptr_release(AISyncServer* server); + +struct LL_COMMON_API AISyncClientData +{ + AISyncClient* mClientPtr; + synceventset_t mReadyEvents; + + AISyncClientData(AISyncClient* client) : mClientPtr(client), mReadyEvents(0) { } +}; + +class LL_COMMON_API AISyncServer +{ + public: + typedef std::list client_list_t; + + private: + int mRefCount; // Number of boost::intrusive_ptr objects pointing to this object. + AISyncKey* mKey; // The key of the first client that was added. + client_list_t mClients; // A list with pointers to all registered clients. + bool mSynchronized; // Set when a server gets more than one client, and not reset anymore after that. + synceventset_t mReadyEvents; // 0xFFFFFFFF bitwise-AND-ed with all clients. + synceventset_t mPendingEvents; // The bitwise-OR of all clients. + + public: + AISyncServer(AISyncKey* key) : mRefCount(0), mKey(key), mSynchronized(false), mReadyEvents((synceventset_t)-1), mPendingEvents(0) { } + ~AISyncServer() { delete mKey; } + + // Add a new client to this server. + void add(AISyncClient* client); + + // Remove a client from this server. + void remove(AISyncClient* client); + + // Return the key associated to this server (which is the key produced by the first client of the largest synckeytype_t that was added). + AISyncKey const& key(void) const { return *mKey; } + // Replace they key with another key (of larger synckeytype_t). + void swapkey(AISyncKey*& key_ptr) { AISyncKey* tmp = key_ptr; key_ptr = mKey; mKey = tmp; } + + // Returns true if this server never had more than one client. + bool never_synced(void) const { return !mSynchronized; } + + // Set readiness of all events at once. + void ready(synceventset_t events, synceventset_t yesno, AISyncClient* client); + + // Unregister the (only) client because it's own its own and will never need synchronization. + void unregister_last_client(void); + + // Return the events that all clients for. + synceventset_t events_with_all_clients_ready(void) const { return mReadyEvents; } + + // Return events that at least one client is ready for. + synceventset_t events_with_at_least_one_client_ready(void) const { return mPendingEvents; } + + // Return a list of all registered clients. + client_list_t const& getClients(void) const { return mClients; } + + private: + // Call event1_ready() or event1_not_ready() on all clients if the least significant bit of mReadyEvents changed. + void trigger(synceventset_t old_ready_events); + +#ifdef SYNC_TESTSUITE + void sanity_check(void) const; +#endif + + private: + friend LL_COMMON_API void intrusive_ptr_add_ref(AISyncServer* server); + friend LL_COMMON_API void intrusive_ptr_release(AISyncServer* server); +}; + +class LL_COMMON_API AISyncServerMap : public LLSingleton +{ + public: + typedef boost::intrusive_ptr server_ptr_t; // The type of a (stored) pointer to the server objects. + typedef std::list server_list_t; // The type of the list with pointers to the server objects. + + private: + server_list_t mServers; // A list with pointers to all server objects. + + public: + // Find or create a server object that the client belongs to and store the client in it. + // If a new server is created, it is stored in mServers. + void register_client(AISyncClient* client, AISyncKey* new_key); + + private: + friend LL_COMMON_API void intrusive_ptr_release(AISyncServer* server); + // Remove a server from the map, only called by intrusive_ptr_release when there is one pointer left; + // therefore, the server should not have any clients. + void remove_server(AISyncServer* server); +}; + +class LL_COMMON_API AISyncClient +{ + private: + friend class AISyncServer; + boost::intrusive_ptr mServer; // The server this client was registered with, or NULL when unregistered. + + public: +#ifdef SHOW_ASSERT + synceventset_t mReadyEvents; + AISyncClient(void) : mReadyEvents(0) { } +#endif + virtual ~AISyncClient() { llassert(!mServer); /* If this fails then you need to add unregister_client() to the top of the destructor of the derived class that implements deregistered(). */ } + virtual AISyncKey* createSyncKey(AISyncKey const* from_key = NULL) const = 0; + + virtual void event1_ready(void) = 0; + virtual void event1_not_ready(void) = 0; + + // Only client. Client was forcefully deregistered from expired server because it was the only client. + virtual void deregistered(void) + { +#ifdef SHOW_ASSERT + mReadyEvents = 0; +#endif + } + + AISyncServer* server(void) const { return mServer.get(); } + + // Add this client to a server with matching sync key. Optionally the server is first created. + void register_client(void) { AISyncServerMap::instance().register_client(this, createSyncKey()); } + + // Remove this client from its server, if any. + void unregister_client(void) { if (mServer) mServer->remove(this); } + + // Call 'ready' when you are ready (or not) to get a call to start(). + // Returns true if that call was made (immediately), otherwise it may happen later. + + // Set readiness of all events at once. + void ready(synceventset_t events, synceventset_t yesno) + { + if (!mServer) + { + register_client(); + } + mServer->ready(events, yesno, this); + } +}; + +#endif diff --git a/indra/llcommon/fix_macros.h b/indra/llcommon/fix_macros.h new file mode 100644 index 000000000..ef959decf --- /dev/null +++ b/indra/llcommon/fix_macros.h @@ -0,0 +1,25 @@ +/** + * @file fix_macros.h + * @author Nat Goodspeed + * @date 2012-11-16 + * @brief The Mac system headers seem to #define macros with obnoxiously + * generic names, preventing any library from using those names. We've + * had to fix these in so many places that it's worth making a header + * file to handle it. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Copyright (c) 2012, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// DON'T use an #include guard: every time we encounter this header, #undef +// these macros all over again. + +// who injects MACROS with such generic names?! Grr. +#ifdef equivalent +#undef equivalent +#endif + +#ifdef check +#undef check +#endif diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h index 2813150c5..30bc58dd9 100644 --- a/indra/llcommon/llframetimer.h +++ b/indra/llcommon/llframetimer.h @@ -47,6 +47,10 @@ public: // Create an LLFrameTimer and start it. After creation it is running and in the state expired (hasExpired will return true). LLFrameTimer(void) : mExpiry(0), mRunning(true), mPaused(false) { if (!sGlobalMutex) global_initialization(); setAge(0.0); } + // + void copy(LLFrameTimer const& timer) { mStartTime = timer.mStartTime; mExpiry = timer.mExpiry; mRunning = timer.mRunning; mPaused = timer.mPaused; } + // + // Atomic reads of static variables. // Return the number of seconds since the start of the application. @@ -142,6 +146,9 @@ public: bool hasExpired() const { return getElapsedSeconds() >= mExpiry; } F32 getElapsedTimeF32() const { llassert(mRunning); return mPaused ? (F32)mStartTime : (F32)(getElapsedSeconds() - mStartTime); } bool getStarted() const { return mRunning; } + // + F64 getStartTime() const { llassert(!mPaused); return mStartTime; } + // // return the seconds since epoch when this timer will expire. F64 expiresAt() const; diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 5e8b9e22a..deb25c74c 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -268,7 +268,7 @@ void LLInventoryObject::updateServer(BOOL) const llwarns << "LLInventoryObject::updateServer() called. Doesn't do anything." << llendl; } -inline +// inline void LLInventoryObject::correctInventoryName(std::string& name) { LLStringUtil::replaceNonstandardASCII(name, ' '); @@ -1169,7 +1169,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd) // Because WT_UNKNOWN now has locally a special meaning, make sure we don't receive it from the server. if (wt == WT_UNKNOWN) { - llwarns << "Received inventory item with wearable type WT_UNKNOWN from server! You should upgrade your viewer." << llendl; + lldebugs << "Received inventory item with wearable type WT_UNKNOWN from server!" << llendl; // Change this new wearable type to WT_COUNT, as if when we had not inserted WT_UNKNOWN locally. mFlags += 1; wt = WT_COUNT; diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index a88894da9..b3c141cfd 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -84,9 +84,13 @@ public: void setParent(const LLUUID& new_parent); void setType(LLAssetType::EType type); -private: +// [RLVa:KB] - Checked: 2014-01-07 (RLVa-1.4.10) // in place correction for inventory name string - void correctInventoryName(std::string& name); + static void correctInventoryName(std::string& name); +// [/RLVa:KB] +private: +// // in place correction for inventory name string +// void correctInventoryName(std::string& name); //-------------------------------------------------------------------- // File Support diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 36d691a5d..b16b086a0 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -669,25 +669,31 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) return false; } +const S32& LLAvatarNameCache::phoenix_name_system() +{ + static const LLCachedControl name_system("PhoenixNameSystem", 0); + return name_system; +} + // Return true when name has been set to Phoenix Name System Name, if not return false. -bool LLAvatarNameCache::getPNSName(const LLUUID& agent_id, std::string& name) +bool LLAvatarNameCache::getPNSName(const LLUUID& agent_id, std::string& name, const S32& name_system) { LLAvatarName avatar_name; if (get(agent_id, &avatar_name)) - getPNSName(avatar_name, name); + getPNSName(avatar_name, name, name_system); else return false; return true; } // get() with callback compatible version of getPNSName -void LLAvatarNameCache::getPNSName(const LLAvatarName& avatar_name, std::string& name) +void LLAvatarNameCache::getPNSName(const LLAvatarName& avatar_name, std::string& name, const S32& name_system) { - static LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) + switch (name_system) { case 0 : name = avatar_name.getLegacyName(); break; case 1 : name = avatar_name.getCompleteName(); break; case 2 : name = avatar_name.mDisplayName; break; + case 3 : name = avatar_name.getLegacyName() + (avatar_name.mIsDisplayNameDefault ? "" : " (" + avatar_name.mDisplayName + ")"); break; default : name = avatar_name.getLegacyName(); break; } } diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 99e3fba57..f98988769 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -65,12 +65,13 @@ namespace LLAvatarNameCache // If name is in cache, returns true and fills in provided LLAvatarName // otherwise returns false bool get(const LLUUID& agent_id, LLAvatarName *av_name); + const S32& phoenix_name_system(); // If get() succeeds, returns true and fills in name string // via void function below, otherwise returns false - bool getPNSName(const LLUUID& agent_id, std::string& name); + bool getPNSName(const LLUUID& agent_id, std::string& name, const S32& name_system = phoenix_name_system()); // Perform a filling of name string according to Phoenix Name System, // when we have an LLAvatarName already. - void getPNSName(const LLAvatarName& avatar_name, std::string& name); + void getPNSName(const LLAvatarName& avatar_name, std::string& name, const S32& name_system = phoenix_name_system()); // Callback types for get() below typedef boost::signals2::signal< diff --git a/indra/llmessage/llmessagethrottle.cpp b/indra/llmessage/llmessagethrottle.cpp index 579d6d718..6d6e9a924 100644 --- a/indra/llmessage/llmessagethrottle.cpp +++ b/indra/llmessage/llmessagethrottle.cpp @@ -30,6 +30,7 @@ #include "llmessagethrottle.h" #include "llframetimer.h" +#include "fix_macros.h" // This is used for the stl search_n function. #if _MSC_VER >= 1500 // VC9 has a bug in search_n diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 8b5310beb..064183d49 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -442,6 +442,8 @@ LLGLManager::LLGLManager() : mHasCubeMap(FALSE), mHasDebugOutput(FALSE), + mHasAdaptiveVsync(FALSE), + mIsATI(FALSE), mIsNVIDIA(FALSE), mIsIntel(FALSE), @@ -956,6 +958,12 @@ void LLGLManager::initExtensions() mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts)); #endif +#if LL_WINDOWS + mHasAdaptiveVsync = ExtensionExists("WGL_EXT_swap_control_tear", gGLHExts.mSysExts); +#elif LL_LINUX + mHasAdaptiveVsync = ExtensionExists("GLX_EXT_swap_control_tear", gGLHExts.mSysExts); +#endif + #if LL_LINUX || LL_SOLARIS llinfos << "initExtensions() checking shell variables to adjust features..." << llendl; // Our extension support for the Linux Client is very young with some @@ -980,6 +988,7 @@ void LLGLManager::initExtensions() mHasShaderObjects = FALSE; mHasVertexShader = FALSE; mHasFragmentShader = FALSE; + mHasAdaptiveVsync = FALSE; LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL; } else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */ diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 65161a6fa..9b277c70a 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -113,6 +113,8 @@ public: BOOL mHasCubeMap; BOOL mHasDebugOutput; + BOOL mHasAdaptiveVsync; + // Vendor-specific extensions BOOL mIsATI; BOOL mIsNVIDIA; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 8dab8bbc8..37a16ff6f 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1225,6 +1225,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("matrixPalette"); mReservedUniforms.push_back("translationPalette"); + mReservedUniforms.push_back("maxWeight"); mReservedUniforms.push_back("screenTex"); mReservedUniforms.push_back("screenDepth"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 5cf22f58f..e29f80f10 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -179,6 +179,7 @@ public: AVATAR_MATRIX, AVATAR_TRANSLATION, + AVATAR_MAX_WEIGHT, WATER_SCREENTEX, WATER_SCREENDEPTH, diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index fb1673245..6276c0f50 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -921,6 +921,23 @@ void LLLineEditor::addChar(const llwchar uni_char) mText.insert(getCursor(), w_buf); setCursor(getCursor() + 1); + + if (!mReadOnly && mAutoreplaceCallback != NULL) + { + // autoreplace the text, if necessary + S32 replacement_start; + S32 replacement_length; + LLWString replacement_string; + S32 new_cursor_pos = getCursor(); + mAutoreplaceCallback(replacement_start, replacement_length, replacement_string, new_cursor_pos, mText); + + if (replacement_length > 0 || !replacement_string.empty()) + { + mText.erase(replacement_start, replacement_length); + mText.insert(replacement_start, replacement_string); + setCursor(new_cursor_pos); + } + } } else { diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index bc6df16f3..91a7983f4 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -167,6 +167,10 @@ public: virtual BOOL isSpellDirty() const { return mText.getString() != mPrevSpelledText; } // Returns TRUE if user changed value at all virtual void resetSpellDirty() { mPrevSpelledText = mText.getString(); } // Clear dirty state + typedef boost::function autoreplace_callback_t; + autoreplace_callback_t mAutoreplaceCallback; + void setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; } + // assumes UTF8 text virtual void setValue(const LLSD& value ) { setText(value.asString()); } virtual LLSD getValue() const { return LLSD(getText()); } diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index f066ef6dc..e0ec85523 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1503,14 +1503,13 @@ LLNotificationPtr LLNotifications::add(AIAlert::Error const& error, int type, un } //-------------------------------------------------------------------------------- -// class UpdateItem +// struct UpdateItem // // Allow LLNotifications::add, LLNotifications::cancel and LLNotifications::update // to be called from any thread. -class UpdateItem +struct UpdateItem { -public: char const* sigtype; LLNotificationPtr pNotif; UpdateItem(char const* st, LLNotificationPtr const& np) : sigtype(st), pNotif(np) { } diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index df0168ae7..f6f267f57 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -197,7 +197,7 @@ class LLNotification : { LOG_CLASS(LLNotification); friend class LLNotifications; -friend class UpdateItem; +friend struct UpdateItem; public: // parameter object used to instantiate a new notification @@ -568,7 +568,7 @@ class LLNotificationChannelBase : public boost::signals2::trackable { LOG_CLASS(LLNotificationChannelBase); - friend class UpdateItem; + friend struct UpdateItem; public: LLNotificationChannelBase(LLNotificationFilter filter, LLNotificationComparator comp) : mFilter(filter), mItems_sf(comp) diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index bae86672c..fb9383ecb 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -57,6 +57,8 @@ static LLRegisterWidget r("scroll_list"); +LLMenuGL* sScrollListMenus[1] = {}; // List menus that recur, such as general avatars or groups menus + // local structures & classes. struct SortScrollListItem { @@ -2552,7 +2554,15 @@ void LLScrollListCtrl::setScrollListParameters(LLXMLNodePtr node) node->getAttribute_bool("mouse_wheel_opaque", mMouseWheelOpaque); } - if (node->hasAttribute("menu_file")) + if (node->hasAttribute("menu_num")) + { + // Some scroll lists use common menus identified by number + // 0 is menu_avs_list.xml, 1 will be for groups, 2 could be for lists of objects + S32 menu_num; + node->getAttributeS32("menu_num", menu_num); + mPopupMenu = sScrollListMenus[menu_num]; + } + else if (node->hasAttribute("menu_file")) { std::string menu_file; node->getAttributeString("menu_file", menu_file); diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 8df242331..b3b37d705 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -388,7 +388,7 @@ LLWindow* LLWindowManager::createWindow( const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + const S32 vsync_mode, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples) @@ -400,26 +400,26 @@ LLWindow* LLWindowManager::createWindow( #if LL_MESA_HEADLESS new_window = new LLWindowMesaHeadless(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth); #elif LL_SDL new_window = new LLWindowSDL(callbacks, title, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth, fsaa_samples); #elif LL_WINDOWS new_window = new LLWindowWin32(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth, fsaa_samples); #elif LL_DARWIN new_window = new LLWindowMacOSX(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth, fsaa_samples); #endif } else { new_window = new LLWindowHeadless(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth); } if (FALSE == new_window->isValid()) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 575c57816..0d53f5951 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -82,7 +82,7 @@ public: BOOL setSize(LLCoordScreen size); BOOL setSize(LLCoordWindow size); virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); - virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0; + virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL) = 0; virtual BOOL setCursorPosition(LLCoordWindow position) = 0; virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; virtual void showCursor() = 0; @@ -121,6 +121,8 @@ public: virtual BOOL setGamma(const F32 gamma) = 0; // Set the gamma virtual void setFSAASamples(const U32 fsaa_samples) = 0; //set number of FSAA samples virtual U32 getFSAASamples() = 0; + virtual void setVsyncMode(const S32 vsync_mode) = 0; + virtual S32 getVsyncMode() = 0; virtual BOOL restoreGamma() = 0; // Restore original gamma table (before updating gamma) virtual ESwapMethod getSwapMethod() { return mSwapMethod; } virtual void processMiscNativeEvents(); @@ -274,7 +276,7 @@ public: U32 flags = 0, BOOL fullscreen = FALSE, BOOL clearBg = FALSE, - BOOL disable_vsync = TRUE, + const S32 vsync_mode = 0, BOOL use_gl = TRUE, BOOL ignore_pixel_depth = FALSE, U32 fsaa_samples = 0); diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp index dbdb40f5b..d07521cf2 100644 --- a/indra/llwindow/llwindowheadless.cpp +++ b/indra/llwindow/llwindowheadless.cpp @@ -35,7 +35,7 @@ // LLWindowHeadless::LLWindowHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL disable_vsync, BOOL ignore_pixel_depth) + const S32 vsync_mode, BOOL ignore_pixel_depth) : LLWindow(callbacks, fullscreen, flags) { // Initialize a headless keyboard. diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index 72f9684ca..491f9afd2 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -48,7 +48,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL) {return FALSE;}; /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; /*virtual*/ void showCursor() {}; @@ -69,6 +69,8 @@ public: /*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { } /*virtual*/ U32 getFSAASamples() { return 0; } + /*virtual*/ void setVsyncMode(const S32 vsync_mode) {} + /*virtual*/ S32 getVsyncMode() { return 0; } /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma) //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput() {}; @@ -96,7 +98,7 @@ public: S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL disable_vsync, BOOL ignore_pixel_depth); + const S32 vsync_mode, BOOL ignore_pixel_depth); virtual ~LLWindowHeadless(); private: diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 303a23959..91e4c00cf 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -210,7 +210,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(NULL, fullscreen, flags) @@ -253,6 +253,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mPreeditor = NULL; mRawKeyEvent = NULL; mFSAASamples = fsaa_samples; + mVsyncMode = vsync_mode; mForceRebuild = FALSE; // For reasons that aren't clear to me, LLTimers seem to be created in the "started" state. @@ -283,7 +284,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, gWindowImplementation = this; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + if(createContext(x, y, width, height, 32, fullscreen, vsync_mode)) { if(mWindow != NULL) { @@ -323,7 +324,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, stop_glerror(); } -BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) +BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, const S32 vsync_mode) { OSStatus err; BOOL glNeedsInit = FALSE; @@ -780,7 +781,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // Disable vertical sync for swap GLint frames_per_swap = 0; - if (disable_vsync) + if (vsync_mode != 1) { LL_DEBUGS("GLInit") << "Disabling vertical sync" << LL_ENDL; frames_per_swap = 0; @@ -816,7 +817,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // changing fullscreen resolution, or switching between windowed and fullscreen mode. -BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp) { BOOL needsRebuild = FALSE; BOOL result = true; @@ -892,7 +893,7 @@ BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, B { mForceRebuild = FALSE; destroyContext(); - result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); + result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, vsync_mode); if (result) { if(mWindow != NULL) @@ -1341,6 +1342,16 @@ void LLWindowMacOSX::setFSAASamples(const U32 samples) mForceRebuild = TRUE; } +S32 LLWindowMacOSX::getVsyncMode() +{ + return mVsyncMode; +} +void LLWindowMacOSX::setVsyncMode(const S32 vsync_mode) +{ + mVsyncMode = vsync_mode; + mForceRebuild = TRUE; +} + BOOL LLWindowMacOSX::restoreGamma() { CGDisplayRestoreColorSyncSettings(); diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 3f75dc9ab..7f7181a58 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -60,7 +60,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position); /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); /*virtual*/ void showCursor(); @@ -81,6 +81,8 @@ public: /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma /*virtual*/ U32 getFSAASamples(); /*virtual*/ void setFSAASamples(const U32 fsaa_samples); + /*virtual*/ void setVsyncMode(const S32 vsync_mode); + /*virtual*/ S32 getVsyncMode(); /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput(); @@ -124,7 +126,7 @@ public: protected: LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, + BOOL fullscreen, BOOL clearBg, const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowMacOSX(); @@ -152,7 +154,7 @@ protected: // // create or re-create the GL context/window. Called from the constructor and switchContext(). - BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync); + BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, const S32 vsync_mode); void destroyContext(); void setupFailure(const std::string& text, const std::string& caption, U32 type); static pascal OSStatus staticEventHandler (EventHandlerCallRef myHandler, EventRef event, void* userData); @@ -201,6 +203,7 @@ protected: BOOL mMaximized; BOOL mMinimized; U32 mFSAASamples; + S32 mVsyncMode; BOOL mForceRebuild; S32 mDragOverrideCursor; diff --git a/indra/llwindow/llwindowmesaheadless.cpp b/indra/llwindow/llwindowmesaheadless.cpp index 2b668d3fc..095a7d17c 100644 --- a/indra/llwindow/llwindowmesaheadless.cpp +++ b/indra/llwindow/llwindowmesaheadless.cpp @@ -41,7 +41,7 @@ U16 *gMesaBuffer = NULL; LLWindowMesaHeadless::LLWindowMesaHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL ignore_pixel_depth) + const S32 vsync_mode, BOOL ignore_pixel_depth) : LLWindow(callbacks, fullscreen, flags) { llinfos << "MESA Init" << llendl; diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index c8d2bf282..438964dae 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -52,7 +52,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL) {return FALSE;}; /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; /*virtual*/ void showCursor() {}; @@ -74,6 +74,8 @@ public: /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma) /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { /* FSAA not supported yet on Mesa headless.*/ } /*virtual*/ U32 getFSAASamples() { return 0; } + /*virtual*/ void setVsyncMode(const S32 vsync_mode) {} + /*virtual*/ S32 getVsyncMode() { return 0; } //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput() {}; /*virtual*/ void delayInputProcessing() {}; @@ -98,7 +100,7 @@ public: LLWindowMesaHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL ignore_pixel_depth); + const S32 vsync_mode, BOOL ignore_pixel_depth); ~LLWindowMesaHeadless(); private: diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 10bcf816a..923b29be7 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -192,7 +192,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, const std::string& title, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags), Lock_Display(NULL), @@ -233,7 +233,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, mWindowTitle = title; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + if(createContext(x, y, width, height, 32, fullscreen, vsync_mode)) { gGLManager.initGL(); @@ -373,7 +373,7 @@ static int x11_detect_VRAM_kb() } #endif // LL_X11 -BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) +BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, const S32 vsync_mode) { //bool glneedsinit = false; @@ -721,6 +721,50 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B } #endif // LL_X11 +#if SDL_VERSION_ATLEAST(1,3,0) + // Disable vertical sync for swap + if (vsync_mode == 0) + { + LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL; + SDL_GL_SetSwapInterval(0); + } + else if(vsync_mode == -1) + { + LL_DEBUGS("Window") << "Enabling adaptive vertical sync" << LL_ENDL; + if(SDL_GL_SetSwapInterval(-1) == -1) + { + LL_DEBUGS("Window") << "Failed to enable adaptive vertical sync. Disabling vsync." << LL_ENDL; + SDL_GL_SetSwapInterval(0); + } + } + else + { + LL_DEBUGS("Window") << "Enabling vertical sync" << LL_ENDL; + SDL_GL_SetSwapInterval(1); + } +#else // SDL_VERSION_ATLEAST(1,3,0) +#ifdef SDL_GL_SWAP_CONTROL + if (vsync_mode == 0) + { + LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL; + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0); + } + else if(vsync_mode == -1) + { + LL_DEBUGS("Window") << "Enabling adaptive vertical sync" << LL_ENDL; + if(SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, -1) == -1) + { + LL_DEBUGS("Window") << "Failed to enable adaptive vertical sync. Disabling vsync." << LL_ENDL; + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0); + } + } + else + { + LL_DEBUGS("Window") << "Enabling vertical sync" << LL_ENDL; + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); + } +#endif // SDL_GL_SWAP_CONTROL +#endif // SDL_VERSION_ATLEAST(1,3,0) //make sure multisampling is disabled by default glDisable(GL_MULTISAMPLE_ARB); @@ -736,7 +780,7 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B // changing fullscreen resolution, or switching between windowed and fullscreen mode. -BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp) { const BOOL needsRebuild = TRUE; // Just nuke the context and start over. BOOL result = true; @@ -746,7 +790,7 @@ BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL if(needsRebuild) { destroyContext(); - result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); + result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, vsync_mode); if (result) { gGLManager.initGL(); @@ -987,6 +1031,16 @@ void LLWindowSDL::setFSAASamples(const U32 samples) mFSAASamples = samples; } +S32 LLWindowSDL::getVsyncMode() +{ + return mVsyncMode; +} + +void LLWindowSDL::setVsyncMode(const S32 vsync_mode) +{ + mVsyncMode = vsync_mode; +} + F32 LLWindowSDL::getGamma() { return 1/mGamma; diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 134554e6e..3334fcb98 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -65,7 +65,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position); /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); /*virtual*/ void showCursor(); @@ -92,6 +92,8 @@ public: /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma /*virtual*/ U32 getFSAASamples(); /*virtual*/ void setFSAASamples(const U32 samples); + /*virtual*/ void setVsyncMode(const S32 vsync_mode); + /*virtual*/ S32 getVsyncMode(); /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void processMiscNativeEvents(); @@ -149,7 +151,7 @@ public: protected: LLWindowSDL(LLWindowCallbacks* callbacks, const std::string& title, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, + BOOL fullscreen, BOOL clearBg, const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowSDL(); @@ -174,7 +176,7 @@ protected: // // create or re-create the GL context/window. Called from the constructor and switchContext(). - BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync); + BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, const S32 vsync_mode); void destroyContext(); void setupFailure(const std::string& text, const std::string& caption, U32 type); void fixWindowSize(void); @@ -194,6 +196,7 @@ protected: F32 mOverrideAspectRatio; F32 mGamma; U32 mFSAASamples; + S32 mVsyncMode; int mSDLFlags; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 807c547bd..8e6b4c57c 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -363,7 +363,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags) @@ -903,7 +903,7 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size) } // changing fullscreen resolution -BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp) { GLuint pixel_format; DEVMODE dev_mode; @@ -1650,14 +1650,27 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO } // Disable vertical sync for swap - if (disable_vsync && wglSwapIntervalEXT) + if(wglSwapIntervalEXT) { - LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL; - wglSwapIntervalEXT(0); - } - else - { - LL_DEBUGS("Window") << "Keeping vertical sync" << LL_ENDL; + if (vsync_mode == 0) + { + LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL; + wglSwapIntervalEXT(0); + } + else if(vsync_mode == -1) + { + LL_DEBUGS("Window") << "Enabling adaptive vertical sync" << LL_ENDL; + if(wglSwapIntervalEXT(-1) == 0) + { + LL_DEBUGS("Window") << "Failed to enable adaptive vertical sync. Disabling vsync." << LL_ENDL; + wglSwapIntervalEXT(0); + } + } + else + { + LL_DEBUGS("Window") << "Enabling vertical sync" << LL_ENDL; + wglSwapIntervalEXT(1); + } } SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this); @@ -3030,6 +3043,16 @@ U32 LLWindowWin32::getFSAASamples() return mFSAASamples; } +S32 LLWindowWin32::getVsyncMode() +{ + return mVsyncMode; +} + +void LLWindowWin32::setVsyncMode(const S32 vsync_mode) +{ + mVsyncMode = vsync_mode; +} + LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions) { if (!mSupportedResolutions) diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 9f678b96c..07dc67c20 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -59,7 +59,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position); /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); /*virtual*/ void showCursor(); @@ -80,6 +80,8 @@ public: /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma /*virtual*/ void setFSAASamples(const U32 fsaa_samples); /*virtual*/ U32 getFSAASamples(); + /*virtual*/ void setVsyncMode(const S32 vsync_mode); + /*virtual*/ S32 getVsyncMode(); /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput(); @@ -121,7 +123,7 @@ public: protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, + BOOL fullscreen, BOOL clearBg, const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowWin32(); @@ -186,6 +188,7 @@ protected: F32 mCurrentGamma; U32 mFSAASamples; + S32 mVsyncMode; WORD mPrevGammaRamp[256*3]; WORD mCurrentGammaRamp[256*3]; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 41f172981..454779901 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -126,6 +126,7 @@ set(viewer_SOURCE_FILES llassetuploadresponders.cpp llattachmentsmgr.cpp llaudiosourcevo.cpp + llautoreplace.cpp llavataractions.cpp llavatarpropertiesprocessor.cpp llbox.cpp @@ -181,6 +182,7 @@ set(viewer_SOURCE_FILES llfloaterabout.cpp llfloateractivespeakers.cpp llfloaterauction.cpp + llfloaterautoreplacesettings.cpp llfloateravatarinfo.cpp llfloateravatarlist.cpp llfloateravatarpicker.cpp @@ -574,9 +576,10 @@ set(viewer_SOURCE_FILES noise.cpp pipeline.cpp qtoolalign.cpp + rlvactions.cpp rlvcommon.cpp rlvextensions.cpp - rlvfloaterbehaviour.cpp + rlvfloaters.cpp rlvhandler.cpp rlvhelper.cpp rlvinventory.cpp @@ -645,6 +648,7 @@ set(viewer_HEADER_FILES llassetuploadresponders.h llattachmentsmgr.h llaudiosourcevo.h + llautoreplace.h llavataractions.h llavatarpropertiesprocessor.h llbox.h @@ -700,6 +704,7 @@ set(viewer_HEADER_FILES llfloaterabout.h llfloateractivespeakers.h llfloaterauction.h + llfloaterautoreplacesettings.h llfloateravatarinfo.h llfloateravatarlist.h llfloateravatarpicker.h @@ -1100,10 +1105,11 @@ set(viewer_HEADER_FILES noise.h pipeline.h qtoolalign.h + rlvactions.h rlvcommon.h rlvdefines.h rlvextensions.h - rlvfloaterbehaviour.h + rlvfloaters.h rlvhandler.h rlvhelper.h rlvinventory.h @@ -1138,7 +1144,7 @@ if (DARWIN) # Add resource files to the project. set(viewer_RESOURCE_FILES - ${VIEWER_BRANDING_ID}.icns + ${VIEWER_BRANDING_ID}_icon.icns macview.r gpu_table.txt SecondLife.nib/ @@ -1516,7 +1522,7 @@ if (WINDOWS) COMMAND ${PYTHON_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py - --arch=${ARCH} + --arch=${ARCH} --artwork=${ARTWORK_DIR} --branding_id=${VIEWER_BRANDING_ID} --build=${CMAKE_CURRENT_BINARY_DIR} @@ -1538,7 +1544,7 @@ if (WINDOWS) COMMAND ${PYTHON_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py - --arch=${ARCH} + --arch=${ARCH} --artwork=${ARTWORK_DIR} --actions=copy --branding_id=${VIEWER_BRANDING_ID} @@ -1700,7 +1706,7 @@ if (DARWIN) PROPERTIES OUTPUT_NAME "${product}" MACOSX_BUNDLE_INFO_STRING "A stable third-party Second Life viewer." - MACOSX_BUNDLE_ICON_FILE "${VIEWER_BRANDING_ID}.icns" + MACOSX_BUNDLE_ICON_FILE "${VIEWER_BRANDING_ID}_icon.icns" MACOSX_BUNDLE_GUI_IDENTIFIER "${VIEWER_BRANDING_NAME}" MACOSX_BUNDLE_LONG_VERSION_STRING "${viewer_VERSION}" MACOSX_BUNDLE_BUNDLE_NAME "${VIEWER_BRANDING_NAME}" diff --git a/indra/newview/aihttpview.cpp b/indra/newview/aihttpview.cpp index 3bc6b18f7..d3de57171 100644 --- a/indra/newview/aihttpview.cpp +++ b/indra/newview/aihttpview.cpp @@ -310,16 +310,12 @@ U32 AIHTTPView::updateColumn(U32 col, U32 start) return mStartColumn[col]; } -//static -void AIHTTPView::toggle_visibility(void* user_data) +// virtual +void AIHTTPView::setVisible(BOOL visible) { - LLView* viewp = (LLView*)user_data; - bool visible = !viewp->getVisible(); - if (visible) - { - AIPerService::resetUsed(); - } - viewp->setVisible(visible); + if (visible && visible != getVisible()) + AIPerService::resetUsed(); + LLContainerView::setVisible(visible); } U64 AIHTTPView::sTime_40ms; diff --git a/indra/newview/aihttpview.h b/indra/newview/aihttpview.h index 3fb80ea03..e9a749afd 100644 --- a/indra/newview/aihttpview.h +++ b/indra/newview/aihttpview.h @@ -49,6 +49,7 @@ class AIHTTPView : public LLContainerView ~AIHTTPView(); /*virtual*/ void draw(void); + /*virtual*/ void setVisible(BOOL visible); /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); @@ -66,7 +67,6 @@ class AIHTTPView : public LLContainerView public: static U64 getTime_40ms(void) { return sTime_40ms; } - static void toggle_visibility(void* user_data); }; extern AIHTTPView *gHttpView; diff --git a/indra/newview/app_settings/autoreplace.xml b/indra/newview/app_settings/autoreplace.xml new file mode 100644 index 000000000..09d19f7b0 --- /dev/null +++ b/indra/newview/app_settings/autoreplace.xml @@ -0,0 +1,8330 @@ + + + + name + Abbreviations + replacements + + afaic + As far as I am concerned + afaik + As far as I know + afk + away from keyboard + atm + at the moment + bbiab + be back in a bit + bbl + be back later + brb + be right back + btw + by the way + fyi + For your information + fwiw + For what its worth + gtg + got to go + idk + I don't know + iirc + if I recall correctly + imho + in my humble opinion + imo + in my opinion + irl + in real life + np + no problem + nsfw + not safe for work + nvm + nevermind + tc + take care + thx + thanks + ttfn + ta-ta for now + ttyl + talk to you later + ty + thank you + tyvm + thank you very much + wb + welcome back + yw + you're welcome + yvw + you're very welcome + + + + name + Spelling Corrections + replacements + + Amercia + America + Bernouilli + Bernoulli + Blitzkreig + Blitzkrieg + Bonnano + Bonanno + Brasillian + Brazilian + Britian + Britain + Brittish + British + Buddah + Buddha + Buddist + Buddhist + Cambrige + Cambridge + Capetown + Cape Town + Carmalite + Carmelite + Carnagie + Carnegie + Carnagie-Mellon + Carnegie-Mellon + Carnigie + Carnegie + Carnigie-Mellon + Carnegie-Mellon + Carribbean + Caribbean + Carribean + Caribbean + Carthagian + Carthaginian + Cataline + Catiline + Ceasar + Caesar + Celcius + Celsius + Champange + Champagne + Cincinatti + Cincinnati + Cincinnatti + Cincinnati + Conneticut + Connecticut + Dardenelles + Dardanelles + Dravadian + Dravidian + Enlish + English + Europian + European + Europians + Europeans + Eurpean + European + Eurpoean + European + Farenheit + Fahrenheit + Febuary + February + Feburary + February + Flemmish + Flemish + Formalhaut + Fomalhaut + Foundland + Newfoundland + Fransiscan + Franciscan + Fransiscans + Franciscans + Galations + Galatians + Gameboy + Game Boy + Ghandi + Gandhi + Godounov + Godunov + Gothenberg + Gothenburg + Gottleib + Gottlieb + Guaduloupe + Guadalupe + Guadulupe + Guadalupe + Guatamala + Guatemala + Guatamalan + Guatemalan + Guilia + Giulia + Guilio + Giulio + Guiness + Guinness + Guiseppe + Giuseppe + Habsbourg + Habsburg + Hallowean + Halloween + Heidelburg + Heidelberg + Ihaca + Ithaca + Israelies + Israelis + Janurary + January + Januray + January + Japanes + Japanese + Johanine + Johannine + Jospeh + Joseph + Juadaism + Judaism + Juadism + Judaism + Lybia + Libya + Malcom + Malcolm + Massachussets + Massachusetts + Massachussetts + Massachusetts + Mediteranean + Mediterranean + Michagan + Michigan + Misouri + Missouri + Missisipi + Mississippi + Missisippi + Mississippi + Monserrat + Montserrat + Montnana + Montana + Morisette + Morissette + Morrisette + Morissette + Mythraic + Mithraic + Naploeon + Napoleon + Napolean + Napoleon + Napoleonian + Napoleonic + Nazereth + Nazareth + Newyorker + New Yorker + Novermber + November + Nullabour + Nullarbor + Nuremburg + Nuremberg + Palistian + Palestinian + Palistinian + Palestinian + Palistinians + Palestinians + Papanicalou + Papanicolaou + Peloponnes + Peloponnesus + Pennyslvania + Pennsylvania + Pharoah + Pharaoh + Philipines + Philippines + Phillipine + Philippine + Phillipines + Philippines + Phillippines + Philippines + Phonecian + Phoenecian + Portugese + Portuguese + Postdam + Potsdam + Premonasterians + Premonstratensians + Pucini + Puccini + Puertorrican + Puerto Rican + Puertorricans + Puerto Ricans + Queenland + Queensland + Rockerfeller + Rockefeller + Russion + Russian + Sanhedrim + Sanhedrin + Saterday + Saturday + Saterdays + Saturdays + Sionist + Zionist + Sionists + Zionists + Sixtin + Sistine + Skagerak + Skagerrak + Tolkein + Tolkien + Tuscon + Tucson + Ukranian + Ukrainian + UnitesStates + UnitedStates + Yementite + Yemenite + abandonned + abandoned + aberation + aberration + abilties + abilities + abilty + ability + abondon + abandon + abondoned + abandoned + abondoning + abandoning + abondons + abandons + aborigene + aborigine + abortificant + abortifacient + abreviate + abbreviate + abreviated + abbreviated + abreviation + abbreviation + abritrary + arbitrary + absail + abseil + absailing + abseiling + absense + absence + absolutly + absolutely + absorbsion + absorption + absorbtion + absorption + abundacies + abundances + abundancies + abundances + abundunt + abundant + abutts + abuts + acadamy + academy + acadmic + academic + accademic + academic + accademy + academy + acccused + accused + accelleration + acceleration + accension + ascension + acceptence + acceptance + acceptible + acceptable + accessable + accessible + accidentaly + accidentally + accidently + accidentally + acclimitization + acclimatization + accomadate + accommodate + accomadated + accommodated + accomadates + accommodates + accomadating + accommodating + accomadation + accommodation + accomadations + accommodations + accomdate + accommodate + accomodate + accommodate + accomodated + accommodated + accomodates + accommodates + accomodating + accommodating + accomodation + accommodation + accomodations + accommodations + accompanyed + accompanied + accordeon + accordion + accordian + accordion + accoring + according + accoustic + acoustic + accquainted + acquainted + accrediation + accreditation + accredidation + accreditation + accross + across + accussed + accused + acedemic + academic + acheive + achieve + acheived + achieved + acheivement + achievement + acheivements + achievements + acheives + achieves + acheiving + achieving + acheivment + achievement + acheivments + achievements + achievment + achievement + achievments + achievements + achivement + achievement + achivements + achievements + acknowldeged + acknowledged + acknowledgeing + acknowledging + ackward + awkward + acommodate + accommodate + acomplish + accomplish + acomplished + accomplished + acomplishment + accomplishment + acomplishments + accomplishments + acording + according + acordingly + accordingly + acquaintence + acquaintance + acquaintences + acquaintances + acquiantence + acquaintance + acquiantences + acquaintances + acquited + acquitted + activites + activities + activly + actively + actualy + actually + acuracy + accuracy + acused + accused + acustom + accustom + acustommed + accustomed + adavanced + advanced + adbandon + abandon + additinally + additionally + additionaly + additionally + additonal + additional + additonally + additionally + addmission + admission + addopt + adopt + addopted + adopted + addoptive + adoptive + addres + address + addresable + addressable + addresed + addressed + addresing + addressing + addressess + addresses + addtion + addition + addtional + additional + adecuate + adequate + adequit + adequate + adhearing + adhering + adherance + adherence + admendment + amendment + admininistrative + administrative + adminstered + administered + adminstrate + administrate + adminstration + administration + adminstrative + administrative + adminstrator + administrator + admissability + admissibility + admissable + admissible + admited + admitted + admitedly + admittedly + adn + and + adolecent + adolescent + adquire + acquire + adquired + acquired + adquires + acquires + adquiring + acquiring + adres + address + adresable + addressable + adresing + addressing + adress + address + adressable + addressable + adressed + addressed + adressing + addressing + adventrous + adventurous + advertisment + advertisement + advertisments + advertisements + advesary + adversary + adviced + advised + aeriel + aerial + aeriels + aerials + afair + affair + afficianados + aficionados + afficionado + aficionado + afficionados + aficionados + affilate + affiliate + affilliate + affiliate + affort + afford + aforememtioned + aforementioned + againnst + against + agains + against + agaisnt + against + aganist + against + aggaravates + aggravates + aggreed + agreed + aggreement + agreement + aggregious + egregious + aggresive + aggressive + agian + again + agianst + against + agin + again + agina + again + aginst + against + agravate + aggravate + agre + agree + agred + agreed + agreeement + agreement + agreemnt + agreement + agregate + aggregate + agregates + aggregates + agreing + agreeing + agression + aggression + agressive + aggressive + agressively + aggressively + agressor + aggressor + agricuture + agriculture + agrieved + aggrieved + ahev + have + ahppen + happen + ahve + have + aicraft + aircraft + aiport + airport + airbourne + airborne + aircaft + aircraft + aircrafts + aircraft + airporta + airports + airrcraft + aircraft + aisian + asian + albiet + albeit + alchohol + alcohol + alchoholic + alcoholic + alchol + alcohol + alcholic + alcoholic + alcohal + alcohol + alcoholical + alcoholic + aledge + allege + aledged + alleged + aledges + alleges + alege + allege + aleged + alleged + alegience + allegiance + algebraical + algebraic + algorhitms + algorithms + algoritm + algorithm + algoritms + algorithms + alientating + alienating + alledge + allege + alledged + alleged + alledgedly + allegedly + alledges + alleges + allegedely + allegedly + allegedy + allegedly + allegely + allegedly + allegence + allegiance + allegience + allegiance + allign + align + alligned + aligned + alliviate + alleviate + allopone + allophone + allopones + allophones + allready + already + allthough + although + alltime + all-time + alltogether + altogether + almsot + almost + alochol + alcohol + alomst + almost + alot + a lot + alotted + allotted + alowed + allowed + alowing + allowing + alreayd + already + alse + else + alsot + also + alternitives + alternatives + altho + although + althought + although + altough + although + alusion + allusion + alwasy + always + alwyas + always + amalgomated + amalgamated + amatuer + amateur + amature + armature + amendmant + amendment + amerliorate + ameliorate + amke + make + amking + making + ammend + amend + ammended + amended + ammendment + amendment + ammendments + amendments + ammount + amount + ammused + amused + amoung + among + amoungst + amongst + amung + among + amunition + ammunition + analagous + analogous + analitic + analytic + analogeous + analogous + anarchim + anarchism + anarchistm + anarchism + anbd + and + ancestory + ancestry + ancilliary + ancillary + androgenous + androgynous + androgeny + androgyny + anihilation + annihilation + aniversary + anniversary + annoint + anoint + annointed + anointed + annointing + anointing + annoints + anoints + annouced + announced + annualy + annually + annuled + annulled + anohter + another + anomolies + anomalies + anomolous + anomalous + anomoly + anomaly + anonimity + anonymity + anounced + announced + anouncement + announcement + ansalisation + nasalisation + ansalization + nasalization + ansestors + ancestors + antartic + antarctic + anthromorphization + anthropomorphization + anthropolgist + anthropologist + anthropolgy + anthropology + anual + annual + anulled + annulled + anwsered + answered + anyhwere + anywhere + anyother + any other + anytying + anything + aparent + apparent + aparment + apartment + apenines + apennines + aplication + application + aplied + applied + apolegetics + apologetics + apon + apron + apparant + apparent + apparantly + apparently + appart + apart + appartment + apartment + appartments + apartments + appealling + appealing + appeareance + appearance + appearence + appearance + appearences + appearances + apperance + appearance + apperances + appearances + appereance + appearance + appereances + appearances + applicaiton + application + applicaitons + applications + appologies + apologies + appology + apology + apprearance + appearance + apprieciate + appreciate + approachs + approaches + appropiate + appropriate + appropraite + appropriate + appropropiate + appropriate + approproximate + approximate + approxamately + approximately + approxiately + approximately + approximitely + approximately + aprehensive + apprehensive + apropriate + appropriate + aproximate + approximate + aproximately + approximately + aquaduct + aqueduct + aquaintance + acquaintance + aquainted + acquainted + aquiantance + acquaintance + aquire + acquire + aquired + acquired + aquiring + acquiring + aquisition + acquisition + aquitted + acquitted + aranged + arranged + arangement + arrangement + arbitarily + arbitrarily + arbitary + arbitrary + archaelogists + archaeologists + archaelogy + archaeology + archaoelogy + archaeology + archaology + archaeology + archeaologist + archaeologist + archeaologists + archaeologists + archetect + architect + archetects + architects + archetectural + architectural + archetecturally + architecturally + archetecture + architecture + archiac + archaic + archictect + architect + archimedian + archimedean + architecht + architect + architechturally + architecturally + architechture + architecture + architechtures + architectures + architectual + architectural + archtype + archetype + archtypes + archetypes + aready + already + areodynamics + aerodynamics + argubly + arguably + arguement + argument + arguements + arguments + arised + arose + arival + arrival + armamant + armament + armistace + armistice + arogant + arrogant + arogent + arrogant + aroud + around + arrangment + arrangement + arrangments + arrangements + arround + around + artical + article + artice + article + articel + article + artifical + artificial + artifically + artificially + artillary + artillery + arund + around + asetic + ascetic + asfar + as far + asign + assign + aslo + also + asociated + associated + asorbed + absorbed + asphyxation + asphyxiation + assasin + assassin + assasinate + assassinate + assasinated + assassinated + assasinates + assassinates + assasination + assassination + assasinations + assassinations + assasined + assassinated + assasins + assassins + assassintation + assassination + assemple + assemble + assertation + assertion + asside + aside + assisnate + assassinate + assit + assist + assitant + assistant + assocation + association + assoicate + associate + assoicated + associated + assoicates + associates + assosication + assassination + asssassans + assassins + assualt + assault + assualted + assaulted + assymetric + asymmetric + assymetrical + asymmetrical + asteriod + asteroid + asthetic + aesthetic + asthetical + aesthetical + asthetically + aesthetically + asume + assume + aswell + as well + atain + attain + atempting + attempting + atheistical + atheistic + athenean + athenian + atheneans + athenians + athiesm + atheism + athiest + atheist + atorney + attorney + atribute + attribute + atributed + attributed + atributes + attributes + attaindre + attainder + attemp + attempt + attemped + attempted + attemt + attempt + attemted + attempted + attemting + attempting + attemts + attempts + attendence + attendance + attendent + attendant + attendents + attendants + attened + attended + attension + attention + attitide + attitude + attributred + attributed + attrocities + atrocities + audeince + audience + auromated + automated + austrailia + Australia + austrailian + Australian + auther + author + authobiographic + autobiographic + authobiography + autobiography + authorative + authoritative + authorites + authorities + authorithy + authority + authoritiers + authorities + authoritive + authoritative + authrorities + authorities + autochtonous + autochthonous + autoctonous + autochthonous + automaticly + automatically + automibile + automobile + automonomous + autonomous + autor + author + autority + authority + auxilary + auxiliary + auxillaries + auxiliaries + auxillary + auxiliary + auxilliaries + auxiliaries + auxilliary + auxiliary + availabe + available + availablity + availability + availaible + available + availble + available + availiable + available + availible + available + avalable + available + avalance + avalanche + avaliable + available + avation + aviation + avengence + a vengeance + averageed + averaged + avilable + available + awared + awarded + awya + away + baceause + because + backgorund + background + backrounds + backgrounds + bakc + back + banannas + bananas + bandwith + bandwidth + bankrupcy + bankruptcy + banruptcy + bankruptcy + baout + about + basicaly + basically + basicly + basically + bcak + back + beachead + beachhead + beacuse + because + beastiality + bestiality + beatiful + beautiful + beaurocracy + bureaucracy + beaurocratic + bureaucratic + beautyfull + beautiful + becamae + became + becames + becomes + becasue + because + beccause + because + becomeing + becoming + becomming + becoming + becouse + because + becuase + because + bedore + before + befoer + before + beggin + begin + begginer + beginner + begginers + beginners + beggining + beginning + begginings + beginnings + beggins + begins + begining + beginning + beginnig + beginning + behavour + behavior + beleagured + beleaguered + beleif + belief + beleive + believe + beleived + believed + beleives + believes + beleiving + believing + beligum + belgium + belive + believe + belived + believed + belives + believes + belligerant + belligerent + bellweather + bellwether + bemusemnt + bemusement + beneficary + beneficiary + beng + being + benificial + beneficial + benifit + benefit + benifits + benefits + bergamont + bergamot + beseige + besiege + beseiged + besieged + beseiging + besieging + betwen + between + beween + between + bewteen + between + bilateraly + bilaterally + billingualism + bilingualism + binominal + binomial + bizzare + bizarre + blaim + blame + blaimed + blamed + blessure + blessing + bodydbuilder + bodybuilder + bombardement + bombardment + bombarment + bombardment + bondary + boundary + borke + broke + boundry + boundary + bouyancy + buoyancy + bouyant + buoyant + boyant + buoyant + breakthough + breakthrough + breakthroughts + breakthroughs + breif + brief + breifly + briefly + brethen + brethren + bretheren + brethren + briliant + brilliant + brillant + brilliant + brimestone + brimstone + broacasted + broadcast + broadacasting + broadcasting + broady + broadly + buisness + business + buisnessman + businessman + buoancy + buoyancy + burried + buried + busineses + businesses + busness + business + bussiness + business + caculater + calculator + cacuses + caucuses + cahracters + characters + calaber + caliber + calculater + calculator + calculs + calculus + calenders + calendars + caligraphy + calligraphy + caluclate + calculate + caluclated + calculated + caluculate + calculate + caluculated + calculated + calulate + calculate + calulated + calculated + calulater + calculator + camoflage + camouflage + campain + campaign + campains + campaigns + candadate + candidate + candiate + candidate + candidiate + candidate + cannister + canister + cannisters + canisters + cannnot + cannot + cannonical + canonical + cannotation + connotation + cannotations + connotations + cant + can't + caost + coast + caperbility + capability + capible + capable + captial + capital + captued + captured + capturd + captured + carachter + character + caracterized + characterized + carcas + carcass + carefull + careful + careing + caring + carismatic + charismatic + carnege + carnage + carnige + carnage + carniverous + carnivorous + carreer + career + carrers + careers + cartdridge + cartridge + carthographer + cartographer + cartilege + cartilage + cartilidge + cartilage + cartrige + cartridge + casette + cassette + casion + caisson + cassawory + cassowary + cassowarry + cassowary + casulaties + casualties + casulaty + casualty + catagories + categories + catagorized + categorized + catagory + category + catapillar + caterpillar + catapillars + caterpillars + catapiller + caterpillar + catapillers + caterpillars + catepillar + caterpillar + catepillars + caterpillars + catergorize + categorize + catergorized + categorized + caterpilar + caterpillar + caterpilars + caterpillars + caterpiller + caterpillar + caterpillers + caterpillars + cathlic + catholic + catholocism + catholicism + catterpilar + caterpillar + catterpilars + caterpillars + catterpillar + caterpillar + catterpillars + caterpillars + cattleship + battleship + causalities + casualties + cellpading + cellpadding + cementary + cemetery + cemetarey + cemetery + cemetaries + cemeteries + cemetary + cemetery + cencus + census + censur + censor + cententenial + centennial + centruies + centuries + centruy + century + ceratin + certain + cerimonial + ceremonial + cerimonies + ceremonies + cerimonious + ceremonious + cerimony + ceremony + ceromony + ceremony + certainity + certainty + certian + certain + chalenging + challenging + challange + challenge + challanged + challenged + challege + challenge + changable + changeable + charachter + character + charachters + characters + charactersistic + characteristic + charactor + character + charactors + characters + charasmatic + charismatic + charaterized + characterized + chariman + chairman + charistics + characteristics + cheif + chief + cheifs + chiefs + chemcial + chemical + chemcially + chemically + chemestry + chemistry + chemicaly + chemically + childbird + childbirth + childen + children + choosen + chosen + chracter + character + chuch + church + churchs + churches + circulaton + circulation + circumsicion + circumcision + circut + circuit + ciricuit + circuit + ciriculum + curriculum + civillian + civilian + claer + clear + claerer + clearer + claerly + clearly + claimes + claims + clas + class + clasic + classic + clasical + classical + clasically + classically + cleareance + clearance + clera + clear + clincial + clinical + clinicaly + clinically + cmo + com + cmoputer + computer + co-incided + coincided + coctail + cocktail + coform + conform + cognizent + cognizant + coincedentally + coincidentally + colaborations + collaborations + colateral + collateral + colelctive + collective + collaberative + collaborative + collecton + collection + collegue + colleague + collegues + colleagues + collonade + colonnade + collonies + colonies + collony + colony + collosal + colossal + colonizators + colonizers + comander + commander + comando + commando + comandos + commandos + comany + company + comapany + company + comback + comeback + combanations + combinations + combinatins + combinations + combusion + combustion + comdemnation + condemnation + comemmorates + commemorates + comemoretion + commemoration + comision + commission + comisioned + commissioned + comisioner + commissioner + comisioning + commissioning + comisions + commissions + comission + commission + comissioned + commissioned + comissioner + commissioner + comissioning + commissioning + comissions + commissions + comited + committed + comiting + committing + comitted + committed + comittee + committee + comitting + committing + commandoes + commandos + commedic + comedic + commemerative + commemorative + commemmorate + commemorate + commemmorating + commemorating + commerical + commercial + commerically + commercially + commericial + commercial + commericially + commercially + commerorative + commemorative + comming + coming + comminication + communication + commision + commission + commisioned + commissioned + commisioner + commissioner + commisioning + commissioning + commisions + commissions + commited + committed + commitee + committee + commiting + committing + committe + committee + committment + commitment + committments + commitments + commmemorated + commemorated + commongly + commonly + commonweath + commonwealth + commuications + communications + commuinications + communications + communciation + communication + communiation + communication + communites + communities + compability + compatibility + comparision + comparison + comparisions + comparisons + comparitive + comparative + comparitively + comparatively + compatabilities + compatibilities + compatability + compatibility + compatable + compatible + compatablities + compatibilities + compatablity + compatibility + compatiable + compatible + compatiblities + compatibilities + compatiblity + compatibility + compeitions + competitions + compensantion + compensation + competance + competence + competant + competent + competative + competitive + competion + competition + competitiion + competition + competive + competitive + competiveness + competitiveness + comphrehensive + comprehensive + compitent + competent + completedthe + completed the + completelyl + completely + completetion + completion + complier + compiler + componant + component + comprable + comparable + comprimise + compromise + compulsary + compulsory + compulsery + compulsory + computarized + computerized + concensus + consensus + concider + consider + concidered + considered + concidering + considering + conciders + considers + concieted + conceited + concieved + conceived + concious + conscious + conciously + consciously + conciousness + consciousness + condamned + condemned + condemmed + condemned + condidtion + condition + condidtions + conditions + conditionsof + conditions of + conected + connected + conection + connection + conesencus + consensus + confidental + confidential + confidentally + confidentially + confids + confides + configureable + configurable + confortable + comfortable + congradulations + congratulations + congresional + congressional + conived + connived + conjecutre + conjecture + conjuction + conjunction + conotations + connotations + conquerd + conquered + conquerer + conqueror + conquerers + conquerors + conqured + conquered + conscent + consent + consciouness + consciousness + consdider + consider + consdidered + considered + consdiered + considered + consectutive + consecutive + consenquently + consequently + consentrate + concentrate + consentrated + concentrated + consentrates + concentrates + consept + concept + consequentually + consequently + consequeseces + consequences + consern + concern + conserned + concerned + conserning + concerning + conservitive + conservative + consiciousness + consciousness + consicousness + consciousness + considerd + considered + consideres + considered + consious + conscious + consistant + consistent + consistantly + consistently + consituencies + constituencies + consituency + constituency + consituted + constituted + consitution + constitution + consitutional + constitutional + consolodate + consolidate + consolodated + consolidated + consonent + consonant + consonents + consonants + consorcium + consortium + conspiracys + conspiracies + conspiriator + conspirator + constaints + constraints + constanly + constantly + constarnation + consternation + constatn + constant + constinually + continually + constituant + constituent + constituants + constituents + constituion + constitution + constituional + constitutional + consttruction + construction + constuction + construction + consulant + consultant + consumate + consummate + consumated + consummated + contaiminate + contaminate + containes + contains + contamporaries + contemporaries + contamporary + contemporary + contempoary + contemporary + contemporaneus + contemporaneous + contempory + contemporary + contendor + contender + contibute + contribute + contibuted + contributed + contibutes + contributes + contigent + contingent + contined + continued + continous + continuous + continously + continuously + continueing + continuing + contravercial + controversial + contraversy + controversy + contributer + contributor + contributers + contributors + contritutions + contributions + controled + controlled + controling + controlling + controll + control + controlls + controls + controvercial + controversial + controvercy + controversy + controveries + controversies + controversal + controversial + controversey + controversy + controvertial + controversial + controvery + controversy + contruction + construction + conveinent + convenient + convenant + covenant + convential + conventional + convertables + convertibles + convertion + conversion + conveyer + conveyor + conviced + convinced + convienient + convenient + coordiantion + coordination + coorperations + corporations + copmetitors + competitors + coputer + computer + copywrite + copyright + coridal + cordial + cornmitted + committed + corosion + corrosion + corparate + corporate + corperations + corporations + correcters + correctors + correponding + corresponding + correposding + corresponding + correspondant + correspondent + correspondants + correspondents + corridoors + corridors + corrispond + correspond + corrispondant + correspondent + corrispondants + correspondents + corrisponded + corresponded + corrisponding + corresponding + corrisponds + corresponds + costitution + constitution + coucil + council + counries + countries + countains + contains + countires + countries + coururier + courier + coverted + converted + cpoy + copy + creaeted + created + creedence + credence + critereon + criterion + criterias + criteria + criticists + critics + critising + criticising + critisising + criticising + critisism + criticism + critisisms + criticisms + critisize + criticise + critisized + criticised + critisizes + criticises + critisizing + criticising + critized + criticized + critizing + criticizing + crockodiles + crocodiles + crowm + crown + crtical + critical + crticised + criticised + crucifiction + crucifixion + crusies + cruises + crystalisation + crystallisation + culiminating + culminating + cumulatative + cumulative + curch + church + curcuit + circuit + currenly + currently + curriculem + curriculum + cxan + cyan + cyclinder + cylinder + dacquiri + daiquiri + dael + deal + dalmation + dalmatian + damenor + demeanor + dammage + damage + daugher + daughter + debateable + debatable + decendant + descendant + decendants + descendants + decendent + descendant + decendents + descendants + decideable + decidable + decidely + decidedly + decieved + deceived + decison + decision + decomissioned + decommissioned + decomposit + decompose + decomposited + decomposed + decompositing + decomposing + decomposits + decomposes + decress + decrees + decribe + describe + decribed + described + decribes + describes + decribing + describing + dectect + detect + defendent + defendant + defendents + defendants + deffensively + defensively + deffine + define + deffined + defined + definance + defiance + definate + definite + definately + definitely + definatly + definitely + definetly + definitely + definining + defining + definit + definite + definitly + definitely + definiton + definition + defintion + definition + degrate + degrade + delagates + delegates + delapidated + dilapidated + delerious + delirious + delevopment + development + deliberatly + deliberately + delusionally + delusively + demenor + demeanor + demographical + demographic + demolision + demolition + demorcracy + democracy + demostration + demonstration + denegrating + denigrating + densly + densely + deparment + department + deparmental + departmental + deparments + departments + dependance + dependence + dependancy + dependency + dependant + dependent + deram + dream + deriviated + derived + derivitive + derivative + derogitory + derogatory + descendands + descendants + descibed + described + descision + decision + descisions + decisions + descriibes + describes + descripters + descriptors + descripton + description + desctruction + destruction + descuss + discuss + desgined + designed + deside + decide + desigining + designing + desinations + destinations + desintegrated + disintegrated + desintegration + disintegration + desireable + desirable + desitned + destined + desktiop + desktop + desorder + disorder + desoriented + disoriented + desparate + desperate + despict + depict + despiration + desperation + dessicated + desiccated + dessigned + designed + destablized + destabilized + destory + destroy + detailled + detailed + detatched + detached + deteoriated + deteriorated + deteriate + deteriorate + deterioriating + deteriorating + determinining + determining + detremental + detrimental + devasted + devastated + develope + develop + developement + development + developped + developed + develpment + development + devels + delves + devestated + devastated + devestating + devastating + devide + divide + devided + divided + devistating + devastating + devolopement + development + diablical + diabolical + diamons + diamonds + diaster + disaster + dichtomy + dichotomy + diconnects + disconnects + dicover + discover + dicovered + discovered + dicovering + discovering + dicovers + discovers + dicovery + discovery + dicussed + discussed + didnt + didn't + diea + idea + dieing + dying + dieties + deities + diety + deity + diferent + different + diferrent + different + differentiatiations + differentiations + differnt + different + difficulity + difficulty + diffrent + different + dificulties + difficulties + dificulty + difficulty + dimenions + dimensions + dimention + dimension + dimentional + dimensional + dimentions + dimensions + dimesnional + dimensional + diminuitive + diminutive + dimunitive + diminutive + diosese + diocese + diphtong + diphthong + diphtongs + diphthongs + diplomancy + diplomacy + dipthong + diphthong + dipthongs + diphthongs + dirived + derived + disagreeed + disagreed + disapeared + disappeared + disapointing + disappointing + disappearred + disappeared + disaproval + disapproval + disasterous + disastrous + disatisfaction + dissatisfaction + disatisfied + dissatisfied + disatrous + disastrous + discontentment + discontent + discribe + describe + discribed + described + discribes + describes + discribing + describing + disctinction + distinction + disctinctive + distinctive + disemination + dissemination + disenchanged + disenchanted + disiplined + disciplined + disobediance + disobedience + disobediant + disobedient + disolved + dissolved + disover + discover + dispair + despair + disparingly + disparagingly + dispence + dispense + dispenced + dispensed + dispencing + dispensing + dispicable + despicable + dispite + despite + dispostion + disposition + disproportiate + disproportionate + disputandem + disputandum + disricts + districts + dissagreement + disagreement + dissapear + disappear + dissapearance + disappearance + dissapeared + disappeared + dissapearing + disappearing + dissapears + disappears + dissappear + disappear + dissappears + disappears + dissappointed + disappointed + dissarray + disarray + dissobediance + disobedience + dissobediant + disobedient + dissobedience + disobedience + dissobedient + disobedient + distiction + distinction + distingish + distinguish + distingished + distinguished + distingishes + distinguishes + distingishing + distinguishing + distingquished + distinguished + distrubution + distribution + distruction + destruction + distructive + destructive + ditributed + distributed + diversed + diverged + divice + device + divison + division + divisons + divisions + doccument + document + doccumented + documented + doccuments + documents + docrines + doctrines + doctines + doctrines + documenatry + documentary + doens + does + doesnt + doesn't + doign + doing + dominaton + domination + dominent + dominant + dominiant + dominant + donig + doing + dont + don't + dosen't + doesn't + doub + doubt + doulbe + double + dowloads + downloads + dramtic + dramatic + draughtman + draughtsman + dreasm + dreams + driectly + directly + drnik + drink + druming + drumming + drummless + drumless + dupicate + duplicate + durig + during + durring + during + duting + during + dyas + dryas + eahc + each + ealier + earlier + earlies + earliest + earnt + earned + ecclectic + eclectic + eceonomy + economy + ecidious + deciduous + eclispe + eclipse + ecomonic + economic + ect + etc + eearly + early + efel + evil + effeciency + efficiency + effecient + efficient + effeciently + efficiently + efficency + efficiency + efficent + efficient + efficently + efficiently + efford + effort + effords + efforts + effulence + effluence + eigth + eight + eiter + either + elction + election + electic + electric + electon + electron + electrial + electrical + electricly + electrically + electricty + electricity + elementay + elementary + eleminated + eliminated + eleminating + eliminating + eles + eels + eletricity + electricity + elicided + elicited + eligable + eligible + elimentary + elementary + ellected + elected + elphant + elephant + embarass + embarrass + embarassed + embarrassed + embarassing + embarrassing + embarassment + embarrassment + embargos + embargoes + embarras + embarrass + embarrased + embarrassed + embarrasing + embarrassing + embarrasment + embarrassment + embezelled + embezzled + emblamatic + emblematic + eminate + emanate + eminated + emanated + emision + emission + emited + emitted + emiting + emitting + emition + emission + emmediately + immediately + emmigrated + immigrated + emminently + eminently + emmisaries + emissaries + emmisarries + emissaries + emmisarry + emissary + emmisary + emissary + emmision + emission + emmisions + emissions + emmited + emitted + emmiting + emitting + emmitted + emitted + emmitting + emitting + emnity + enmity + emperical + empirical + emphaised + emphasised + emphsis + emphasis + emphysyma + emphysema + emprisoned + imprisoned + enameld + enameled + enchancement + enhancement + encouraing + encouraging + encryptiion + encryption + encylopedia + encyclopedia + endevors + endeavors + endevour + endeavour + endig + ending + endolithes + endoliths + enduce + induce + ened + need + enflamed + inflamed + enforceing + enforcing + engagment + engagement + engeneer + engineer + engeneering + engineering + engieneer + engineer + engieneers + engineers + enlargment + enlargement + enlargments + enlargements + enourmous + enormous + enourmously + enormously + ensconsed + ensconced + entaglements + entanglements + enteratinment + entertainment + enthusiatic + enthusiastic + entitity + entity + entitlied + entitled + entrepeneur + entrepreneur + entrepeneurs + entrepreneurs + enviorment + environment + enviormental + environmental + enviormentally + environmentally + enviorments + environments + enviornment + environment + enviornmental + environmental + enviornmentalist + environmentalist + enviornmentally + environmentally + enviornments + environments + enviroment + environment + enviromental + environmental + enviromentalist + environmentalist + enviromentally + environmentally + enviroments + environments + envolutionary + evolutionary + envrionments + environments + enxt + next + epidsodes + episodes + epsiode + episode + equialent + equivalent + equilibium + equilibrium + equilibrum + equilibrium + equiped + equipped + equippment + equipment + equitorial + equatorial + equivelant + equivalent + equivelent + equivalent + equivilant + equivalent + equivilent + equivalent + equivlalent + equivalent + erally + really + eratic + erratic + eratically + erratically + eraticly + erratically + errupted + erupted + esential + essential + esitmated + estimated + esle + else + especialy + especially + essencial + essential + essense + essence + essentail + essential + essentialy + essentially + essentual + essential + essesital + essential + estabishes + establishes + establising + establishing + ethnocentricm + ethnocentrism + ethose + those + evenhtually + eventually + eventally + eventually + eventhough + even though + eventially + eventually + eventualy + eventually + everthing + everything + everytime + every time + everyting + everything + eveyr + every + evidentally + evidently + exagerate + exaggerate + exagerated + exaggerated + exagerates + exaggerates + exagerating + exaggerating + exagerrate + exaggerate + exagerrated + exaggerated + exagerrates + exaggerates + exagerrating + exaggerating + examinated + examined + exampt + exempt + exapansion + expansion + excact + exact + excange + exchange + excecute + execute + excecuted + executed + excecutes + executes + excecuting + executing + excecution + execution + excedded + exceeded + excelent + excellent + excell + excel + excellance + excellence + excellant + excellent + excells + excels + excercise + exercise + exchanching + exchanging + excisted + existed + exculsivly + exclusively + execising + exercising + exection + execution + exectued + executed + exeedingly + exceedingly + exelent + excellent + exellent + excellent + exemple + example + exept + except + exeptional + exceptional + exerbate + exacerbate + exerbated + exacerbated + exerciese + exercises + exerpt + excerpt + exerpts + excerpts + exersize + exercise + exerternal + external + exhalted + exalted + exhibtion + exhibition + exibition + exhibition + exibitions + exhibitions + exicting + exciting + exinct + extinct + existance + existence + existant + existent + existince + existence + exliled + exiled + exludes + excludes + exmaple + example + exonorate + exonerate + exoskelaton + exoskeleton + expalin + explain + expatriot + expatriate + expeced + expected + expecially + especially + expeditonary + expeditionary + expeiments + experiments + expell + expel + expells + expels + experiance + experience + experianced + experienced + expiditions + expeditions + expierence + experience + explaination + explanation + explaning + explaining + explictly + explicitly + exploititive + exploitative + explotation + exploitation + expropiated + expropriated + expropiation + expropriation + exressed + expressed + extemely + extremely + extention + extension + extentions + extensions + extered + exerted + extermist + extremist + extint + extinct + extradiction + extradition + extraterrestial + extraterrestrial + extraterrestials + extraterrestrials + extravagent + extravagant + extrememly + extremely + extremeophile + extremophile + extremly + extremely + extrordinarily + extraordinarily + extrordinary + extraordinary + eyar + year + eyars + years + eyasr + years + faciliate + facilitate + faciliated + facilitated + faciliates + facilitates + facilites + facilities + facillitate + facilitate + facinated + fascinated + facist + fascist + familes + families + familliar + familiar + famoust + famous + fanatism + fanaticism + fatc + fact + faught + fought + favoutrable + favourable + feasable + feasible + fedreally + federally + feromone + pheromone + fertily + fertility + fianite + finite + fianlly + finally + ficticious + fictitious + fictious + fictitious + fidn + find + fiercly + fiercely + fightings + fighting + filiament + filament + fimilies + families + finacial + financial + finaly + finally + financialy + financially + firends + friends + firts + first + fisionable + fissionable + flamable + flammable + flawess + flawless + fleed + fled + florescent + fluorescent + flourescent + fluorescent + flourine + fluorine + fluorish + flourish + follwoing + following + folowing + following + fomed + formed + fomr + from + fonetic + phonetic + fontrier + fontier + foootball + football + forbad + forbade + forbiden + forbidden + foreward + foreword + forfiet + forfeit + forhead + forehead + foriegn + foreign + formallize + formalize + formallized + formalized + formaly + formally + formelly + formerly + formidible + formidable + formost + foremost + forsaw + foresaw + forseeable + foreseeable + fortelling + foretelling + forunner + forerunner + foucs + focus + foudn + found + fougth + fought + foundaries + foundries + foundary + foundry + fourties + forties + fourty + forty + fouth + fourth + foward + forward + freind + friend + freindly + friendly + frequentily + frequently + frome + from + fromed + formed + froniter + frontier + fucntion + function + fucntioning + functioning + fufill + fulfill + fufilled + fulfilled + fulfiled + fulfilled + fullfill + fulfill + fullfilled + fulfilled + fundametal + fundamental + fundametals + fundamentals + funguses + fungi + funtion + function + furuther + further + futher + further + futhermore + furthermore + galatic + galactic + gallaxies + galaxies + galvinized + galvanized + ganerate + generate + ganes + games + ganster + gangster + garantee + guarantee + garanteed + guaranteed + garantees + guarantees + garnison + garrison + gaurantee + guarantee + gauranteed + guaranteed + gaurantees + guarantees + gaurd + guard + gaurentee + guarantee + gaurenteed + guaranteed + gaurentees + guarantees + geneological + genealogical + geneologies + genealogies + geneology + genealogy + generaly + generally + generatting + generating + genialia + genitalia + geographicial + geographical + geometrician + geometer + geometricians + geometers + gerat + great + glight + flight + gnawwed + gnawed + godess + goddess + godesses + goddesses + gogin + going + goign + going + gonig + going + gouvener + governor + govement + government + govenment + government + govenrment + government + goverance + governance + goverment + government + govermental + governmental + governer + governor + governmnet + government + govorment + government + govormental + governmental + govornment + government + gracefull + graceful + graet + great + grafitti + graffiti + gramatically + grammatically + grammaticaly + grammatically + grammer + grammar + grat + great + gratuitious + gratuitous + greatful + grateful + greatfully + gratefully + greif + grief + gridles + griddles + gropu + group + grwo + grow + guage + gauge + guarentee + guarantee + guarenteed + guaranteed + guarentees + guarantees + guerilla + guerrilla + guerillas + guerrillas + guerrila + guerrilla + guerrilas + guerrillas + guidence + guidance + gunanine + guanine + gurantee + guarantee + guranteed + guaranteed + gurantees + guarantees + guttaral + guttural + gutteral + guttural + habaeus + habeas + habeus + habeas + haemorrage + haemorrhage + haev + have + halp + help + hapen + happen + hapened + happened + hapening + happening + happend + happened + happended + happened + happenned + happened + harased + harassed + harases + harasses + harasment + harassment + harasments + harassments + harassement + harassment + harras + harass + harrased + harassed + harrases + harasses + harrasing + harassing + harrasment + harassment + harrasments + harassments + harrassed + harassed + harrasses + harassed + harrassing + harassing + harrassment + harassment + harrassments + harassments + hasnt + hasn't + haviest + heaviest + headquarer + headquarter + headquater + headquarter + headquatered + headquartered + headquaters + headquarters + healthercare + healthcare + heared + heard + heathy + healthy + heigher + higher + heirarchy + hierarchy + heiroglyphics + hieroglyphics + helment + helmet + helpfull + helpful + helpped + helped + hemmorhage + hemorrhage + herad + heard + heridity + heredity + heroe + hero + heros + heroes + hertiage + heritage + hertzs + hertz + hesistant + hesitant + heterogenous + heterogeneous + hieght + height + hierachical + hierarchical + hierachies + hierarchies + hierachy + hierarchy + hierarcical + hierarchical + hierarcy + hierarchy + hieroglph + hieroglyph + hieroglphs + hieroglyphs + higer + higher + higest + highest + higway + highway + hillarious + hilarious + himselv + himself + hinderance + hindrance + hinderence + hindrance + hindrence + hindrance + hipopotamus + hippopotamus + hismelf + himself + histocompatability + histocompatibility + historicians + historians + hitsingles + hit singles + holliday + holiday + homestate + home state + homogeneize + homogenize + homogeneized + homogenized + honory + honorary + horrifing + horrifying + hosited + hoisted + hospitible + hospitable + hounour + honour + housr + hours + howver + however + hsitorians + historians + hstory + history + hten + then + htere + there + htey + they + htikn + think + hting + thing + htink + think + htis + this + humer + humor + humerous + humorous + huminoid + humanoid + humoural + humoral + humurous + humorous + husban + husband + hvae + have + hvaing + having + hvea + have + hwihc + which + hwile + while + hwole + whole + hydogen + hydrogen + hydropile + hydrophile + hydropilic + hydrophilic + hydropobe + hydrophobe + hydropobic + hydrophobic + hygeine + hygiene + hypocracy + hypocrisy + hypocrasy + hypocrisy + hypocricy + hypocrisy + hypocrit + hypocrite + hypocrits + hypocrites + i + I + iconclastic + iconoclastic + idaeidae + idea + idaes + ideas + idealogies + ideologies + idealogy + ideology + identicial + identical + identifers + identifiers + ideosyncratic + idiosyncratic + idesa + ideas + idiosyncracy + idiosyncrasy + illegimacy + illegitimacy + illegitmate + illegitimate + illess + illness + illiegal + illegal + illution + illusion + ilness + illness + ilogical + illogical + imagenary + imaginary + imagin + imagine + imaginery + imaginary + imcomplete + incomplete + imediately + immediately + imense + immense + immediatley + immediately + immediatly + immediately + immidately + immediately + immidiately + immediately + immitate + imitate + immitated + imitated + immitating + imitating + immitator + imitator + immunosupressant + immunosuppressant + impecabbly + impeccably + impedence + impedance + implamenting + implementing + impliment + implement + implimented + implemented + imploys + employs + importamt + important + imprioned + imprisoned + imprisonned + imprisoned + improvision + improvisation + improvments + improvements + inablility + inability + inaccessable + inaccessible + inadiquate + inadequate + inadquate + inadequate + inadvertant + inadvertent + inadvertantly + inadvertently + inagurated + inaugurated + inaguration + inauguration + inappropiate + inappropriate + inaugures + inaugurates + inbalance + imbalance + inbalanced + imbalanced + inbetween + between + incarcirated + incarcerated + incidentially + incidentally + incidently + incidentally + inclreased + increased + includ + include + includng + including + incompatabilities + incompatibilities + incompatability + incompatibility + incompatable + incompatible + incompatablities + incompatibilities + incompatablity + incompatibility + incompatiblities + incompatibilities + incompatiblity + incompatibility + incompetance + incompetence + incompetant + incompetent + incomptable + incompatible + incomptetent + incompetent + inconsistant + inconsistent + incoroporated + incorporated + incorperation + incorporation + incorportaed + incorporated + incorprates + incorporates + incorruptable + incorruptible + incramentally + incrementally + increadible + incredible + incredable + incredible + inctroduce + introduce + inctroduced + introduced + incuding + including + incunabla + incunabula + indefinately + indefinitely + indefineable + undefinable + indefinitly + indefinitely + indentical + identical + indepedantly + independently + indepedence + independence + independance + independence + independant + independent + independantly + independently + independece + independence + independendet + independent + indespensable + indispensable + indespensible + indispensable + indictement + indictment + indigineous + indigenous + indipendence + independence + indipendent + independent + indipendently + independently + indispensible + indispensable + indisputible + indisputable + indisputibly + indisputably + indite + indict + individualy + individually + indpendent + independent + indpendently + independently + indulgue + indulge + indutrial + industrial + indviduals + individuals + inefficienty + inefficiently + inevatible + inevitable + inevitible + inevitable + inevititably + inevitably + infalability + infallibility + infallable + infallible + infectuous + infectious + infered + inferred + infilitrate + infiltrate + infilitrated + infiltrated + infilitration + infiltration + infinit + infinite + inflamation + inflammation + influencial + influential + influented + influenced + infomation + information + informtion + information + infrantryman + infantryman + infrigement + infringement + ingenius + ingenious + ingreediants + ingredients + inhabitans + inhabitants + inherantly + inherently + inheritence + inheritance + inital + initial + initally + initially + initation + initiation + initiaitive + initiative + inlcuding + including + inmigrant + immigrant + inmigrants + immigrants + innoculated + inoculated + inocence + innocence + inofficial + unofficial + inot + into + inpeach + impeach + inpolite + impolite + inprisonment + imprisonment + inproving + improving + insectiverous + insectivorous + insensative + insensitive + inseperable + inseparable + insistance + insistence + insitution + institution + insitutions + institutions + inspite + in spite + instade + instead + instatance + instance + institue + institute + instuction + instruction + instuments + instruments + instutionalized + institutionalized + instutions + intuitions + insurence + insurance + intelectual + intellectual + inteligence + intelligence + inteligent + intelligent + intenational + international + intented + intended + intepretation + interpretation + intepretator + interpretor + interational + international + interbread + interbreed + interchangable + interchangeable + interchangably + interchangeably + intercontinetal + intercontinental + intered + interred + interelated + interrelated + interferance + interference + interfereing + interfering + intergrated + integrated + intergration + integration + interm + interim + internation + international + interpet + interpret + interrim + interim + interrugum + interregnum + intertaining + entertaining + interupt + interrupt + intervines + intervenes + intevene + intervene + intial + initial + intially + initially + intrduced + introduced + intrest + interest + introdued + introduced + intruduced + introduced + intrument + instrument + intrumental + instrumental + intruments + instruments + intrusted + entrusted + intutive + intuitive + intutively + intuitively + inudstry + industry + inventer + inventor + invertibrates + invertebrates + investingate + investigate + involvment + involvement + irelevent + irrelevant + iresistable + irresistible + iresistably + irresistibly + iresistible + irresistible + iresistibly + irresistibly + iritable + irritable + iritated + irritated + ironicly + ironically + irregardless + regardless + irrelevent + irrelevant + irreplacable + irreplaceable + irresistable + irresistible + irresistably + irresistibly + isnt + isn't + issueing + issuing + itnroduced + introduced + iunior + junior + iwll + will + iwth + with + jaques + jacques + jeapardy + jeopardy + jewllery + jewellery + jouney + journey + journied + journeyed + journies + journeys + jstu + just + jsut + just + judical + judicial + judisuary + judiciary + juducial + judicial + juristiction + jurisdiction + juristictions + jurisdictions + kindergarden + kindergarten + klenex + kleenex + knifes + knives + knive + knife + knowlege + knowledge + knowlegeable + knowledgeable + knwo + know + knwos + knows + konw + know + konws + knows + kwno + know + labatory + laboratory + labratory + laboratory + laguage + language + laguages + languages + larg + large + largst + largest + larrry + larry + lastr + last + lattitude + latitude + launhed + launched + lavae + larvae + layed + laid + lazyness + laziness + leage + league + leanr + learn + leathal + lethal + lefted + left + legitamate + legitimate + legitmate + legitimate + leibnitz + leibniz + lenght + length + leran + learn + lerans + learns + leutenant + lieutenant + levetate + levitate + levetated + levitated + levetates + levitates + levetating + levitating + levle + level + liasion + liaison + liason + liaison + liasons + liaisons + libary + library + libell + libel + libguistic + linguistic + libguistics + linguistics + libitarianisn + libertarianism + lieing + lying + liek + like + liekd + liked + liesure + leisure + lieuenant + lieutenant + lieved + lived + liftime + lifetime + lightyear + light year + lightyears + light years + likelyhood + likelihood + linnaena + linnaean + lippizaner + lipizzaner + liquify + liquefy + liscense + license + lisence + license + lisense + license + listners + listeners + litature + literature + literaly + literally + literture + literature + littel + little + litterally + literally + liuke + like + livley + lively + lmits + limits + loev + love + lonelyness + loneliness + longitudonal + longitudinal + lonley + lonely + lonly + lonely + loosing + losing + lotharingen + lothringen + lsat + last + lukid + likud + lveo + love + lvoe + love + maching + machine + mackeral + mackerel + magasine + magazine + magincian + magician + magnificient + magnificent + magolia + magnolia + mailny + mainly + maintainance + maintenance + maintainence + maintenance + maintance + maintenance + maintenence + maintenance + maintinaing + maintaining + maintioned + mentioned + majoroty + majority + maked + marked + makse + makes + maltesian + Maltese + mamal + mammal + mamalian + mammalian + managable + manageable + managment + management + maneouvre + manoeuvre + maneouvred + manoeuvred + maneouvres + manoeuvres + maneouvring + manoeuvring + manisfestations + manifestations + manoeuverability + maneuverability + manouver + maneuver + manouverability + maneuverability + manouverable + maneuverable + manouvers + maneuvers + mantained + maintained + manuever + maneuver + manuevers + maneuvers + manufacturedd + manufactured + manufature + manufacture + manufatured + manufactured + manufaturing + manufacturing + manuver + maneuver + mariage + marriage + marjority + majority + markes + marks + marketting + marketing + marmelade + marmalade + marrage + marriage + marraige + marriage + marrtyred + martyred + marryied + married + massmedia + mass media + masterbation + masturbation + mataphysical + metaphysical + materalists + materialist + mathamatics + mathematics + mathematican + mathematician + mathematicas + mathematics + matheticians + mathematicians + mathmatically + mathematically + mathmatician + mathematician + mathmaticians + mathematicians + mccarthyst + mccarthyist + mchanics + mechanics + meaninng + meaning + mear + wear + mechandise + merchandise + medacine + medicine + medeival + medieval + medevial + medieval + mediciney + mediciny + medievel + medieval + mediterainnean + mediterranean + meerkrat + meerkat + melieux + milieux + membranaphone + membranophone + memeber + member + menally + mentally + meranda + Miranda + mercentile + mercantile + messanger + messenger + messenging + messaging + metalic + metallic + metalurgic + metallurgic + metalurgical + metallurgical + metalurgy + metallurgy + metamorphysis + metamorphosis + metaphoricial + metaphorical + meterologist + meteorologist + meterology + meteorology + methaphor + metaphor + methaphors + metaphors + micoscopy + microscopy + midwifes + midwives + mileau + milieu + milennia + millennia + milennium + millennium + mileu + milieu + miliary + military + milion + million + miliraty + military + millenia + millennia + millenial + millennial + millenialism + millennialism + millenium + millennium + millepede + millipede + millioniare + millionaire + millitary + military + millon + million + miltary + military + minature + miniature + minerial + mineral + miniscule + minuscule + ministery + ministry + minstries + ministries + minstry + ministry + minumum + minimum + mirrorred + mirrored + miscelaneous + miscellaneous + miscellanious + miscellaneous + miscellanous + miscellaneous + mischeivous + mischievous + mischevious + mischievous + mischievious + mischievous + misdameanor + misdemeanor + misdameanors + misdemeanors + misdemenor + misdemeanor + misdemenors + misdemeanors + misfourtunes + misfortunes + misile + missile + mispell + misspell + mispelled + misspelled + mispelling + misspelling + missen + mizzen + missle + missile + missonary + missionary + misterious + mysterious + mistery + mystery + misteryous + mysterious + mkae + make + mkaes + makes + mkaing + making + mkea + make + moderm + modem + modle + model + moent + moment + moeny + money + mohammedans + muslims + moil + soil + moleclues + molecules + momento + memento + monestaries + monasteries + monestary + monastery + monickers + monikers + monolite + monolithic + montains + mountains + montanous + mountainous + monts + months + montypic + monotypic + moreso + more so + morgage + mortgage + morroccan + moroccan + morrocco + morocco + morroco + morocco + mortage + mortgage + mosture + moisture + motiviated + motivated + mounth + month + movei + movie + movment + movement + mroe + more + mucuous + mucous + muder + murder + mudering + murdering + muhammadan + muslim + multicultralism + multiculturalism + multipled + multiplied + multiplers + multipliers + munbers + numbers + muncipalities + municipalities + muncipality + municipality + munnicipality + municipality + muscels + muscles + muscial + musical + muscician + musician + muscicians + musicians + mutiliated + mutilated + myraid + myriad + mysef + myself + mysogynist + misogynist + mysogyny + misogyny + mysterous + mysterious + naieve + naive + naturaly + naturally + naturely + naturally + naturual + natural + naturually + naturally + neccesarily + necessarily + neccesary + necessary + neccessarily + necessarily + neccessary + necessary + neccessities + necessities + necesarily + necessarily + necesary + necessary + necessiate + necessitate + neglible + negligible + negligable + negligible + negociate + negotiate + negociation + negotiation + negociations + negotiations + negotation + negotiation + neice + niece + neigborhood + neighborhood + neigbour + neighbour + neigbourhood + neighbourhood + neolitic + neolithic + nessasarily + necessarily + nessecary + necessary + nestin + nesting + neverthless + nevertheless + newletters + newsletters + nickle + nickel + nightfa;; + nightfall + nightime + nighttime + nineth + ninth + ninteenth + nineteenth + ninties + 1990s + ninty + ninety + nkow + know + nkwo + know + nmae + name + noncombatents + noncombatants + nonsence + nonsense + nontheless + nonetheless + noone + no one + norhern + northern + northen + northern + northereastern + northeastern + notabley + notably + noteable + notable + noteably + notably + noteriety + notoriety + noth + north + nothern + northern + noticable + noticeable + noticably + noticeably + noticeing + noticing + noticible + noticeable + notwhithstanding + notwithstanding + noveau + nouveau + nowdays + nowadays + nowe + now + nto + not + nucular + nuclear + nuculear + nuclear + nuisanse + nuisance + numberous + numerous + nusance + nuisance + nutritent + nutrient + nutritents + nutrients + nuturing + nurturing + obediance + obedience + obediant + obedient + obession + obsession + obssessed + obsessed + obstacal + obstacle + obstancles + obstacles + obstruced + obstructed + ocasion + occasion + ocasional + occasional + ocasionally + occasionally + ocasionaly + occasionally + ocasioned + occasioned + ocasions + occasions + ocassion + occasion + ocassional + occasional + ocassionally + occasionally + ocassionaly + occasionally + ocassioned + occasioned + ocassions + occasions + occaison + occasion + occassion + occasion + occassional + occasional + occassionally + occasionally + occassionaly + occasionally + occassioned + occasioned + occassions + occasions + occationally + occasionally + occour + occur + occurance + occurrence + occurances + occurrences + occured + occurred + occurence + occurrence + occurences + occurrences + occuring + occurring + occurr + occur + occurrance + occurrence + occurrances + occurrences + octohedra + octahedra + octohedral + octahedral + octohedron + octahedron + ocuntries + countries + ocuntry + country + ocurr + occur + ocurrance + occurrence + ocurred + occurred + ocurrence + occurrence + offcers + officers + offcially + officially + offereings + offerings + offical + official + offically + officially + officals + officials + officaly + officially + officialy + officially + offred + offered + oftenly + often + oging + going + omision + omission + omited + omitted + omiting + omitting + omlette + omelette + ommision + omission + ommited + omitted + ommiting + omitting + ommitted + omitted + ommitting + omitting + omniverous + omnivorous + omniverously + omnivorously + omre + more + onot + note + onxy + onyx + onyl + only + openess + openness + oponent + opponent + oportunity + opportunity + opose + oppose + oposite + opposite + oposition + opposition + oppenly + openly + oppinion + opinion + opponant + opponent + oppononent + opponent + oppositition + opposition + oppossed + opposed + opprotunity + opportunity + opression + oppression + opressive + oppressive + opthalmic + ophthalmic + opthalmologist + ophthalmologist + opthalmology + ophthalmology + opthamologist + ophthalmologist + optmizations + optimizations + optomism + optimism + orded + ordered + organim + organism + organistion + organisation + organiztion + organization + orgin + origin + orginal + original + orginally + originally + orginize + organise + oridinarily + ordinarily + origanaly + originally + originall + original + originaly + originally + originially + originally + originnally + originally + origional + original + orignally + originally + orignially + originally + otehr + other + oublisher + publisher + ouevre + oeuvre + oustanding + outstanding + overshaddowed + overshadowed + overthere + over there + overwelming + overwhelming + overwheliming + overwhelming + owrk + work + owudl + would + oxigen + oxygen + oximoron + oxymoron + p0enis + penis + paide + paid + paitience + patience + palce + place + paleolitic + paleolithic + paliamentarian + parliamentarian + pallete + palette + pamflet + pamphlet + pamplet + pamphlet + pantomine + pantomime + paralel + parallel + paralell + parallel + paralelly + parallelly + paralely + parallelly + parallely + parallelly + paranthesis + parenthesis + paraphenalia + paraphernalia + parellels + parallels + parituclar + particular + parliment + parliament + parrakeets + parakeets + parralel + parallel + parrallel + parallel + parrallell + parallel + parrallelly + parallelly + parrallely + parallelly + partialy + partially + particually + particularly + particualr + particular + particuarly + particularly + particularily + particularly + particulary + particularly + pary + party + pased + passed + pasengers + passengers + passerbys + passersby + pasttime + pastime + pastural + pastoral + paticular + particular + pattented + patented + pavillion + pavilion + payed + paid + pblisher + publisher + pbulisher + publisher + peacefuland + peaceful and + peageant + pageant + peculure + peculiar + pedestrain + pedestrian + peformed + performed + peice + piece + penatly + penalty + penerator + penetrator + penisula + peninsula + penisular + peninsular + penninsula + peninsula + penninsular + peninsular + pennisula + peninsula + pensinula + peninsula + peom + poem + peoms + poems + peopel + people + peotry + poetry + perade + parade + percepted + perceived + percieve + perceive + percieved + perceived + perenially + perennially + perfomance + performance + perfomers + performers + performence + performance + performes + performed + perhasp + perhaps + perheaps + perhaps + perhpas + perhaps + peripathetic + peripatetic + peristent + persistent + perjery + perjury + perjorative + pejorative + permanant + permanent + permenant + permanent + permenantly + permanently + permissable + permissible + perogative + prerogative + peronal + personal + perosnality + personality + perphas + perhaps + perpindicular + perpendicular + perseverence + perseverance + persistance + persistence + persistant + persistent + personel + personnel + personell + personnel + personnell + personnel + persuded + persuaded + persue + pursue + persued + pursued + persuing + pursuing + persuit + pursuit + persuits + pursuits + pertubation + perturbation + pertubations + perturbations + pessiary + pessary + petetion + petition + phenomenom + phenomenon + phenomenonal + phenomenal + phenomenonly + phenomenally + phenomonenon + phenomenon + phenomonon + phenomenon + phenonmena + phenomena + philisopher + philosopher + philisophical + philosophical + philisophy + philosophy + phillosophically + philosophically + philospher + philosopher + philosphies + philosophies + philosphy + philosophy + phongraph + phonograph + phylosophical + philosophical + physicaly + physically + piblisher + publisher + pich + pitch + pilgrimmage + pilgrimage + pilgrimmages + pilgrimages + pinapple + pineapple + pinnaple + pineapple + pinoneered + pioneered + plagarism + plagiarism + planation + plantation + planed + planned + plantiff + plaintiff + plateu + plateau + plausable + plausible + playright + playwright + playwrite + playwright + playwrites + playwrights + pleasent + pleasant + plebicite + plebiscite + plesant + pleasant + poenis + penis + poeoples + peoples + poety + poetry + poisin + poison + polical + political + polinator + pollinator + polinators + pollinators + politican + politician + politicans + politicians + poltical + political + polute + pollute + poluted + polluted + polutes + pollutes + poluting + polluting + polution + pollution + polyphonyic + polyphonic + polysaccaride + polysaccharide + polysaccharid + polysaccharide + pomegranite + pomegranate + pomotion + promotion + poportional + proportional + popoulation + population + popularaty + popularity + populare + popular + populer + popular + portait + portrait + portayed + portrayed + portraing + portraying + portuguease + portuguese + portugues + Portuguese + posess + possess + posessed + possessed + posesses + possesses + posessing + possessing + posession + possession + posessions + possessions + posion + poison + positon + position + possable + possible + possably + possibly + posseses + possesses + possesing + possessing + possesion + possession + possessess + possesses + possibile + possible + possibilty + possibility + possiblility + possibility + possiblilty + possibility + possiblities + possibilities + possiblity + possibility + possition + position + posthomous + posthumous + postion + position + postive + positive + potatos + potatoes + potrait + portrait + potrayed + portrayed + poulations + populations + poverful + powerful + poweful + powerful + powerfull + powerful + ppublisher + publisher + practial + practical + practially + practically + practicaly + practically + practicioner + practitioner + practicioners + practitioners + practicly + practically + practioner + practitioner + practioners + practitioners + prairy + prairie + prarie + prairie + praries + prairies + pratice + practice + preample + preamble + precedessor + predecessor + preceed + precede + preceeded + preceded + preceeding + preceding + preceeds + precedes + precentage + percentage + precice + precise + precisly + precisely + precurser + precursor + predecesors + predecessors + predicatble + predictable + predicitons + predictions + predomiantly + predominately + prefered + preferred + prefering + preferring + preferrably + preferably + pregancies + pregnancies + preiod + period + preliferation + proliferation + premeire + premiere + premeired + premiered + premillenial + premillennial + preminence + preeminence + premission + permission + preocupation + preoccupation + prepair + prepare + prepartion + preparation + prepatory + preparatory + preperation + preparation + preperations + preparations + preriod + period + presedential + presidential + presense + presence + presidenital + presidential + presidental + presidential + presitgious + prestigious + prespective + perspective + prestigeous + prestigious + prestigous + prestigious + presumabely + presumably + presumibly + presumably + pretection + protection + prevelant + prevalent + preverse + perverse + previvous + previous + pricipal + principal + priciple + principle + priestood + priesthood + primarly + primarily + primative + primitive + primatively + primitively + primatives + primitives + primordal + primordial + priveledges + privileges + privelege + privilege + priveleged + privileged + priveleges + privileges + privelige + privilege + priveliged + privileged + priveliges + privileges + privelleges + privileges + privilage + privilege + priviledge + privilege + priviledges + privileges + privledge + privilege + privte + private + probabilaty + probability + probablistic + probabilistic + probablly + probably + probalibity + probability + probaly + probably + probelm + problem + proccess + process + proccessing + processing + procede + proceed + proceded + proceeded + procedes + proceeds + procedger + procedure + proceding + proceeding + procedings + proceedings + proceedure + procedure + proces + process + processer + processor + proclaimation + proclamation + proclamed + proclaimed + proclaming + proclaiming + proclomation + proclamation + profesion + profession + profesor + professor + professer + professor + proffesed + professed + proffesion + profession + proffesional + professional + proffesor + professor + profilic + prolific + progessed + progressed + programable + programmable + progrom + program + progroms + programs + prohabition + prohibition + prologomena + prolegomena + prominance + prominence + prominant + prominent + prominantly + prominently + prominately + prominently + promiscous + promiscuous + promotted + promoted + pronomial + pronominal + pronouced + pronounced + pronounched + pronounced + pronounciation + pronunciation + proove + prove + prooved + proved + prophacy + prophecy + propietary + proprietary + propmted + prompted + propoganda + propaganda + propogate + propagate + propogates + propagates + propogation + propagation + propostion + proposition + propotions + proportions + propper + proper + propperly + properly + proprietory + proprietary + proseletyzing + proselytizing + protaganist + protagonist + protaganists + protagonists + protocal + protocol + protoganist + protagonist + protrayed + portrayed + protruberance + protuberance + protruberances + protuberances + prouncements + pronouncements + provacative + provocative + provded + provided + provicial + provincial + provinicial + provincial + provisiosn + provision + provisonal + provisional + proximty + proximity + pseudononymous + pseudonymous + pseudonyn + pseudonym + psuedo + pseudo + psycology + psychology + psyhic + psychic + pubilsher + publisher + pubisher + publisher + publiaher + publisher + publically + publicly + publicaly + publicly + publicher + publisher + publihser + publisher + publisehr + publisher + publiser + publisher + publisger + publisher + publisheed + published + publisherr + publisher + publishher + publisher + publishor + publisher + publishre + publisher + publissher + publisher + publlisher + publisher + publsiher + publisher + publusher + publisher + puchasing + purchasing + pulisher + publisher + pumkin + pumpkin + puplisher + publisher + puritannical + puritanical + purposedly + purposely + purpotedly + purportedly + pursuade + persuade + pursuaded + persuaded + pursuades + persuades + pususading + persuading + puting + putting + pwoer + power + pyscic + psychic + qtuie + quiet + quantaty + quantity + quantitiy + quantity + quarantaine + quarantine + questonable + questionable + quicklyu + quickly + quinessential + quintessential + quitted + quit + quizes + quizzes + qutie + quiet + rabinnical + rabbinical + racaus + raucous + radiactive + radioactive + radify + ratify + raelly + really + rarified + rarefied + reaccurring + recurring + reacing + reaching + reacll + recall + readmition + readmission + realitvely + relatively + realsitic + realistic + realtions + relations + realy + really + realyl + really + reasearch + research + rebiulding + rebuilding + rebllions + rebellions + rebounce + rebound + reccomend + recommend + reccomendations + recommendations + reccomended + recommended + reccomending + recommending + reccommend + recommend + reccommended + recommended + reccommending + recommending + reccuring + recurring + receeded + receded + receeding + receding + receivedfrom + received from + recepient + recipient + recepients + recipients + receving + receiving + rechargable + rechargeable + reched + reached + recide + reside + recided + resided + recident + resident + recidents + residents + reciding + residing + reciepents + recipients + reciept + receipt + recieve + receive + recieved + received + reciever + receiver + recievers + receivers + recieves + receives + recieving + receiving + recipiant + recipient + recipiants + recipients + recived + received + recivership + receivership + recogise + recognise + recogize + recognize + recomend + recommend + recomended + recommended + recomending + recommending + recomends + recommends + recommedations + recommendations + reconaissance + reconnaissance + reconcilation + reconciliation + reconized + recognized + reconnaisance + reconnaissance + reconnaissence + reconnaissance + recontructed + reconstructed + recordproducer + record producer + recquired + required + recrational + recreational + recrod + record + recuiting + recruiting + recuring + recurring + recurrance + recurrence + rediculous + ridiculous + reedeming + redeeming + reenforced + reinforced + refect + reflect + refedendum + referendum + referal + referral + referece + reference + refereces + references + refered + referred + referemce + reference + referemces + references + referencs + references + referenece + reference + refereneced + referenced + refereneces + references + referiang + referring + refering + referring + refernce + references + refernces + references + referrence + reference + referrences + references + referrs + refers + reffered + referred + refference + reference + reffering + referring + refrence + reference + refrences + references + refrers + refers + refridgeration + refrigeration + refridgerator + refrigerator + refromist + reformist + refusla + refusal + regardes + regards + regluar + regular + reguarly + regularly + regulaion + regulation + regulaotrs + regulators + regularily + regularly + rehersal + rehearsal + reicarnation + reincarnation + reigining + reigning + reknown + renown + reknowned + renowned + rela + real + relaly + really + relatiopnship + relationship + relativly + relatively + relected + reelected + releive + relieve + releived + relieved + releiver + reliever + releses + releases + relevence + relevance + relevent + relevant + reliablity + reliability + relient + reliant + religeous + religious + religous + religious + religously + religiously + relinqushment + relinquishment + relitavely + relatively + relized + realized + relpacement + replacement + remaing + remaining + remeber + remember + rememberable + memorable + rememberance + remembrance + remembrence + remembrance + remenant + remnant + remenicent + reminiscent + reminent + remnant + reminescent + reminiscent + reminscent + reminiscent + reminsicent + reminiscent + rendevous + rendezvous + rendezous + rendezvous + renedered + rende + renewl + renewal + rennovate + renovate + rennovated + renovated + rennovating + renovating + rennovation + renovation + rentors + renters + reoccurrence + recurrence + reorganision + reorganisation + repatition + repetition + repectively + respectively + repeition + repetition + repentence + repentance + repentent + repentant + repeteadly + repeatedly + repetion + repetition + repid + rapid + reponse + response + reponsible + responsible + reportadly + reportedly + represantative + representative + representive + representative + representives + representatives + reproducable + reproducible + reprtoire + repertoire + repsectively + respectively + reptition + repetition + requirment + requirement + requred + required + resaurant + restaurant + resembelance + resemblance + resembes + resembles + resemblence + resemblance + resevoir + reservoir + residental + residential + resignement + resignment + resistable + resistible + resistence + resistance + resistent + resistant + respectivly + respectively + responce + response + responibilities + responsibilities + responisble + responsible + responnsibilty + responsibility + responsability + responsibility + responsibile + responsible + responsibilites + responsibilities + responsiblities + responsibilities + responsiblity + responsibility + ressemblance + resemblance + ressemble + resemble + ressembled + resembled + ressemblence + resemblance + ressembling + resembling + resssurecting + resurrecting + ressurect + resurrect + ressurected + resurrected + ressurection + resurrection + ressurrection + resurrection + restarant + restaurant + restarants + restaurants + restaraunt + restaurant + restaraunteur + restaurateur + restaraunteurs + restaurateurs + restaraunts + restaurants + restauranteurs + restaurateurs + restauration + restoration + restauraunt + restaurant + resteraunt + restaurant + resteraunts + restaurants + resticted + restricted + restraunt + restraint + resturant + restaurant + resturants + restaurants + resturaunt + restaurant + resturaunts + restaurants + resurecting + resurrecting + retalitated + retaliated + retalitation + retaliation + retreive + retrieve + returnd + returned + revaluated + reevaluated + reveiw + review + reveral + reversal + reversable + reversible + revolutionar + revolutionary + rewitten + rewritten + rewriet + rewrite + rference + reference + rferences + references + rhymme + rhyme + rhythem + rhythm + rhythim + rhythm + rhytmic + rhythmic + rigourous + rigorous + rininging + ringing + rised + rose + rococco + rococo + rocord + record + roomate + roommate + rougly + roughly + rucuperate + recuperate + rudimentatry + rudimentary + rulle + rule + runing + running + runnung + running + russina + Russian + rwite + write + rythem + rhythm + rythim + rhythm + rythm + rhythm + rythmic + rhythmic + rythyms + rhythms + sacrafice + sacrifice + sacreligious + sacrilegious + sacrifical + sacrificial + saftey + safety + safty + safety + salery + salary + sanctionning + sanctioning + sandwhich + sandwich + santioned + sanctioned + sargant + sergeant + sargeant + sergeant + satelite + satellite + satelites + satellites + satisfactority + satisfactorily + satric + satiric + satrical + satirical + satrically + satirically + sattelite + satellite + sattelites + satellites + saught + sought + saveing + saving + saxaphone + saxophone + scaleable + scalable + scandanavia + Scandinavia + scaricity + scarcity + scavanged + scavenged + schedual + schedule + scholarhip + scholarship + scholarstic + scholastic + scientfic + scientific + scientifc + scientific + scientis + scientist + scince + science + scinece + science + scirpt + script + scoll + scroll + screenwrighter + screenwriter + scrutinity + scrutiny + scuptures + sculptures + seach + search + seached + searched + seaches + searches + secratary + secretary + secretery + secretary + sedereal + sidereal + seeked + sought + segementation + segmentation + seguoys + segues + seige + siege + seing + seeing + seinor + senior + seldomly + seldom + senarios + scenarios + senstive + sensitive + sensure + censure + seperate + separate + seperated + separated + seperately + separately + seperates + separates + seperating + separating + seperation + separation + seperatism + separatism + seperatist + separatist + sepina + subpoena + sergent + sergeant + settelement + settlement + settlment + settlement + severeal + several + severley + severely + severly + severely + sevice + service + shadasloo + shadaloo + shaddow + shadow + shadoloo + shadaloo + shamen + shaman + sheat + sheath + sheild + shield + sherif + sheriff + shineing + shining + shiped + shipped + shiping + shipping + shopkeeepers + shopkeepers + shorly + shortly + shortwhile + short while + shoudl + should + shoudln + shouldn't + shouldnt + shouldn't + shreak + shriek + shrinked + shrunk + sicne + since + sideral + sidereal + siezure + seizure + siezures + seizures + siginificant + significant + signficant + significant + signficiant + significant + signfies + signifies + signifantly + significantly + significently + significantly + signifigant + significant + signifigantly + significantly + signitories + signatories + signitory + signatory + similarily + similarly + similiar + similar + similiarity + similarity + similiarly + similarly + simmilar + similar + simpley + simply + simplier + simpler + simultanous + simultaneous + simultanously + simultaneously + sincerley + sincerely + singsog + singsong + sinse + since + skateing + skating + slaugterhouses + slaughterhouses + slighly + slightly + slowy + slowly + smae + same + smealting + smelting + smoe + some + sneeks + sneaks + snese + sneeze + socalism + socialism + socities + societies + soem + some + sofware + software + sohw + show + soilders + soldiers + solatary + solitary + soley + solely + soliders + soldiers + soliliquy + soliloquy + soluable + soluble + somene + someone + somtimes + sometimes + somwhere + somewhere + sophicated + sophisticated + sophmore + sophomore + sorceror + sorcerer + sorrounding + surrounding + sotry + story + sotyr + story + soudn + sound + soudns + sounds + sould + could + sountrack + soundtrack + sourth + south + sourthern + southern + souvenier + souvenir + souveniers + souvenirs + soveits + soviets + sovereignity + sovereignty + soverign + sovereign + soverignity + sovereignty + soverignty + sovereignty + spainish + Spanish + speach + speech + specfic + specific + speciallized + specialized + specifiying + specifying + speciman + specimen + spectauclar + spectacular + spectaulars + spectaculars + spectum + spectrum + speices + species + spendour + splendour + spermatozoan + spermatozoon + spoace + space + sponser + sponsor + sponsered + sponsored + spontanous + spontaneous + sponzored + sponsored + spoonfulls + spoonfuls + sppeches + speeches + spreaded + spread + sprech + speech + spred + spread + spriritual + spiritual + spritual + spiritual + sqaure + square + stablility + stability + stainlees + stainless + staion + station + standars + standards + stange + strange + startegic + strategic + startegies + strategies + startegy + strategy + stateman + statesman + statememts + statements + statment + statement + steriods + steroids + sterotypes + stereotypes + stilus + stylus + stingent + stringent + stiring + stirring + stirrs + stirs + stlye + style + stomache + stomach + stong + strong + stopry + story + storeis + stories + storise + stories + stornegst + strongest + stoyr + story + stpo + stop + stradegies + strategies + stradegy + strategy + strat + start + stratagically + strategically + streemlining + streamlining + stregth + strength + strenghen + strengthen + strenghened + strengthened + strenghening + strengthening + strenght + strength + strenghten + strengthen + strenghtened + strengthened + strenghtening + strengthening + strengtened + strengthened + strenous + strenuous + strictist + strictest + strikely + strikingly + strnad + strand + stroy + story + structual + structural + stubborness + stubbornness + stucture + structure + stuctured + structured + studdy + study + studing + studying + stuggling + struggling + sturcture + structure + subcatagories + subcategories + subcatagory + subcategory + subconsiously + subconsciously + subjudgation + subjugation + submachne + submachine + subpecies + subspecies + subsidary + subsidiary + subsiduary + subsidiary + subsquent + subsequent + subsquently + subsequently + substace + substance + substancial + substantial + substatial + substantial + substituded + substituted + substract + subtract + substracted + subtracted + substracting + subtracting + substraction + subtraction + substracts + subtracts + subtances + substances + subterranian + subterranean + suburburban + suburban + succceeded + succeeded + succcesses + successes + succedded + succeeded + succeded + succeeded + succeds + succeeds + succesful + successful + succesfully + successfully + succesfuly + successfully + succesion + succession + succesive + successive + successfull + successful + successully + successfully + succsess + success + succsessfull + successful + suceed + succeed + suceeded + succeeded + suceeding + succeeding + suceeds + succeeds + sucesful + successful + sucesfully + successfully + sucesfuly + successfully + sucesion + succession + sucess + success + sucesses + successes + sucessful + successful + sucessfull + successful + sucessfully + successfully + sucessfuly + successfully + sucession + succession + sucessive + successive + sucessor + successor + sucessot + successor + sucide + suicide + sucidial + suicidal + sufferage + suffrage + sufferred + suffered + sufferring + suffering + sufficent + sufficient + sufficently + sufficiently + sumary + summary + sunglases + sunglasses + suop + soup + superceeded + superseded + superintendant + superintendent + suphisticated + sophisticated + suplimented + supplemented + supose + suppose + suposed + supposed + suposedly + supposedly + suposes + supposes + suposing + supposing + supplamented + supplemented + suppliementing + supplementing + suppoed + supposed + supposingly + supposedly + suppy + supply + supress + suppress + supressed + suppressed + supresses + suppresses + supressing + suppressing + suprise + surprise + suprised + surprised + suprising + surprising + suprisingly + surprisingly + suprize + surprise + suprized + surprised + suprizing + surprising + suprizingly + surprisingly + surfce + surface + surley + surely + suround + surround + surounded + surrounded + surounding + surrounding + suroundings + surroundings + surounds + surrounds + surplanted + supplanted + surpress + suppress + surpressed + suppressed + surprize + surprise + surprized + surprised + surprizing + surprising + surprizingly + surprisingly + surrended + surrendered + surrepetitious + surreptitious + surrepetitiously + surreptitiously + surreptious + surreptitious + surreptiously + surreptitiously + surronded + surrounded + surrouded + surrounded + surrouding + surrounding + surrundering + surrendering + surveilence + surveillance + surveill + surveil + surveyer + surveyor + surviver + survivor + survivers + survivors + survivied + survived + suseptable + susceptible + suseptible + susceptible + suspention + suspension + swaer + swear + swaers + swears + swepth + swept + swiming + swimming + syas + says + symetrical + symmetrical + symetrically + symmetrically + symetry + symmetry + symettric + symmetric + symmetral + symmetric + symmetricaly + symmetrically + synagouge + synagogue + syncronization + synchronization + synonomous + synonymous + synonymns + synonyms + synphony + symphony + syphyllis + syphilis + sypmtoms + symptoms + syrap + syrup + sysmatically + systematically + sytem + system + sytle + style + tabacco + tobacco + tahn + than + taht + that + talekd + talked + targetted + targeted + targetting + targeting + tast + taste + tath + that + tattooes + tattoos + taxanomic + taxonomic + taxanomy + taxonomy + teached + taught + techician + technician + techicians + technicians + techiniques + techniques + technitian + technician + technnology + technology + technolgy + technology + teh + the + tehy + they + telelevision + television + televsion + television + telphony + telephony + temerature + temperature + tempalte + template + tempaltes + templates + temparate + temperate + temperarily + temporarily + temperment + temperament + tempertaure + temperature + temperture + temperature + temprary + temporary + tenacle + tentacle + tenacles + tentacles + tendacy + tendency + tendancies + tendencies + tendancy + tendency + tennisplayer + tennis player + tepmorarily + temporarily + terrestial + terrestrial + terriories + territories + terriory + territory + territorist + terrorist + territoy + territory + terroist + terrorist + testiclular + testicular + tghe + the + thast + that's + theather + theater + theese + these + theif + thief + theives + thieves + themselfs + themselves + themslves + themselves + ther + there + therafter + thereafter + therby + thereby + theri + their + theyre + they're + thgat + that + thge + the + thier + their + thign + thing + thigns + things + thigsn + things + thikn + think + thikning + thinking + thikns + thinks + thiunk + think + thn + then + thna + than + thne + then + thnig + thing + thnigs + things + thoughout + throughout + threatend + threatened + threatning + threatening + threee + three + threshhold + threshold + thrid + third + throrough + thorough + throughly + thoroughly + throught + throat + througout + throughout + thru + through + thsi + this + thsoe + those + thta + that + thyat + that + tiem + time + tihkn + think + tihs + this + timne + time + tiome + time + tje + the + tjhe + the + tjpanishad + upanishad + tkae + take + tkaes + takes + tkaing + taking + tlaking + talking + tobbaco + tobacco + todays + today's + todya + today + toghether + together + toke + took + tolerence + tolerance + tomatos + tomatoes + tommorow + tomorrow + tommorrow + tomorrow + tongiht + tonight + toriodal + toroidal + tormenters + tormentors + tornadoe + tornado + torpeados + torpedoes + torpedos + torpedoes + tothe + to the + toubles + troubles + tounge + tongue + tourch + torch + towords + towards + towrad + toward + tradionally + traditionally + traditionaly + traditionally + traditionnal + traditional + traditition + tradition + tradtionally + traditionally + trafficed + trafficked + trafficing + trafficking + trafic + traffic + trancendent + transcendent + trancending + transcending + tranform + transform + tranformed + transformed + transcendance + transcendence + transcendant + transcendent + transcendentational + transcendental + transcripting + transcribing + transending + transcending + transesxuals + transsexuals + transfered + transferred + transfering + transferring + transformaton + transformation + transistion + transition + translater + translator + translaters + translators + transmissable + transmissible + transporation + transportation + tremelo + tremolo + tremelos + tremolos + triguered + triggered + triology + trilogy + troling + trolling + troup + troupe + troups + troops + truely + truly + trustworthyness + trustworthiness + turnk + trunk + tust + trust + twelth + twelfth + twon + town + twpo + two + tyhat + that + tyhe + they + typcial + typical + typicaly + typically + tyranies + tyrannies + tyrany + tyranny + tyrranies + tyrannies + tyrrany + tyranny + ubiquitious + ubiquitous + ublisher + publisher + uise + use + ultimely + ultimately + unacompanied + unaccompanied + unahppy + unhappy + unanymous + unanimous + unathorised + unauthorised + unavailible + unavailable + unballance + unbalance + unbeknowst + unbeknownst + unbeleivable + unbelievable + uncertainity + uncertainty + unchallengable + unchallengeable + unchangable + unchangeable + uncompetive + uncompetitive + unconcious + unconscious + unconciousness + unconsciousness + unconfortability + discomfort + uncontitutional + unconstitutional + unconvential + unconventional + undecideable + undecidable + understoon + understood + undesireable + undesirable + undetecable + undetectable + undoubtely + undoubtedly + undreground + underground + uneccesary + unnecessary + unecessary + unnecessary + unequalities + inequalities + unforetunately + unfortunately + unforgetable + unforgettable + unforgiveable + unforgivable + unfortunatley + unfortunately + unfortunatly + unfortunately + unfourtunately + unfortunately + unihabited + uninhabited + unilateraly + unilaterally + unilatreal + unilateral + unilatreally + unilaterally + uninterruped + uninterrupted + uninterupted + uninterrupted + univeral + universal + univeristies + universities + univeristy + university + univerity + university + universtiy + university + univesities + universities + univesity + university + unkown + unknown + unlikey + unlikely + unmanouverable + unmaneuverable + unmistakeably + unmistakably + unneccesarily + unnecessarily + unneccesary + unnecessary + unneccessarily + unnecessarily + unneccessary + unnecessary + unnecesarily + unnecessarily + unnecesary + unnecessary + unoffical + unofficial + unoperational + nonoperational + unoticeable + unnoticeable + unplease + displease + unplesant + unpleasant + unprecendented + unprecedented + unprecidented + unprecedented + unrepentent + unrepentant + unrepetant + unrepentant + unrepetent + unrepentant + unsed + unused + unsubstanciated + unsubstantiated + unsuccesful + unsuccessful + unsuccesfully + unsuccessfully + unsuccessfull + unsuccessful + unsucesful + unsuccessful + unsucesfuly + unsuccessfully + unsucessful + unsuccessful + unsucessfull + unsuccessful + unsucessfully + unsuccessfully + unsuprised + unsurprised + unsuprising + unsurprising + unsuprisingly + unsurprisingly + unsuprized + unsurprised + unsuprizing + unsurprising + unsuprizingly + unsurprisingly + unsurprized + unsurprised + unsurprizing + unsurprising + unsurprizingly + unsurprisingly + untill + until + untranslateable + untranslatable + unuseable + unusable + unusuable + unusable + unviersity + university + unwarrented + unwarranted + unweildly + unwieldy + unwieldly + unwieldy + upcomming + upcoming + upgradded + upgraded + upto + up to + usally + usually + useage + usage + usefull + useful + usefuly + usefully + useing + using + usualy + usually + ususally + usually + vaccum + vacuum + vaccume + vacuum + vacinity + vicinity + vaguaries + vagaries + vaieties + varieties + vailidty + validity + valetta + valletta + valuble + valuable + valueable + valuable + varations + variations + varient + variant + variey + variety + varing + varying + varities + varieties + varity + variety + vasall + vassal + vasalls + vassals + vegatarian + vegetarian + vegitable + vegetable + vegitables + vegetables + vegtable + vegetable + vehicule + vehicle + vell + well + venemous + venomous + vengance + vengeance + vengence + vengeance + verfication + verification + verison + version + verisons + versions + vermillion + vermilion + versitilaty + versatility + versitlity + versatility + vetween + between + veyr + very + vigeur + vigor + vigilence + vigilance + vigourous + vigorous + villian + villain + villification + vilification + villify + vilify + villin + villain + vincinity + vicinity + violentce + violence + virtualy + virtually + virutal + virtual + virutally + virtually + visable + visible + visably + visibly + visting + visiting + vistors + visitors + vitories + victories + volcanoe + volcano + voleyball + volleyball + volontary + voluntary + volonteer + volunteer + volonteered + volunteered + volonteering + volunteering + volonteers + volunteers + volounteer + volunteer + volounteered + volunteered + volounteering + volunteering + volounteers + volunteers + volumne + volume + vreity + variety + vrey + very + vriety + variety + vulnerablility + vulnerability + vyer + very + vyre + very + waht + what + wanna + want to + warantee + warranty + wardobe + wardrobe + warrent + warrant + warrriors + warriors + wasnt + wasn't + wass + was + watn + want + wayword + wayward + weaponary + weaponry + weas + was + wehn + when + weild + wield + weilded + wielded + wendsay + Wednesday + wensday + Wednesday + wereabouts + whereabouts + whant + want + whants + wants + whcih + which + wheras + whereas + wherease + whereas + whereever + wherever + whic + which + whihc + which + whith + with + whlch + which + whn + when + wholey + wholly + wholy + holy + whta + what + whther + whether + wich + which + widesread + widespread + wief + wife + wierd + weird + wiew + view + wih + with + wiht + with + wille + will + willingless + willingness + wirting + writing + withdrawl + withdrawal + witheld + withheld + withh + with + withing + within + withold + withhold + witht + with + witn + with + wiull + will + wnat + want + wnated + wanted + wnats + wants + wohle + whole + wokr + work + wokring + working + wonderfull + wonderful + wont + won't + wordlwide + worldwide + workststion + workstation + worls + world + worstened + worsened + woudl + would + wresters + wrestlers + wriet + write + writen + written + wroet + wrote + wrok + work + wroking + working + wtih + with + wupport + support + xenophoby + xenophobia + yaching + yachting + yaer + year + yaerly + yearly + yaers + years + yatch + yacht + yearm + year + yeasr + years + yeild + yield + yeilding + yielding + yera + year + yeras + years + yersa + years + yotube + YouTube + youre + you're + youseff + yousef + youself + yourself + ytou + you + yuo + you + zeebra + zebra + + + + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index eceee5233..dc28dd4a6 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -55,7 +55,7 @@ SGAllowRiggedMeshSelection Comment - Allow selection of your worn rigged meshes in build mode + Allow selection of worn rigged meshes in build or inspect mode Persist 1 Type @@ -573,7 +573,7 @@ CheckForGridUpdates Comment - Fetch list of grids from Hippo server + Fetch list of grids from location set in GridUpdateList Persist 1 Type @@ -592,6 +592,17 @@ Value Second Life + GridUpdateList + + Comment + URL to fetch Grid updates from + Persist + 1 + Type + String + Value + + VivoxLicenseAccepted @@ -651,6 +662,22 @@ Value 0 + LiruCrosshairColor + + Comment + Color of crosshairs in mouselook + Persist + 1 + Type + Color4 + Value + + 1.0 + 1.0 + 1.0 + 1.0 + + LiruGridInTitle Comment @@ -719,6 +746,17 @@ Value 1 + LiruLegacyOutfitAllLinks + + Comment + Legacy outfits in clothing folder, completely made of links.. no other settings will apply for legacy outfits as they'll all be links. + Persist + 1 + Type + Boolean + Value + 0 + LiruLegacyOutfitStoreObjChanges Comment @@ -730,17 +768,6 @@ Value 1 - LiruLegacySpeakerNames - - Comment - Whether all lists of speakers use legacy names, or your desired way of displaying names. - Persist - 1 - Type - Boolean - Value - 0 - LiruLocalTime Comment @@ -763,6 +790,17 @@ Value 0 + LiruMiniBuildFloater + + Comment + Whether or not the build tools floater is tinified (except in Land tool) + Persist + 1 + Type + Boolean + Value + 0 + LiruMouselookHidesFloaters Comment @@ -796,6 +834,17 @@ Value 0 + LiruMouselookHidesToolbar + + Comment + Whether or not the toolbar will be hidden in mouselook + Persist + 1 + Type + Boolean + Value + 1 + LiruMouselookMenu Comment @@ -979,6 +1028,17 @@ Found in Advanced->Rendering->Info Displays Value 1 + LocalBitmapUpdate + + Comment + Default setting for whether local textures should update or not upon change, changed by toggling on or off. + Persist + 1 + Type + Boolean + Value + 0 + InstantMessageLogPathAnyAccount Comment @@ -990,6 +1050,32 @@ Found in Advanced->Rendering->Info Displays Value + ScriptMessageAPI + + Comment + Channel used for interaction with the Script Message API + Persist + 1 + Type + S32 + Value + 0 + IsCOA + 1 + + ScriptMessageAPIKey + + Comment + Key to encode messages sent to the Script Message API + Persist + 1 + Type + String + Value + Enter Key Here + IsCOA + 1 + UseConciseIMButtons Comment @@ -2618,6 +2704,17 @@ This should be as low as possible, but too low may break functionality Value 0 + AutoReplace + + Comment + Replaces keywords with a configured word or phrase + Persist + 1 + Type + Boolean + Value + 0 + AutoAcceptAllNewInventory Comment @@ -6021,6 +6118,17 @@ This should be as low as possible, but too low may break functionality Value 0 + DoubleClickShowWorldMap + + Comment + Enable double-click to show world map from mini map + Persist + 1 + Type + Boolean + Value + 1 + DragAndDropToolTipDelay Comment @@ -8402,7 +8510,7 @@ This should be as low as possible, but too low may break functionality Type Boolean Value - 0 + 1 ForceMandatoryUpdate @@ -10139,6 +10247,28 @@ This should be as low as possible, but too low may break functionality Value 1 + MiniMapCollisionParcels + + Comment + Show collision parcels on the mini-map as they become available + Persist + 1 + Type + Boolean + Value + 0 + + MiniMapForSaleParcels + + Comment + Show for-sale parcels with a yellow highlight on the mini-map + Persist + 1 + Type + Boolean + Value + 0 + MiniMapPrimMaxAltitudeDelta Comment @@ -10172,6 +10302,28 @@ This should be as low as possible, but too low may break functionality Value 256.0 + MiniMapPropertyLines + + Comment + Show property boundaries on the mini-map + Persist + 1 + Type + Boolean + Value + 0 + + MiniMapRadarTrackingCircles + + Comment + Show tracking circles around the avatars you've selected on the radar in the minimap + Persist + 1 + Type + Boolean + Value + 0 + MiniMapCenter Comment @@ -10286,6 +10438,17 @@ This should be as low as possible, but too low may break functionality Value 128.0 + MiniMapWorldMapTextures + + Comment + Use the world map texture tile on the mini-map rather than the terrain texture + Persist + 1 + Type + Boolean + Value + 0 + MouseSensitivity Comment @@ -16487,7 +16650,7 @@ This should be as low as possible, but too low may break functionality Type String Value - -1 + 0 VivoxDebugSIPURIHostName diff --git a/indra/newview/app_settings/settings_ascent.xml b/indra/newview/app_settings/settings_ascent.xml index bc4537109..d19529164 100644 --- a/indra/newview/app_settings/settings_ascent.xml +++ b/indra/newview/app_settings/settings_ascent.xml @@ -25,10 +25,43 @@ Value 0 + FriendNameSystem + + Comment + For friends list names. 0 = Old Style, 1 = Display Names and Username, 2 = Displayname only, 3 = Old Style (Display Name) + Persist + 1 + Type + S32 + Value + 1 + + GroupMembersNameSystem + + Comment + For lists of group members names. 0 = Old Style, 1 = Display Names and Username, 2 = Displayname only, 3 = Old Style (Display Name) + Persist + 1 + Type + S32 + Value + 1 + + LandManagementNameSystem + + Comment + For names land management lists. 0 = Old Style, 1 = Display Names and Username, 2 = Displayname only, 3 = Old Style (Display Name) + Persist + 1 + Type + S32 + Value + 1 + PhoenixNameSystem Comment - Use Display Names instead of Legacy Names. 0 = Old Style, 1 = Display Names and Username, 2 = Displayname only + For general purpose names in the viewer. 0 = Old Style, 1 = Display Names and Username, 2 = Displayname only, 3 = Old Style (Display Name) Persist 2 Type @@ -36,6 +69,28 @@ Value 1 + RadarNameSystem + + Comment + For names in the radar. 0 = Old Style, 1 = Display Names and Username, 2 = Displayname only, 3 = Old Style (Display Name) + Persist + 1 + Type + S32 + Value + 1 + + SpeakerNameSystem + + Comment + For names in lists of speakers. 0 = Old Style, 1 = Display Names and Username, 2 = Displayname only, 3 = Old Style (Display Name) + Persist + 1 + Type + S32 + Value + 1 + AscentPowerfulWizard Comment @@ -741,5 +796,1001 @@ Value pages/login/ + + ToolbarVisibleAbout + + Comment + Whether or not the button for about is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAboutLand + + Comment + Whether or not the button for about land is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAboutRegion + + Comment + Whether or not the button for region/estate is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleActiveSpeakers + + Comment + Whether or not the button for active speakers is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAlwaysRun + + Comment + Whether or not the button for run is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAnimsExplorer + + Comment + Whether or not the button for anims explorer is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAO + + Comment + Whether or not the button for the AO Floater is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAppearance + + Comment + Whether or not the button for appearance is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAreaSearch + + Comment + Whether or not the button for areasearch is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAssetBlacklist + + Comment + Whether or not the button for asset blacklist is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAutoReplace + + Comment + Whether or not the button for autoreplace is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleBeacons + + Comment + Whether or not the button for beacons is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleBuild + + Comment + Whether or not the button for build is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleBuyCurrency + + Comment + Whether or not the button for buy currency is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleBuyLand + + Comment + Whether or not the button for buy land is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleCameraControls + + Comment + Whether or not the button for camera controls is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleChatbar + + Comment + Whether or not the button for toggling the chatbar is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleChatHistory + + Comment + Whether or not the button for local chat history is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleCommunicate + + Comment + Whether or not the button for communicate floater is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleCommunicateIM + + Comment + Whether or not the flyout button for communicate is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleComplaintReporter + + Comment + Whether or not the button for abuse report is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDayCycle + + Comment + Whether or not the button for day cycle editor is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDebugAvatar + + Comment + Whether or not the button for debug avatar textures is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDebugConsole + + Comment + Whether or not the button for the debug console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDebugSettings + + Comment + Whether or not the button for debug settings is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDisplayName + + Comment + Whether or not the button for display name is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleEditUI + + Comment + Whether or not the button for edit ui is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleEnvSettings + + Comment + Whether or not the button for the environment settings editor is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleFastTimers + + Comment + Whether or not the button for fast timers is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleFly + + Comment + Whether or not the button for fly is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleFontTest + + Comment + Whether or not the button for font test is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleFrameConsole + + Comment + Whether or not the button for the frame console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleFriends + + Comment + Whether or not the button for friends is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGestures + + Comment + Whether or not the button for gestures is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGodTools + + Comment + Whether or not the button for god tools is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGridOptions + + Comment + Whether or not the button for grid options for the build tools is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGroups + + Comment + Whether or not the button for groups is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGroupTitles + + Comment + Whether or not the button for group titles is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + + ToolbarVisibleHelpTutorial + + Comment + Whether or not the button for the tutorial is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleHTTPConsole + + Comment + Whether or not the button for the http console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleInspect + + Comment + Whether or not the button for inspect is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleInventory + + Comment + Whether or not the button for inventory is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleInventoryFavs + + Comment + Whether or not the button for favorites is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleInventoryOutfits + + Comment + Whether or not the button for outfits is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleLagMeter + + Comment + Whether or not the button for lag meter is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleLocalAssets + + Comment + Whether or not the button for local textures is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMeanEvents + + Comment + Whether or not the button for bumps, pushes, and hits is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMediaFilter + + Comment + Whether or not the button for media filter is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMediaTicker + + Comment + Whether or not the button for the streaming audio display is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMemLeak + + Comment + Whether or not the button for memory leak is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMessageLog + + Comment + Whether or not the button for message log is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMiniMap + + Comment + Whether or not the button for the mini-map is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleMouselook + + Comment + Whether or not the button for mouselook is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMovementControls + + Comment + Whether or not the button for movement controls is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMuteList + + Comment + Whether or not the button for mute list is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMyLand + + Comment + Whether or not the button for my land is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleOutbox + + Comment + Whether or not the button for outbox is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleNotificationsConsole + + Comment + Whether or not the button for the notifications console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleOutbox + + Comment + Whether or not the button for the merchant outbox is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleOutfit + + Comment + Whether or not the button for make outfit is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePathfindingCharacters + + Comment + Whether or not the button for pathfinding characters is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePathfindingLinksets + + Comment + Whether or not the button for pathfinding linksets is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePermPrefs + + Comment + Whether or not the button for default upload permissions is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePostProcess + + Comment + Whether or not the button for post-processing effects is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePreferences + + Comment + Whether or not the button for preferences is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleRadar + + Comment + Whether or not the button for the radar is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleRegionDebugConsole + + Comment + Whether or not the button for the region debug console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleScriptErrors + + Comment + Whether or not the button for script errors is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleScriptInfo + + Comment + Whether or not the button for script info is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleSearch + + Comment + Whether or not the button for search is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleSit + + Comment + Whether or not the button for sit is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleSnapshot + + Comment + Whether or not the button for snapshot is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleSoundExplorer + + Comment + Whether or not the button for the sound explorer is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleStatBar + + Comment + Whether or not the button for the statistics bar is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTeleportHistory + + Comment + Whether or not the button for teleport history is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTest + + Comment + Whether or not the button for the test floater is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTextureCategoryConsole + + Comment + Whether or not the button for the texture category console is on the toolbar (requires a relog with AuditTexture true for the button to work) + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTextureConsole + + Comment + Whether or not the button for the texture console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTextureSizeConsole + + Comment + Whether or not the button for the texture size console is on the toolbar (requires a relog with AuditTexture true for the button to work) + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleToolbarPrefs + + Comment + Whether or not the button for the floater to change buttons on the toolbar is on the toolbar (Nonfunctional, yet. Poke Liru.) + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleVelocity + + Comment + Whether or not the button for velocity is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleVoiceEffect + + Comment + Whether or not the button for voice effects is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleWaterSettings + + Comment + Whether or not the button for the water editor is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleWeb + + Comment + Whether or not the button for the web browser is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleWindlight + + Comment + Whether or not the button for the windlight editor is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleWorldMap + + Comment + Whether or not the button for the world map is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + + ToolbarVisibleRLVLocks + + Comment + Whether or not the button for RLVa Locks is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleRLVRestrictions + + Comment + Whether or not the button for RLVa Restrictions is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleRLVStrings + + Comment + Whether or not the button for RLVa Strings is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + diff --git a/indra/newview/app_settings/settings_rlv.xml b/indra/newview/app_settings/settings_rlv.xml index 7dd83af41..c0bd30a1a 100644 --- a/indra/newview/app_settings/settings_rlv.xml +++ b/indra/newview/app_settings/settings_rlv.xml @@ -11,7 +11,7 @@ Type Boolean Value - 1 + 1 RestrainedLoveDebug @@ -22,7 +22,7 @@ Type Boolean Value - 0 + 0 RestrainedLoveCanOOC @@ -33,7 +33,7 @@ Type Boolean Value - 1 + 1 RestrainedLoveForbidGiveToRLV @@ -44,7 +44,7 @@ Type Boolean Value - 0 + 0 RestrainedLoveNoSetEnv @@ -55,19 +55,8 @@ Type Boolean Value - 0 + 0 - RestrainedLoveOffsetAvatarZ - - Comment - Offset the avatar. - Persist - 1 - Type - F32 - Value - 0.0 - RestrainedLoveReplaceWhenFolderBeginsWith Comment @@ -88,7 +77,7 @@ Type Boolean Value - 1 + 1 RestrainedLoveStackWhenFolderBeginsWith @@ -110,7 +99,7 @@ Type Boolean Value - 0 + 0 RLVaEnableCompositeFolders @@ -121,7 +110,7 @@ Type Boolean Value - 0 + 0 RLVaEnableLegacyNaming @@ -132,7 +121,7 @@ Type Boolean Value - 1 + 1 RLVaEnableSharedWear @@ -143,7 +132,7 @@ Type Boolean Value - 1 + 1 RLVaHideLockedLayers @@ -154,7 +143,7 @@ Type Boolean Value - 0 + 0 RLVaHideLockedAttachments @@ -165,7 +154,7 @@ Type Boolean Value - 0 + 0 RLVaSharedInvAutoRename @@ -176,7 +165,7 @@ Type Boolean Value - 1 + 1 RLVaShowAssertionFailures @@ -187,7 +176,7 @@ Type Boolean Value - 1 + 1 RLVaShowNameTags @@ -198,7 +187,7 @@ Type Boolean Value - 0 + 0 RLVaTopLevelMenu @@ -209,7 +198,7 @@ Type Boolean Value - 0 + 0 RLVaWearReplaceUnlocked @@ -220,18 +209,7 @@ Type Boolean Value - 0 - - WarnFirstRLVGiveToRLV - - Comment - Enables FirstRLVGiveToRLV warning dialog - Persist - 1 - Type - Boolean - Value - 1 + 0 ForceInitialCOFDelay diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index 5fb2c4826..c06a6f710 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -240,5 +240,27 @@ Value .5 + SHAltBatching + + Comment + Experimental retooling of face batching. + Persist + 1 + Type + Boolean + Value + 1 + + SHRenderVsyncMode + + Comment + Desired vertical sychronization method. (0 = Disabled, 1 = Standard [Double-buffered], -1 = Adaptive [if supported]) + Persist + 1 + Type + S32 + Value + 0 + diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 57129c3bd..44bd9f5ed 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -26,6 +26,7 @@ ATTRIBUTE vec4 weight4; uniform mat3 matrixPalette[52]; uniform vec3 translationPalette[52]; +uniform float maxWeight; mat4 getObjectSkinnedTransform() { @@ -34,7 +35,7 @@ mat4 getObjectSkinnedTransform() vec4 w = fract(weight4); vec4 index = floor(weight4); - index = min(index, vec4(51.0)); + index = min(index, vec4(maxWeight)); index = max(index, vec4( 0.0)); float scale = 1.0/(w.x+w.y+w.z+w.w); diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index d504a38fa..660be832d 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -37,6 +37,7 @@ #include "llagent.h" #include "llcolorswatch.h" #include "llcombobox.h" +#include "llfloaterautoreplacesettings.h" #include "llradiogroup.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" @@ -92,6 +93,7 @@ LLPrefsAscentChat::LLPrefsAscentChat() getChild("antispam_checkbox")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitDialogBlock, this, _1, _2)); getChild("Group Invites")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitDialogBlock, this, _1, _2)); + getChild("autoreplace")->setCommitCallback(boost::bind(LLFloaterAutoReplaceSettings::showInstance, LLSD())); getChild("KeywordsOn")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitKeywords, this, _1)); getChild("KeywordsList")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitKeywords, this, _1)); getChild("KeywordsSound")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitKeywords, this, _1)); @@ -298,7 +300,11 @@ void LLPrefsAscentChat::refreshValues() mOnlyComm = gSavedSettings.getBOOL("CommunicateSpecificShortcut"); mItalicizeActions = gSavedSettings.getBOOL("LiruItalicizeActions"); mLegacyLogLaunch = gSavedSettings.getBOOL("LiruLegacyLogLaunch"); - mLegacySpeakerNames = gSavedSettings.getBOOL("LiruLegacySpeakerNames"); + mFriendNames = gSavedSettings.getS32("FriendNameSystem"); + mGroupMembersNames = gSavedSettings.getS32("GroupMembersNameSystem"); + mLandManagementNames = gSavedSettings.getS32("LandManagementNameSystem"); + mRadarNames = gSavedSettings.getS32("RadarNameSystem"); + mSpeakerNames = gSavedSettings.getS32("SpeakerNameSystem"); //Autoresponse ------------------------------------------------------------------------ mIMResponseAnyoneItemID = gSavedPerAccountSettings.getString("AutoresponseAnyoneItemID"); @@ -376,6 +382,18 @@ void LLPrefsAscentChat::refresh() combo->setCurrentByIndex(mDateFormat); } + //Chat UI ----------------------------------------------------------------------------- + if (combo = getChild("friends_namesystem_combobox")) + combo->setCurrentByIndex(mFriendNames); + if (combo = getChild("group_members_namesystem_combobox")) + combo->setCurrentByIndex(mGroupMembersNames); + if (combo = getChild("land_management_namesystem_combobox")) + combo->setCurrentByIndex(mLandManagementNames); + if (combo = getChild("radar_namesystem_combobox")) + combo->setCurrentByIndex(mRadarNames); + if (combo = getChild("speaker_namesystem_combobox")) + combo->setCurrentByIndex(mSpeakerNames); + //Antispam ------------------------------------------------------------------------ // sensitivity tuners childSetEnabled("spammsg_checkbox", mEnableAS); @@ -537,7 +555,11 @@ void LLPrefsAscentChat::cancel() gSavedSettings.setBOOL("CommunicateSpecificShortcut", mOnlyComm); gSavedSettings.setBOOL("LiruItalicizeActions", mItalicizeActions); gSavedSettings.setBOOL("LiruLegacyLogLaunch", mLegacyLogLaunch); - gSavedSettings.setBOOL("LiruLegacySpeakerNames", mLegacySpeakerNames); + gSavedSettings.setS32("FriendNameSystem", mFriendNames); + gSavedSettings.setS32("GroupMembersNameSystem", mGroupMembersNames); + gSavedSettings.setS32("LandManagementNameSystem", mLandManagementNames); + gSavedSettings.setS32("RadarNameSystem", mRadarNames); + gSavedSettings.setS32("SpeakerNameSystem", mSpeakerNames); //Autoresponse ------------------------------------------------------------------------ gSavedPerAccountSettings.setString("AutoresponseAnyoneItemID", mIMResponseAnyoneItemID); diff --git a/indra/newview/ascentprefschat.h b/indra/newview/ascentprefschat.h index 5b235dafa..d3f324a60 100644 --- a/indra/newview/ascentprefschat.h +++ b/indra/newview/ascentprefschat.h @@ -87,8 +87,12 @@ private: bool mOneLineConfButt; bool mOnlyComm; bool mItalicizeActions; - bool mLegacySpeakerNames; bool mLegacyLogLaunch; + S32 mFriendNames; + S32 mGroupMembersNames; + S32 mLandManagementNames; + S32 mRadarNames; + S32 mSpeakerNames; //Autoresponse ------------------------------------------------------------------------ std::string mIMResponseAnyoneItemID; diff --git a/indra/newview/floaterlocalassetbrowse.cpp b/indra/newview/floaterlocalassetbrowse.cpp index abcb19c98..a3af2928d 100644 --- a/indra/newview/floaterlocalassetbrowse.cpp +++ b/indra/newview/floaterlocalassetbrowse.cpp @@ -72,6 +72,8 @@ this feature is still a work in progress. #include "llvovolume.h" #include "llface.h" +/* static pointer to self, wai? oh well. */ +static FloaterLocalAssetBrowser* sLFInstance = NULL; /*=======================================*/ /* Instantiating manager class */ @@ -79,7 +81,7 @@ this feature is still a work in progress. /*=======================================*/ LocalAssetBrowser* gLocalBrowser; LocalAssetBrowserTimer* gLocalBrowserTimer; -std::vector LocalAssetBrowser::loaded_bitmaps; +std::vector LocalAssetBrowser::loaded_bitmaps; bool LocalAssetBrowser::mLayerUpdated; bool LocalAssetBrowser::mSculptUpdated; @@ -93,54 +95,54 @@ bool LocalAssetBrowser::mSculptUpdated; LocalBitmap::LocalBitmap(std::string fullpath) { - this->valid = false; + valid = false; if ( gDirUtilp->fileExists(fullpath) ) { /* taking care of basic properties */ - this->id.generate(); - this->filename = fullpath; - this->linkstatus = LINK_OFF; - this->keep_updating = false; - this->shortname = gDirUtilp->getBaseFileName(this->filename, true); - this->bitmap_type = TYPE_TEXTURE; - this->sculpt_dirty = false; - this->volume_dirty = false; - this->valid = false; + id.generate(); + filename = fullpath; + keep_updating = gSavedSettings.getBOOL("LocalBitmapUpdate"); + linkstatus = keep_updating ? LINK_ON : LINK_OFF; + shortname = gDirUtilp->getBaseFileName(filename, true); + bitmap_type = TYPE_TEXTURE; + sculpt_dirty = false; + volume_dirty = false; + valid = false; /* taking care of extension type now to avoid switch madness */ - std::string temp_exten = gDirUtilp->getExtension(this->filename); + std::string temp_exten = gDirUtilp->getExtension(filename); - if (temp_exten == "bmp") { this->extension = IMG_EXTEN_BMP; } - else if (temp_exten == "tga") { this->extension = IMG_EXTEN_TGA; } - else if (temp_exten == "jpg" || temp_exten == "jpeg") { this->extension = IMG_EXTEN_JPG; } - else if (temp_exten == "png") { this->extension = IMG_EXTEN_PNG; } - else { return; } // no valid extension. + if (temp_exten == "bmp") extension = IMG_EXTEN_BMP; + else if (temp_exten == "tga") extension = IMG_EXTEN_TGA; + else if (temp_exten == "jpg" || temp_exten == "jpeg") extension = IMG_EXTEN_JPG; + else if (temp_exten == "png") extension = IMG_EXTEN_PNG; + else return; // no valid extension. /* getting file's last modified */ llstat temp_stat; - LLFile::stat(this->filename, &temp_stat); + LLFile::stat(filename, &temp_stat); std::time_t time = temp_stat.st_mtime; - this->last_modified = asctime( localtime(&time) ); + last_modified = asctime( localtime(&time) ); /* checking if the bitmap is valid && decoding if it is */ - LLImageRaw* raw_image = new LLImageRaw(); - if ( this->decodeSelf(raw_image) ) + LLPointer raw_image = new LLImageRaw; + if (decodeSelf(raw_image)) { /* creating a shell LLViewerTexture and fusing raw image into it */ - LLViewerFetchedTexture* viewer_image = new LLViewerFetchedTexture( "file://"+this->filename, this->id, LOCAL_USE_MIPMAPS ); + LLViewerFetchedTexture* viewer_image = new LLViewerFetchedTexture( "file://"+filename, id, LOCAL_USE_MIPMAPS ); viewer_image->createGLTexture( LOCAL_DISCARD_LEVEL, raw_image ); viewer_image->setCachedRawImage(-1,raw_image); /* making damn sure gTextureList will not delete it prematurely */ - viewer_image->ref(); + viewer_image->ref(); /* finalizing by adding LLViewerTexture instance into gTextureList */ gTextureList.addImage(viewer_image); /* filename is valid, bitmap is decoded and valid, i can haz liftoff! */ - this->valid = true; + valid = true; } } } @@ -152,60 +154,64 @@ LocalBitmap::~LocalBitmap() /* [maintenence functions] */ void LocalBitmap::updateSelf() { - if ( this->linkstatus == LINK_ON || this->linkstatus == LINK_UPDATING ) + if (linkstatus == LINK_ON || linkstatus == LINK_UPDATING) { /* making sure file still exists */ - if ( !gDirUtilp->fileExists(this->filename) ) { this->linkstatus = LINK_BROKEN; return; } + if (!gDirUtilp->fileExists(filename)) + { + linkstatus = LINK_BROKEN; + return; + } /* exists, let's check if it's lastmod has changed */ llstat temp_stat; - LLFile::stat(this->filename, &temp_stat); + LLFile::stat(filename, &temp_stat); std::time_t temp_time = temp_stat.st_mtime; LLSD new_last_modified = asctime( localtime(&temp_time) ); - if ( this->last_modified.asString() == new_last_modified.asString() ) { return; } + if (last_modified.asString() == new_last_modified.asString()) return; /* here we update the image */ - LLImageRaw* new_imgraw = new LLImageRaw(); - - if ( !decodeSelf(new_imgraw) ) { this->linkstatus = LINK_UPDATING; return; } - else { this->linkstatus = LINK_ON; } - - LLViewerFetchedTexture* image = gTextureList.findImage(this->id); - - if (!image->forSculpt()) - { image->createGLTexture( LOCAL_DISCARD_LEVEL, new_imgraw ); } + LLPointer new_imgraw = new LLImageRaw; + if (!decodeSelf(new_imgraw)) + { + linkstatus = LINK_UPDATING; + return; + } else - { image->setCachedRawImage(-1,new_imgraw); } + { + linkstatus = LINK_ON; + } + + LLViewerFetchedTexture* image = gTextureList.findImage(id); + if (!image->forSculpt()) + image->createGLTexture(LOCAL_DISCARD_LEVEL, new_imgraw); + else + image->setCachedRawImage(-1,new_imgraw); /* finalizing by updating lastmod to current */ - this->last_modified = new_last_modified; + last_modified = new_last_modified; /* setting unit property to reflect that it has been changed */ - switch (this->bitmap_type) + switch (bitmap_type) { - case TYPE_TEXTURE: - { break; } - case TYPE_SCULPT: - { - /* sets a bool to run through all visible sculpts in one go, and update the ones necessary. */ - this->sculpt_dirty = true; - this->volume_dirty = true; - gLocalBrowser->setSculptUpdated( true ); - break; - } - + { + /* sets a bool to run through all visible sculpts in one go, and update the ones necessary. */ + sculpt_dirty = true; + volume_dirty = true; + gLocalBrowser->setSculptUpdated( true ); + break; + } case TYPE_LAYER: - { - /* sets a bool to rebake layers after the iteration is done with */ - gLocalBrowser->setLayerUpdated( true ); - break; - } - + { + /* sets a bool to rebake layers after the iteration is done with */ + gLocalBrowser->setLayerUpdated( true ); + break; + } + case TYPE_TEXTURE: default: - { break; } - + break; } } @@ -213,51 +219,47 @@ void LocalBitmap::updateSelf() bool LocalBitmap::decodeSelf(LLImageRaw* rawimg) { - switch (this->extension) + switch (extension) { case IMG_EXTEN_BMP: - { - LLPointer bmp_image = new LLImageBMP; - if ( !bmp_image->load(filename) ) { break; } - if ( !bmp_image->decode(rawimg, 0.0f) ) { break; } - - rawimg->biasedScaleToPowerOfTwo( LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT ); - return true; - } + { + LLPointer bmp_image = new LLImageBMP; + if (!bmp_image->load(filename)) break; + if (!bmp_image->decode(rawimg, 0.0f)) break; + rawimg->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); + return true; + } case IMG_EXTEN_TGA: - { - LLPointer tga_image = new LLImageTGA; - if ( !tga_image->load(filename) ) { break; } - if ( !tga_image->decode(rawimg) ) { break; } - - if( ( tga_image->getComponents() != 3) && - ( tga_image->getComponents() != 4) ) { break; } - - rawimg->biasedScaleToPowerOfTwo( LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT ); - return true; - } + { + LLPointer tga_image = new LLImageTGA; + if (!tga_image->load(filename)) break; + if (!tga_image->decode(rawimg)) break; + if (( tga_image->getComponents() != 3) && + ( tga_image->getComponents() != 4) ) + break; + rawimg->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); + return true; + } case IMG_EXTEN_JPG: - { - LLPointer jpeg_image = new LLImageJPEG; - if ( !jpeg_image->load(filename) ) { break; } - if ( !jpeg_image->decode(rawimg, 0.0f) ) { break; } - - rawimg->biasedScaleToPowerOfTwo( LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT ); - return true; - } + { + LLPointer jpeg_image = new LLImageJPEG; + if (!jpeg_image->load(filename)) break; + if (!jpeg_image->decode(rawimg, 0.0f)) break; + rawimg->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); + return true; + } case IMG_EXTEN_PNG: - { - LLPointer png_image = new LLImagePNG; - if ( !png_image->load(filename) ) { break; } - if ( !png_image->decode(rawimg, 0.0f) ) { break; } - - rawimg->biasedScaleToPowerOfTwo( LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT ); - return true; - } + { + LLPointer png_image = new LLImagePNG; + if ( !png_image->load(filename) ) break; + if ( !png_image->decode(rawimg, 0.0f) ) break; + rawimg->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); + return true; + } default: break; } @@ -266,54 +268,55 @@ bool LocalBitmap::decodeSelf(LLImageRaw* rawimg) void LocalBitmap::setUpdateBool() { - if ( this->linkstatus != LINK_BROKEN ) + if (linkstatus != LINK_BROKEN) { - if ( !this->keep_updating ) + if (!keep_updating) { - this->linkstatus = LINK_ON; - this->keep_updating = true; + linkstatus = LINK_ON; + keep_updating = true; } else { - this->linkstatus = LINK_OFF; - this->keep_updating = false; + linkstatus = LINK_OFF; + keep_updating = false; } } else { - this->keep_updating = false; + keep_updating = false; } + gSavedSettings.setBOOL("LocalBitmapUpdate", keep_updating); } void LocalBitmap::setType( S32 type ) { - this->bitmap_type = type; + bitmap_type = type; } /* [information query functions] */ std::string LocalBitmap::getShortName() { - return this->shortname; + return shortname; } std::string LocalBitmap::getFileName() { - return this->filename; + return filename; } LLUUID LocalBitmap::getID() { - return this->id; + return id; } LLSD LocalBitmap::getLastModified() { - return this->last_modified; + return last_modified; } std::string LocalBitmap::getLinkStatus() { - switch(this->linkstatus) + switch(linkstatus) { case LINK_ON: return "On"; @@ -334,22 +337,17 @@ std::string LocalBitmap::getLinkStatus() bool LocalBitmap::getUpdateBool() { - return this->keep_updating; + return keep_updating; } bool LocalBitmap::getIfValidBool() { - return this->valid; -} - -LocalBitmap* LocalBitmap::getThis() -{ - return this; + return valid; } S32 LocalBitmap::getType() { - return this->bitmap_type; + return bitmap_type; } std::vector LocalBitmap::getFaceUsesThis(LLDrawable* drawable) @@ -360,8 +358,8 @@ std::vector LocalBitmap::getFaceUsesThis(LLDrawable* drawable) { LLFace* newface = drawable->getFace(face_iter); - if ( this->id == newface->getTexture()->getID() ) - { matching_faces.push_back(newface); } + if (id == newface->getTexture()->getID()) + matching_faces.push_back(newface); } return matching_faces; @@ -389,10 +387,10 @@ std::vector LocalBitmap::getUsingObjects(bool seek_by_type, boo if ( obj && obj->mDrawable ) { /* looking for textures */ - if ( seek_textures || ( seek_by_type && this->bitmap_type == TYPE_TEXTURE ) ) + if (seek_textures || (seek_by_type && bitmap_type == TYPE_TEXTURE)) { - std::vector affected_faces = this->getFaceUsesThis( obj->mDrawable ); - if ( !affected_faces.empty() ) + std::vector affected_faces = getFaceUsesThis(obj->mDrawable); + if (!affected_faces.empty()) { shell.face_list = affected_faces; obj_relevant = true; @@ -400,22 +398,18 @@ std::vector LocalBitmap::getUsingObjects(bool seek_by_type, boo } /* looking for sculptmaps */ - if ( ( seek_sculptmaps || ( seek_by_type && this->bitmap_type == TYPE_SCULPT ) ) - && obj->isSculpted() && obj->getVolume() - && this->id == obj->getVolume()->getParams().getSculptID() - ) + if ((seek_sculptmaps || (seek_by_type && bitmap_type == TYPE_SCULPT)) + && obj->isSculpted() && obj->getVolume() + && id == obj->getVolume()->getParams().getSculptID()) { shell.local_sculptmap = true; obj_relevant = true; } } - if (obj_relevant) - { affected_vector.push_back(shell); } + if (obj_relevant) affected_vector.push_back(shell); } - - return affected_vector; } @@ -423,15 +417,15 @@ void LocalBitmap::getDebugInfo() { /* debug function: dumps everything human readable into llinfos */ llinfos << "===[local bitmap debug]===" << "\n" - << "path: " << this->filename << "\n" - << "name: " << this->shortname << "\n" - << "extension: " << this->extension << "\n" - << "uuid: " << this->id << "\n" - << "last modified: " << this->last_modified << "\n" - << "link status: " << this->getLinkStatus() << "\n" - << "keep updated: " << this->keep_updating << "\n" - << "type: " << this->bitmap_type << "\n" - << "is valid: " << this->valid << "\n" + << "path: " << filename << "\n" + << "name: " << shortname << "\n" + << "extension: " << extension << "\n" + << "uuid: " << id << "\n" + << "last modified: " << last_modified << "\n" + << "link status: " << getLinkStatus() << "\n" + << "keep updated: " << keep_updating << "\n" + << "type: " << bitmap_type << "\n" + << "is valid: " << valid << "\n" << "==========================" << llendl; } @@ -447,8 +441,8 @@ void LocalBitmap::getDebugInfo() LocalAssetBrowser::LocalAssetBrowser() { - this->mLayerUpdated = false; - this->mSculptUpdated = false; + mLayerUpdated = false; + mSculptUpdated = false; } LocalAssetBrowser::~LocalAssetBrowser() @@ -472,17 +466,15 @@ void LocalAssetBrowser::AddBitmap_continued(AIFilePicker* filepicker) std::vector const& filenames(filepicker->getFilenames()); for(std::vector::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) { - LocalBitmap* unit = new LocalBitmap(*filename); - - if ( unit->getIfValidBool() ) + LocalBitmap unit(*filename); + if (unit.getIfValidBool()) { - loaded_bitmaps.push_back( unit ); + loaded_bitmaps.push_back(unit); change_happened = true; } } - if ( change_happened ) - { onChangeHappened(); } + if (change_happened) onChangeHappened(); } void LocalAssetBrowser::DelBitmap( std::vector delete_vector, S32 column ) @@ -498,34 +490,26 @@ void LocalAssetBrowser::DelBitmap( std::vector delete_vector, for (local_list_iter iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end();) { - LocalBitmap* unit = (*iter)->getThis(); - - if ( unit->getID() == id ) + if ((*iter).getID() == id) { LLViewerFetchedTexture* image = gTextureList.findImage(id); gTextureList.deleteImage( image ); image->unref(); - iter = loaded_bitmaps.erase(iter); - delete unit; - unit = NULL; - change_happened = true; } else - { iter++; } + ++iter; } } } - if ( change_happened ) - { onChangeHappened(); } + if (change_happened) onChangeHappened(); } void LocalAssetBrowser::onUpdateBool(LLUUID id) { - LocalBitmap* unit = GetBitmapUnit( id ); - if ( unit ) + if (LocalBitmap* unit = GetBitmapUnit(id)) { unit->setUpdateBool(); PingTimer(); @@ -534,32 +518,22 @@ void LocalAssetBrowser::onUpdateBool(LLUUID id) void LocalAssetBrowser::onSetType(LLUUID id, S32 type) { - LocalBitmap* unit = GetBitmapUnit( id ); - if ( unit ) - { unit->setType(type); } + if (LocalBitmap* unit = GetBitmapUnit(id)) unit->setType(type); } LocalBitmap* LocalAssetBrowser::GetBitmapUnit(LLUUID id) { - local_list_iter iter = loaded_bitmaps.begin(); - for (; iter != loaded_bitmaps.end(); iter++) - { - if ( (*iter)->getID() == id ) - { - return (*iter)->getThis(); - } - } - + for (local_list_iter iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); ++iter) + if ((*iter).getID() == id) + return &(*iter); return NULL; } bool LocalAssetBrowser::IsDoingUpdates() { - local_list_iter iter = loaded_bitmaps.begin(); - for (; iter != loaded_bitmaps.end(); iter++) + for (local_list_iter iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); iter++) { - if ( (*iter)->getUpdateBool() ) - { return true; } /* if at least one unit in the list needs updates - we need a timer. */ + if ((*iter).getUpdateBool()) return true; /* if at least one unit in the list needs updates - we need a timer. */ } return false; @@ -572,7 +546,7 @@ bool LocalAssetBrowser::IsDoingUpdates() void LocalAssetBrowser::onChangeHappened() { /* own floater update */ - FloaterLocalAssetBrowser::UpdateBitmapScrollList(); + if (sLFInstance) sLFInstance->UpdateBitmapScrollList(); /* texturepicker related */ const LLView::child_list_t* child_list = gFloaterView->getChildList(); @@ -599,44 +573,37 @@ void LocalAssetBrowser::onChangeHappened() void LocalAssetBrowser::PingTimer() { - if ( !loaded_bitmaps.empty() && IsDoingUpdates() ) + if (!loaded_bitmaps.empty() && IsDoingUpdates()) { - if (!gLocalBrowserTimer) - { gLocalBrowserTimer = new LocalAssetBrowserTimer(); } - - if ( !gLocalBrowserTimer->isRunning() ) - { gLocalBrowserTimer->start(); } + if (!gLocalBrowserTimer) + gLocalBrowserTimer = new LocalAssetBrowserTimer(); + if (!gLocalBrowserTimer->isRunning()) + gLocalBrowserTimer->start(); } - - else + else if (gLocalBrowserTimer && gLocalBrowserTimer->isRunning()) { - if (gLocalBrowserTimer) - { - if ( gLocalBrowserTimer->isRunning() ) - { gLocalBrowserTimer->stop(); } - } + gLocalBrowserTimer->stop(); } } /* This function refills the texture picker floater's scrolllist with the updated contents of bitmaplist */ void LocalAssetBrowser::UpdateTextureCtrlList(LLScrollListCtrl* ctrl) { - if ( ctrl ) // checking again in case called externally for some silly reason. + if (ctrl) // checking again in case called externally for some silly reason. { ctrl->clearRows(); if ( !loaded_bitmaps.empty() ) { - local_list_iter iter = loaded_bitmaps.begin(); - for ( ; iter != loaded_bitmaps.end(); iter++ ) + for (local_list_iter iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); ++iter) { LLSD element; element["columns"][0]["column"] = "unit_name"; element["columns"][0]["type"] = "text"; - element["columns"][0]["value"] = (*iter)->shortname; + element["columns"][0]["value"] = (*iter).shortname; element["columns"][1]["column"] = "unit_id_HIDDEN"; element["columns"][1]["type"] = "text"; - element["columns"][1]["value"] = (*iter)->id; + element["columns"][1]["value"] = (*iter).id; ctrl->addElement(element); } @@ -644,73 +611,58 @@ void LocalAssetBrowser::UpdateTextureCtrlList(LLScrollListCtrl* ctrl) } } -void LocalAssetBrowser::PerformTimedActions(void) +void LocalAssetBrowser::PerformTimedActions() { // perform checking if updates are needed && update if so. - local_list_iter iter; - for (iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); iter++) - { (*iter)->updateSelf(); } - - // one or more sculpts have been updated, refreshing them. - if ( mSculptUpdated ) + for (local_list_iter iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); ++iter) { - LocalAssetBrowser::local_list_iter iter; - for(iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); iter++) + (*iter).updateSelf(); + // one or more sculpts have been updated, refreshing them. + if (mSculptUpdated && (*iter).sculpt_dirty) { - if ( (*iter)->sculpt_dirty ) - { - PerformSculptUpdates( (*iter)->getThis() ); - (*iter)->sculpt_dirty = false; - } + PerformSculptUpdates(*iter); + (*iter).sculpt_dirty = false; } - mSculptUpdated = false; } + mSculptUpdated = false; // one of the layer bitmaps has been updated, we need to rebake. - if ( mLayerUpdated ) + if (mLayerUpdated) { - if (isAgentAvatarValid()) - { + if (isAgentAvatarValid()) gAgentAvatarp->forceBakeAllTextures(SLAM_FOR_DEBUG); - } - mLayerUpdated = false; } } -void LocalAssetBrowser::PerformSculptUpdates(LocalBitmap* unit) +void LocalAssetBrowser::PerformSculptUpdates(LocalBitmap& unit) { - /* looking for sculptmap using objects only */ - std::vector object_list = unit->getUsingObjects(false, false, true); + std::vector object_list = unit.getUsingObjects(false, false, true); if (object_list.empty()) { return; } for( std::vector::iterator iter = object_list.begin(); iter != object_list.end(); iter++ ) { affected_object aobj = *iter; - if ( aobj.object ) + if (aobj.object) { - if ( !aobj.local_sculptmap ) { continue; } // should never get here. only in case of misuse. - + if (!aobj.local_sculptmap) continue; // should never get here. only in case of misuse. // update code [begin] - if ( unit->volume_dirty ) + if (unit.volume_dirty) { - LLImageRaw* rawimage = gTextureList.findImage( unit->getID() )->getCachedRawImage(); + LLImageRaw* rawimage = gTextureList.findImage(unit.getID())->getCachedRawImage(); - aobj.object->getVolume()->sculpt(rawimage->getWidth(), rawimage->getHeight(), - rawimage->getComponents(), rawimage->getData(), 0); - unit->volume_dirty = false; + aobj.object->getVolume()->sculpt(rawimage->getWidth(), rawimage->getHeight(), rawimage->getComponents(), rawimage->getData(), 0); + unit.volume_dirty = false; } - // tell affected drawable it's got updated - aobj.object->mDrawable->getVOVolume()->setSculptChanged( true ); - aobj.object->mDrawable->getVOVolume()->markForUpdate( true ); + // tell affected drawable it's got updated + aobj.object->mDrawable->getVOVolume()->setSculptChanged(true); + aobj.object->mDrawable->getVOVolume()->markForUpdate(true); // update code [end] } - } - } /*==================================================*/ @@ -722,36 +674,6 @@ void LocalAssetBrowser::PerformSculptUpdates(LocalBitmap* unit) Destroyed when the floater is closed. */ - -// Floater Globals -FloaterLocalAssetBrowser* FloaterLocalAssetBrowser::sLFInstance = NULL; - -// widgets: - LLButton* mAddBtn; - LLButton* mDelBtn; - LLButton* mMoreBtn; - LLButton* mLessBtn; - LLButton* mUploadBtn; - - - LLScrollListCtrl* mBitmapList; - LLTextureCtrl* mTextureView; - LLCheckBoxCtrl* mUpdateChkBox; - - LLLineEditor* mPathTxt; - LLLineEditor* mUUIDTxt; - LLLineEditor* mNameTxt; - - LLTextBox* mLinkTxt; - LLTextBox* mTimeTxt; - LLComboBox* mTypeComboBox; - - LLTextBox* mCaptionPathTxt; - LLTextBox* mCaptionUUIDTxt; - LLTextBox* mCaptionLinkTxt; - LLTextBox* mCaptionNameTxt; - LLTextBox* mCaptionTimeTxt; - FloaterLocalAssetBrowser::FloaterLocalAssetBrowser() : LLFloater(std::string("local_bitmap_browser_floater")) { @@ -791,12 +713,15 @@ FloaterLocalAssetBrowser::FloaterLocalAssetBrowser() mDelBtn->setEnabled( false ); mUploadBtn->setEnabled( false ); + // Initialize visibility + FloaterResize(true); + // setting button callbacks: - mAddBtn->setClickedCallback( onClickAdd, this); - mDelBtn->setClickedCallback( onClickDel, this); - mMoreBtn->setClickedCallback( onClickMore, this); - mLessBtn->setClickedCallback( onClickLess, this); - mUploadBtn->setClickedCallback( onClickUpload, this); + mAddBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::onClickAdd, this)); + mDelBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::onClickDel, this)); + mMoreBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::FloaterResize, this, true)); + mLessBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::FloaterResize, this, false)); + mUploadBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::onClickUpload, this)); // combo callback mTypeComboBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onCommitTypeCombo,this)); @@ -806,48 +731,35 @@ FloaterLocalAssetBrowser::FloaterLocalAssetBrowser() // checkbox callbacks mUpdateChkBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onClickUpdateChkbox,this)); - } void FloaterLocalAssetBrowser::show(void*) { - if (!sLFInstance) - sLFInstance = new FloaterLocalAssetBrowser(); - sLFInstance->open(); + if (!sLFInstance) + sLFInstance = new FloaterLocalAssetBrowser(); + sLFInstance->open(); sLFInstance->UpdateBitmapScrollList(); } FloaterLocalAssetBrowser::~FloaterLocalAssetBrowser() { - sLFInstance=NULL; + sLFInstance = NULL; } -void FloaterLocalAssetBrowser::onClickAdd(void* userdata) +void FloaterLocalAssetBrowser::onClickAdd() { gLocalBrowser->AddBitmap(); } -void FloaterLocalAssetBrowser::onClickDel(void* userdata) +void FloaterLocalAssetBrowser::onClickDel() { - gLocalBrowser->DelBitmap( sLFInstance->mBitmapList->getAllSelected() ); + gLocalBrowser->DelBitmap(mBitmapList->getAllSelected()); } -/* what stopped me from using a single button and simply changing it's label - is the fact that i'd need to hardcode the button labels here, and that is griff. */ -void FloaterLocalAssetBrowser::onClickMore(void* userdata) -{ - FloaterResize(true); -} - -void FloaterLocalAssetBrowser::onClickLess(void* userdata) -{ - FloaterResize(false); -} - -void FloaterLocalAssetBrowser::onClickUpload(void* userdata) +void FloaterLocalAssetBrowser::onClickUpload() { std::string filename = gLocalBrowser->GetBitmapUnit( - (LLUUID)sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID) )->getFileName(); + (LLUUID)mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID) )->getFileName(); if ( !filename.empty() ) { @@ -858,9 +770,9 @@ void FloaterLocalAssetBrowser::onClickUpload(void* userdata) void FloaterLocalAssetBrowser::onChooseBitmapList() { - bool button_status = mBitmapList->isEmpty(); - mDelBtn->setEnabled(!button_status); - mUploadBtn->setEnabled(!button_status); + bool button_status = !mBitmapList->isEmpty() && mBitmapList->getFirstSelected(); + mDelBtn->setEnabled(button_status); + mUploadBtn->setEnabled(button_status); UpdateRightSide(); } @@ -879,71 +791,59 @@ void FloaterLocalAssetBrowser::onCommitTypeCombo() { std::string temp_str = mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); - if ( !temp_str.empty() ) + if (!temp_str.empty()) { - S32 selection = sLFInstance->mTypeComboBox->getCurrentIndex(); - gLocalBrowser->onSetType( (LLUUID)temp_str, selection ); + S32 selection = mTypeComboBox->getCurrentIndex(); + gLocalBrowser->onSetType((LLUUID)temp_str, selection); } } void FloaterLocalAssetBrowser::FloaterResize(bool expand) { - sLFInstance->mMoreBtn->setVisible(!expand); - sLFInstance->mLessBtn->setVisible(expand); - sLFInstance->mTextureView->setVisible(expand); - sLFInstance->mUpdateChkBox->setVisible(expand); - sLFInstance->mCaptionPathTxt->setVisible(expand); - sLFInstance->mCaptionUUIDTxt->setVisible(expand); - sLFInstance->mCaptionLinkTxt->setVisible(expand); - sLFInstance->mCaptionNameTxt->setVisible(expand); - sLFInstance->mCaptionTimeTxt->setVisible(expand); - sLFInstance->mTypeComboBox->setVisible(expand); + mMoreBtn->setVisible(!expand); + mLessBtn->setVisible(expand); + mTextureView->setVisible(expand); + mUpdateChkBox->setVisible(expand); + mCaptionPathTxt->setVisible(expand); + mCaptionUUIDTxt->setVisible(expand); + mCaptionLinkTxt->setVisible(expand); + mCaptionNameTxt->setVisible(expand); + mCaptionTimeTxt->setVisible(expand); + mTypeComboBox->setVisible(expand); - sLFInstance->mTimeTxt->setVisible(expand); - sLFInstance->mPathTxt->setVisible(expand); - sLFInstance->mUUIDTxt->setVisible(expand); - sLFInstance->mLinkTxt->setVisible(expand); - sLFInstance->mNameTxt->setVisible(expand); - - if(expand) - { - sLFInstance->reshape(LF_FLOATER_EXPAND_WIDTH, LF_FLOATER_HEIGHT); - sLFInstance->setResizeLimits(LF_FLOATER_EXPAND_WIDTH, LF_FLOATER_HEIGHT); - sLFInstance->UpdateRightSide(); - } - else - { - sLFInstance->reshape(LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); - sLFInstance->setResizeLimits(LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); - } + mTimeTxt->setVisible(expand); + mPathTxt->setVisible(expand); + mUUIDTxt->setVisible(expand); + mLinkTxt->setVisible(expand); + mNameTxt->setVisible(expand); + reshape(expand ? LF_FLOATER_EXPAND_WIDTH : LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); + setResizeLimits(expand ? LF_FLOATER_EXPAND_WIDTH : LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); + if (expand) UpdateRightSide(); } void FloaterLocalAssetBrowser::UpdateBitmapScrollList() { - if ( !sLFInstance ) { return; } - - sLFInstance->mBitmapList->clearRows(); + mBitmapList->clearRows(); if (!gLocalBrowser->loaded_bitmaps.empty()) { - LocalAssetBrowser::local_list_iter iter; for(iter = gLocalBrowser->loaded_bitmaps.begin(); iter != gLocalBrowser->loaded_bitmaps.end(); iter++) { LLSD element; element["columns"][BITMAPLIST_COL_NAME]["column"] = "bitmap_name"; element["columns"][BITMAPLIST_COL_NAME]["type"] = "text"; - element["columns"][BITMAPLIST_COL_NAME]["value"] = (*iter)->getShortName(); + element["columns"][BITMAPLIST_COL_NAME]["value"] = (*iter).getShortName(); element["columns"][BITMAPLIST_COL_ID]["column"] = "bitmap_uuid"; element["columns"][BITMAPLIST_COL_ID]["type"] = "text"; - element["columns"][BITMAPLIST_COL_ID]["value"] = (*iter)->getID(); + element["columns"][BITMAPLIST_COL_ID]["value"] = (*iter).getID(); - sLFInstance->mBitmapList->addElement(element); + mBitmapList->addElement(element); } } - sLFInstance->UpdateRightSide(); + onChooseBitmapList(); } void FloaterLocalAssetBrowser::UpdateRightSide() @@ -951,47 +851,45 @@ void FloaterLocalAssetBrowser::UpdateRightSide() /* Since i'm not keeping a bool on if the floater is expanded or not, i'll just check if one of the widgets that shows when the floater is expanded is visible. - Also obviously before updating - checking if something IS actually selected :o */ + if (!mTextureView->getVisible()) return; - if ( !sLFInstance->mTextureView->getVisible() ) { return; } - - if ( !sLFInstance->mBitmapList->getAllSelected().empty() ) - { - LocalBitmap* unit = gLocalBrowser->GetBitmapUnit( LLUUID(sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID)) ); + if (!mBitmapList->getAllSelected().empty()) + { + LocalBitmap* unit = gLocalBrowser->GetBitmapUnit( LLUUID(mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID)) ); if ( unit ) { - sLFInstance->mTextureView->setImageAssetID( unit->getID() ); - sLFInstance->mUpdateChkBox->set( unit->getUpdateBool() ); - sLFInstance->mPathTxt->setText( unit->getFileName() ); - sLFInstance->mUUIDTxt->setText( unit->getID().asString() ); - sLFInstance->mNameTxt->setText( unit->getShortName() ); - sLFInstance->mTimeTxt->setText( unit->getLastModified().asString() ); - sLFInstance->mLinkTxt->setText( unit->getLinkStatus() ); - sLFInstance->mTypeComboBox->selectNthItem( unit->getType() ); + mTextureView->setImageAssetID(unit->getID()); + mUpdateChkBox->set(unit->getUpdateBool()); + mPathTxt->setText(unit->getFileName()); + mUUIDTxt->setText(unit->getID().asString()); + mNameTxt->setText(unit->getShortName()); + mTimeTxt->setText(unit->getLastModified().asString()); + mLinkTxt->setText(unit->getLinkStatus()); + mTypeComboBox->selectNthItem(unit->getType()); - sLFInstance->mTextureView->setEnabled(true); - sLFInstance->mUpdateChkBox->setEnabled(true); - sLFInstance->mTypeComboBox->setEnabled(true); + mTextureView->setEnabled(true); + mUpdateChkBox->setEnabled(true); + mTypeComboBox->setEnabled(true); } } else { - sLFInstance->mTextureView->setImageAssetID( NO_IMAGE ); - sLFInstance->mTextureView->setEnabled( false ); - sLFInstance->mUpdateChkBox->set( false ); - sLFInstance->mUpdateChkBox->setEnabled( false ); + mTextureView->setImageAssetID(NO_IMAGE); + mTextureView->setEnabled(false); + mUpdateChkBox->set(false); + mUpdateChkBox->setEnabled(false); - sLFInstance->mTypeComboBox->selectFirstItem(); - sLFInstance->mTypeComboBox->setEnabled( false ); - - sLFInstance->mPathTxt->setText( LLStringExplicit("None") ); - sLFInstance->mUUIDTxt->setText( LLStringExplicit("None") ); - sLFInstance->mNameTxt->setText( LLStringExplicit("None") ); - sLFInstance->mLinkTxt->setText( LLStringExplicit("None") ); - sLFInstance->mTimeTxt->setText( LLStringExplicit("None") ); + mTypeComboBox->selectFirstItem(); + mTypeComboBox->setEnabled(false); + + mPathTxt->setText(LLStringExplicit("None")); + mUUIDTxt->setText(LLStringExplicit("None")); + mNameTxt->setText(LLStringExplicit("None")); + mLinkTxt->setText(LLStringExplicit("None")); + mTimeTxt->setText(LLStringExplicit("None")); } } diff --git a/indra/newview/floaterlocalassetbrowse.h b/indra/newview/floaterlocalassetbrowse.h index b4cbc149f..dd7e618ea 100644 --- a/indra/newview/floaterlocalassetbrowse.h +++ b/indra/newview/floaterlocalassetbrowse.h @@ -98,7 +98,7 @@ class LocalBitmap { public: LocalBitmap(std::string filename); - virtual ~LocalBitmap(void); + virtual ~LocalBitmap(); friend class LocalAssetBrowser; public: /* [enums, typedefs, etc] */ @@ -127,23 +127,22 @@ class LocalBitmap }; public: /* [information query functions] */ - std::string getShortName(void); - std::string getFileName(void); - LLUUID getID(void); - LLSD getLastModified(void); - std::string getLinkStatus(void); - bool getUpdateBool(void); + std::string getShortName(); + std::string getFileName(); + LLUUID getID(); + LLSD getLastModified(); + std::string getLinkStatus(); + bool getUpdateBool(); void setType( S32 ); - bool getIfValidBool(void); - S32 getType(void); - void getDebugInfo(void); + bool getIfValidBool(); + S32 getType(); + void getDebugInfo(); private: /* [maintenence functions] */ - void updateSelf(void); + void updateSelf(); bool decodeSelf(LLImageRaw* rawimg); - void setUpdateBool(void); + void setUpdateBool(); - LocalBitmap* getThis(void); std::vector getFaceUsesThis(LLDrawable*); std::vector getUsingObjects(bool seek_by_type = true, bool seek_textures = false, bool seek_sculptmaps = false); @@ -184,7 +183,7 @@ class LocalAssetBrowser static void UpdateTextureCtrlList(LLScrollListCtrl*); static void setLayerUpdated(bool toggle) { mLayerUpdated = toggle; } static void setSculptUpdated(bool toggle) { mSculptUpdated = toggle; } - static void AddBitmap(void); + static void AddBitmap(); static void AddBitmap_continued(AIFilePicker* filepicker); static void DelBitmap( std::vector, S32 column = BITMAPLIST_COL_ID ); @@ -194,18 +193,18 @@ class LocalAssetBrowser the latter - each time the button's pressed. */ private: - static void onChangeHappened(void); + static void onChangeHappened(); static void onUpdateBool(LLUUID); static void onSetType(LLUUID, S32); static LocalBitmap* GetBitmapUnit(LLUUID); - static bool IsDoingUpdates(void); - static void PingTimer(void); - static void PerformTimedActions(void); - static void PerformSculptUpdates(LocalBitmap*); + static bool IsDoingUpdates(); + static void PingTimer(); + static void PerformTimedActions(); + static void PerformSculptUpdates(LocalBitmap&); protected: - static std::vector loaded_bitmaps; - typedef std::vector::iterator local_list_iter; + static std::vector loaded_bitmaps; + typedef std::vector::iterator local_list_iter; static bool mLayerUpdated; static bool mSculptUpdated; }; @@ -225,17 +224,13 @@ public: FloaterLocalAssetBrowser(); virtual ~FloaterLocalAssetBrowser(); static void show(void*); - - private: /* Widget related callbacks */ - // Button callback declarations - static void onClickAdd(void* userdata); - static void onClickDel(void* userdata); - static void onClickMore(void* userdata); - static void onClickLess(void* userdata); - static void onClickUpload(void* userdata); + // Button callback declarations + void onClickAdd(); + void onClickDel(); + void onClickUpload(); // ScrollList callback declarations void onChooseBitmapList(); @@ -271,17 +266,12 @@ private: LLTextBox* mCaptionNameTxt; LLTextBox* mCaptionTimeTxt; - /* static pointer to self, wai? oh well. */ - static FloaterLocalAssetBrowser* sLFInstance; - // non-widget functions - static void FloaterResize(bool expand); - static void UpdateRightSide(void); + void FloaterResize(bool expand); + void UpdateRightSide(); public: - static void UpdateBitmapScrollList(void); - - + void UpdateBitmapScrollList(); }; /*==================================================*/ diff --git a/indra/newview/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp index 9057109d2..b0fd2b254 100644 --- a/indra/newview/hippogridmanager.cpp +++ b/indra/newview/hippogridmanager.cpp @@ -891,6 +891,8 @@ void HippoGridManager::loadFromFile() void HippoGridManager::parseUrl(const std::string url, bool mergeIfNewer) { + if (url.empty()) return; + llinfos << "Loading grid info from '" << url << "'." << llendl; // query update server diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index e78317e3f..3f2cfbd0f 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -31,6 +31,7 @@ RequestExecutionLevel admin ; on Vista we must be admin because we write to Prog ;; !define INSTNAME "SecondLife%(grid_caps)s" ;; !define SHORTCUT "Second Life (%(grid_caps)s)" ;; !define URLNAME "secondlife%(grid)s" +;; !define AUTHOR "Linden Research, Inc." ;; !define UNINSTALL_SETTINGS 1 %%GRID_VARS%% @@ -76,8 +77,8 @@ Name "${VIEWERNAME}" SubCaption 0 $(LicenseSubTitleSetup) ; override "license agreement" text BrandingText "Prepare to Implode!" ; bottom of window text -Icon %%SOURCE%%\installers\windows\install_icon_singularity.ico -UninstallIcon %%SOURCE%%\installers\windows\uninstall_icon_singularity.ico +Icon %%SOURCE%%\installers\windows\${INSTALL_ICON} +UninstallIcon %%SOURCE%%\installers\windows\${UNINSTALL_ICON} WindowIcon off ; show our icon in left corner # BGGradient 9090b0 000000 notext CRCCheck on ; make sure CRC is OK @@ -89,7 +90,7 @@ SetOverwrite on ; stomp files by default AutoCloseWindow true ; after all files install, close window InstallDir "%%INSTALLDIR%%" -InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "" +InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\${INSTNAME}" "" DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -191,7 +192,7 @@ FunctionEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function CheckIfAlreadyCurrent Push $0 - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\$INSTPROG" "Version" StrCmp $0 ${VERSION_LONG} 0 DONE MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK DONE Quit @@ -550,7 +551,7 @@ SetShellVarContext all Call un.CloseSecondLife ; Clean up registry keys and subkeys (these should all be !defines somewhere) -DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" +DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\$INSTPROG" DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" ; Clean up shortcuts @@ -693,7 +694,7 @@ lbl_check_silent: ; If we currently have a version of SL installed, default to the language of that install ; Otherwise don't change $LANGUAGE and it will default to the OS UI language. - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\${INSTNAME}" "InstallerLanguage" IfErrors lbl_build_menu StrCpy $LANGUAGE $0 @@ -711,7 +712,7 @@ lbl_build_menu: StrCpy $LANGUAGE $0 ; save language in registry - WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" $LANGUAGE + WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\${INSTNAME}" "InstallerLanguage" $LANGUAGE lbl_return: Pop $0 Return @@ -721,7 +722,7 @@ FunctionEnd Function un.onInit ; read language from registry and set for uninstaller ; Key will be removed on successful uninstall - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\${INSTNAME}" "InstallerLanguage" IfErrors lbl_end StrCpy $LANGUAGE $0 lbl_end: @@ -810,11 +811,11 @@ CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Write registry -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags" "$INSTFLAGS" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" "$INSTSHORTCUT" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$INSTEXE" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\$INSTPROG" "" "$INSTDIR" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\$INSTPROG" "Version" "${VERSION_LONG}" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\$INSTPROG" "Flags" "$INSTFLAGS" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\$INSTPROG" "Shortcut" "$INSTSHORTCUT" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\${AUTHOR}\$INSTPROG" "Exe" "$INSTEXE" WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayName" "$INSTPROG (remove only)" WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "UninstallString" '"$INSTDIR\uninst.exe"' diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 78c5c666e..973466967 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -103,10 +103,11 @@ #include "lluictrlfactory.h" //For LLUICtrlFactory::getLayeredXMLNode -// [RLVa:KB] - Checked: 2010-09-27 (RLVa-1.1.3b) +// [RLVa:KB] - Checked: 2011-11-04 (RLVa-1.4.4a) +#include "rlvactions.h" #include "rlvhandler.h" -#include "rlvinventory.h" -#include "llattachmentsmgr.h" +#include "rlvhelper.h" +#include "rlvui.h" // [/RLVa:KB] #include "NACLantispam.h" // for NaCl Antispam Registry @@ -420,6 +421,7 @@ LLAgent::LLAgent() : mNextFidgetTime(0.f), mCurrentFidget(0), + mCrouch(false), mFirstLogin(FALSE), mGenderChosen(FALSE), mAppearanceSerialNum(0), @@ -639,13 +641,14 @@ void LLAgent::moveUp(S32 direction) if (direction > 0) { setControlFlags(AGENT_CONTROL_UP_POS | AGENT_CONTROL_FAST_UP); + mCrouch = false; } else if (direction < 0) { setControlFlags(AGENT_CONTROL_UP_NEG | AGENT_CONTROL_FAST_UP); } - if (!isCrouch) camera_reset_on_motion(); + if (!mCrouch) camera_reset_on_motion(); } //----------------------------------------------------------------------------- @@ -687,6 +690,11 @@ void LLAgent::movePitch(F32 mag) } } +bool LLAgent::isCrouching() const +{ + return mCrouch && !getFlying(); // Never crouch when flying +} + // Does this parcel allow you to fly? BOOL LLAgent::canFly() @@ -770,6 +778,7 @@ void LLAgent::setFlying(BOOL fly) { LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT); } + mCrouch = false; setControlFlags(AGENT_CONTROL_FLY); } else @@ -818,17 +827,20 @@ void LLAgent::standUp() // setControlFlags(AGENT_CONTROL_STAND_UP); // [RLVa:KB] - Checked: 2010-03-07 (RLVa-1.2.0c) | Added: RLVa-1.2.0a // RELEASE-RLVa: [SL-2.0.0] Check this function's callers since usually they require explicit blocking - if ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.canStand()) ) + if ( (!rlv_handler_t::isEnabled()) || (RlvActions::canStand()) ) { setControlFlags(AGENT_CONTROL_STAND_UP); } // [/RLVa:KB] } + void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id) { llinfos << "called" << llendl; + + // Old-style appearance entering a server-bake region. if (isAgentAvatarValid() && !gAgentAvatarp->isUsingServerBakes() && (mRegionp->getCentralBakeVersion()>0)) @@ -971,7 +983,6 @@ const LLHost& LLAgent::getRegionHost() const } } - //----------------------------------------------------------------------------- // inPrelude() //----------------------------------------------------------------------------- @@ -1148,7 +1159,7 @@ void LLAgent::sitDown() // setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); // [RLVa:KB] - Checked: 2010-08-28 (RLVa-1.2.1a) | Added: RLVa-1.2.1a // RELEASE-RLVa: [SL-2.0.0] Check this function's callers since usually they require explicit blocking - if ( (!rlv_handler_t::isEnabled()) || ((gRlvHandler.canStand()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SIT))) ) + if ( (!rlv_handler_t::isEnabled()) || ((RlvActions::canStand()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SIT))) ) { setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); } @@ -4330,7 +4341,7 @@ void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global) // [RLVa:KB] - Checked: 2010-10-07 (RLVa-1.2.1f) | Added: RLVa-1.2.1f // RELEASE-RLVa: [SL-2.2.0] Make sure this isn't used for anything except double-click teleporting if ( (rlv_handler_t::isEnabled()) && (!RlvUtil::isForceTp()) && - ((gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) || (!gRlvHandler.canStand())) ) + ((gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) || (!RlvActions::canStand())) ) { RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_TELEPORT); return; diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 26501953a..a66b375f4 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -302,6 +302,15 @@ private: F32 mNextFidgetTime; S32 mCurrentFidget; + //-------------------------------------------------------------------- + // Crouch + //-------------------------------------------------------------------- +public: + bool isCrouching() const; + void toggleCrouch() { mCrouch = !mCrouch; } +private: + bool mCrouch; + //-------------------------------------------------------------------- // Fly //-------------------------------------------------------------------- diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index d08bd8a36..5c21a75a3 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2076,7 +2076,7 @@ void LLAgentCamera::handleScrollWheel(S32 clicks) if (MASK mask = gKeyboard->currentMask(true)) // Singu Note: Conveniently set view offsets while modifier keys are held during scroll { static const LLCachedControl enableCameraOffsetScroll("SinguOffsetScrollKeys"); - if (mask & MASK_CONTROL|MASK_SHIFT && enableCameraOffsetScroll) + if (mask & (MASK_CONTROL|MASK_SHIFT) && enableCameraOffsetScroll) { const F32 change(static_cast(clicks) * 0.1f); if (mask & MASK_SHIFT) @@ -2191,8 +2191,8 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate) //gViewerWindow->stopGrab(); LLSelectMgr::getInstance()->deselectAll(); - gViewerWindow->hideCursor(); - gViewerWindow->moveCursorToCenter(); +// gViewerWindow->hideCursor(); +// gViewerWindow->moveCursorToCenter(); if (mCameraMode != CAMERA_MODE_MOUSELOOK) { diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 9bb230124..9b0132be7 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -52,7 +52,7 @@ #include "llfloatercustomize.h" -// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) #include "rlvhandler.h" #include "rlvinventory.h" #include "llattachmentsmgr.h" @@ -65,7 +65,7 @@ LLAgentWearables gAgentWearables; BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; -// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-3.0.0a) | Added: Catznip-2.1.1d +// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1) bool LLAgentWearables::mInitialWearablesLoaded = false; // [/SL:KB] @@ -829,7 +829,7 @@ const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 return LLUUID(); } -// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f +// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0) void LLAgentWearables::getWearableItemIDs(uuid_vec_t& idItems) const { for (wearableentry_map_t::const_iterator itWearableType = mWearableDatas.begin(); @@ -844,8 +844,8 @@ void LLAgentWearables::getWearableItemIDs(LLWearableType::EType eType, uuid_vec_ wearableentry_map_t::const_iterator itWearableType = mWearableDatas.find(eType); if (mWearableDatas.end() != itWearableType) { - for (wearableentry_vec_t::const_iterator itWearable = itWearableType->second.begin(), endWearable = itWearableType->second.end(); - itWearable != endWearable; ++itWearable) + for (wearableentry_vec_t::const_iterator itWearable = itWearableType->second.begin(); + itWearable != itWearableType->second.end(); ++itWearable) { LLViewerWearable* wearable = dynamic_cast(*itWearable); if(wearable) @@ -1402,7 +1402,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // Start rendering & update the server mWearablesLoaded = TRUE; checkWearablesLoaded(); -// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-09-22 (Catznip-3.0.0a) | Modified: Catznip-2.2.0a +// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-09-22 (Catznip-2.2) if (!mInitialWearablesLoaded) { mInitialWearablesLoaded = true; @@ -1830,7 +1830,7 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); msg->addU8Fast(_PREHASH_AttachmentPt, replace? 0 : ATTACHMENT_ADD); // Wear at the previous or default attachment point -// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) if ( (rlv_handler_t::isEnabled()) && (sInitialAttachmentsRequested) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) { RlvAttachmentLockWatchdog::instance().onWearAttachment(item, RLV_WEAR_ADD); @@ -1847,7 +1847,7 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra } } -// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) sInitialAttachmentsRequested = true; // [/RLVa:KB] } @@ -2076,7 +2076,7 @@ boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_ return mLoadedSignal.connect(cb); } -// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-3.0.0a) | Added: Catznip-2.1.1d +// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1) boost::signals2::connection LLAgentWearables::addInitialWearablesLoadedCallback(loaded_callback_t cb) { return mInitialWearablesLoadedSignal.connect(cb); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 9416febb2..c76abdf64 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -583,7 +583,7 @@ public: void onWearableAssetFetch(LLViewerWearable *wearable); void onAllComplete(); -// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-3.0.0a) | Added: Catznip-2.0.0a +// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0) bool pollStopped(); // [/SL:KB] @@ -670,7 +670,7 @@ void LLWearableHoldingPattern::eraseTypeToRecover(LLWearableType::EType type) mTypesToRecover.erase(type); } -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-06-19 (Catznip-3.0.0a) | Added: Catznip-2.1.2a +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-06-19 (Catznip-2.1) //void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items) //{ // mObjItems = items; @@ -780,10 +780,11 @@ void LLWearableHoldingPattern::onAllComplete() LL_INFOS("Avatar") << self_av_string() << "Updating agent wearables with " << mResolved << " wearable items " << LL_ENDL; LLAppearanceMgr::instance().updateAgentWearables(this, false); -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-03-22 (Catznip-3.0.0a) | Added: Catznip-2.1.2a +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-03-22 (Catznip-2.1) // // Update attachments to match those requested. // if (isAgentAvatarValid()) // { +// LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.count() << " attachments" << LL_ENDL; // llinfos << "Updating " << mObjItems.count() << " attachments" << llendl; // LLAgentWearables::userUpdateAttachments(mObjItems); // } @@ -821,7 +822,7 @@ bool LLWearableHoldingPattern::pollFetchCompletion() // runway skip here? llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; -// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-3.0.0a) | Added: Catznip-2.0.0a +// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0) // If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollStopped, this)); return true; @@ -897,7 +898,7 @@ void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLView // runway skip here? llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; -// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-3.0.0a) | Added: Catznip-2.0.0a +// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0) // If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves return; // [/SL:KB] @@ -971,7 +972,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() } } -// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-3.0.0a) | Added: Catznip-2.0.0a +// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0) bool LLWearableHoldingPattern::pollStopped() { // We have to keep on polling until we're sure that all callbacks have completed or they'll cause a crash @@ -991,7 +992,7 @@ bool LLWearableHoldingPattern::pollMissingWearables() // runway skip here? llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; -// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-3.0.0a) | Added: Catznip-2.0.0a +// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0) // If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollStopped, this)); return true; @@ -1386,7 +1387,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) { - LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&wear_on_avatar_cb,_1,replace)); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace)); copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb); return false; } @@ -1525,7 +1526,7 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id) LLInventoryModel::item_array_t items; LLFindWearablesEx collector(/*is_worn=*/ true, /*include_body_parts=*/ false); - gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector); + gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector, true); LLInventoryModel::item_array_t::const_iterator it = items.begin(); const LLInventoryModel::item_array_t::const_iterator it_end = items.end(); @@ -1536,6 +1537,18 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id) uuids_to_remove.push_back(item->getUUID()); } removeItemsFromAvatar(uuids_to_remove); + + // deactivate all gestures in the outfit folder + LLInventoryModel::item_array_t gest_items; + getDescendentsOfAssetType(cat_id, gest_items, LLAssetType::AT_GESTURE, true); + for(S32 i = 0; i < gest_items.count(); ++i) + { + LLViewerInventoryItem* gest_item = gest_items.get(i); + if (LLGestureMgr::instance().isGestureActive(gest_item->getLinkedUUID())) + { + LLGestureMgr::instance().deactivateGesture(gest_item->getLinkedUUID()); + } + } } // Create a copy of src_id + contents as a subfolder of dst_id. @@ -1711,8 +1724,19 @@ bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id) cats, items, LLInventoryModel::EXCLUDE_TRASH, - is_worn); - return items.size() > 0; + is_worn, + /*follow_folder_links=*/ true); + + if (items.size()) return true; + + // Is there an active gesture in outfit_cat_id? + items.reset(); + LLIsType is_gesture(LLAssetType::AT_GESTURE); + gInventory.collectDescendentsIf(outfit_cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_gesture, /*follow_folder_links=*/ true); + for(S32 i = 0; i < items.count(); ++i) + if (LLGestureMgr::instance().isGestureActive(items.get(i)->getLinkedUUID())) + return true; + return false; } // static @@ -1744,7 +1768,7 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id) // Check whether it's the base outfit. // if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID()) -// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-21 (Catznip-3.0.0a) | Added: Catznip-2.1.2d +// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-21 (Catznip-2.1) if ( (outfit_cat_id.isNull()) || ((outfit_cat_id == getBaseOutfitUUID()) && (!isOutfitDirty())) ) // [/SL:KB] { @@ -1798,8 +1822,19 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin continue; if (item->getIsLinkType()) { +#if 0 + if (keep_items && keep_items->find(item) != LLInventoryModel::item_array_t::FAIL) + { + llinfos << "preserved item" << llendl; + } + else + { + gInventory.purgeObject(item->getUUID()); + } +#else gInventory.purgeObject(item->getUUID()); } +#endif } } @@ -1892,9 +1927,8 @@ void LLAppearanceMgr::filterWearableItems( if (size <= 0) continue; // S32 start_index = llmax(0,size-max_per_type); -// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-05-11 (Catznip-3.0.0a) | Added: Catznip-2.0.0h - S32 start_index = - llmax(0, size - ((LLAssetType::AT_BODYPART == LLWearableType::getAssetType((LLWearableType::EType)i)) ? 1 : max_per_type)); +// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-05-11 (Catznip-2.0) + S32 start_index = llmax(0, size - ((LLAssetType::AT_BODYPART == LLWearableType::getAssetType((LLWearableType::EType)i)) ? 1 : max_per_type)); // [/SL:KB[ for (S32 j = start_index; jgetName() : "[UNKNOWN]") << llendl; +// LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL; // [RLVa:KB] - Checked: 2010-03-26 (RLVa-1.2.0b) | Added: RLVa-1.2.0b // RELEASE-RLVa: [SL-2.0.0] If pcat ever gets used for anything further down the beta we'll know about it llinfos << "starting" << llendl; @@ -2220,8 +2254,6 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo { gAgentWearables.setWearableOutfit(items, wearables, !append); } - -// dec_busy_count(); } static void remove_non_link_items(LLInventoryModel::item_array_t &items) @@ -2334,7 +2366,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF); selfStartPhase("update_appearance_from_cof"); - LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; + LL_DEBUGS("Avatar") << self_av_string() << "starting" << LL_ENDL; //checking integrity of the COF in terms of ordering of wearables, //checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state) @@ -2372,7 +2404,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) remove_non_link_items(wear_items); remove_non_link_items(obj_items); remove_non_link_items(gest_items); -// [SL:KB] - Patch: Apperance-Misc | Checked: 2010-11-24 (Catznip-3.0.0a) | Added: Catzip-2.4.0f +// [SL:KB] - Patch: Apperance-Misc | Checked: 2010-11-24 (Catznip-2.4) // Since we're following folder links we might have picked up new duplicates, or exceeded MAX_CLOTHING_PER_TYPE removeDuplicateItems(wear_items); removeDuplicateItems(obj_items); @@ -2387,7 +2419,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) dumpItemArray(wear_items,"asset_dump: wear_item"); dumpItemArray(obj_items,"asset_dump: obj_item"); -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-3.0.0a) | Added: Catznip-2.2.0a +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2) // Update attachments to match those requested. if (isAgentAvatarValid()) { @@ -2704,7 +2736,6 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego void LLAppearanceMgr::wearOutfitByName(const std::string& name) { LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL; - //inc_busy_count(); LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; @@ -3006,21 +3037,25 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id) LLInventoryModel::EXCLUDE_TRASH); for (S32 i=0; igetIsLinkType() && item->getLinkedUUID() == item_id) { -// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) -#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG +#if 0 // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG // NOTE-RLVa: debug-only, can be removed down the line if (rlv_handler_t::isEnabled()) { RLV_ASSERT(rlvPredCanRemoveItem(item)); } #endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG -// [/RLVa:KB] - gInventory.purgeObject(item->getUUID()); } +// [/RLVa:KB] +// const LLInventoryItem* item = item_array.get(i).get(); +// if (item->getIsLinkType() && item->getLinkedUUID() == item_id) +// { +// gInventory.purgeObject(item->getUUID()); +// } } } @@ -3038,7 +3073,7 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type) if (item->getIsLinkType()) // we must operate on links only { // [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) -#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG +#if 0 // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG // NOTE-RLVa: debug-only, can be removed down the line if (rlv_handler_t::isEnabled()) { @@ -3487,7 +3522,7 @@ public: // Error /*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content) { - llwarns << "appearance update request failed, status: " << status << " reason: " << reason << llendl; + llwarns << "appearance update request failed, status: " << status << " reason: " << reason << " code: " << content["code"].asInteger() << " error: \"" << content["error"].asString() << "\"" << llendl; LL_DEBUGS("Avatar") << "content: " << ll_pretty_print_sd(content) << LL_ENDL; onFailure(status); } @@ -3724,6 +3759,9 @@ public: */ LLAppearanceMgr::instance().changeOutfit(true, mFolderID, false); } + + void setFailed() { mFailed = true; } // Singu Note: Lies and hacks + private: class LLCreateBase : public LLInventoryCallback { @@ -3912,12 +3950,18 @@ LLUUID LLAppearanceMgr::makeNewOutfitLegacy(const std::string& new_folder_name, LLPointer cb = new LLCreateLegacyOutfit(folder_id,boost::bind(&scroll_to_folder,folder_id),boost::bind(&show_created_outfit,folder_id,true)); uuid_vec_t obj_ids; // Collect the uuids of copyable objects, in order to keep any changes made in the copies + bool use_all_links(gSavedSettings.getBOOL("LiruLegacyOutfitAllLinks")); for (LLInventoryModel::item_array_t::const_iterator iter = items.begin(); iter != items.end(); ++iter) { LLViewerInventoryItem* item = (*iter); + if (use_all_links) + { + cb->makeLink(item, item->LLInventoryItem::getDescription()); + continue; + } LLViewerInventoryItem* base_item = item->getLinkedItem() ? item->getLinkedItem() : item; bool is_copy = base_item->getPermissions().allowCopyBy(gAgent.getID()); bool is_obj = base_item->getInventoryType() == LLInventoryType::IT_OBJECT; @@ -3936,10 +3980,12 @@ LLUUID LLAppearanceMgr::makeNewOutfitLegacy(const std::string& new_folder_name, cb->makeCopy(item,is_multi && use_links); } } - if (gSavedSettings.getBOOL("LiruLegacyOutfitStoreObjChanges")) // As a last resort, someone may create a legacy outfit to undo attachment changes + if (!use_all_links && gSavedSettings.getBOOL("LiruLegacyOutfitStoreObjChanges")) // As a last resort, someone may create a legacy outfit to undo attachment changes LLAppearanceMgr::instance().removeItemsFromAvatar(obj_ids); // The avatar will have to go without these for now cb->dispatch(); + if (use_all_links) cb->setFailed(); // Cause an early return to avoid rewearing + return folder_id; } @@ -3953,6 +3999,11 @@ void LLAppearanceMgr::wearBaseOutfit() void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) { + if (ids_to_remove.empty()) + { + llwarns << "called with empty list, nothing to do" << llendl; + } + // [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) bool fUpdateAppearance = false; for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) @@ -4400,7 +4451,6 @@ void wear_multiple(const uuid_vec_t& ids, bool replace) // SLapp for easy-wearing of a stock (library) avatar // -/* class LLWearFolderHandler : public LLCommandHandler { public: @@ -4430,4 +4480,4 @@ public: } }; -LLWearFolderHandler gWearFolderHandler;*/ +LLWearFolderHandler gWearFolderHandler; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 32501de62..45fa8dcd7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -304,6 +304,8 @@ const std::string MARKER_FILE_NAME("Singularity.exec_marker"); const std::string ERROR_MARKER_FILE_NAME("Singularity.error_marker"); const std::string LLERROR_MARKER_FILE_NAME("Singularity.llerror_marker"); const std::string LOGOUT_MARKER_FILE_NAME("Singularity.logout_marker"); +const std::string LOG_FILE("Singularity.log"); +extern const std::string OLD_LOG_FILE("Singularity.old"); static BOOL gDoDisconnect = FALSE; static std::string gLaunchFileOnQuit; @@ -353,6 +355,7 @@ void init_default_trans_args() { default_trans_args.insert("SECOND_LIFE"); // World default_trans_args.insert("APP_NAME"); + default_trans_args.insert("SHORT_APP_NAME"); default_trans_args.insert("CAPITALIZED_APP_NAME"); default_trans_args.insert("SECOND_LIFE_GRID"); default_trans_args.insert("SUPPORT_SITE"); @@ -1220,7 +1223,7 @@ bool LLAppViewer::mainLoop() { joystick->scanJoystick(); gKeyboard->scanKeyboard(); - if(isCrouch) + if (gAgent.isCrouching()) { gAgent.moveUp(-1); } @@ -1946,13 +1949,11 @@ bool LLAppViewer::initLogging() LLError::setFatalFunction(errorCallback); // Remove the last ".old" log file. - std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - "Singularity.old"); + std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, OLD_LOG_FILE); LLFile::remove(old_log_file); // Rename current log file to ".old" - std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - "Singularity.log"); + std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOG_FILE); LLFile::rename(log_file, old_log_file); // Set the log file to Singularity.log @@ -2363,23 +2364,6 @@ bool LLAppViewer::initConfiguration() #if LL_DARWIN // Initialize apple menubar and various callbacks init_apple_menu(LLTrans::getString("APP_NAME").c_str()); - -#if __ppc__ - // If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further. - // Only test PowerPC - all Intel Macs have SSE. - if(!gSysCPU.hasAltivec()) - { - std::ostringstream msg; - msg << LLTrans::getString("MBRequiresAltiVec"); - OSMessageBox( - msg.str(), - LLStringUtil::null, - OSMB_OK); - removeMarkerFile(); - return false; - } -#endif - #endif // LL_DARWIN // Display splash screen. Must be after above check for previous @@ -2664,7 +2648,7 @@ void LLAppViewer::writeSystemInfo() // that the crash report will go to the proper location in the case of a // prior freeze. std::string crashHostUrl = gSavedSettings.get("CrashHostUrl"); - if(crashHostUrl != "") + if (!crashHostUrl.empty()) { gDebugInfo["CrashHostUrl"] = crashHostUrl; } @@ -2725,7 +2709,7 @@ void LLAppViewer::handleViewerCrash() // Insert crash host url (url to post crash log to) if configured. std::string crashHostUrl = gSavedSettings.get("CrashHostUrl"); - if(crashHostUrl != "") + if (!crashHostUrl.empty()) { gDebugInfo["Dynamic"]["CrashHostUrl"] = crashHostUrl; } diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp new file mode 100644 index 000000000..2e8926f45 --- /dev/null +++ b/indra/newview/llautoreplace.cpp @@ -0,0 +1,802 @@ +/** + * @file llautoreplace.cpp + * @brief Auto Replace Manager + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llautoreplace.h" +#include "llsdserialize.h" +#include "llboost.h" +#include "llcontrol.h" +#include "llviewercontrol.h" +#include "llnotificationsutil.h" + +const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml"; + +void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text) +{ + // make sure these returned values are cleared in case there is no replacement + replacement_start = 0; + replacement_length = 0; + replacement_string.clear(); + + static LLCachedControl perform_autoreplace(gSavedSettings, "AutoReplace", 0); + if (perform_autoreplace) + { + S32 word_end = cursor_pos - 1; + + bool at_space = (input_text[word_end] == ' '); + bool have_word = (LLWStringUtil::isPartOfWord(input_text[word_end])); + + if (at_space || have_word) + { + if (at_space && word_end > 0) + { + // find out if this space immediately follows a word + word_end--; + have_word = (LLWStringUtil::isPartOfWord(input_text[word_end])); + } + if (have_word) + { + // word_end points to the end of a word, now find the start of the word + std::string word; + S32 word_start = word_end; + for (S32 back_one = word_start - 1; + back_one >= 0 && LLWStringUtil::isPartOfWord(input_text[back_one]); + back_one-- + ) + { + word_start--; // walk word_start back to the beginning of the word + } + LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL; + std::string str_text = std::string(input_text.begin(), input_text.end()); + std::string last_word = str_text.substr(word_start, word_end - word_start + 1); + std::string replacement_word(mSettings.replaceWord(last_word)); + + if (replacement_word != last_word) + { + // The last word is one for which we have a replacement + if (at_space) + { + // return the replacement string + replacement_start = word_start; + replacement_length = last_word.length(); + replacement_string = utf8str_to_wstring(replacement_word); + LLWString old_string = utf8str_to_wstring(last_word); + S32 size_change = replacement_string.size() - old_string.size(); + cursor_pos += size_change; + } + } + } + } + } +} + +std::string LLAutoReplace::getUserSettingsFileName() +{ + std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); + + if (!path.empty()) + { + path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, SETTINGS_FILE_NAME); + } + return path; +} + +std::string LLAutoReplace::getAppSettingsFileName() +{ + std::string path=gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""); + + if (!path.empty()) + { + path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, SETTINGS_FILE_NAME); + } + else + { + LL_ERRS("AutoReplace") << "Failed to get app settings directory name" << LL_ENDL; + } + return path; +} + +LLAutoReplaceSettings LLAutoReplace::getSettings() +{ + return mSettings; +} + +void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings) +{ + mSettings.set(newSettings); + /// Make the newSettings active and write them to user storage + saveToUserSettings(); +} + +LLAutoReplace::LLAutoReplace() +{ +} + +void LLAutoReplace::initSingleton() +{ + loadFromSettings(); +} + +void LLAutoReplace::loadFromSettings() +{ + std::string filename=getUserSettingsFileName(); + if (filename.empty()) + { + LL_INFOS("AutoReplace") << "no valid user settings directory." << LL_ENDL; + } + if(gDirUtilp->fileExists(filename)) + { + LLSD userSettings; + llifstream file; + file.open(filename.c_str()); + if (file.is_open()) + { + LLSDSerialize::fromXML(userSettings, file); + } + file.close(); + if ( mSettings.setFromLLSD(userSettings) ) + { + LL_INFOS("AutoReplace") << "settings loaded from '" << filename << "'" << LL_ENDL; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings found in '" << filename << "'" << LL_ENDL; + } + } + else // no user settings found, try application settings + { + std::string defaultName = getAppSettingsFileName(); + LL_INFOS("AutoReplace") << " user settings file '" << filename << "' not found"<< LL_ENDL; + + bool gotSettings = false; + if(gDirUtilp->fileExists(defaultName)) + { + LLSD appDefault; + llifstream file; + file.open(defaultName.c_str()); + if (file.is_open()) + { + LLSDSerialize::fromXMLDocument(appDefault, file); + } + file.close(); + + if ( mSettings.setFromLLSD(appDefault) ) + { + LL_INFOS("AutoReplace") << "settings loaded from '" << defaultName.c_str() << "'" << LL_ENDL; + gotSettings = true; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings found in '" << defaultName.c_str() << "'" << LL_ENDL; + } + } + + if ( ! gotSettings ) + { + if (mSettings.setFromLLSD(mSettings.getExampleLLSD())) + { + LL_WARNS("AutoReplace") << "no settings found; loaded example." << LL_ENDL; + } + else + { + LL_WARNS("AutoReplace") << "no settings found and example invalid!" << LL_ENDL; + } + } + } +} + +void LLAutoReplace::saveToUserSettings() +{ + std::string filename=getUserSettingsFileName(); + llofstream file; + file.open(filename.c_str()); + LLSDSerialize::toPrettyXML(mSettings.asLLSD(), file); + file.close(); + LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL; +} + +// ================================================================ +// LLAutoReplaceSettings +// ================================================================ + +const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_NAME = "name"; ///< key for looking up list names +const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_REPLACEMENTS = "replacements"; ///< key for looking up replacement map + +LLAutoReplaceSettings::LLAutoReplaceSettings() +{ +} + +LLAutoReplaceSettings::LLAutoReplaceSettings(const LLAutoReplaceSettings& settings) +{ + // copy all values through fundamental type intermediates for thread safety + mLists = LLSD::emptyArray(); + + for ( LLSD::array_const_iterator list = settings.mLists.beginArray(), listEnd = settings.mLists.endArray(); + list != listEnd; + list++ + ) + { + if ( (*list).isMap() ) // can fail due to LLSD-30: ignore it + { + LLSD listMap = LLSD::emptyMap(); + std::string listName = (*list)[AUTOREPLACE_LIST_NAME]; + listMap[AUTOREPLACE_LIST_NAME] = listName; + listMap[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap(); + + for ( LLSD::map_const_iterator + entry = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(), + entriesEnd = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].endMap(); + entry != entriesEnd; + entry++ + ) + { + std::string keyword = entry->first; + std::string replacement = entry->second.asString(); + listMap[AUTOREPLACE_LIST_REPLACEMENTS].insert(keyword, LLSD(replacement)); + } + + mLists.append(listMap); + } + } +} + +void LLAutoReplaceSettings::set(const LLAutoReplaceSettings& newSettings) +{ + mLists = newSettings.mLists; +} + +bool LLAutoReplaceSettings::setFromLLSD(const LLSD& settingsFromLLSD) +{ + bool settingsValid = true; + + if ( settingsFromLLSD.isArray() ) + { + for ( LLSD::array_const_iterator + list = settingsFromLLSD.beginArray(), + listEnd = settingsFromLLSD.endArray(); + settingsValid && list != listEnd; + list++ + ) + { + if ( (*list).isDefined() ) // can be undef due to LLSD-30: ignore it + { + settingsValid = listIsValid(*list); + } + } + } + else + { + settingsValid = false; + LL_WARNS("AutoReplace") << "settings are not an array" << LL_ENDL; + } + + if ( settingsValid ) + { + mLists = settingsFromLLSD; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings discarded; using hard coded example" << LL_ENDL; + } + + return settingsValid; +} + +bool LLAutoReplaceSettings::listNameMatches( const LLSD& list, const std::string name ) +{ + return list.isMap() + && list.has(AUTOREPLACE_LIST_NAME) + && list[AUTOREPLACE_LIST_NAME].asString() == name; +} + +const LLSD* LLAutoReplaceSettings::getListEntries(std::string listName) +{ + const LLSD* returnedEntries = NULL; + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + returnedEntries == NULL && list != endList; + list++ + ) + { + const LLSD& thisList = *list; + if ( listNameMatches(thisList, listName) ) + { + returnedEntries = &thisList[AUTOREPLACE_LIST_REPLACEMENTS]; + } + } + return returnedEntries; +} + +std::string LLAutoReplaceSettings::replacementFor(std::string keyword, std::string listName) +{ + std::string replacement; + bool foundList = false; + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + ! foundList && list != endList; + list++ + ) + { + const LLSD& thisList = *list; + if ( listNameMatches(thisList, listName) ) + { + foundList = true; // whether there is a replacement or not, we're done + if ( thisList.isMap() + && thisList.has(AUTOREPLACE_LIST_REPLACEMENTS) + && thisList[AUTOREPLACE_LIST_REPLACEMENTS].has(keyword) + ) + { + replacement = thisList[AUTOREPLACE_LIST_REPLACEMENTS][keyword].asString(); + LL_DEBUGS("AutoReplace")<<"'"< '"<second.isString() ) + { + listValid = false; + LL_WARNS("AutoReplace") + << "non-string replacement value found in list '" + << list[AUTOREPLACE_LIST_NAME].asString() << "'" + << LL_ENDL; + } + } + } + + return listValid; +} + +const LLSD* LLAutoReplaceSettings::exportList(std::string listName) +{ + const LLSD* exportedList = NULL; + for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray(); + exportedList == NULL && list != listEnd; + list++ + ) + { + if ( listNameMatches(*list, listName) ) + { + const LLSD& namedList = (*list); + exportedList = &namedList; + } + } + return exportedList; +} + +bool LLAutoReplaceSettings::listNameIsUnique(const LLSD& newList) +{ + bool nameIsUnique = true; + // this must always be called with a valid list, so it is safe to assume it has a name + std::string newListName = newList[AUTOREPLACE_LIST_NAME].asString(); + for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray(); + nameIsUnique && list != listEnd; + list++ + ) + { + if ( listNameMatches(*list, newListName) ) + { + LL_WARNS("AutoReplace")<<"duplicate list name '"<= 0) + { + LL_DEBUGS("AutoReplace") << "erase "< autoreplace_enabled(gSavedSettings, "AutoReplace", false); + if ( autoreplace_enabled ) + { + LL_DEBUGS("AutoReplace")<<"checking '"< '" << replacements[currentWord].asString() << "'" + << LL_ENDL; + returnedWord = replacements[currentWord].asString(); + } + } + } + return returnedWord; +} + +bool LLAutoReplaceSettings::addEntryToList(LLWString keyword, LLWString replacement, std::string listName) +{ + bool added = false; + + if ( ! keyword.empty() && ! replacement.empty() ) + { + bool isOneWord = true; + for (size_t character = 0; isOneWord && character < keyword.size(); character++ ) + { + if ( ! LLWStringUtil::isPartOfWord(keyword[character]) ) + { + LL_WARNS("AutoReplace") << "keyword '" << wstring_to_utf8str(keyword) << "' not a single word (len "< replacement test pairs + + /// Get the replacement for the keyword from the specified list + std::string replacementFor(std::string keyword, std::string listName); + + /// Adds a keywword/replacement pair to the named list + bool addEntryToList(LLWString keyword, LLWString replacement, std::string listName); + + /// Removes the keywword and its replacement from the named list + bool removeEntryFromList(std::string keyword, std::string listName); + + /** + * Look for currentWord in the lists in order, returning any substitution found + * If no configured substitution is found, returns currentWord + */ + std::string replaceWord(const std::string currentWord /**< word to search for */ ); + + /// Provides a hard-coded example of settings + LLSD getExampleLLSD(); + + /// Get the actual settings as LLSD + const LLSD& asLLSD(); + ///< @note for use only in AutoReplace::saveToUserSettings + + private: + /// Efficiently and safely compare list names + bool listNameMatches( const LLSD& list, const std::string name ); + + /// The actual llsd data structure + LLSD mLists; + + static const std::string AUTOREPLACE_LIST_NAME; ///< key for looking up list names + static const std::string AUTOREPLACE_LIST_REPLACEMENTS; ///< key for looking up replacement map + + /**< + * LLSD structure of the lists + * - The configuration is an array (mLists), + * - Each entry in the array is a replacement list + * - Each replacement list is a map with three keys: + * @verbatim + * "name" String the name of the list + * "replacements" Map keyword -> replacement pairs + * + * + * + * + * name List 1 + * data + * + * keyword1 replacement1 + * keyword2 replacement2 + * + * + * + * name List 2 + * data + * + * keyword1 replacement1 + * keyword2 replacement2 + * + * + * + * + * @endverbatim + */ +}; + +/** Provides a facility to auto-replace text dynamically as it is entered. + * + * When the end of a word is detected (defined as any punctuation character, + * or any whitespace except newline or return), the preceding word is used + * as a lookup key in an ordered list of maps. If a match is found in any + * map, the replacement start index and length are returned along with the + * new replacement string. + * + * See the autoreplaceCallback method for how to add autoreplace functionality + * to a text entry tool. + */ +class LLAutoReplace : public LLSingleton +{ +public: + /// Callback that provides the hook for use in text entry methods + void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text); + + /// Get a copy of the current settings + LLAutoReplaceSettings getSettings(); + + /// Commit new settings after making changes + void setSettings(const LLAutoReplaceSettings& settings); + +private: + friend class LLSingleton; + LLAutoReplace(); + /*virtual*/ void initSingleton(); + + LLAutoReplaceSettings mSettings; ///< configuration information + + /// Read settings from persistent storage + void loadFromSettings(); + + /// Make the newSettings active and write them to user storage + void saveToUserSettings(); + + /// Compute the user settings file name + std::string getUserSettingsFileName(); + + /// Compute the (read-ony) application settings file name + std::string getAppSettingsFileName(); + + /// basename for the settings files + static const char* SETTINGS_FILE_NAME; +}; + +#endif /* LLAUTOREPLACE_H */ diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 42f2e73d8..d9c5e9153 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -52,8 +52,9 @@ #include "llslurl.h" // IDEVO #include "llavatarname.h" #include "llagentui.h" -// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h -#include "rlvhandler.h" +// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0) +#include "rlvactions.h" +#include "rlvcommon.h" // [/RLVa:KB] #include "llviewerwindow.h" @@ -182,16 +183,12 @@ void LLAvatarActions::startIM(const LLUUID& id) if (id.isNull() || gAgentID == id) return; -// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h - if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(id)) ) +// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9) + if ( (!RlvActions::canStartIM(id)) && (!RlvActions::hasOpenP2PSession(id)) ) { - LLUUID idSession = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id); - if ( (idSession.notNull()) && (!gIMMgr->hasSession(idSession)) ) - { - make_ui_sound("UISndInvalidOp"); - RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString())); - return; - } + make_ui_sound("UISndInvalidOp"); + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString())); + return; } // [/RLVa:KB] @@ -234,16 +231,12 @@ void LLAvatarActions::startCall(const LLUUID& id) return; } -// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h - if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(id)) ) +// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9) + if ( (!RlvActions::canStartIM(id)) && (!RlvActions::hasOpenP2PSession(id)) ) { - LLUUID idSession = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id); - if ( (idSession.notNull()) && (!gIMMgr->hasSession(idSession)) ) - { - make_ui_sound("UISndInvalidOp"); - RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString())); - return; - } + make_ui_sound("UISndInvalidOp"); + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString())); + return; } // [/RLVa:KB] @@ -262,12 +255,12 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids) LLDynamicArray id_array; for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { -// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h +// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0) const LLUUID& idAgent = *it; - if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(idAgent)) ) + if (!RlvActions::canStartIM(idAgent)) { make_ui_sound("UISndInvalidOp"); - RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF, LLSD().with("RECIPIENT", LLSLURL("agent", idAgent, "completename").getSLURLString())); + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF); return; } id_array.push_back(idAgent); @@ -315,12 +308,12 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids) { for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { -// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h +// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0) const LLUUID& idAgent = *it; - if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(idAgent)) ) + if (!RlvActions::canStartIM(idAgent)) { make_ui_sound("UISndInvalidOp"); - RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF, LLSD().with("RECIPIENT", LLSLURL("agent", idAgent, "completename").getSLURLString())); + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF); return; } // [/RLVa:KB] diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 9a31e0d6f..8c38b0597 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -44,6 +44,7 @@ #include "llfocusmgr.h" #include "llagent.h" +#include "llautoreplace.h" #include "llbutton.h" #include "llcombobox.h" #include "llcommandhandler.h" // secondlife:///app/chat/ support @@ -149,6 +150,7 @@ BOOL LLChatBar::postBuild() mInputEditor = findChild("Chat Editor"); if (mInputEditor) { + mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5)); mInputEditor->setKeystrokeCallback(boost::bind(&LLChatBar::onInputEditorKeystroke,this)); mInputEditor->setFocusLostCallback(boost::bind(&LLChatBar::onInputEditorFocusLost)); mInputEditor->setFocusReceivedCallback(boost::bind(&LLChatBar::onInputEditorGainFocus)); diff --git a/indra/newview/llcrashlogger.cpp b/indra/newview/llcrashlogger.cpp index e0a52cc62..cf06a402d 100644 --- a/indra/newview/llcrashlogger.cpp +++ b/indra/newview/llcrashlogger.cpp @@ -47,6 +47,7 @@ class AIHTTPTimeoutPolicy; extern AIHTTPTimeoutPolicy crashLoggerResponder_timeout; +extern const std::string OLD_LOG_FILE; class LLCrashLoggerResponder : public LLHTTPClient::ResponderWithResult { @@ -284,7 +285,7 @@ void LLCrashLogger::gatherFiles() mCrashInfo["DebugLog"] = mDebugLog; mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"stats.log"); // Singu Note: we have just started again, log has been renamed - mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "Singularity.old"); + mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, OLD_LOG_FILE); llinfos << "Encoding files..." << llendl; diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index fad98ddbd..b27bb9a14 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -295,14 +295,7 @@ void LLDrawPoolAlpha::render(S32 pass) } } - if (mVertexShaderLevel > 0) - { - renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass); - } - else - { - renderAlpha(getVertexDataMask(), pass); - } + renderAlpha(getVertexDataMask(), pass); //getVertexDataMask base mask if fixed-function. gGL.setColorMask(true, false); @@ -380,6 +373,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) BOOL light_enabled = TRUE; BOOL use_shaders = gPipeline.canUseVertexShaders(); + + BOOL depth_only = (pass == 1 && !LLPipeline::sImpostorRender); for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { @@ -394,7 +389,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) || group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_CLOUD || group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; - bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow. + bool draw_glow_for_this_partition = !depth_only && mVertexShaderLevel > 0; // no shaders = no glow. static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group"); LLFastTimer t(FTM_RENDER_ALPHA_GROUP_LOOP); @@ -408,16 +403,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) { LLDrawInfo& params = **k; - if ((params.mVertexBuffer->getTypeMask() & mask) != mask) + /*if ((params.mVertexBuffer->getTypeMask() & mask) != mask) { //FIXME! llwarns << "Missing required components, skipping render batch." << llendl; continue; - } + }*/ // Fix for bug - NORSPEC-271 // If the face is more than 90% transparent, then don't update the Depth buffer for Dof // We don't want the nearly invisible objects to cause of DoF effects - if(pass == 1 && !LLPipeline::sImpostorRender) + if(depth_only) { LLFace* face = params.mFace; if(face) @@ -450,18 +445,19 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) llassert_always(!LLGLSLShader::sNoFixedFunction); llassert_always(!LLGLSLShader::sCurBoundShaderPtr); - if(params.mFullbright == light_enabled || !initialized_lighting) + bool fullbright = depth_only || params.mFullbright; + if(fullbright == !!light_enabled || !initialized_lighting) { - light_enabled = !params.mFullbright; + light_enabled = !fullbright; initialized_lighting = true; if (light_enabled) // Turn off lighting if it hasn't already been so. { - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + gPipeline.enableLightsDynamic(); } else // Turn on lighting if it isn't already. { - gPipeline.enableLightsDynamic(); + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } } } @@ -512,7 +508,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); } } - else if(deferred_render && current_shader == simple_shader) + /*else if(deferred_render && current_shader == simple_shader) { current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f); @@ -520,7 +516,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); - } + }*/ if (params.mTextureList.size() > 1) { @@ -567,12 +563,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_PUSH("Alpha Push Verts"); { LLFastTimer t(FTM_RENDER_ALPHA_PUSH); - gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - // Singu Note: Only remove tan/texcoord1/texcoord2 if actually using the fullbright shader. Material faces ignore fullbright bit. - params.mVertexBuffer->setBuffer(mask & ~((current_shader == fullbright_shader) ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); + + gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); + // Singu Note: If using shaders, pull the attribute mask from it, else used passed base mask. + params.mVertexBuffer->setBuffer(current_shader ? current_shader->mAttributeMask : mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); } // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. @@ -588,7 +585,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) emissive_shader->bind(); // glow doesn't use vertex colors from the mesh data - params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); + // Singu Note: Pull attribs from shader, since we always have one here. + params.mVertexBuffer->setBuffer(emissive_shader->mAttributeMask); // do the actual drawing, again params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index d4962256e..42dcd4547 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1575,6 +1575,10 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* for (U32 j = 0; j < count; ++j) { LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); + if(!joint) + { + joint = avatar->getJoint("mRoot"); + } if (joint) { mat[j] = skin->mInvBindMatrix[j]; @@ -1599,7 +1603,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* { F32 w = weight[j][k]; - idx[k] = llclamp((S32) floorf(w), 0, 63); + idx[k] = llclamp((S32) floorf(w), 0, S32(count-1)); wght[k] = w - floorf(w); scale += wght[k]; } @@ -1703,6 +1707,10 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) for (U32 i = 0; i < count; ++i) { LLJoint* joint = avatar->getJoint(skin->mJointNames[i]); + if(!joint) + { + joint = avatar->getJoint("mRoot"); + } if (joint) { mat[i] = skin->mInvBindMatrix[i]; @@ -1747,7 +1755,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) (GLfloat*) mp); LLDrawPoolAvatar::sVertexProgram->uniform3fv(LLShaderMgr::AVATAR_TRANSLATION, count, transp); - + LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(count-1)); stop_glerror(); } @@ -1943,7 +1951,7 @@ void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) LLRender::BF_ONE_MINUS_SOURCE_ALPHA); renderRigged(avatar, RIGGED_ALPHA); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + //gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setColorMask(true, false); } } @@ -1961,7 +1969,7 @@ void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) LLRender::BF_ONE_MINUS_SOURCE_ALPHA); renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + //gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setColorMask(true, false); } } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index d9eac7b7b..6a4c1b2ba 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -270,7 +270,7 @@ void LLDrawPoolBump::render(S32 pass) { LLFastTimer t(FTM_RENDER_BUMP); - if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE)) + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) { return; } diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 012a4b9dd..a0d6dbf92 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -548,11 +548,17 @@ void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) { if (LLPipeline::sUnderWaterRender) { - gDeferredFullbrightWaterProgram.bind(); + //gDeferredFullbrightWaterProgram.bind(); + //Use alpha-mask version to ignore alpha values while still allowing us to occlude glow. + gDeferredFullbrightAlphaMaskWaterProgram.bind(); + gDeferredFullbrightAlphaMaskWaterProgram.setMinimumAlpha(0.f); } else { - gDeferredFullbrightProgram.bind(); + //gDeferredFullbrightProgram.bind(); + //Use alpha-mask version to ignore alpha values while still allowing us to occlude glow. + gDeferredFullbrightAlphaMaskProgram.bind(); + gDeferredFullbrightAlphaMaskProgram.setMinimumAlpha(0.f); } } @@ -573,11 +579,11 @@ void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) { if (LLPipeline::sUnderWaterRender) { - gDeferredFullbrightWaterProgram.unbind(); + gDeferredFullbrightAlphaMaskWaterProgram.unbind(); } else { - gDeferredFullbrightProgram.unbind(); + gDeferredFullbrightAlphaMaskProgram.unbind(); } LLRenderPass::endRenderPass(pass); } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 0872f5f9d..12f91ea67 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -253,6 +253,7 @@ void LLDrawPoolWater::render(S32 pass) glClearStencil(1); glClear(GL_STENCIL_BUFFER_BIT); + glClearStencil(0); LLGLEnable gls_stencil(GL_STENCIL_TEST); glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 3d0762132..864975460 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -326,6 +326,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius(); + LLGLDisable stencil(GL_STENCIL_TEST); LLGLSNoFog disableFog; LLGLDepthTest depth(GL_TRUE, GL_FALSE); LLGLDisable clip(GL_CLIP_PLANE0); diff --git a/indra/newview/llemote.cpp b/indra/newview/llemote.cpp index c83846215..47bd57969 100644 --- a/indra/newview/llemote.cpp +++ b/indra/newview/llemote.cpp @@ -48,7 +48,7 @@ // LLEmote() // Class Constructor //----------------------------------------------------------------------------- -LLEmote::LLEmote(const LLUUID &id) : LLMotion(id) +LLEmote::LLEmote(LLUUID const& id, LLMotionController* controller) : LLMotion(id, controller) { mCharacter = NULL; diff --git a/indra/newview/llemote.h b/indra/newview/llemote.h index 99d05b9a2..173719121 100644 --- a/indra/newview/llemote.h +++ b/indra/newview/llemote.h @@ -55,7 +55,7 @@ class LLEmote : { public: // Constructor - LLEmote(const LLUUID &id); + LLEmote(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLEmote(); @@ -67,7 +67,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLEmote(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLEmote(id, controller); } public: //------------------------------------------------------------------------- diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index b7147b9f6..15430989e 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1297,15 +1297,33 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_color) // FALSE if tep == NULL { //decide if shiny goes in alpha channel of color + + static const LLCachedControl alt_batching("SHAltBatching",true); if (tep && - getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny + ((!alt_batching && getPoolType() != LLDrawPool::POOL_ALPHA) || + (alt_batching && getPoolType() != LLDrawPool::POOL_ALPHA && + getPoolType() != LLDrawPool::POOL_ALPHA_MASK && + getPoolType() != LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK && // <--- alpha channel MUST contain transparency, not shiny + (getPoolType() != LLDrawPool::POOL_SIMPLE || LLPipeline::sRenderDeferred)))) // Impostor pass for simple uses alpha masking. Need to be opaque. { LLMaterial* mat = tep->getMaterialParams().get(); - bool shiny_in_alpha = false; + bool shiny_in_alpha = alt_batching ? true : false; + if(alt_batching) + { if (LLPipeline::sRenderDeferred) { //store shiny in alpha if we don't have a specular map + if (getPoolType() == LLDrawPool::POOL_MATERIALS && mat->getSpecularID().notNull()) + { + shiny_in_alpha = false; + } + } + } + else + { + if (LLPipeline::sRenderDeferred) + { if (!mat || mat->getSpecularID().isNull()) { shiny_in_alpha = true; @@ -1318,10 +1336,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, shiny_in_alpha = true; } } + } - if (shiny_in_alpha) + if(getPoolType() == LLDrawPool::POOL_FULLBRIGHT) + { + color.mV[3] = 1.f; //Simple fullbright reads alpha for fog contrib, not shiny/transparency, so since opaque, force to 1. + } + else if (shiny_in_alpha) { - GLfloat alpha[4] = { 0.00f, diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index d47f5fb43..27b0ded9e 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -62,8 +62,9 @@ #include "hippogridmanager.h" -// [RLVa:KB] -#include "rlvhandler.h" +// [RLVa:KB] - Checked: 2010-04-18 (RLVa-1.4.0) +#include "rlvactions.h" +#include "rlvhelper.h" // [/RLVa:KB] #if LL_WINDOWS @@ -168,15 +169,7 @@ LLFloaterAbout::LLFloaterAbout() // Position LLViewerRegion* region = gAgent.getRegion(); -// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) - { - support.append(RlvStrings::getString(RLV_STRING_HIDDEN)); - support.append("\n\n"); - } - else if (region) -// [/RLVa:KB] -// if (region) + if (region) { LLStyleSP server_link_style(new LLStyle); server_link_style->setVisible(true); @@ -184,6 +177,9 @@ LLFloaterAbout::LLFloaterAbout() server_link_style->setLinkHREF(region->getCapability("ServerReleaseNotes")); server_link_style->setColor(gSavedSettings.getColor4("HTMLLinkColor")); +// [RLVa:KB] - Checked: 2014-02-24 (RLVa-1.4.10) + if (RlvActions::canShowLocation()) + { const LLVector3d &pos = gAgent.getPositionGlobal(); LLUIString pos_text = getString("you_are_at"); pos_text.setArg("[POSITION]", @@ -204,6 +200,10 @@ LLFloaterAbout::LLFloaterAbout() support.append(buffer); support.append(")"); } + } + else + support.append(RlvStrings::getString(RLV_STRING_HIDDEN_REGION)); +// [/RLVa:KN] support.append("\n"); support.append(gLastVersionChannel); @@ -267,6 +267,10 @@ LLFloaterAbout::LLFloaterAbout() support.append("OpenGL Version: "); support.append( (const char*) glGetString(GL_VERSION) ); +// [RLVa:KB] - Checked: 2010-04-18 (RLVa-1.2.0) + support.append("\n"); + support.append("RLV Version: " + (RlvActions::isRlvEnabled()) ? RlvStrings::getVersionAbout() : "(disabled)"); +// [/RLVa:KB] support.append("\n\n"); support.append("Viewer SSE Version: "); diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp new file mode 100644 index 000000000..eabd8c13e --- /dev/null +++ b/indra/newview/llfloaterautoreplacesettings.cpp @@ -0,0 +1,632 @@ +/** + * @file llfloaterautoreplacesettings.cpp + * @brief Auto Replace List floater + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterautoreplacesettings.h" + +#include "statemachine/aifilepicker.h" +#include "llscrolllistctrl.h" +#include "lluictrlfactory.h" + +#include "llautoreplace.h" +#include "llsdserialize.h" +#include "llsdutil.h" + +#include + +#include "llnotificationsutil.h" + + +LLFloaterAutoReplaceSettings::LLFloaterAutoReplaceSettings(const LLSD& key) + : LLFloater(/*key*/) + , mSelectedListName("") + , mListNames(NULL) + , mReplacementsList(NULL) + , mKeyword(NULL) + , mPreviousKeyword("") + , mReplacement(NULL) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_autoreplace.xml"); +} + +BOOL LLFloaterAutoReplaceSettings::postBuild(void) +{ + // get copies of the current settings that we will operate on + mEnabled = gSavedSettings.getBOOL("AutoReplace"); + LL_DEBUGS("AutoReplace") << ( mEnabled ? "enabled" : "disabled") << LL_ENDL; + + mSettings = LLAutoReplace::getInstance()->getSettings(); + + // global checkbox for whether or not autoreplace is active + LLUICtrl* enabledCheckbox = getChild("autoreplace_enable"); + enabledCheckbox->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onAutoReplaceToggled, this)); + enabledCheckbox->setValue(LLSD(mEnabled)); + + // top row list creation and deletion + getChild("autoreplace_import_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onImportList,this)); + getChild("autoreplace_export_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onExportList,this)); + getChild("autoreplace_new_list")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onNewList,this)); + getChild("autoreplace_delete_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteList,this)); + + // the list of keyword->replacement lists + mListNames = getChild("autoreplace_list_name"); + mListNames->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectList, this)); + mListNames->setCommitOnSelectionChange(true); + + // list ordering + getChild("autoreplace_list_up")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onListUp,this)); + getChild("autoreplace_list_down")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onListDown,this)); + + // keyword->replacement entry add / delete + getChild("autoreplace_add_entry")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onAddEntry,this)); + getChild("autoreplace_delete_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteEntry,this)); + + // entry edits + mKeyword = getChild("autoreplace_keyword"); + mReplacement = getChild("autoreplace_replacement"); + getChild("autoreplace_save_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveEntry, this)); + + // dialog termination ( Save Changes / Cancel ) + getChild("autoreplace_save_changes")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveChanges, this)); + getChild("autoreplace_cancel")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::close, this, false)); + + // the list of keyword->replacement pairs + mReplacementsList = getChild("autoreplace_list_replacements"); + mReplacementsList->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectEntry, this)); + mReplacementsList->setCommitOnSelectionChange(true); + + center(); + + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + + return true; +} + + +void LLFloaterAutoReplaceSettings::updateListNames() +{ + mListNames->deleteAllItems(); // start from scratch + + LLSD listNames = mSettings.getListNames(); // Array of Strings + + for ( LLSD::array_const_iterator entry = listNames.beginArray(), end = listNames.endArray(); + entry != end; + ++entry + ) + { + const std::string& listName = entry->asString(); + mListNames->addSimpleElement(listName); + } + + if (!mSelectedListName.empty()) + { + mListNames->setSelectedByValue( LLSD(mSelectedListName), true ); + } +} + +void LLFloaterAutoReplaceSettings::updateListNamesControls() +{ + if ( mSelectedListName.empty() ) + { + // There is no selected list + + // Disable all controls that operate on the selected list + getChild("autoreplace_export_list")->setEnabled(false); + getChild("autoreplace_delete_list")->setEnabled(false); + getChild("autoreplace_list_up")->setEnabled(false); + getChild("autoreplace_list_down")->setEnabled(false); + + mReplacementsList->deleteAllItems(); + } + else + { + // Enable the controls that operate on the selected list + getChild("autoreplace_export_list")->setEnabled(true); + getChild("autoreplace_delete_list")->setEnabled(true); + getChild("autoreplace_list_up")->setEnabled(!selectedListIsFirst()); + getChild("autoreplace_list_down")->setEnabled(!selectedListIsLast()); + } +} + +void LLFloaterAutoReplaceSettings::onSelectList() +{ + std::string previousSelectedListName = mSelectedListName; + // only one selection allowed + LLSD selected = mListNames->getSelectedValue(); + if (selected.isDefined()) + { + mSelectedListName = selected.asString(); + LL_DEBUGS("AutoReplace")<<"selected list '"<getSelectedValue(); + if (selectedRow.isDefined()) + { + mPreviousKeyword = selectedRow.asString(); + LL_DEBUGS("AutoReplace")<<"selected entry '"<setValue(selectedRow); + std::string replacement = mSettings.replacementFor(mPreviousKeyword, mSelectedListName ); + mReplacement->setValue(replacement); + enableReplacementEntry(); + mReplacement->setFocus(true); + } + else + { + // no entry selection, so the entry panel should be off + disableReplacementEntry(); + LL_DEBUGS("AutoReplace")<<"no row selected"<deleteAllItems(); + + if ( mSelectedListName.empty() ) + { + mReplacementsList->setEnabled(false); + getChild("autoreplace_add_entry")->setEnabled(false); + disableReplacementEntry(); + } + else + { + // Populate the keyword->replacement list from the selected list + const LLSD* mappings = mSettings.getListEntries(mSelectedListName); + for ( LLSD::map_const_iterator entry = mappings->beginMap(), end = mappings->endMap(); + entry != end; + entry++ + ) + { + LLSD row; + row["id"] = entry->first; + row["columns"][0]["column"] = "Keyword"; + row["columns"][0]["value"] = entry->first; + row["columns"][1]["column"] = "Replacement"; + row["columns"][1]["value"] = entry->second; + + mReplacementsList->addElement(row, ADD_BOTTOM); + } + + mReplacementsList->deselectAllItems(false /* don't call commit */); + mReplacementsList->setEnabled(true); + + getChild("autoreplace_add_entry")->setEnabled(true); + disableReplacementEntry(); + } +} + +void LLFloaterAutoReplaceSettings::enableReplacementEntry() +{ + LL_DEBUGS("AutoReplace")<setEnabled(true); + mReplacement->setEnabled(true); + getChild("autoreplace_save_entry")->setEnabled(true); + getChild("autoreplace_delete_entry")->setEnabled(true); +} + +void LLFloaterAutoReplaceSettings::disableReplacementEntry() +{ + LL_DEBUGS("AutoReplace")<clear(); + mKeyword->setEnabled(false); + mReplacement->clear(); + mReplacement->setEnabled(false); + getChild("autoreplace_save_entry")->setEnabled(false); + getChild("autoreplace_delete_entry")->setEnabled(false); +} + +// called when the global settings checkbox is changed +void LLFloaterAutoReplaceSettings::onAutoReplaceToggled() +{ + // set our local copy of the flag, copied to the global preference in onOk + mEnabled = childGetValue("autoreplace_enable").asBoolean(); + LL_DEBUGS("AutoReplace")<< "autoreplace_enable " << ( mEnabled ? "on" : "off" ) << LL_ENDL; +} + +// called when the List Up button is pressed +void LLFloaterAutoReplaceSettings::onListUp() +{ + S32 selectedRow = mListNames->getFirstSelectedIndex(); + LLSD selectedName = mListNames->getSelectedValue().asString(); + + if ( mSettings.increaseListPriority(selectedName) ) + { + updateListNames(); + updateListNamesControls(); + } + else + { + LL_WARNS("AutoReplace") + << "invalid row ("<getFirstSelectedIndex(); + std::string selectedName = mListNames->getSelectedValue().asString(); + + if ( mSettings.decreaseListPriority(selectedName) ) + { + updateListNames(); + updateListNamesControls(); + } + else + { + LL_WARNS("AutoReplace") + << "invalid row ("<getSelectedValue(); + if (selectedRow.isDefined()) + { + std::string keyword = selectedRow.asString(); + mReplacementsList->deleteSelectedItems(); // delete from the control + mSettings.removeEntryFromList(keyword, mSelectedListName); // delete from the local settings copy + disableReplacementEntry(); // no selection active, so turn off the buttons + } +} + +// called when the Import List button is pressed +void LLFloaterAutoReplaceSettings::onImportList() +{ + AIFilePicker* picker = AIFilePicker::create(); + picker->open(FFLOAD_XML, "", "autoreplace"); + picker->run(boost::bind(&LLFloaterAutoReplaceSettings::onImportList_continued, this, picker)); +} + +void LLFloaterAutoReplaceSettings::onImportList_continued(AIFilePicker* picker) +{ + if (picker->hasFilename()) + { + llifstream file; + file.open(picker->getFilename()); + LLSD newList; + if (file.is_open()) + { + LLSDSerialize::fromXMLDocument(newList, file); + } + file.close(); + + switch ( mSettings.addList(newList) ) + { + case LLAutoReplaceSettings::AddListOk: + mSelectedListName = LLAutoReplaceSettings::getListName(newList); + + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + break; + + case LLAutoReplaceSettings::AddListDuplicateName: + { + std::string newName = LLAutoReplaceSettings::getListName(newList); + LL_WARNS("AutoReplace")<<"name '"<getSelectedValue().asString(); + if ( ! listName.empty() ) + { + if ( mSettings.removeReplacementList(listName) ) + { + LL_INFOS("AutoReplace")<<"deleted list '"<deleteSelectedItems(); // remove from the scrolling list + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + } + else + { + LL_WARNS("AutoReplace")<<"failed to delete list '"<getFirstSelected()->getColumn(0)->getValue().asString(); + std::string listFileName = listName + ".xml"; + AIFilePicker* picker = AIFilePicker::create(); + picker->open(listFileName, FFSAVE_XML, "", "autoreplace"); + picker->run(boost::bind(&LLFloaterAutoReplaceSettings::onExportList_continued, this, picker, mSettings.exportList(listName))); +} +void LLFloaterAutoReplaceSettings::onExportList_continued(AIFilePicker* picker, const LLSD* list) +{ + if (picker->hasFilename()) + { + llofstream file; + file.open(picker->getFilename()); + LLSDSerialize::toPrettyXML(*list, file); + file.close(); + } +} + +void LLFloaterAutoReplaceSettings::onAddEntry() +{ + mPreviousKeyword.clear(); + mReplacementsList->deselectAllItems(false /* don't call commit */); + mKeyword->clear(); + mReplacement->clear(); + enableReplacementEntry(); + mKeyword->setFocus(true); +} + +void LLFloaterAutoReplaceSettings::onSaveEntry() +{ + LL_DEBUGS("AutoReplace")<<"called"<getWText(); + LLWString replacement = mReplacement->getWText(); + if ( mSettings.addEntryToList(keyword, replacement, mSelectedListName) ) + { + // insert the new keyword->replacement pair + LL_INFOS("AutoReplace") + << "list '" << mSelectedListName << "' " + << "added '" << wstring_to_utf8str(keyword) + << "' -> '" << wstring_to_utf8str(replacement) + << "'" << LL_ENDL; + + updateReplacementsList(); + } + else + { + LLNotificationsUtil::add("InvalidAutoReplaceEntry"); + LL_WARNS("AutoReplace")<<"invalid entry " + << "keyword '" << wstring_to_utf8str(keyword) + << "' replacement '" << wstring_to_utf8str(replacement) + << "'" << LL_ENDL; + } +} + +void LLFloaterAutoReplaceSettings::onSaveChanges() +{ + // put our local copy of the settings into the active copy + LLAutoReplace::getInstance()->setSettings( mSettings ); + // save our local copy of the global feature enable/disable value + gSavedSettings.setBOOL("AutoReplace", mEnabled); + close(); +} + +bool LLFloaterAutoReplaceSettings::selectedListIsFirst() +{ + bool isFirst = false; + + if (!mSelectedListName.empty()) + { + LLSD lists = mSettings.getListNames(); // an Array of Strings + LLSD first = lists.get(0); + if ( first.isString() && first.asString() == mSelectedListName ) + { + isFirst = true; + } + } + return isFirst; +} + +bool LLFloaterAutoReplaceSettings::selectedListIsLast() +{ + bool isLast = false; + + if (!mSelectedListName.empty()) + { + LLSD last; + LLSD lists = mSettings.getListNames(); // an Array of Strings + for ( LLSD::array_const_iterator list = lists.beginArray(), listEnd = lists.endArray(); + list != listEnd; + list++ + ) + { + last = *list; + } + if ( last.isString() && last.asString() == mSelectedListName ) + { + isLast = true; + } + } + return isLast; +} + +/* TBD +mOldText = getChild("autoreplace_old_text"); +mNewText = getChild("autoreplace_new_text"); +*/ diff --git a/indra/newview/llfloaterautoreplacesettings.h b/indra/newview/llfloaterautoreplacesettings.h new file mode 100644 index 000000000..c9cc98d9f --- /dev/null +++ b/indra/newview/llfloaterautoreplacesettings.h @@ -0,0 +1,111 @@ +/** + * @file llfloaterautoreplacesettings.h + * @brief Auto Replace List floater + * @copyright Copyright (c) 2011 LordGregGreg Back + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * $/LicenseInfo$ + */ + +#ifndef LLFLOATERAUTOREPLACESETTINGS_H +#define LLFLOATERAUTOREPLACESETTINGS_H + +#include "llfloater.h" +#include "llautoreplace.h" + +class AIFilePicker; +class LLLineEditor; +class LLScrollListCtrl; + +class LLFloaterAutoReplaceSettings : public LLFloater, public LLFloaterSingleton +{ +public: + LLFloaterAutoReplaceSettings(const LLSD& key = LLSD()); + + /*virtual*/ BOOL postBuild(); + +private: + + /** @{ @name Local Copies of Settings + * These are populated in the postBuild method with the values + * current when the floater is instantiated, and then either + * discarded when Cancel is pressed, or copied back to the active + * settings if Ok is pressed. + */ + bool mEnabled; ///< the global preference for AutoReplace + LLAutoReplaceSettings mSettings; ///< settings being modified + /** @} */ + + /// convenience variable - the name of the currently selected list (if any) + std::string mSelectedListName; + /// the scrolling list of list names (one column, no headings, order manually controlled) + LLScrollListCtrl* mListNames; + /// the scroling list of keyword->replacement pairs + LLScrollListCtrl* mReplacementsList; + + /// the keyword for the entry editing pane + LLLineEditor* mKeyword; + /// saved keyword value + std::string mPreviousKeyword; + /// the replacement for the entry editing pane + LLLineEditor* mReplacement; + + /// callback for when the feature enable/disable checkbox changes + void onAutoReplaceToggled(); + /// callback for when an entry in the list of list names is selected + void onSelectList(); + + void onImportList(); + void onImportList_continued(AIFilePicker* picker); + void onExportList(); + void onExportList_continued(AIFilePicker* picker, const LLSD* list); + void onNewList(); + void onDeleteList(); + + void onListUp(); + void onListDown(); + + void onSelectEntry(); + void onAddEntry(); + void onDeleteEntry(); + void onSaveEntry(); + + void onSaveChanges(); + + /// updates the contents of the mListNames + void updateListNames(); + /// updates the controls associated with mListNames (depends on whether a name is selected or not) + void updateListNamesControls(); + /// updates the contents of the mReplacementsList + void updateReplacementsList(); + /// enables the components that should only be active when a keyword is selected + void enableReplacementEntry(); + /// disables the components that should only be active when a keyword is selected + void disableReplacementEntry(); + + /// called from the AddAutoReplaceList notification dialog + bool callbackNewListName(const LLSD& notification, const LLSD& response); + /// called from the RenameAutoReplaceList notification dialog + bool callbackListNameConflict(const LLSD& notification, const LLSD& response); + + bool selectedListIsFirst(); + bool selectedListIsLast(); +}; + +#endif // LLFLOATERAUTOREPLACESETTINGS_H diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 5f1a0f47c..86d87d049 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -291,7 +291,7 @@ LLFloaterAvatarList::~LLFloaterAvatarList() } //static -void LLFloaterAvatarList::toggle(void*) +void LLFloaterAvatarList::toggleInstance(const LLSD&) { // [RLVa:KB] if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) @@ -301,7 +301,7 @@ void LLFloaterAvatarList::toggle(void*) } else // [/RLVa:KB] - if(!instanceExists() || !getInstance()->getVisible()) + if (!instanceVisible()) { showInstance(); } @@ -603,8 +603,9 @@ void LLFloaterAvatarList::updateAvatarList() { const LLUUID &avid = avatar_ids[i]; + static const LLCachedControl namesystem("RadarNameSystem"); std::string name; - if (!LLAvatarNameCache::getPNSName(avid, name)) + if (!LLAvatarNameCache::getPNSName(avid, name, namesystem)) continue; //prevent (Loading...) LLAvatarListEntry* entry = getAvatarEntry(avid); @@ -1547,6 +1548,11 @@ LLUUID LLFloaterAvatarList::getSelectedID() return LLUUID::null; } +uuid_vec_t LLFloaterAvatarList::getSelectedIDs() +{ + return mAvatarList->getSelectedIDs(); +} + //static void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& response) { diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 33f02ce9b..a18b4f9cb 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -212,9 +212,10 @@ public: * @brief Toggles interface visibility * There is only one instance of the avatar scanner at any time. */ - static void toggle(void*); + static void toggleInstance(const LLSD& = LLSD()); static void showInstance(); + static bool instanceVisible(const LLSD& = LLSD()) { return instanceExists() && instance().getVisible(); } // Decides which user-chosen columns to show and hide. void assessColumns(); @@ -241,6 +242,7 @@ public: std::string getSelectedNames(const std::string& separator = ", "); std::string getSelectedName(); LLUUID getSelectedID(); + uuid_vec_t getSelectedIDs(); static void lookAtAvatar(LLUUID &uuid); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index dec0a2ef7..f503fa3ba 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -37,6 +37,7 @@ #include "llviewerregion.h" // getCapability() #include "llworld.h" // [RLVa:KB] - Checked: 2010-06-04 (RLVa-1.2.2a) +#include "rlvactions.h" #include "rlvhandler.h" // [/RLVa:KB] @@ -549,8 +550,8 @@ BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask, if (dest_agent_id.notNull() && dest_agent_id != gAgentID) { // if (drop) -// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h - if ( (drop) && ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.canStartIM(dest_agent_id)) ) ) +// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0) + if ( (drop) && (RlvActions::canStartIM(dest_agent_id)) ) // [/RLVa:KB] { // Start up IM before give the item diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 58e27b914..251397fa6 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -375,6 +375,10 @@ BOOL LLFloaterBvhPreview::postBuild() } } + if (motionp && mInWorld) + { + gAgentAvatarp->removeMotion(mMotionID); + } //setEnabled(FALSE); mMotionID.setNull(); mAnimPreview = NULL; diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h index 7f31054c0..deae420fb 100644 --- a/indra/newview/llfloaterbvhpreview.h +++ b/indra/newview/llfloaterbvhpreview.h @@ -42,7 +42,7 @@ class LLViewerJointMesh; class LLPreviewAnimation : public LLViewerDynamicTexture { -protected: +public: virtual ~LLPreviewAnimation(); public: diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index 0df0663b9..fdba40110 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -253,6 +253,8 @@ void LLFloaterCustomize::editWearable(LLViewerWearable* wearable, bool disable_c //static void LLFloaterCustomize::show() { + if (!gAgentWearables.areWearablesLoaded()) return; + if(!LLFloaterCustomize::instanceExists()) { const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(LLWearableType::WT_SHAPE); diff --git a/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp index 3cf67821f..33ae1b35f 100644 --- a/indra/newview/llfloaterdaycycle.cpp +++ b/indra/newview/llfloaterdaycycle.cpp @@ -59,6 +59,7 @@ #include "llwlparammanager.h" #include "llfloaterwindlight.h" +#include "rlvactions.h" LLFloaterDayCycle* LLFloaterDayCycle::sDayCycle = NULL; std::map LLFloaterDayCycle::sSliderToKey; @@ -277,6 +278,7 @@ bool LLFloaterDayCycle::isOpen() void LLFloaterDayCycle::show() { + if (RlvActions::hasBehaviour(RLV_BHVR_SETENV)) return; LLFloaterDayCycle* dayCycle = instance(); dayCycle->syncMenu(); syncSliderTrack(); diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp index 57a952244..c28501932 100644 --- a/indra/newview/llfloaterenvsettings.cpp +++ b/indra/newview/llfloaterenvsettings.cpp @@ -50,6 +50,7 @@ #include "llviewerwindow.h" #include "pipeline.h" +#include "rlvactions.h" #include @@ -175,13 +176,12 @@ LLFloaterEnvSettings* LLFloaterEnvSettings::instance() if (!sEnvSettings) { sEnvSettings = new LLFloaterEnvSettings(); - sEnvSettings->open(); - sEnvSettings->setFocus(TRUE); } return sEnvSettings; } void LLFloaterEnvSettings::show() { + if (RlvActions::hasBehaviour(RLV_BHVR_SETENV)) return; LLFloaterEnvSettings* envSettings = instance(); envSettings->syncMenu(); @@ -189,7 +189,10 @@ void LLFloaterEnvSettings::show() //LLUICtrlFactory::getInstance()->buildFloater(envSettings, "floater_env_settings.xml"); //envSettings->initCallbacks(); - envSettings->open(); + if (envSettings->getVisible()) + envSettings->close(); + else + envSettings->open(); } bool LLFloaterEnvSettings::isOpen() diff --git a/indra/newview/llfloaterexploreanimations.cpp b/indra/newview/llfloaterexploreanimations.cpp index 5ffe000b6..bfc08d700 100644 --- a/indra/newview/llfloaterexploreanimations.cpp +++ b/indra/newview/llfloaterexploreanimations.cpp @@ -4,6 +4,7 @@ #include "llfloaterexploreanimations.h" #include "lluictrlfactory.h" #include "llscrolllistctrl.h" +#include "llagentdata.h" #include "llfloaterbvhpreview.h" #include "llvoavatar.h" #include "llviewercamera.h" @@ -14,42 +15,51 @@ #include "llselectmgr.h" // -std::map< LLUUID, std::list< LLAnimHistoryItem* > > LLFloaterExploreAnimations::animHistory; -LLFloaterExploreAnimations* LLFloaterExploreAnimations::sInstance; +std::map< LLUUID, std::list< LLAnimHistoryItem > > LLFloaterExploreAnimations::animHistory; - -LLAnimHistoryItem::LLAnimHistoryItem(LLUUID assetid) +LLAnimHistoryItem::LLAnimHistoryItem(LLUUID assetid, bool playing) +: mAssetID(assetid) +, mPlaying(playing) +, mTimeStarted(LLTimer::getElapsedSeconds()) +, mTimeStopped(playing ? 0.f : mTimeStarted) +{} +bool LLAnimHistoryItem::setPlaying(bool playing) { - mAssetID = assetid; + if (mPlaying == playing) return false; + mPlaying = playing; + playing ? mTimeStarted : mTimeStopped = LLTimer::getElapsedSeconds(); + return true; } -LLFloaterExploreAnimations::LLFloaterExploreAnimations(LLUUID avatarid) -: LLFloater() +void LLFloaterExploreAnimations::show() +{ + LLViewerObject* avatar = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + const LLUUID& id(avatar ? avatar->getID() : gAgentID); + if (LLFloaterExploreAnimations* f = getInstance(id)) + if (avatar) f->open(); + else f->close(); + else + (new LLFloaterExploreAnimations(id))->open(); +} + +LLFloaterExploreAnimations::LLFloaterExploreAnimations(const LLUUID avatarid) +: LLInstanceTracker(avatarid) +, mAnimPreview(256, 256) { mLastMouseX = 0; mLastMouseY = 0; - LLFloaterExploreAnimations::sInstance = this; - mAvatarID = avatarid; - mAnimPreview = new LLPreviewAnimation(256, 256); - mAnimPreview->setZoom(2.0f); + mAnimPreview.setZoom(2.0f); LLUICtrlFactory::getInstance()->buildFloater(this, "floater_explore_animations.xml"); } -void LLFloaterExploreAnimations::close(bool app_quitting) -{ - LLFloater::close(app_quitting); -} - LLFloaterExploreAnimations::~LLFloaterExploreAnimations() { - mAnimPreview = NULL; - LLFloaterExploreAnimations::sInstance = NULL; } -BOOL LLFloaterExploreAnimations::postBuild(void) +BOOL LLFloaterExploreAnimations::postBuild() { - childSetCommitCallback("anim_list", onSelectAnimation, this); + getChild("anim_list")->setCommitCallback(boost::bind(&LLFloaterExploreAnimations::onSelectAnimation, this)); LLRect r = getRect(); mPreviewRect.set(r.getWidth() - 266, r.getHeight() - 25, r.getWidth() - 10, r.getHeight() - 256); update(); @@ -59,29 +69,28 @@ BOOL LLFloaterExploreAnimations::postBuild(void) void LLFloaterExploreAnimations::update() { LLScrollListCtrl* list = getChild("anim_list"); - LLUUID selection = list->getSelectedValue().asUUID(); + LLUUID selection = list->getCurrentID(); list->clearRows(); // do this differently probably - std::list history = animHistory[mAvatarID]; - std::list::iterator iter = history.begin(); - std::list::iterator end = history.end(); - for( ; iter != end; ++iter) + std::list history = animHistory[getKey()]; + std::list::iterator end = history.end(); + for(std::list::iterator iter = history.begin(); iter != end; ++iter) { - LLAnimHistoryItem* item = (*iter); + LLAnimHistoryItem item = (*iter); LLSD element; - element["id"] = item->mAssetID; + element["id"] = item.mAssetID; LLSD& name_column = element["columns"][0]; name_column["column"] = "name"; - name_column["value"] = item->mAssetID.asString(); + name_column["value"] = item.mAssetID.asString(); LLSD& info_column = element["columns"][1]; info_column["column"] = "info"; - if(item->mPlaying) + if(item.mPlaying) info_column["value"] = "Playing"; else - info_column["value"] = llformat("%.1f min ago", (LLTimer::getElapsedSeconds() - item->mTimeStopped) / 60.f); + info_column["value"] = llformat("%.1f min ago", (LLTimer::getElapsedSeconds() - item.mTimeStopped) / 60.f); list->addElement(element, ADD_BOTTOM); } @@ -98,7 +107,7 @@ void LLFloaterExploreAnimations::draw() gGL.color3f(1.f, 1.f, 1.f); - gGL.getTexUnit(0)->bind(mAnimPreview); + gGL.getTexUnit(0)->bind(&mAnimPreview); gGL.begin( LLRender::QUADS ); { @@ -115,157 +124,82 @@ void LLFloaterExploreAnimations::draw() gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - //LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); + //LLVOAvatar* avatarp = mAnimPreview.getDummyAvatar(); //if (!avatarp->areAnimationsPaused()) //{ - // mAnimPreview->requestUpdate(); + // mAnimPreview.requestUpdate(); //} } - - - - // static -void LLFloaterExploreAnimations::startAnim(LLUUID avatarid, LLUUID assetid) +void LLFloaterExploreAnimations::processAnim(LLUUID avatarid, LLUUID assetid, bool playing) { std::string asset_str = assetid.asString(); if(asset_str.find("17132261-c061") != std::string::npos) return; // dog1 else if(asset_str.find("fea558cb-8b9b") != std::string::npos) return; // dog2 else if(asset_str.find("50cb5750-0743") != std::string::npos) return; // dog3 - else if(asset_str.find("-dead-") != std::string::npos) return; // emo - LLAnimHistoryItem* item = NULL; - - std::list history = animHistory[avatarid]; - std::list::iterator iter = history.begin(); - std::list::iterator end = history.end(); - for( ; iter != end; ++iter) + std::list& history = animHistory[avatarid]; + std::list::iterator end = history.end(); + for(std::list::iterator iter = history.begin(); iter != end; ++iter) { - if((*iter)->mAssetID == assetid) - { - item = (*iter); - break; - } + LLAnimHistoryItem& item = (*iter); + if (item.mAssetID != assetid) continue; + if (item.setPlaying(playing)) + handleHistoryChange(avatarid); + return; } - if(!item) - { - item = new LLAnimHistoryItem(assetid); - item->mAvatarID = avatarid; - item->mTimeStarted = LLTimer::getElapsedSeconds(); - } - item->mPlaying = true; - history.push_back(item); - animHistory[avatarid] = history; // is this really necessary? - handleHistoryChange(); -} + // Trim it + if (history.size() > 31) + history.resize(31); -// static -void LLFloaterExploreAnimations::stopAnim(LLUUID avatarid, LLUUID assetid) -{ - std::string asset_str = assetid.asString(); - if(asset_str.find("17132261-c061") != std::string::npos) return; // dog1 - else if(asset_str.find("fea558cb-8b9b") != std::string::npos) return; // dog2 - else if(asset_str.find("50cb5750-0743") != std::string::npos) return; // dog3 - else if(asset_str.find("-dead-") != std::string::npos) return; // emo - - LLAnimHistoryItem* item = NULL; - - std::list history = animHistory[avatarid]; - std::list::iterator iter = history.begin(); - std::list::iterator end = history.end(); - for( ; iter != end; ++iter) - { - if((*iter)->mAssetID == assetid) - { - item = (*iter); - break; - } - } - if(!item) - { - item = new LLAnimHistoryItem(assetid); - item->mAvatarID = avatarid; - item->mTimeStarted = LLTimer::getElapsedSeconds(); - history.push_back(item); - } - item->mPlaying = false; - item->mTimeStopped = LLTimer::getElapsedSeconds(); - handleHistoryChange(); + history.push_back(LLAnimHistoryItem(assetid, playing)); + handleHistoryChange(avatarid); } class LLAnimHistoryItemCompare { public: - bool operator() (LLAnimHistoryItem* first, LLAnimHistoryItem* second) + bool operator() (LLAnimHistoryItem first, LLAnimHistoryItem second) { - if(first->mPlaying) + if (first.mPlaying) { - if(second->mPlaying) + if (second.mPlaying) { - return (first->mTimeStarted > second->mTimeStarted); + return (first.mTimeStarted > second.mTimeStarted); } else { return true; } } - else if(second->mPlaying) + else if (second.mPlaying) { return false; } else { - return (first->mTimeStopped > second->mTimeStopped); + return (first.mTimeStopped > second.mTimeStopped); } } }; // static -void LLFloaterExploreAnimations::handleHistoryChange() +void LLFloaterExploreAnimations::handleHistoryChange(LLUUID avatarid) { - std::map< LLUUID, std::list< LLAnimHistoryItem* > >::iterator av_iter = animHistory.begin(); - std::map< LLUUID, std::list< LLAnimHistoryItem* > >::iterator av_end = animHistory.end(); - for( ; av_iter != av_end; ++av_iter) - { - std::list history = (*av_iter).second; - - // Sort it - LLAnimHistoryItemCompare c; - history.sort(c); - - // Remove dupes - history.unique(); - - // Trim it - if(history.size() > 32) - { - history.resize(32); - } - - animHistory[(*av_iter).first] = history; - } + // Sort it + animHistory[avatarid].sort(LLAnimHistoryItemCompare()); // Update floater - if(LLFloaterExploreAnimations::sInstance) - LLFloaterExploreAnimations::sInstance->update(); + if (LLFloaterExploreAnimations* f = getInstance(avatarid)) + f->update(); } - - - - -// static -void LLFloaterExploreAnimations::onSelectAnimation(LLUICtrl* ctrl, void* user_data) +void LLFloaterExploreAnimations::onSelectAnimation() { - LLFloaterExploreAnimations* floater = (LLFloaterExploreAnimations*)user_data; - LLPreviewAnimation* preview = (LLPreviewAnimation*)floater->mAnimPreview; - LLScrollListCtrl* list = floater->getChild("anim_list"); - LLUUID selection = list->getSelectedValue().asUUID(); - - preview->getDummyAvatar()->deactivateAllMotions(); - preview->getDummyAvatar()->startMotion(selection, 0.f); - preview->setZoom(2.0f); + mAnimPreview.getDummyAvatar()->deactivateAllMotions(); + mAnimPreview.getDummyAvatar()->startMotion(getChild("anim_list")->getCurrentID(), 0.f); + mAnimPreview.setZoom(2.0f); } //----------------------------------------------------------------------------- @@ -305,35 +239,35 @@ BOOL LLFloaterExploreAnimations::handleHover(S32 x, S32 y, MASK mask) { MASK local_mask = mask & ~MASK_ALT; - if (mAnimPreview && hasMouseCapture()) + if (hasMouseCapture()) { if (local_mask == MASK_PAN) { // pan here - mAnimPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); + mAnimPreview.pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); } else if (local_mask == MASK_ORBIT) { F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f; - mAnimPreview->rotate(yaw_radians, pitch_radians); + mAnimPreview.rotate(yaw_radians, pitch_radians); } else { F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f; - mAnimPreview->rotate(yaw_radians, 0.f); - mAnimPreview->zoom(zoom_amt); + mAnimPreview.rotate(yaw_radians, 0.f); + mAnimPreview.zoom(zoom_amt); } - mAnimPreview->requestUpdate(); + mAnimPreview.requestUpdate(); LLUI::setMousePositionLocal(this, mLastMouseX, mLastMouseY); } - if (!mPreviewRect.pointInRect(x, y) || !mAnimPreview) + if (!mPreviewRect.pointInRect(x, y)) { return LLFloater::handleHover(x, y, mask); } @@ -358,8 +292,8 @@ BOOL LLFloaterExploreAnimations::handleHover(S32 x, S32 y, MASK mask) //----------------------------------------------------------------------------- BOOL LLFloaterExploreAnimations::handleScrollWheel(S32 x, S32 y, S32 clicks) { - mAnimPreview->zoom((F32)clicks * -0.2f); - mAnimPreview->requestUpdate(); + mAnimPreview.zoom((F32)clicks * -0.2f); + mAnimPreview.requestUpdate(); return TRUE; } diff --git a/indra/newview/llfloaterexploreanimations.h b/indra/newview/llfloaterexploreanimations.h index 383b16e6d..95d97c050 100644 --- a/indra/newview/llfloaterexploreanimations.h +++ b/indra/newview/llfloaterexploreanimations.h @@ -2,16 +2,15 @@ #ifndef LL_LLFLOATEREXPLOREANIMATIONS_H #define LL_LLFLOATEREXPLOREANIMATIONS_H -#include "llfloater.h" #include "llfloaterbvhpreview.h" -#include "llviewerwindow.h" // gViewerWindow +#include "llinstancetracker.h" class LLAnimHistoryItem { public: - LLAnimHistoryItem(LLUUID assetid); + LLAnimHistoryItem(LLUUID assetid = LLUUID(), bool playing = true); + bool setPlaying(bool playing); - LLUUID mAvatarID; LLUUID mAssetID; bool mPlaying; F64 mTimeStarted; @@ -19,25 +18,20 @@ public: }; class LLFloaterExploreAnimations -: public LLFloater +: public LLFloater, public LLInstanceTracker { public: + static void show(); LLFloaterExploreAnimations(LLUUID avatarid); - BOOL postBuild(void); - void close(bool app_quitting); + BOOL postBuild(); void update(); - LLUUID mAvatarID; - LLPointer mAnimPreview; - private: virtual ~LLFloaterExploreAnimations(); - -// static stuff! public: - static void onSelectAnimation(LLUICtrl* ctrl, void* user_data); + void onSelectAnimation(); BOOL handleMouseDown(S32 x, S32 y, MASK mask); BOOL handleMouseUp(S32 x, S32 y, MASK mask); @@ -45,16 +39,17 @@ public: BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); void onMouseCaptureLost(); - static void startAnim(LLUUID avatarid, LLUUID assetid); - static void stopAnim(LLUUID avatarid, LLUUID assetid); +// static stuff! + static void processAnim(LLUUID avatarid, LLUUID assetid, bool playing); - static std::map< LLUUID, std::list< LLAnimHistoryItem* > > animHistory; - static LLFloaterExploreAnimations* sInstance; + static std::map< LLUUID, std::list< LLAnimHistoryItem > > animHistory; private: - static void handleHistoryChange(); + static void handleHistoryChange(LLUUID avatarid); protected: void draw(); + + LLPreviewAnimation mAnimPreview; LLRect mPreviewRect; S32 mLastMouseX; S32 mLastMouseY; diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 303b985c7..d85ea0f59 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -407,6 +407,12 @@ BOOL LLPanelFriends::postBuild() return TRUE; } +static const S32& friend_name_system() +{ + static const LLCachedControl name_system("FriendNameSystem", 0); + return name_system; +} + BOOL LLPanelFriends::addFriend(const LLUUID& agent_id) { LLAvatarTracker& at = LLAvatarTracker::instance(); @@ -417,7 +423,7 @@ BOOL LLPanelFriends::addFriend(const LLUUID& agent_id) bool isOnline = relationInfo->isOnline(); std::string fullname; - BOOL have_name = LLAvatarNameCache::getPNSName(agent_id, fullname); + bool have_name = LLAvatarNameCache::getPNSName(agent_id, fullname, friend_name_system()); if (!have_name) gCacheName->getFullName(agent_id, fullname); LLSD element; @@ -505,7 +511,7 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh bool isOnline = info->isOnline(); std::string fullname; - BOOL have_name = LLAvatarNameCache::getPNSName(agent_id, fullname); + bool have_name = LLAvatarNameCache::getPNSName(agent_id, fullname, friend_name_system()); if (!have_name) gCacheName->getFullName(agent_id, fullname); // Name of the status icon to use @@ -1083,7 +1089,7 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& rights, EGrantRevoke comm { LLSD args; std::string fullname; - if (LLAvatarNameCache::getPNSName(rights.begin()->first, fullname)) + if (LLAvatarNameCache::getPNSName(rights.begin()->first, fullname, friend_name_system())) args["NAME"] = fullname; if (command == GRANT) diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index 4a146a4e2..7e2ad97c3 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -174,9 +174,9 @@ void LLFloaterGesture::show() } // static -void LLFloaterGesture::toggleVisibility() +void LLFloaterGesture::toggleInstance(const LLSD&) { - if(sInstance && sInstance->getVisible()) + if (instanceVisible()) { sInstance->close(); } @@ -187,7 +187,7 @@ void LLFloaterGesture::toggleVisibility() } // static -bool LLFloaterGesture::instanceVisible() +bool LLFloaterGesture::instanceVisible(const LLSD&) { return sInstance && sInstance->getVisible(); } diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h index 0ded59467..40bb1de96 100644 --- a/indra/newview/llfloatergesture.h +++ b/indra/newview/llfloatergesture.h @@ -62,9 +62,9 @@ public: virtual BOOL postBuild(); static void show(); - static void toggleVisibility(); + static void toggleInstance(const LLSD& = LLSD()); static void refreshAll(); - static bool instanceVisible(); + static bool instanceVisible(const LLSD& = LLSD()); protected: // Reads from the gesture manager's list of active gestures diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 7c5801680..4c063e953 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -882,12 +882,6 @@ void LLPanelLandGeneral::setGroup(const LLUUID& group_id) // static void LLPanelLandGeneral::onClickBuyLand(void* data) { -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) - if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) - { - return; - } -// [/RLVa:KB] BOOL* for_group = (BOOL*)data; LLViewerParcelMgr::getInstance()->startBuyLand(*for_group); } diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp index df51918e3..a15bd9520 100644 --- a/indra/newview/llfloatermemleak.cpp +++ b/indra/newview/llfloatermemleak.cpp @@ -256,6 +256,10 @@ LLFloaterMemLeak* LLFloaterMemLeak::instance() void LLFloaterMemLeak::show(void*) { +#ifdef LL_RELEASE_FOR_DOWNLOAD + if (!gSavedSettings.getBOOL("QAMode")) + return; // Singu Note: We should probably tell them why this won't work before returning. +#endif instance()->open(); } diff --git a/indra/newview/llfloatermute.cpp b/indra/newview/llfloatermute.cpp index b4ea23ef4..cced63ab1 100644 --- a/indra/newview/llfloatermute.cpp +++ b/indra/newview/llfloatermute.cpp @@ -182,19 +182,12 @@ LLFloaterMute::LLFloaterMute(const LLSD& seed) : LLFloater(std::string("mute floater"), std::string("FloaterMuteRect3"), FLOATER_TITLE, RESIZE_YES, 220, 140, DRAG_ON_TOP, MINIMIZE_YES, CLOSE_YES) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_mute.xml", NULL, FALSE); } -// LLMuteListObserver callback interface implementation. -/* virtual */ void LLFloaterMute::onChange() -{ - refreshMuteList(); -} - BOOL LLFloaterMute::postBuild() { - childSetCommitCallback("mutes", onSelectName, this); + childSetCommitCallback("mutes", boost::bind(&LLFloaterMute::updateButtons, this)); childSetAction("Mute resident...", onClickPick, this); childSetAction("Mute object by name...", onClickMuteByName, this); childSetAction("Unmute", onClickRemove, this); @@ -233,17 +226,11 @@ void LLFloaterMute::refreshMuteList() mMuteDict.clear(); std::vector mutes = LLMuteList::getInstance()->getMutes(); - std::vector::iterator it; - U32 count = 0; - for (it = mutes.begin(); it != mutes.end(); ++it) + for (std::vector::iterator it = mutes.begin(); it != mutes.end(); ++it) { std::string display_name = it->mName; LLNameListCtrl::NameItem element; - LLUUID entry_id; - if(it->mType == LLMute::GROUP || it->mType == LLMute::AGENT) - entry_id = it->mID; - else - entry_id.generate(boost::lexical_cast( count++ )); + LLUUID entry_id = it->mID; mMuteDict.insert(std::make_pair(entry_id,*it)); element.value = entry_id; element.name = display_name; @@ -299,24 +286,7 @@ void LLFloaterMute::selectMute(const LLUUID& mute_id) //----------------------------------------------------------------------------- void LLFloaterMute::updateButtons() { - if (mMuteList->getFirstSelected()) - { - childSetEnabled("Unmute", TRUE); - } - else - { - childSetEnabled("Unmute", FALSE); - } -} - -//----------------------------------------------------------------------------- -// onSelectName() -//----------------------------------------------------------------------------- -void LLFloaterMute::onSelectName(LLUICtrl *caller, void *data) -{ - LLFloaterMute *floater = (LLFloaterMute*)data; - - floater->updateButtons(); + getChildView("Unmute")->setEnabled(!!mMuteList->getFirstSelected()); } //----------------------------------------------------------------------------- @@ -328,11 +298,11 @@ void LLFloaterMute::onClickRemove(void *data) S32 last_selected = floater->mMuteList->getFirstSelectedIndex(); bool removed = false; - const std::vector items = floater->mMuteList->getAllSelected(); - for(std::vector::const_iterator it = items.begin(); it != items.end(); ++it) + uuid_vec_t items = floater->mMuteList->getSelectedIDs(); + for(uuid_vec_t::const_iterator it = items.begin(); it != items.end(); ++it) { - std::map::iterator mute_it = floater->mMuteDict.find((*it)->getUUID()); - if(mute_it != floater->mMuteDict.end() && LLMuteList::getInstance()->remove(mute_it->second)) + std::map::iterator mute_it = floater->mMuteDict.find(*it); + if (mute_it != floater->mMuteDict.end() && LLMuteList::getInstance()->remove(mute_it->second)) { floater->mMuteDict.erase(mute_it); removed = true; diff --git a/indra/newview/llfloatermute.h b/indra/newview/llfloatermute.h index 8abb6afdf..1a04ae198 100644 --- a/indra/newview/llfloatermute.h +++ b/indra/newview/llfloatermute.h @@ -63,13 +63,12 @@ public: void updateButtons(); // LLMuteListObserver callback interface implementation. - /* virtual */ void onChange(); + /* virtual */ void onChange() { refreshMuteList(); } private: // UI callbacks static void onClickRemove(void *data); static void onClickPick(void *data); - static void onSelectName(LLUICtrl* caller, void *data); void onPickUser(const uuid_vec_t& ids, const std::vector& names); static void onClickMuteByName(void*); static void callbackMuteByName(const std::string& text, void*); diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp index 07b626de9..f98f9f006 100644 --- a/indra/newview/llfloateroutbox.cpp +++ b/indra/newview/llfloateroutbox.cpp @@ -111,7 +111,6 @@ LLFloaterOutbox::LLFloaterOutbox(const LLSD& key) , mInventoryText(NULL) , mInventoryTitle(NULL) , mOutboxId(LLUUID::null) - , mOutboxInventoryPanel(NULL) , mOutboxItemCount(0) , mOutboxTopLevelDropZone(NULL) // , mWindowShade(NULL) @@ -149,11 +148,10 @@ BOOL LLFloaterOutbox::postBuild() mImportButton = getChild("outbox_import_btn"); mImportButton->setCommitCallback(boost::bind(&LLFloaterOutbox::onImportButtonClicked, this)); - // // Set up the outbox inventory view - // - mOutboxInventoryPanel = getChild("panel_outbox_inventory"); - llassert(mOutboxInventoryPanel); + LLInventoryPanel* inventory_panel = getChild("panel_outbox_inventory"); + mOutboxInventoryPanel = inventory_panel->getInventoryPanelHandle(); + llassert(mOutboxInventoryPanel.get() != NULL); mOutboxTopLevelDropZone = getChild("outbox_generic_drag_target"); @@ -166,6 +164,17 @@ BOOL LLFloaterOutbox::postBuild() return TRUE; } +void LLFloaterOutbox::cleanOutbox() +{ + // Note: we cannot delete the mOutboxInventoryPanel as that point + // as this is called through callback observers of the panel itself. + // Doing so would crash rapidly. + + // Invalidate the outbox data + mOutboxId.setNull(); + mOutboxItemCount = 0; +} + void LLFloaterOutbox::onClose(bool app_quitting) { /* @@ -228,14 +237,26 @@ void LLFloaterOutbox::setupOutbox() } // We are a merchant. Get the outbox, create it if needs be. - mOutboxId = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true, false); - if (mOutboxId.isNull()) + LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true); + if (outbox_id.isNull()) { - // We should never get there unles inventory fails badly + // We should never get there unless inventory fails badly llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl; return; } + // Consolidate Merchant Outbox + // We shouldn't have to do that but with a client/server system relying on a "well known folder" convention, things get messy and conventions get broken down eventually + gInventory.consolidateForType(outbox_id, LLFolderType::FT_OUTBOX); + + if (outbox_id == mOutboxId) + { + + llwarns << "Inventory warning: Merchant outbox already set" << llendl; + return; + } + mOutboxId = outbox_id; + // No longer need to observe new category creation if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver)) { @@ -245,25 +266,28 @@ void LLFloaterOutbox::setupOutbox() } llassert(!mCategoryAddedObserver); - // Create observer for outbox modifications - if (mCategoriesObserver == NULL) + // Create observer for outbox modifications : clear the old one and create a new one + if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) { - mCategoriesObserver = new LLInventoryCategoriesObserver(); - gInventory.addObserver(mCategoriesObserver); - mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this)); + gInventory.removeObserver(mCategoriesObserver); + delete mCategoriesObserver; } + mCategoriesObserver = new LLInventoryCategoriesObserver(); + gInventory.addObserver(mCategoriesObserver); + mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this)); llassert(mCategoriesObserver); // Set up the outbox inventory view // Singu Note: we handle this in postBuild, grabbing the panel from the built xml. + LLInventoryPanel* inventory_panel = mOutboxInventoryPanel.get(); // Reshape the inventory to the proper size LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect(); - mOutboxInventoryPanel->setShape(inventory_placeholder_rect); + inventory_panel->setShape(inventory_placeholder_rect); // Set the sort order newest to oldest - mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME); - mOutboxInventoryPanel->getFilter()->markDefault(); + inventory_panel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME); + inventory_panel->getFilter()->markDefault(); // Get the content of the outbox fetchOutboxContents(); @@ -274,13 +298,15 @@ void LLFloaterOutbox::initializeMarketPlace() // // Initialize the marketplace import API // - LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance(); - importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2)); - importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1)); - importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2)); - importer.initialize(); + if (!importer.isInitialized()) + { + importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2)); + importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1)); + importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2)); + importer.initialize(); + } } void LLFloaterOutbox::setStatusString(const std::string& statusString) @@ -292,18 +318,26 @@ void LLFloaterOutbox::setStatusString(const std::string& statusString) void LLFloaterOutbox::updateFolderCount() { - S32 item_count = 0; - - if (mOutboxId.notNull()) + if (mOutboxInventoryPanel.get() && mOutboxId.notNull()) { - LLInventoryModel::cat_array_t * cats; - LLInventoryModel::item_array_t * items; - gInventory.getDirectDescendentsOf(mOutboxId, cats, items); + S32 item_count = 0; - item_count = cats->count() + items->count(); + if (mOutboxId.notNull()) + { + LLInventoryModel::cat_array_t * cats; + LLInventoryModel::item_array_t * items; + gInventory.getDirectDescendentsOf(mOutboxId, cats, items); + + item_count = cats->count() + items->count(); + } + + mOutboxItemCount = item_count; + } + else + { + // If there's no outbox, the number of items in it should be set to 0 for consistency + mOutboxItemCount = 0; } - - mOutboxItemCount = item_count; if (!mImportBusy) { @@ -313,7 +347,7 @@ void LLFloaterOutbox::updateFolderCount() void LLFloaterOutbox::updateFolderCountStatus() { - if (mOutboxInventoryPanel) + if (mOutboxInventoryPanel.get() && mOutboxId.notNull()) { switch (mOutboxItemCount) { @@ -339,18 +373,19 @@ void LLFloaterOutbox::updateView() { //updateView() is called twice the first time. updateFolderCount(); + LLInventoryPanel* panel = mOutboxInventoryPanel.get(); if (mOutboxItemCount > 0) { - mOutboxInventoryPanel->setVisible(TRUE); + panel->setVisible(TRUE); mInventoryPlaceholder->setVisible(FALSE); mOutboxTopLevelDropZone->setVisible(TRUE); } else { - if (mOutboxInventoryPanel) + if (panel) { - mOutboxInventoryPanel->setVisible(FALSE); + panel->setVisible(FALSE); } // Show the drop zone if there is an outbox folder @@ -372,6 +407,11 @@ void LLFloaterOutbox::updateView() if (mOutboxId.notNull()) { + // Does the outbox needs recreation? + if ((mOutboxInventoryPanel.get() == NULL) || !gInventory.getCategory(mOutboxId)) + { + setupOutbox(); + } // "Outbox is empty!" message strings outbox_text = LLTrans::getString("InventoryOutboxNoItems"); subs_link = "[MARKETPLACE_DASHBOARD_URL]"; @@ -436,9 +476,10 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EAcceptance* accept, std::string& tooltip_msg) { - if ((mOutboxInventoryPanel == NULL) || + if ((mOutboxInventoryPanel.get() == NULL) || //(mWindowShade && mWindowShade->isShown()) || - LLMarketplaceInventoryImporter::getInstance()->isImportInProgress()) + LLMarketplaceInventoryImporter::getInstance()->isImportInProgress() || + mOutboxId.isNull()) { return FALSE; } @@ -449,15 +490,16 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, // Determine if the mouse is inside the inventory panel itself or just within the floater bool pointInInventoryPanel = false; bool pointInInventoryPanelChild = false; - LLFolderView * root_folder = mOutboxInventoryPanel->getRootFolder(); - if (mOutboxInventoryPanel->getVisible()) + LLInventoryPanel* panel = mOutboxInventoryPanel.get(); + LLFolderView * root_folder = panel->getRootFolder(); + if (panel->getVisible()) { S32 inv_x, inv_y; - localPointToOtherView(x, y, &inv_x, &inv_y, mOutboxInventoryPanel); + localPointToOtherView(x, y, &inv_x, &inv_y, panel); - pointInInventoryPanel = mOutboxInventoryPanel->getRect().pointInRect(inv_x, inv_y); + pointInInventoryPanel = panel->getRect().pointInRect(inv_x, inv_y); - LLView * inventory_panel_child_at_point = mOutboxInventoryPanel->childFromPoint(inv_x, inv_y, true); + LLView * inventory_panel_child_at_point = panel->childFromPoint(inv_x, inv_y, true); pointInInventoryPanelChild = (inventory_panel_child_at_point != root_folder); } @@ -497,23 +539,26 @@ void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask) */ void LLFloaterOutbox::onImportButtonClicked() { - mOutboxInventoryPanel->clearSelection(); + if (mOutboxInventoryPanel.get()) + { + mOutboxInventoryPanel.get()->clearSelection(); + } mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport(); } void LLFloaterOutbox::onOutboxChanged() { - llassert(!mOutboxId.isNull()); - - if (mOutboxInventoryPanel) + LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId); + if (mOutboxId.notNull() && category) { - mOutboxInventoryPanel->requestSort(); + fetchOutboxContents(); + updateView(); + } + else + { + cleanOutbox(); } - - fetchOutboxContents(); - - updateView(); } void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content) diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h index 9f9222cb6..61a11c50d 100644 --- a/indra/newview/llfloateroutbox.h +++ b/indra/newview/llfloateroutbox.h @@ -72,6 +72,7 @@ public: protected: void setupOutbox(); + void cleanOutbox(); void fetchOutboxContents(); void importReportResults(U32 status, const LLSD& content); @@ -106,7 +107,7 @@ private: LLTextBox * mInventoryTitle; LLUUID mOutboxId; - LLInventoryPanel * mOutboxInventoryPanel; + LLHandle mOutboxInventoryPanel; U32 mOutboxItemCount; LLPanel * mOutboxTopLevelDropZone; diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index d41cbf17a..31cf83c4a 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -43,6 +43,7 @@ #include "llfontgl.h" #include "llimagej2c.h" #include "llinventory.h" +#include "llmenugl.h" #include "llnotificationsutil.h" #include "llstring.h" #include "llsys.h" @@ -462,6 +463,8 @@ void LLFloaterReporter::showFromMenu(EReportType report_type) return; } + // Prevent menu from appearing in screen shot. + LLMenuGL::sMenuContainer->hideMenus(); LLFloaterReporter* f = getInstance(); if (f) { diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 062ada4ba..a690b42e5 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -829,7 +829,18 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) childSetVisible("link_num_obj_count", !land_visible); childSetVisible("prim_count", !land_visible); - mTab->setVisible(!land_visible); + static const LLCachedControl mini("LiruMiniBuildFloater"); + mTab->setVisible(!mini && !land_visible); + getChildView("mini_button")->setVisible(!land_visible); + bool small = mini && !land_visible; + const S32 cur_height = getRect().getHeight(); + static const S32 full_height = cur_height; + if (small == (cur_height == full_height)) + { + S32 new_height = small ? full_height - mTab->getRect().getHeight() + 8 : full_height; + translate(0, cur_height - new_height); + reshape(getRect().getWidth(), new_height); + } mPanelLandInfo->setVisible(land_visible); } diff --git a/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp index f444a7cbc..43507d0fd 100644 --- a/indra/newview/llfloaterwater.cpp +++ b/indra/newview/llfloaterwater.cpp @@ -48,6 +48,7 @@ #include "llagent.h" #include "llwaterparammanager.h" #include "llwaterparamset.h" +#include "rlvactions.h" #undef max // Fixes a Windows compiler error @@ -284,6 +285,7 @@ LLFloaterWater* LLFloaterWater::instance() } void LLFloaterWater::show() { + if (RlvActions::hasBehaviour(RLV_BHVR_SETENV)) return; if (!sWaterMenu) { LLFloaterWater* water = instance(); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 4b6142a39..7494e9b90 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -176,7 +176,7 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item) // Default constructor LLFolderView::LLFolderView( const std::string& name, - const LLRect& rect, const LLUUID& source_id, LLPanel *parent_view, LLFolderViewEventListener* listener ) : + const LLRect& rect, const LLUUID& source_id, LLPanel* parent_panel, LLFolderViewEventListener* listener ) : #if LL_WINDOWS #pragma warning( push ) #pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list @@ -208,12 +208,13 @@ LLFolderView::LLFolderView( const std::string& name, mSignalSelectCallback(0), mMinWidth(0), mDragAndDropThisFrame(FALSE), - mParentPanel(parent_view), mUseEllipses(FALSE), mDraggingOverItem(NULL), mStatusTextBox(NULL), mSearchType(1) { + LLPanel* panel = parent_panel; + mParentPanel = panel->getHandle(); mRoot = this; mShowLoadStatus = TRUE; @@ -256,7 +257,7 @@ LLFolderView::LLFolderView( const std::string& name, mStatusTextBox->setVPad(STATUS_TEXT_VPAD); mStatusTextBox->setFollows(FOLLOWS_LEFT|FOLLOWS_TOP); // make the popup menu available - LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_inventory.xml", parent_view); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_inventory.xml", parent_panel); if (!menu) { menu = new LLMenuGL(LLStringUtil::null); @@ -645,7 +646,7 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem, if( selection && take_keyboard_focus) { - mParentPanel->setFocus(TRUE); + mParentPanel.get()->setFocus(TRUE); } // clear selection down here because change of keyboard focus can potentially @@ -1110,11 +1111,11 @@ void LLFolderView::removeSelectedItems( void ) // change selection on successful delete if (new_selection) { - setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus()); + setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel.get()->hasFocus()); } else { - setSelectionFromRoot(NULL, mParentPanel->hasFocus()); + setSelectionFromRoot(NULL, mParentPanel.get()->hasFocus()); } } } @@ -1140,11 +1141,11 @@ void LLFolderView::removeSelectedItems( void ) } if (new_selection) { - setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus()); + setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel.get()->hasFocus()); } else { - setSelectionFromRoot(NULL, mParentPanel->hasFocus()); + setSelectionFromRoot(NULL, mParentPanel.get()->hasFocus()); } for(S32 i = 0; i < count; ++i) @@ -1715,7 +1716,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) break; } - if (!handled && mParentPanel->hasFocus()) + if (!handled && mParentPanel.get()->hasFocus()) { if (key == KEY_BACKSPACE) { @@ -1747,7 +1748,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char) } BOOL handled = FALSE; - if (mParentPanel->hasFocus()) + if (mParentPanel.get()->hasFocus()) { // SL-51858: Key presses are not being passed to the Popup menu. // A proper fix is non-trivial so instead just close the menu. @@ -1804,7 +1805,7 @@ BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask ) mKeyboardSelection = FALSE; mSearchString.clear(); - mParentPanel->setFocus(TRUE); + mParentPanel.get()->setFocus(TRUE); LLEditMenuHandler::gEditMenuHandler = this; @@ -1887,7 +1888,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) { // all user operations move keyboard focus to inventory // this way, we know when to stop auto-updating a search - mParentPanel->setFocus(TRUE); + mParentPanel.get()->setFocus(TRUE); BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; S32 count = mSelectedItems.size(); @@ -2157,7 +2158,7 @@ void LLFolderView::doIdle() { // If this is associated with the user's inventory, don't do anything // until that inventory is loaded up. - const LLInventoryPanel *inventory_panel = dynamic_cast(mParentPanel); + const LLInventoryPanel *inventory_panel = dynamic_cast(mParentPanel.get()); if (inventory_panel && !inventory_panel->getIsViewsInitialized()) { return; diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index f441e8995..bf89339de 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -244,7 +244,7 @@ public: BOOL getDebugFilters() { return mDebugFilters; } - LLPanel* getParentPanel() { return mParentPanel; } + LLPanel* getParentPanel() { return mParentPanel.get(); } // DEBUG only void dumpSelectionInformation(); @@ -253,6 +253,9 @@ public: bool useLabelSuffix() { return mUseLabelSuffix; } void updateMenu(); + // Note: We may eventually have to move that method up the hierarchy to LLFolderViewItem. + LLHandle getHandle() const { return getDerivedHandle(); } + private: void updateMenuOptions(LLMenuGL* menu); void updateRenamerPosition(); @@ -317,7 +320,7 @@ protected: LLUUID mSelectThisID; // if non null, select this item - LLPanel* mParentPanel; + LLHandle mParentPanel; /** * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll. diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index c0f37fe5f..f94872837 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -170,7 +170,7 @@ void LLGestureMgr::activateGestures(LLViewerInventoryItem::item_array_t& items) continue; } else - { // Make gesture active and persistent through login sessions. -spatters 07-12-06 + { // Make gesture active and persistent through login sessions. -Aura 07-12-06 activateGesture(item->getUUID()); } diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 60a4a6caf..da27ac259 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -41,8 +41,10 @@ #include "llviewermessage.h" #include "groupchatlistener.h" #include "hippolimits.h" // for getMaxAgentGroups -// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) +// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0) #include "llslurl.h" +#include "rlvactions.h" +#include "rlvcommon.h" #include "rlvhandler.h" // [/RLVa:KB] @@ -142,8 +144,8 @@ void LLGroupActions::startCall(const LLUUID& group_id) return; } -// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h - if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(group_id)) && (!gIMMgr->hasSession(group_id)) ) +// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9) + if ( (!RlvActions::canStartIM(group_id)) && (!RlvActions::hasOpenGroupSession(group_id)) ) { make_ui_sound("UISndInvalidOp"); RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("group", group_id, "about").getSLURLString())); @@ -398,8 +400,8 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id) { if (group_id.isNull()) return LLUUID::null; -// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h - if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(group_id)) && (!gIMMgr->hasSession(group_id)) ) +// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9) + if ( (!RlvActions::canStartIM(group_id)) && (!RlvActions::hasOpenGroupSession(group_id)) ) { make_ui_sound("UISndInvalidOp"); RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("group", group_id, "about").getSLURLString())); diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index eaef2534b..cc42294fd 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -2049,7 +2049,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) for ( ; member_iter_start != member_iter_end; ++member_iter_start) { // Reset defaults - online_status = "unknown"; + online_status = LLTrans::getString("group_member_status_unknown"); title = titles[0].asString(); contribution = 0; member_powers = default_powers; diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index eef650101..9f6acb60b 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -611,8 +611,9 @@ void LLHUDEffectLookAt::update() { if (calcTargetPosition()) { - LLMotion* head_motion = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->findMotion(ANIM_AGENT_HEAD_ROT); - if (!head_motion || head_motion->isStopped()) + //LLMotion* head_motion = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->findMotion(ANIM_AGENT_HEAD_ROT); + //if (!head_motion || head_motion->isStopped()) + // singu: startMotion does basically the same as the above two lines... it starts it, unless it was already started. { ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->startMotion(ANIM_AGENT_HEAD_ROT); } diff --git a/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp index cb9a2c1d3..15872a0db 100644 --- a/indra/newview/llhudmanager.cpp +++ b/indra/newview/llhudmanager.cpp @@ -80,14 +80,33 @@ void LLHUDManager::updateEffects() void LLHUDManager::sendEffects() { + static LLCachedControl disable_lookat_effect(gSavedSettings, "PrivateLookAt", false); + static LLCachedControl disable_pointat_effect(gSavedSettings, "DisablePointAtAndBeam", false); + static LLCachedControl broadcast_viewer_effects(gSavedSettings, "BroadcastViewerEffects", true); - if(!gSavedSettings.getBOOL("BroadcastViewerEffects")) - return; - S32 i; for (i = 0; i < mHUDEffects.count(); i++) { LLHUDEffect *hep = mHUDEffects[i]; + if (hep->mType == LLHUDObject::LL_HUD_EFFECT_LOOKAT) + { + if (disable_lookat_effect) + { + continue; + } + } + else if (hep->mType == LLHUDObject::LL_HUD_EFFECT_POINTAT || + hep->mType == LLHUDObject::LL_HUD_EFFECT_BEAM) + { + if (disable_pointat_effect) + { + continue; + } + } + else if (!broadcast_viewer_effects) + { + continue; + } if (hep->isDead()) { llwarns << "Trying to send dead effect!" << llendl; diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index abae430f6..9603208c7 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -35,6 +35,7 @@ #include "ascentkeyword.h" #include "llagent.h" +#include "llautoreplace.h" #include "llavataractions.h" #include "llavatarnamecache.h" #include "llbutton.h" @@ -60,10 +61,11 @@ #include "llviewerwindow.h" #include "llvoicechannel.h" -#include "boost/algorithm/string.hpp" +#include -// [RLVa:KB] -#include "rlvhandler.h" +// [RLVa:KB] - Checked: 2013-05-10 (RLVa-1.4.9) +#include "rlvactions.h" +#include "rlvcommon.h" // [/RLVa:KB] class AIHTTPTimeoutPolicy; @@ -320,6 +322,7 @@ LLFloaterIMPanel::LLFloaterIMPanel( case IM_SESSION_GROUP_START: case IM_SESSION_INVITE: case IM_SESSION_CONFERENCE_START: + mCommitCallbackRegistrar.add("FlipDing", boost::bind(boost::lambda::_1 = !boost::lambda::_1, boost::ref(mDing))); // determine whether it is group or conference session if (gAgent.isInGroup(mSessionUUID)) { @@ -441,12 +444,12 @@ LLFloaterIMPanel::~LLFloaterIMPanel() // virtual void LLFloaterIMPanel::changed(U32 mask) { - if (mask & REMOVE|ADD) // Fix remove/add friend choices + if (mask & (REMOVE|ADD)) // Fix remove/add friend choices rebuildDynamics(getChild("instant_message_flyout")); /* Singu TODO: Chat UI - Online icons? if (mask & ONLINE) // Show online icon here - else if (mask & NONE) + else // Show offline icon here */ } @@ -464,6 +467,7 @@ BOOL LLFloaterIMPanel::postBuild() LLAvatarNameCache::get(mOtherParticipantUUID, boost::bind(&LLFloaterIMPanel::onAvatarNameLookup, this, _2)); mInputEditor = getChild("chat_editor"); + mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5)); mInputEditor->setFocusReceivedCallback( boost::bind(&LLFloaterIMPanel::onInputEditorFocusReceived, this) ); mFocusLostSignal = mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMPanel::setTyping, this, false)); mInputEditor->setKeystrokeCallback( boost::bind(&LLFloaterIMPanel::onInputEditorKeystroke, this, _1) ); @@ -963,9 +967,11 @@ void LLFloaterIMPanel::addDynamics(LLComboBox* flyout) //flyout->add(LLAvatarActions::isBlocked(mOtherParticipantUUID) ? getString("unmute") : getString("mute"), 9); } +void copy_profile_uri(const LLUUID& id, bool group = false); + void LLFloaterIMPanel::onFlyoutCommit(LLComboBox* flyout, const LLSD& value) { - if (value.isUndefined()) + if (value.isUndefined() || value.asInteger() == 0) { LLAvatarActions::showProfile(mOtherParticipantUUID); return; @@ -977,6 +983,7 @@ void LLFloaterIMPanel::onFlyoutCommit(LLComboBox* flyout, const LLSD& value) else if (option == 3) LLAvatarActions::teleportRequest(mOtherParticipantUUID); else if (option == 4) LLAvatarActions::pay(mOtherParticipantUUID); else if (option == 5) LLAvatarActions::inviteToGroup(mOtherParticipantUUID); + else if (option == -1) copy_profile_uri(mOtherParticipantUUID); else if (option >= 6) // Options that use dynamic items { // First remove them all @@ -1142,6 +1149,7 @@ void deliver_message(const std::string& utf8_text, bool convert_roleplay_text(std::string& text); // Returns true if text is an action +// Singu Note: LLFloaterIMSession::sendMsg void LLFloaterIMPanel::onSendMsg() { if (!gAgent.isGodlike() @@ -1164,17 +1172,18 @@ void LLFloaterIMPanel::onSendMsg() bool action = convert_roleplay_text(utf8_text); if (!action && mRPMode) utf8_text = "((" + utf8_text + "))"; -// [RLVa:KB] - Checked: 2011-09-17 (RLVa-1.1.4b) | Modified: RLVa-1.1.4b - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) ) + +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0) + if ( (RlvActions::hasBehaviour(RLV_BHVR_SENDIM)) || (RlvActions::hasBehaviour(RLV_BHVR_SENDIMTO)) ) { bool fRlvFilter = false; switch (mSessionType) { case P2P_SESSION: // One-on-one IM - fRlvFilter = !gRlvHandler.canSendIM(mOtherParticipantUUID); + fRlvFilter = !RlvActions::canSendIM(mOtherParticipantUUID); break; case GROUP_SESSION: // Group chat - fRlvFilter = !gRlvHandler.canSendIM(mSessionUUID); + fRlvFilter = !RlvActions::canSendIM(mSessionUUID); break; case ADHOC_SESSION: // Conference chat: allow if all participants can be sent an IM { @@ -1190,7 +1199,7 @@ void LLFloaterIMPanel::onSendMsg() itSpeaker != speakers.end(); ++itSpeaker) { const LLSpeaker* pSpeaker = *itSpeaker; - if ( (gAgentID != pSpeaker->mID) && (!gRlvHandler.canSendIM(pSpeaker->mID)) ) + if ( (gAgentID != pSpeaker->mID) && (!RlvActions::canSendIM(pSpeaker->mID)) ) { fRlvFilter = true; break; @@ -1204,7 +1213,9 @@ void LLFloaterIMPanel::onSendMsg() } if (fRlvFilter) + { utf8_text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM); + } } // [/RLVa:KB] diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 48ae523b7..4a06dd1c8 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -55,8 +55,9 @@ #include "llvoavatar.h" // For mIdleTimer reset #include "llviewerregion.h" -// [RLVa:KB] -#include "rlvhandler.h" +// [RLVa:KB] - Checked: 2013-05-10 (RLVa-1.4.9) +#include "rlvactions.h" +#include "rlvcommon.h" // [/RLVa:KB] class AIHTTPTimeoutPolicy; @@ -82,11 +83,11 @@ LLColor4 agent_chat_color(const LLUUID& id, const std::string& name, bool local_ return gSavedSettings.getColor4("UserChatColor"); static const LLCachedControl color_linden_chat("ColorLindenChat"); - if (color_linden_chat && LLMuteList::getInstance()->isLinden(name)) + if (color_linden_chat && LLMuteList::getInstance()->isLinden(id)) return gSavedSettings.getColor4("AscentLindenColor"); // [RLVa:LF] Chat colors would identify names, don't use them in local chat if restricted - if (local_chat && rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) + if (local_chat && RlvActions::hasBehaviour(RLV_BHVR_SHOWNAMES)) return gSavedSettings.getColor4("AgentChatColor"); static const LLCachedControl color_friend_chat("ColorFriendChat"); @@ -104,11 +105,6 @@ LLColor4 agent_chat_color(const LLUUID& id, const std::string& name, bool local_ return local_chat ? gSavedSettings.getColor4("AgentChatColor") : gSavedSettings.getColor("IMChatColor"); } -// returns true if a should appear before b -//static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b ) -//{ -// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0); -//} class LLViewerChatterBoxInvitationAcceptResponder : public LLHTTPClient::ResponderWithResult { @@ -1492,15 +1488,15 @@ public: } bool group = gAgent.isInGroup(session_id); -// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIMFROM)) ) +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0) + if ( (RlvActions::hasBehaviour(RLV_BHVR_RECVIM)) || (RlvActions::hasBehaviour(RLV_BHVR_RECVIMFROM)) ) { - if (group) // Group chat: don't accept the invite if not an exception + if (group) { - if (!gRlvHandler.canReceiveIM(session_id)) + if (!RlvActions::canReceiveIM(session_id)) return; } - else if (!gRlvHandler.canReceiveIM(from_id)) // Conference chat: don't block; censor if not an exception + else if (!RlvActions::canReceiveIM(from_id)) { message = RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); } diff --git a/indra/newview/llinventoryactions.cpp b/indra/newview/llinventoryactions.cpp index a02de1998..bb69789b5 100644 --- a/indra/newview/llinventoryactions.cpp +++ b/indra/newview/llinventoryactions.cpp @@ -49,6 +49,10 @@ #include "lltrans.h" #include "llvoavatarself.h" #include "llnotifications.h" +// [RLVa:KB] - Checked: 2013-05-08 (RLVa-1.4.9) +#include "rlvactions.h" +#include "rlvcommon.h" +// [/RLVa:KB] extern LLUUID gAgentID; @@ -455,6 +459,10 @@ class LLBeginIMSession : public inventory_panel_listener_t LLDynamicArray members; EInstantMessage type = IM_SESSION_CONFERENCE_START; +// [RLVa:KB] - Checked: 2013-05-08 (RLVa-1.4.9) + bool fRlvCanStartIM = true; +// [/RLVa:KB] + for (std::set::const_iterator iter = selected_items.begin(); iter != selected_items.end(); iter++) { @@ -493,6 +501,9 @@ class LLBeginIMSession : public inventory_panel_listener_t id = item_array.get(i)->getCreatorUUID(); if(at.isBuddyOnline(id)) { +// [RLVa:KB] - Checked: 2013-05-08 (RLVa-1.4.9) + fRlvCanStartIM &= RlvActions::canStartIM(id); +// [RLVa:KB] members.put(id); } } @@ -515,6 +526,9 @@ class LLBeginIMSession : public inventory_panel_listener_t if(at.isBuddyOnline(id)) { +// [RLVa:KB] - Checked: 2013-05-08 (RLVa-1.4.9) + fRlvCanStartIM &= RlvActions::canStartIM(id); +// [RLVa:KB] members.put(id); } } @@ -526,6 +540,15 @@ class LLBeginIMSession : public inventory_panel_listener_t // the session_id is randomly generated UUID which will be replaced later // with a server side generated number +// [RLVa:KB] - Checked: 2013-05-08 (RLVa-1.4.9) + if (!fRlvCanStartIM) + { + make_ui_sound("UISndIvalidOp"); + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF); + return true; + } +// [/RLVa:KB] + if (name.empty()) { name = llformat("Session %d", session_num++); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 3195d87ac..323263d76 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1766,7 +1766,8 @@ BOOL LLItemBridge::removeItem() cat_array, item_array, LLInventoryModel::INCLUDE_TRASH, - is_linked_item_match); + is_linked_item_match, + true); const U32 num_links = cat_array.size() + item_array.size(); if (num_links > 0) @@ -3254,7 +3255,8 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, - is_type); + is_type, + true); return ((item_array.count() > 0) ? TRUE : FALSE ); } @@ -3337,7 +3339,7 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) } } - //Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06 + //Added by aura to force inventory pull on right-click to display folder options correctly. 07-17-06 mCallingCards = mWearables = FALSE; LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); @@ -3542,6 +3544,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, // DAD_LINK type might mean one of two asset types: AT_LINK or AT_LINK_FOLDER. // If we have an item of AT_LINK_FOLDER type we should process the linked // category being dragged or dropped into folder. + /* Note: No, we shouldn't, this behavior is misleading, just copy the link as usual. if (inv_item && LLAssetType::AT_LINK_FOLDER == inv_item->getActualType()) { LLInventoryCategory* linked_category = gInventory.getCategory(inv_item->getLinkedUUID()); @@ -3551,6 +3554,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, } } else + */ { accept = dragItemIntoFolder(inv_item, drop); } @@ -5595,7 +5599,8 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_ cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, - is_wearable); + is_wearable, + true); S32 i; S32 wearable_count = item_array.count(); @@ -5606,7 +5611,8 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_ obj_cat_array, obj_item_array, LLInventoryModel::EXCLUDE_TRASH, - is_object); + is_object, + true); S32 obj_count = obj_item_array.count(); // Find all gestures in this folder @@ -5617,7 +5623,8 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_ gest_cat_array, gest_item_array, LLInventoryModel::EXCLUDE_TRASH, - is_gesture); + is_gesture, + true); S32 gest_count = gest_item_array.count(); if (wearable_count > 0) //Loop through wearables. If worn, remove. diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e36753bfe..4d4e7ce8f 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -405,16 +405,75 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id) mItemLock[cat_id] = false; } +void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::EType type) +{ + // Make a list of folders that are not "main_id" and are of "type" + std::vector folder_ids; + for (cat_map_t::iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit) + { + LLViewerInventoryCategory* cat = cit->second; + if ((cat->getPreferredType() == type) && (cat->getUUID() != main_id)) + { + folder_ids.push_back(cat->getUUID()); + } + } + + // Iterate through those folders + for (std::vector::iterator folder_ids_it = folder_ids.begin(); folder_ids_it != folder_ids.end(); ++folder_ids_it) + { + LLUUID folder_id = (*folder_ids_it); + + // Get the content of this folder + cat_array_t* cats; + item_array_t* items; + getDirectDescendentsOf(folder_id, cats, items); + + // Move all items to the main folder + // Note : we get the list of UUIDs and iterate on them instead of iterating directly on item_array_t + // elements. This is because moving elements modify the maps and, consequently, invalidate iterators on them. + // This "gather and iterate" method is verbose but resilient. + std::vector list_uuids; + for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it) + { + list_uuids.push_back((*it)->getUUID()); + } + for (std::vector::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it) + { + LLViewerInventoryItem* item = getItem(*it); + changeItemParent(item, main_id, TRUE); + } + + // Move all folders to the main folder + list_uuids.clear(); + for (cat_array_t::const_iterator it = cats->begin(); it != cats->end(); ++it) + { + list_uuids.push_back((*it)->getUUID()); + } + for (std::vector::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it) + { + LLViewerInventoryCategory* cat = getCategory(*it); + changeCategoryParent(cat, main_id, TRUE); + } + + // Purge the emptied folder + // Note: we'd like to use purgeObject() but it doesn't cleanly eliminate the folder + // which leads to issues further down the road when the folder is found again + //purgeObject(folder_id); + // We remove the folder and empty the trash instead which seems to work + removeCategory(folder_id); + gInventory.emptyFolderType("", LLFolderType::FT_TRASH); + } +} + // findCategoryUUIDForType() returns the uuid of the category that // specifies 'type' as what it defaults to containing. The category is // not necessarily only for that type. *NOTE: This will create a new // inventory category on the fly if one does not exist. -const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, - bool create_folder, +const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, + bool create_folder, bool find_in_library) { LLUUID rv = LLUUID::null; - const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID(); if(LLFolderType::FT_ROOT_INVENTORY == preferred_type) { @@ -429,7 +488,7 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe S32 count = cats->count(); for(S32 i = 0; i < count; ++i) { - if(cats->get(i)->getPreferredType() == preferred_type) + if (cats->get(i)->getPreferredType() == preferred_type) { rv = cats->get(i)->getUUID(); break; @@ -611,7 +670,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, return id; } -// Starting with the object specified, add it's descendents to the +// Starting with the object specified, add its descendents to the // array provided, but do not add the inventory object specified by // id. There is no guaranteed order. Neither array will be erased // before adding objects to it. Do not store a copy of the pointers @@ -1038,7 +1097,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat) new_cat->copyViewerCategory(cat); addCategory(new_cat); - // make sure this category is correctly referenced by it's parent. + // make sure this category is correctly referenced by its parent. cat_array_t* cat_array; cat_array = getUnlockedCatArray(cat->getParentUUID()); if(cat_array) @@ -1247,12 +1306,6 @@ void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id) // folders, items, etc in a fairly efficient manner. void LLInventoryModel::purgeDescendentsOf(const LLUUID& id) { - EHasChildren children = categoryHasChildren(id); - if(children == CHILDREN_NO) - { - llinfos << "Not purging descendents of " << id << llendl; - return; - } LLPointer cat = getCategory(id); if (cat.notNull()) { @@ -1263,7 +1316,7 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id) << " iterate and purge non hidden items" << llendl; cat_array_t* categories; item_array_t* items; - // Get the list of direct descendants in tha categoy passed as argument + // Get the list of direct descendants in that category passed as argument getDirectDescendentsOf(id, categories, items); std::vector list_uuids; // Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently) diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index a73a1fee6..09a85ba5d 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -275,6 +275,11 @@ public: LLViewerInventoryItem* getLinkedItem(const LLUUID& object_id) const; LLUUID findCategoryByName(std::string name); + + // Copy content of all folders of type "type" into folder "id" and delete/purge the empty folders + // Note : This method has been designed for FT_OUTBOX (aka Merchant Outbox) but can be used for other categories + void consolidateForType(const LLUUID& id, LLFolderType::EType type); + private: mutable LLPointer mLastItem; // cache recent lookups diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 9db175ec2..1cd71cf89 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -690,15 +690,24 @@ void LLInventoryCategoriesObserver::changed(U32 mask) if (!mCategoryMap.size()) return; + std::vector deleted_categories_ids; + for (category_map_t::iterator iter = mCategoryMap.begin(); iter != mCategoryMap.end(); ++iter) { const LLUUID& cat_id = (*iter).first; + LLCategoryData& cat_data = (*iter).second; LLViewerInventoryCategory* category = gInventory.getCategory(cat_id); if (!category) + { + llwarns << "Category : Category id = " << cat_id << " disappeared" << llendl; + cat_data.mCallback(); + // Keep track of those deleted categories so we can remove them + deleted_categories_ids.push_back(cat_id); continue; + } const S32 version = category->getVersion(); const S32 expected_num_descendents = category->getDescendentCount(); @@ -726,8 +735,6 @@ void LLInventoryCategoriesObserver::changed(U32 mask) const S32 current_num_known_descendents = cats->count() + items->count(); - LLCategoryData& cat_data = (*iter).second; - bool cat_changed = false; // If category version or descendents count has changed @@ -757,6 +764,12 @@ void LLInventoryCategoriesObserver::changed(U32 mask) if (cat_changed) cat_data.mCallback(); } + + // Remove deleed categories from the list + for (std::vector::iterator deleted_id = deleted_categories_ids.begin(); deleted_id != deleted_categories_ids.end(); ++deleted_id) + { + removeCategory(*deleted_id); + } } bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb) diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 6d8793a4d..7a7c9b147 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -139,7 +139,6 @@ LLInventoryPanel::LLInventoryPanel(const std::string& name, LLPanel(name, rect, TRUE), mInventoryObserver(NULL), mCompletionObserver(NULL), - mFolderRoot(NULL), mScroller(NULL), mSortOrderSetting(sort_order_setting), mStartFolder(start_folder), @@ -191,7 +190,8 @@ void LLInventoryPanel::buildFolderView() NULL, root_id); - mFolderRoot = createFolderView(new_listener, true/*params.use_label_suffix()*/); + LLFolderView* folder_view = createFolderView(new_listener, true/*params.use_label_suffix()*/); + mFolderRoot = folder_view->getHandle(); } BOOL LLInventoryPanel::postBuild() { @@ -199,16 +199,16 @@ BOOL LLInventoryPanel::postBuild() buildFolderView(); { - // scroller + // Scroller LLRect scroller_view_rect = getRect(); scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); mScroller = new LLScrollContainer(std::string("Inventory Scroller"), scroller_view_rect, - mFolderRoot); + mFolderRoot.get()); mScroller->setFollowsAll(); mScroller->setReserveScrollCorner(TRUE); addChild(mScroller); - mFolderRoot->setScrollContainer(mScroller); + mFolderRoot.get()->setScrollContainer(mScroller); } // Set up the callbacks from the inventory we're viewing, and then build everything. @@ -240,24 +240,42 @@ BOOL LLInventoryPanel::postBuild() LLInventoryPanel::~LLInventoryPanel() { - if (mFolderRoot) + if (mFolderRoot.get()) { - U32 sort_order = mFolderRoot->getSortOrder(); + U32 sort_order = mFolderRoot.get()->getSortOrder(); if (mSortOrderSetting != INHERIT_SORT_ORDER) { gSavedSettings.setU32(mSortOrderSetting, sort_order); } } + clearFolderRoot(); +} + +void LLInventoryPanel::clearFolderRoot() +{ gIdleCallbacks.deleteFunction(onIdle, this); - // LLView destructor will take care of the sub-views. - mInventory->removeObserver(mInventoryObserver); - mInventory->removeObserver(mCompletionObserver); - delete mInventoryObserver; - delete mCompletionObserver; + if (mInventoryObserver) + { + mInventory->removeObserver(mInventoryObserver); + delete mInventoryObserver; + mInventoryObserver = NULL; + } - mScroller = NULL; + if (mCompletionObserver) + { + mInventory->removeObserver(mCompletionObserver); + delete mCompletionObserver; + mCompletionObserver = NULL; + } + + if (mScroller) + { + removeChild(mScroller); + delete mScroller; + mScroller = NULL; + } } // virtual @@ -267,7 +285,7 @@ LLXMLNodePtr LLInventoryPanel::getXML(bool save_children) const node->setName(LL_INVENTORY_PANEL_TAG); - node->createChild("allow_multi_select", TRUE)->setBoolValue(mFolderRoot->getAllowMultiSelect()); + node->createChild("allow_multi_select", TRUE)->setBoolValue(mFolderRoot.get()->getAllowMultiSelect()); return node; } @@ -327,24 +345,24 @@ LLView* LLInventoryPanel::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac void LLInventoryPanel::draw() { // Select the desired item (in case it wasn't loaded when the selection was requested) - mFolderRoot->updateSelection(); + mFolderRoot.get()->updateSelection(); LLPanel::draw(); } LLInventoryFilter* LLInventoryPanel::getFilter() { - if (mFolderRoot) + if (mFolderRoot.get()) { - return mFolderRoot->getFilter(); + return mFolderRoot.get()->getFilter(); } return NULL; } const LLInventoryFilter* LLInventoryPanel::getFilter() const { - if (mFolderRoot) + if (mFolderRoot.get()) { - return mFolderRoot->getFilter(); + return mFolderRoot.get()->getFilter(); } return NULL; } @@ -359,12 +377,12 @@ void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType U32 LLInventoryPanel::getFilterObjectTypes() const { - return mFolderRoot->getFilterObjectTypes(); + return mFolderRoot.get()->getFilterObjectTypes(); } U32 LLInventoryPanel::getFilterPermMask() const { - return mFolderRoot->getFilterPermissions(); + return mFolderRoot.get()->getFilterPermissions(); } @@ -390,7 +408,7 @@ void LLInventoryPanel::setFilterSubString(const std::string& string) const std::string LLInventoryPanel::getFilterSubString() { - return mFolderRoot->getFilterSubString(); + return mFolderRoot.get()->getFilterSubString(); } @@ -399,20 +417,20 @@ void LLInventoryPanel::setSortOrder(U32 order) getFilter()->setSortOrder(order); if (getFilter()->isModified()) { - mFolderRoot->setSortOrder(order); + mFolderRoot.get()->setSortOrder(order); // try to keep selection onscreen, even if it wasn't to start with - mFolderRoot->scrollToShowSelection(); + mFolderRoot.get()->scrollToShowSelection(); } } U32 LLInventoryPanel::getSortOrder() const { - return mFolderRoot->getSortOrder(); + return mFolderRoot.get()->getSortOrder(); } void LLInventoryPanel::requestSort() { - mFolderRoot->requestSort(); + mFolderRoot.get()->requestSort(); } void LLInventoryPanel::setSinceLogoff(BOOL sl) @@ -459,7 +477,7 @@ void LLInventoryPanel::modelChanged(U32 mask) { const LLUUID& item_id = (*items_iter); const LLInventoryObject* model_item = model->getObject(item_id); - LLFolderViewItem* view_item = mFolderRoot->getItemByID(item_id); + LLFolderViewItem* view_item = mFolderRoot.get()->getItemByID(item_id); // LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item // to folder is the fast way to get a folder without searching through folders tree. @@ -548,7 +566,7 @@ void LLInventoryPanel::modelChanged(U32 mask) // Add the UI element for this item. buildNewViews(item_id); // Select any newly created object that has the auto rename at top of folder root set. - if(mFolderRoot->getRoot()->needsAutoRename()) + if(mFolderRoot.get()->getRoot()->needsAutoRename()) { setSelection(item_id, FALSE); } @@ -562,7 +580,7 @@ void LLInventoryPanel::modelChanged(U32 mask) // Don't process the item if it is the root if (view_item->getRoot() != view_item) { - LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot->getItemByID(model_item->getParentUUID()); + LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot.get()->getItemByID(model_item->getParentUUID()); // Item has been moved. if (view_item->getParentFolder() != new_parent) { @@ -570,7 +588,7 @@ void LLInventoryPanel::modelChanged(U32 mask) { // Item is to be moved and we found its new parent in the panel's directory, so move the item's UI. view_item->getParentFolder()->extractItem(view_item); - view_item->addToFolder(new_parent, mFolderRoot); + view_item->addToFolder(new_parent, mFolderRoot.get()); } else { @@ -594,12 +612,6 @@ void LLInventoryPanel::modelChanged(U32 mask) } } -LLFolderView* LLInventoryPanel::getRootFolder() -{ - return mFolderRoot; -} - - // static void LLInventoryPanel::onIdle(void *userdata) { @@ -620,7 +632,7 @@ void LLInventoryPanel::onIdle(void *userdata) const LLUUID& LLInventoryPanel::getRootFolderID() const { - return mFolderRoot->getListener()->getUUID(); + return mFolderRoot.get()->getListener()->getUUID(); } void LLInventoryPanel::initializeViews() @@ -637,14 +649,14 @@ void LLInventoryPanel::initializeViews() if (gAgent.isFirstLogin()) { // Auto open the user's library - LLFolderViewFolder* lib_folder = mFolderRoot->getFolderByID(gInventory.getLibraryRootFolderID()); + LLFolderViewFolder* lib_folder = mFolderRoot.get()->getFolderByID(gInventory.getLibraryRootFolderID()); if (lib_folder) { lib_folder->setOpen(TRUE); } // Auto close the user's my inventory folder - LLFolderViewFolder* my_inv_folder = mFolderRoot->getFolderByID(gInventory.getRootFolderID()); + LLFolderViewFolder* my_inv_folder = mFolderRoot.get()->getFolderByID(gInventory.getRootFolderID()); if (my_inv_folder) { my_inv_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); @@ -654,7 +666,7 @@ void LLInventoryPanel::initializeViews() LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id) { // Destroy the old view for this ID so we can rebuild it. - LLFolderViewItem* old_view = mFolderRoot->getItemByID(id); + LLFolderViewItem* old_view = mFolderRoot.get()->getItemByID(id); if (old_view) { old_view->destroyView(); @@ -687,7 +699,7 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br bridge->getIcon(), bridge->getOpenIcon(), LLUI::getUIImage("inv_link_overlay.tga"), - mFolderRoot, + mFolderRoot.get(), bridge); } @@ -699,25 +711,25 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge bridge->getOpenIcon(), LLUI::getUIImage("inv_link_overlay.tga"), bridge->getCreationDate(), - mFolderRoot, + mFolderRoot.get(), bridge); } LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) { LLInventoryObject const* objectp = gInventory.getObject(id); - LLUUID root_id = mFolderRoot->getListener()->getUUID(); + LLUUID root_id = mFolderRoot.get()->getListener()->getUUID(); LLFolderViewFolder* parent_folder = NULL; LLFolderViewItem* itemp = NULL; if (id == root_id) { - parent_folder = mFolderRoot; + parent_folder = mFolderRoot.get(); } else if (objectp) { const LLUUID &parent_id = objectp->getParentUUID(); - parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id); + parent_folder = (LLFolderViewFolder*)mFolderRoot.get()->getItemByID(parent_id); if (parent_folder) { @@ -737,14 +749,14 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) objectp->getType(), LLInventoryType::IT_CATEGORY, this, - mFolderRoot, + mFolderRoot.get(), objectp->getUUID()); if (new_listener) { LLFolderViewFolder* folderp = createFolderViewFolder(new_listener); if (folderp) { - folderp->setItemSortOrder(mFolderRoot->getSortOrder()); + folderp->setItemSortOrder(mFolderRoot.get()->getSortOrder()); } itemp = folderp; } @@ -757,7 +769,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) item->getActualType(), item->getInventoryType(), this, - mFolderRoot, + mFolderRoot.get(), item->getUUID(), item->getFlags()); @@ -769,7 +781,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) if (itemp) { - itemp->addToFolder(parent_folder, mFolderRoot); + itemp->addToFolder(parent_folder, mFolderRoot.get()); } } } @@ -815,7 +827,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) void LLInventoryPanel::openStartFolderOrMyInventory() { // Find My Inventory folder and open it up by name - for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child)) + for (LLView *child = mFolderRoot.get()->getFirstChild(); child; child = mFolderRoot.get()->findNextSibling(child)) { LLFolderViewFolder *fchild = dynamic_cast(child); if (fchild @@ -862,12 +874,12 @@ protected: void LLInventoryPanel::onItemsCompletion() { - if (mFolderRoot) mFolderRoot->updateMenu(); + if (mFolderRoot.get()) mFolderRoot.get()->updateMenu(); } void LLInventoryPanel::openSelected() { - LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem(); + LLFolderViewItem* folder_item = mFolderRoot.get()->getCurSelectedItem(); if(!folder_item) return; LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener(); if(!bridge) return; @@ -876,7 +888,7 @@ void LLInventoryPanel::openSelected() void LLInventoryPanel::unSelectAll() { - mFolderRoot->setSelection(NULL, FALSE, FALSE); + mFolderRoot.get()->setSelection(NULL, FALSE, FALSE); } @@ -913,14 +925,14 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, // If folder view is empty the (x, y) point won't be in its rect // so the handler must be called explicitly. // but only if was not handled before. See EXT-6746. - if (!handled && !mFolderRoot->hasVisibleChildren()) + if (!handled && !mFolderRoot.get()->hasVisibleChildren()) { - handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + handled = mFolderRoot.get()->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); } if (handled) { - mFolderRoot->setDragAndDropThisFrame(); + mFolderRoot.get()->setDragAndDropThisFrame(); } } @@ -930,7 +942,7 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, void LLInventoryPanel::onFocusLost() { // inventory no longer handles cut/copy/paste/delete - if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot) + if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot.get()) { LLEditMenuHandler::gEditMenuHandler = NULL; } @@ -941,28 +953,28 @@ void LLInventoryPanel::onFocusLost() void LLInventoryPanel::onFocusReceived() { // inventory now handles cut/copy/paste/delete - LLEditMenuHandler::gEditMenuHandler = mFolderRoot; + LLEditMenuHandler::gEditMenuHandler = mFolderRoot.get(); LLPanel::onFocusReceived(); } void LLInventoryPanel::openAllFolders() { - mFolderRoot->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); - mFolderRoot->arrangeAll(); + mFolderRoot.get()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); + mFolderRoot.get()->arrangeAll(); } void LLInventoryPanel::closeAllFolders() { - mFolderRoot->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); - mFolderRoot->arrangeAll(); + mFolderRoot.get()->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); + mFolderRoot.get()->arrangeAll(); } void LLInventoryPanel::openDefaultFolderForType(LLAssetType::EType type) { LLUUID category_id = mInventory->findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(type)); LLOpenFolderByID opener(category_id); - mFolderRoot->applyFunctorRecursively(opener); + mFolderRoot.get()->applyFunctorRecursively(opener); } void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus) @@ -973,20 +985,20 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc { return; } - mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus); + mFolderRoot.get()->setSelectionByID(obj_id, take_keyboard_focus); } void LLInventoryPanel::setSelectCallback(const boost::function& items, BOOL user_action)>& cb) { - if (mFolderRoot) + if (mFolderRoot.get()) { - mFolderRoot->setSelectCallback(cb); + mFolderRoot.get()->setSelectCallback(cb); } } void LLInventoryPanel::clearSelection() { - mFolderRoot->clearSelection(); + mFolderRoot.get()->clearSelection(); } void LLInventoryPanel::onSelectionChange(const std::deque& items, BOOL user_action) @@ -1053,7 +1065,7 @@ BOOL LLInventoryPanel::getSinceLogoff() void LLInventoryPanel::dumpSelectionInformation(void* user_data) { LLInventoryPanel* iv = (LLInventoryPanel*)user_data; - iv->mFolderRoot->dumpSelectionInformation(); + iv->mFolderRoot.get()->dumpSelectionInformation(); } // static LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open) diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 5a858143a..27f9fbb3d 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -114,7 +114,7 @@ public: void setFilterSubString(const std::string& string); const std::string getFilterSubString(); void setFilterWorn(bool worn); - bool getFilterWorn() const { return mFolderRoot->getFilterWorn(); } + bool getFilterWorn() const { return mFolderRoot.get()->getFilterWorn(); } void setSinceLogoff(BOOL sl); void setHoursAgo(U32 hours); @@ -123,10 +123,10 @@ public: void setShowFolderState(LLInventoryFilter::EFolderShow show); LLInventoryFilter::EFolderShow getShowFolderState(); - void setAllowMultiSelect(BOOL allow) { mFolderRoot->setAllowMultiSelect(allow); } + void setAllowMultiSelect(BOOL allow) { mFolderRoot.get()->setAllowMultiSelect(allow); } // This method is called when something has changed about the inventory. void modelChanged(U32 mask); - LLFolderView* getRootFolder(); + LLFolderView* getRootFolder() { return mFolderRoot.get(); } LLScrollContainer* getScrollableContainer() { return mScroller; } void onSelectionChange(const std::deque &items, BOOL user_action); @@ -155,6 +155,9 @@ public: LLInventoryType::EType inv_type, U32 next_owner_perm = 0); + // Clean up stuff when the folder root gets deleted + void clearFolderRoot(); + protected: void openStartFolderOrMyInventory(); // open the first level of inventory void onItemsCompletion(); // called when selected items are complete @@ -164,7 +167,7 @@ protected: LLInvPanelComplObserver* mCompletionObserver; BOOL mAllowMultiSelect; - LLFolderView* mFolderRoot; + LLHandle mFolderRoot; LLScrollContainer* mScroller; /** diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index bdbc132c5..f9a3b0cdd 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1676,6 +1676,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, glStencilMask(stencil_mask); glClearStencil(1); glClear(GL_STENCIL_BUFFER_BIT); + glClearStencil(0); LLGLEnable cull_face(GL_CULL_FACE); LLGLEnable stencil(GL_STENCIL_TEST); LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS); diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 74a8ddbcf..60d2e52c2 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -231,9 +231,11 @@ namespace LLMarketplaceImport llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl; } - // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS + // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions + // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initially empty if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) && - (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS)) + (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) && + (status != MarketplaceErrorCodes::IMPORT_NOT_FOUND)) { if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { @@ -241,9 +243,9 @@ namespace LLMarketplaceImport } sMarketplaceCookie.clear(); } - else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS)) + else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)) { - llinfos << " SLM GET : Got IMPORT_DONE_WITH_ERRORS, marketplace cookie not cleared." << llendl; + llinfos << " SLM GET : Got error status = " << status << ", but marketplace cookie not cleared." << llendl; } sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING); @@ -306,13 +308,15 @@ namespace LLMarketplaceImport std::string url = getInventoryImportURL(); + AIHTTPHeaders headers = LLViewerMedia::getHeaders(); if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM GET: " << url << llendl; + llinfos << " SLM GET: establishMarketplaceSessionCookie, LLHTTPClient::get, url = " << url << llendl; + llinfos << " SLM GET: headers " << llendl; + llinfos << headers << llendl; } slmGetTimer.start(); - AIHTTPHeaders headers = LLViewerMedia::getHeaders(); LLHTTPClient::get(url, new LLImportGetResponder(), headers); return true; @@ -453,7 +457,10 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb void LLMarketplaceInventoryImporter::initialize() { - llassert(!mInitialized); + if (mInitialized) + { + return; + } if (!LLMarketplaceImport::hasSessionCookie()) { diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index 4e9e6ee81..6203af84f 100644 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -92,6 +92,7 @@ public: void initialize(); bool triggerImport(); bool isImportInProgress() const { return mImportInProgress; } + bool isInitialized() const { return mInitialized; } U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; } protected: diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index 756312847..654cba5a0 100644 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -171,10 +171,10 @@ bool LLMediaDataClient::isEmpty() const bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object) { - if(find_matching_request(mQueue, object->getID()) != mQueue.end()) + if(find_matching_request(mQueue, object->getID(), LLMediaDataClient::Request::ANY) != mQueue.end()) return true; - if(find_matching_request(mUnQueuedRequests, object->getID()) != mUnQueuedRequests.end()) + if(find_matching_request(mUnQueuedRequests, object->getID(), LLMediaDataClient::Request::ANY) != mUnQueuedRequests.end()) return true; return false; @@ -183,8 +183,8 @@ bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object) void LLMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr_t &object) { LL_DEBUGS("LLMediaDataClient") << "removing requests matching ID " << object->getID() << LL_ENDL; - remove_matching_requests(mQueue, object->getID()); - remove_matching_requests(mUnQueuedRequests, object->getID()); + remove_matching_requests(mQueue, object->getID(), LLMediaDataClient::Request::ANY); + remove_matching_requests(mUnQueuedRequests, object->getID(), LLMediaDataClient::Request::ANY); } void LLMediaDataClient::startQueueTimer() @@ -776,7 +776,7 @@ bool LLObjectMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &ob if(LLMediaDataClient::isInQueue(object)) return true; - if(find_matching_request(mRoundRobinQueue, object->getID()) != mRoundRobinQueue.end()) + if(find_matching_request(mRoundRobinQueue, object->getID(), LLMediaDataClient::Request::ANY) != mRoundRobinQueue.end()) return true; return false; @@ -787,7 +787,7 @@ void LLObjectMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr // First, call parent impl. LLMediaDataClient::removeFromQueue(object); - remove_matching_requests(mRoundRobinQueue, object->getID()); + remove_matching_requests(mRoundRobinQueue, object->getID(), LLMediaDataClient::Request::ANY); } bool LLObjectMediaDataClient::processQueueTimer() @@ -937,7 +937,7 @@ void LLObjectMediaNavigateClient::enqueue(Request *request) } // If there's already a matching request in the queue, remove it. - request_queue_t::iterator iter = find_matching_request(mQueue, request); + request_queue_t::iterator iter = find_matching_request(mQueue, request, LLMediaDataClient::Request::ANY); if(iter != mQueue.end()) { LL_DEBUGS("LLMediaDataClient") << "removing matching queued request " << (**iter) << LL_ENDL; @@ -945,7 +945,7 @@ void LLObjectMediaNavigateClient::enqueue(Request *request) } else { - request_set_t::iterator set_iter = find_matching_request(mUnQueuedRequests, request); + request_set_t::iterator set_iter = find_matching_request(mUnQueuedRequests, request, LLMediaDataClient::Request::ANY); if(set_iter != mUnQueuedRequests.end()) { LL_DEBUGS("LLMediaDataClient") << "removing matching unqueued request " << (**set_iter) << LL_ENDL; diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h index 19ea5c6ce..093b84468 100644 --- a/indra/newview/llmediadataclient.h +++ b/indra/newview/llmediadataclient.h @@ -282,9 +282,9 @@ private: bool mQueueTimerIsRunning; - template friend typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type = LLMediaDataClient::Request::ANY); - template friend typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type = LLMediaDataClient::Request::ANY); - template friend void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type = LLMediaDataClient::Request::ANY); + template friend typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type); + template friend typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type); + template friend void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type); }; diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index 652b3ed31..f00089379 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -34,116 +34,259 @@ #include "llmenucommands.h" -#include "imageids.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llerror.h" -#include "llstring.h" -#include "message.h" - -#include "llagent.h" +#include "aihttpview.h" +#include "floaterao.h" +#include "floaterlocalassetbrowse.h" +#include "hbfloatergrouptitles.h" +#include "jcfloaterareasearch.h" #include "llagentcamera.h" -#include "llcallingcard.h" #include "llchatbar.h" -#include "llviewercontrol.h" -#include "llfirstuse.h" +#include "llconsole.h" +#include "lldebugview.h" +#include "llfasttimerview.h" +#include "llfloaterabout.h" +#include "llfloateractivespeakers.h" +#include "llfloaterautoreplacesettings.h" +#include "llfloateravatarlist.h" +#include "llfloaterbeacons.h" +#include "llfloaterblacklist.h" +#include "llfloaterbuildoptions.h" +#include "llfloaterbump.h" +#include "llfloaterbuycurrency.h" +#include "llfloatercamera.h" #include "llfloaterchat.h" -#include "llfloaterdirectory.h" +#include "llfloaterchatterbox.h" +#include "llfloatercustomize.h" +#include "llfloaterdaycycle.h" +#include "llfloaterdisplayname.h" +#include "llfloatereditui.h" +#include "llfloaterenvsettings.h" +#include "llfloaterexploreanimations.h" +#include "llfloaterexploresounds.h" +#include "llfloaterfonttest.h" +#include "llfloatergesture.h" +#include "llfloatergodtools.h" +#include "llfloaterhud.h" +#include "llfloaterinspect.h" #include "llfloaterinventory.h" +#include "llfloaterlagmeter.h" +#include "llfloaterland.h" +#include "llfloaterlandholdings.h" #include "llfloatermap.h" +#include "llfloatermemleak.h" +#include "llfloatermessagelog.h" +#include "llfloatermute.h" +#include "llfloaternotificationsconsole.h" +#include "llfloateroutbox.h" +#include "llfloaterpathfindingcharacters.h" +#include "llfloaterpathfindinglinksets.h" +#include "llfloaterperms.h" +#include "llfloaterpostprocess.h" +#include "llfloaterpreference.h" +#include "llfloaterregiondebugconsole.h" +#include "llfloaterregioninfo.h" +#include "llfloaterreporter.h" +#include "llfloaterscriptdebug.h" +#include "llfloaterscriptlimits.h" +#include "llfloatersettingsdebug.h" +#include "llfloatersnapshot.h" +#include "llfloaterstats.h" +#include "llfloaterteleporthistory.h" +#include "llfloatertest.h" +#include "llfloatervoiceeffect.h" +#include "llfloaterwater.h" +#include "llfloaterwebcontent.h" +#include "llfloaterwindlight.h" #include "llfloaterworldmap.h" -#include "llgivemoney.h" -#include "llinventorypanel.h" -#include "llnotify.h" -#include "llstatusbar.h" -#include "llimview.h" -#include "lltextbox.h" -#include "llui.h" -#include "llviewergesture.h" // for triggering gestures -#include "llviewermessage.h" -#include "llviewerparceloverlay.h" -#include "llviewerregion.h" -#include "llviewerstats.h" +#include "llframestatview.h" +#include "llmakeoutfitdialog.h" +#include "llmoveview.h" // LLFloaterMove +#include "lltextureview.h" +#include "lltoolbar.h" +#include "lltoolgrab.h" +#include "lltoolmgr.h" #include "lluictrlfactory.h" -#include "llviewerwindow.h" -#include "llworld.h" -#include "llworldmap.h" -#include "llfocusmgr.h" +#include "llvelocitybar.h" +#include "llviewerparcelmgr.h" +// [RLVa:LF] +#include "rlvfloaters.h" +// [/RLVa:LF] +#include "shfloatermediaticker.h" +#include "slfloatermediafilter.h" -void toggle_search_floater(); - -void handle_track_avatar(const LLUUID& agent_id, const std::string& name) -{ - LLAvatarTracker::instance().track(agent_id, name); - - LLFloaterDirectory::hide(NULL); - LLFloaterWorldMap::show(true); -} - -void handle_mouselook(void*) -{ - gAgentCamera.changeCameraToMouselook(); -} - - -void handle_map(void*) -{ - LLFloaterWorldMap::toggle(); -} - -void handle_mini_map(void*) -{ - LLFloaterMap::toggleInstance(); -} - - -void handle_find(void*) -{ - toggle_search_floater(); -} - - -void handle_events(void*) -{ - LLFloaterDirectory::toggleEvents(NULL); -} - - -void handle_inventory(void*) -{ - // We're using the inventory, possibly for the - // first time. - LLFirstUse::useInventory(); - - LLInventoryView::toggleVisibility(NULL); -} - - -void handle_chat(void*) +void handle_chat() { // give focus to chatbar if it's open but not focused static const LLCachedControl chat_visible("ChatVisible",true); - if (chat_visible && gFocusMgr.childHasKeyboardFocus(gChatBar)) - { - LLChatBar::stopChat(); - } - else - { - LLChatBar::startChat(NULL); - } + (chat_visible && gFocusMgr.childHasKeyboardFocus(gChatBar)) ? LLChatBar::stopChat() : LLChatBar::startChat(NULL); } +void handle_debug_avatar_textures(void*); +template void handle_singleton_toggle(void*); +void show_outfit_dialog() { new LLMakeOutfitDialog(false); } +void toggle_build() { LLToolMgr::getInstance()->toggleBuildMode(); } +void toggle_control(const std::string& name) { if (LLControlVariable* control = gSavedSettings.getControl(name)) control->set(!control->get()); } +void toggle_search_floater(); +void toggle_always_run() { gAgent.getAlwaysRun() ? gAgent.clearAlwaysRun() : gAgent.setAlwaysRun(); } +void toggle_sit(); +void toggle_mouselook() { gAgentCamera.cameraMouselook() ? gAgentCamera.changeCameraToDefault() : gAgentCamera.changeCameraToMouselook(); } -void handle_slash_key(void*) +bool is_visible_view(boost::function get) { - // LLChatBar::startChat("/"); - // - // Don't do this, it results in a double-slash in the input field. - // Another "/" will be automatically typed for us, because the WM_KEYDOWN event - // that generated the menu accelerator call (and hence puts focus in - // the chat edtior) will be followed by a "/" WM_CHAR character message, - // which will type the slash. Yes, it's weird. It only matters for - // menu accelerators that put input focus into a field. And Mac works - // the same way. JC - - LLChatBar::startChat(NULL); + if (LLView* v = get()) + return v->getVisible(); + return false; +} + +struct CommWrapper +{ + static bool only_comm() + { + static const LLCachedControl only("CommunicateSpecificShortcut"); + return only || LLFloaterChatterBox::getInstance()->getFloaterCount(); + } + static bool instanceVisible(const LLSD& key) { return only_comm() ? LLFloaterChatterBox::instanceVisible(key) : LLFloaterMyFriends::instanceVisible(key); } + static void toggleInstance(const LLSD& key) { only_comm() ? LLFloaterChatterBox::toggleInstance(key) : LLFloaterMyFriends::toggleInstance(key); } +}; + +struct MenuFloaterDict : public LLSingleton +{ + typedef std::map, boost::function > > menu_floater_map_t; + menu_floater_map_t mEntries; + + MenuFloaterDict() + { + registerConsole("debug console", gDebugView->mDebugConsolep); + registerConsole("fast timers", gDebugView->mFastTimerView); + registerConsole("frame console", gDebugView->mFrameStatView); + registerConsole("http console", gHttpView); + registerConsole("texture console", gTextureView); + if (gAuditTexture) + { + registerConsole("texture category console", gTextureCategoryView); + registerConsole("texture size console", gTextureSizeView); + } + registerConsole("velocity", gVelocityBar); + registerFloater("about", boost::bind(&LLFloaterAbout::show,(void*)NULL)); + registerFloater("always run", boost::bind(toggle_always_run), boost::bind(&LLAgent::getAlwaysRun, &gAgent)); + registerFloater("anims_explorer", boost::bind(LLFloaterExploreAnimations::show)); + registerFloater("ao", boost::bind(LLFloaterAO::show, (void*)NULL)); + registerFloater("appearance", boost::bind(LLFloaterCustomize::show)); + registerFloater("asset_blacklist", boost::bind(LLFloaterBlacklist::toggle), boost::bind(LLFloaterBlacklist::visible)); + registerFloater("build", boost::bind(toggle_build)); + registerFloater("buy currency", boost::bind(LLFloaterBuyCurrency::buyCurrency)); + registerFloater("buy land", boost::bind(&LLViewerParcelMgr::startBuyLand, boost::bind(LLViewerParcelMgr::getInstance), false)); + registerFloater("chatbar", boost::bind(handle_chat)); + registerFloater("complaint reporter", boost::bind(LLFloaterReporter::showFromMenu, COMPLAINT_REPORT)); + registerFloater("DayCycle", boost::bind(LLFloaterDayCycle::show), boost::bind(LLFloaterDayCycle::isOpen)); + registerFloater("debug avatar", boost::bind(handle_debug_avatar_textures, (void*)NULL)); + registerFloater("debug settings", boost::bind(handle_singleton_toggle, (void*)NULL)); + registerFloater("displayname", boost::bind(LLFloaterDisplayName::show)); + registerFloater("edit ui", boost::bind(LLFloaterEditUI::show, (void*)NULL)); + registerFloater("EnvSettings", boost::bind(LLFloaterEnvSettings::show), boost::bind(LLFloaterEnvSettings::isOpen)); + registerFloater("fly", boost::bind(LLAgent::toggleFlying)); + registerFloater("font test", boost::bind(LLFloaterFontTest::show, (void*)NULL)); + registerFloater("god tools", boost::bind(LLFloaterGodTools::show, (void*)NULL)); + registerFloater("grid options", boost::bind(LLFloaterBuildOptions::show, (void*)NULL)); + registerFloater("group titles", boost::bind(HBFloaterGroupTitles::toggle)); + //Singu TODO: Re-implement f1 help. + //registerFloater("help f1", boost::bind(/*gViewerHtmlHelp.show*/)); + registerFloater("help tutorial", boost::bind(LLFloaterHUD::showHUD)); + registerFloater("inspect", boost::bind(LLFloaterInspect::showInstance)); + registerFloater("inventory", boost::bind(LLInventoryView::toggleVisibility, (void*)NULL), boost::bind(is_visible_view, static_cast >(LLInventoryView::getActiveInventory))); + registerFloater("local assets", boost::bind(FloaterLocalAssetBrowser::show, (void*)0)); + registerFloater("mean events", boost::bind(LLFloaterBump::show, (void*)NULL)); + registerFloater("media ticker", boost::bind(handle_ticker_toggle, (void*)NULL), boost::bind(SHFloaterMediaTicker::instanceExists)); + registerFloater("memleak", boost::bind(LLFloaterMemLeak::show, (void*)NULL)); + registerFloater("messagelog", boost::bind(LLFloaterMessageLog::show)); + registerFloater("mouselook", boost::bind(toggle_mouselook)); + registerFloater("my land", boost::bind(LLFloaterLandHoldings::show, (void*)NULL)); + registerFloater("outfit", boost::bind(show_outfit_dialog)); + registerFloater("PostProcess", boost::bind(LLFloaterPostProcess::show)); + registerFloater("preferences", boost::bind(LLFloaterPreference::show, (void*)NULL)); + registerFloater("RegionDebugConsole", boost::bind(handle_singleton_toggle, (void*)NULL), boost::bind(LLFloaterRegionDebugConsole::instanceExists)); + registerFloater("script errors", boost::bind(LLFloaterScriptDebug::show, LLUUID::null)); + registerFloater("search", boost::bind(toggle_search_floater)); + registerFloater("sit", boost::bind(toggle_sit)); + registerFloater("snapshot", boost::bind(LLFloaterSnapshot::show, (void*)NULL)); + registerFloater("sound_explorer", boost::bind(LLFloaterExploreSounds::toggle), boost::bind(LLFloaterExploreSounds::visible)); + registerFloater("test", boost::bind(LLFloaterTest::show, (void*)NULL)); + // Phoenix: Wolfspirit: Enabled Show Floater out of viewer menu + registerFloater("toolbar", boost::bind(toggle_control, "ShowToolBar"), boost::bind(&LLToolBar::getVisible, gToolBar)); + registerFloater("WaterSettings", boost::bind(LLFloaterWater::show), boost::bind(LLFloaterWater::isOpen)); + registerFloater("web", boost::bind(LLFloaterWebContent::showInstance, "dict web", LLFloaterWebContent::Params())); + registerFloater("Windlight", boost::bind(LLFloaterWindLight::show), boost::bind(LLFloaterWindLight::isOpen)); + registerFloater("world map", boost::bind(LLFloaterWorldMap::toggle)); + registerFloater ("about land"); + registerFloater ("about region"); + registerFloater ("active speakers"); + registerFloater ("areasearch"); + registerFloater ("autoreplace"); + registerFloater ("beacons"); + registerFloater ("camera controls"); + registerFloater ("chat history"); + registerFloater ("communicate"); + registerFloater ("friends", 0); + registerFloater ("gestures"); + registerFloater ("groups", 1); + registerFloater ("im"); + registerFloater ("lag meter"); + registerFloater ("media filter"); + registerFloater ("mini map"); + registerFloater ("movement controls"); + registerFloater ("mute list"); + registerFloater ("notifications console"); + registerFloater ("outbox"); + registerFloater ("pathfinding_characters"); + registerFloater ("pathfinding_linksets"); + registerFloater ("perm prefs"); + registerFloater ("radar"); + registerFloater ("script info"); + registerFloater ("stat bar"); + registerFloater ("teleport history"); + registerFloater ("voice effect"); + // [RLVa:LF] + registerFloater("rlv restrictions"); + registerFloater("rlv locks"); + registerFloater("rlv strings"); + // [/RLVa:LF] + } + template + void registerConsole(const std::string& name, T* console) + { + registerFloater(name, boost::bind(&T::setVisible, console, !boost::bind(&T::getVisible, console)), boost::bind(&T::getVisible, console)); + } + void registerFloater(const std::string& name, boost::function show, boost::function visible = NULL) + { + mEntries.insert( std::make_pair( name, std::make_pair( show, visible ) ) ); + } + template + void registerFloater(const std::string& name, const LLSD& key = LLSD()) + { + registerFloater(name, boost::bind(&T::toggleInstance,key), boost::bind(&T::instanceVisible,key)); + } +}; + +void show_floater(const std::string& floater_name) +{ + if (floater_name.empty()) return; + + MenuFloaterDict::menu_floater_map_t::iterator it = MenuFloaterDict::instance().mEntries.find(floater_name); + if (it == MenuFloaterDict::instance().mEntries.end()) // Simple codeless floater + { + if (LLFloater* floater = LLUICtrlFactory::getInstance()->getBuiltFloater(floater_name)) + gFloaterView->bringToFront(floater); + else + LLUICtrlFactory::getInstance()->buildFloater(new LLFloater(), floater_name); + } + else if (it->second.first) + { + it->second.first(); + } +} + +// Singu TODO: It'd be reallllly nice if we could use this as a control for buttons too. +bool floater_visible(const std::string& floater_name) +{ + MenuFloaterDict::menu_floater_map_t::iterator it = MenuFloaterDict::instance().mEntries.find(floater_name); + return it != MenuFloaterDict::instance().mEntries.end() && it->second.second && it->second.second(); } diff --git a/indra/newview/llmenucommands.h b/indra/newview/llmenucommands.h index 1c4550b07..1ec7be309 100644 --- a/indra/newview/llmenucommands.h +++ b/indra/newview/llmenucommands.h @@ -33,17 +33,4 @@ #ifndef LL_LLMENUCOMMANDS_H #define LL_LLMENUCOMMANDS_H -class LLUUID; - -void handle_track_avatar(const LLUUID& agent_id, const std::string& name); -void handle_mouselook(void*); -void handle_map(void*); -void handle_mini_map(void*); -void handle_find(void*); -void handle_events(void*); -void handle_inventory(void*); -void handle_chat(void*); -void handle_return_key(void*); -void handle_slash_key(void*); - #endif diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index ab2283644..7dd948fc5 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -49,11 +49,11 @@ void LLNameListCtrl::NameTypeNames::declareValues() declare("SPECIAL", LLNameListCtrl::SPECIAL); } -LLNameListCtrl::LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL allow_multiple_selection, BOOL draw_border, bool draw_heading, S32 name_column_index, const std::string& tooltip) +LLNameListCtrl::LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL allow_multiple_selection, BOOL draw_border, bool draw_heading, S32 name_column_index, const std::string& name_system, const std::string& tooltip) : LLScrollListCtrl(name, rect, NULL, allow_multiple_selection, draw_border,draw_heading), mNameColumnIndex(name_column_index), mAllowCallingCardDrop(false), - mShortNames(false), + mNameSystem(name_system), mAvatarNameCacheConnection() { setToolTip(tooltip); @@ -189,10 +189,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( } else if (LLAvatarNameCache::get(id, &av_name)) { - if (mShortNames) - fullname = av_name.mDisplayName; - else - fullname = av_name.getCompleteName(); + LLAvatarNameCache::getPNSName(av_name, fullname, mNameSystem); } else { @@ -266,10 +263,7 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, //mAvatarNameCacheConnection.disconnect(); std::string name; - if (mShortNames) - name = av_name.mDisplayName; - else - name = av_name.getCompleteName(); + LLAvatarNameCache::getPNSName(av_name, name, mNameSystem); LLNameListItem* list_item = item.get(); if (list_item && list_item->getUUID() == agent_id) @@ -326,7 +320,10 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto S32 name_column_index = 0; node->getAttributeS32("name_column_index", name_column_index); - LLNameListCtrl* name_list = new LLNameListCtrl("name_list", rect, multi_select, draw_border, draw_heading, name_column_index); + std::string name_system("PhoenixNameSystem"); + node->getAttributeString("name_system", name_system); + + LLNameListCtrl* name_list = new LLNameListCtrl("name_list", rect, multi_select, draw_border, draw_heading, name_column_index, name_system); if (node->hasAttribute("heading_height")) { S32 heading_height; diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 451f1ae7c..9552ff02d 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -102,7 +102,7 @@ public: }; protected: - LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL allow_multiple_selection, BOOL draw_border = TRUE, bool draw_heading = false, S32 name_column_index = 0, const std::string& tooltip = LLStringUtil::null); + LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL allow_multiple_selection, BOOL draw_border = TRUE, bool draw_heading = false, S32 name_column_index = 0, const std::string& name_system = "PhoenixNameSystem", const std::string& tooltip = LLStringUtil::null); virtual ~LLNameListCtrl() { if (mAvatarNameCacheConnection.connected()) @@ -148,7 +148,7 @@ private: private: S32 mNameColumnIndex; BOOL mAllowCallingCardDrop; - bool mShortNames; // display name only, no SLID + const LLCachedControl mNameSystem; boost::signals2::connection mAvatarNameCacheConnection; }; diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 162d036af..ce43bd8f8 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -1,7 +1,7 @@ /** * @file llnetmap.cpp * @author James Cook - * @brief Display of surrounding regions, objects, and agents. View contained by LLFloaterMap. + * @brief Display of surrounding regions, objects, and agents. * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -35,42 +35,49 @@ #include "llnetmap.h" -#include "llmath.h" // clampf() +#include "llmath.h" #include "llfocusmgr.h" #include "lllocalcliprect.h" +#include "llmenugl.h" #include "llrender.h" +#include "lltextbox.h" +#include "lluictrlfactory.h" -#include "lfsimfeaturehandler.h" -#include "llfloateravatarlist.h" +#include "llglheaders.h" +// Viewer includes #include "llagent.h" #include "llagentcamera.h" +#include "llappviewer.h" // for gDisconnected #include "llavataractions.h" #include "llavatarnamecache.h" #include "llcallingcard.h" #include "llcolorscheme.h" #include "llfloaterworldmap.h" #include "llframetimer.h" +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +#include "llparcel.h" +// [/SL:KB] #include "lltracker.h" -#include "llmenugl.h" #include "llsurface.h" -#include "lltextbox.h" -#include "lluictrlfactory.h" #include "llviewercamera.h" #include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerobjectlist.h" +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +#include "llviewerparcelmgr.h" +#include "llviewerparceloverlay.h" +// [/SL:KB] #include "llviewerregion.h" #include "llviewerwindow.h" -#include "llvoavatar.h" #include "llworld.h" #include "llworldmapview.h" // shared draw code -#include "llappviewer.h" // Only for constants! - -#include "llglheaders.h" // +#include "lfsimfeaturehandler.h" +#include "llfloateravatarlist.h" #include "llmutelist.h" +#include "llvoavatar.h" // // [RLVa:KB] @@ -79,9 +86,10 @@ using namespace LLOldEvents; -const F32 MAP_SCALE_MIN = 32; -const F32 MAP_SCALE_MID = 256; -const F32 MAP_SCALE_MAX = 4096; +const F32 LLNetMap::MAP_SCALE_MIN = 32; +const F32 LLNetMap::MAP_SCALE_MID = 256; +const F32 LLNetMap::MAP_SCALE_MAX = 4096; + const F32 MAP_SCALE_INCREMENT = 16; const F32 MAP_SCALE_ZOOM_FACTOR = 1.1f; // Zoom in factor per click of the scroll wheel (10%) const F32 MAP_MINOR_DIR_THRESHOLD = 0.08f; @@ -90,26 +98,51 @@ const F32 DOT_SCALE = 0.75f; const F32 MIN_PICK_SCALE = 2.f; const S32 MOUSE_DRAG_SLOP = 2; // How far the mouse needs to move before we think it's a drag -const F32 WIDTH_PIXELS = 2.f; -const S32 CIRCLE_STEPS = 100; +const F32 WIDTH_PIXELS = 2.f; +const S32 CIRCLE_STEPS = 100; + +const F64 COARSEUPDATE_MAX_Z = 1020.0f; LLNetMap::LLNetMap(const std::string& name) : LLPanel(name), mScale(128.f), mObjectMapTPM(1.f), mObjectMapPixels(255.f), - mTargetPanX( 0.f ), - mTargetPanY( 0.f ), - mCurPanX( 0.f ), - mCurPanY( 0.f ), - mUpdateNow( FALSE ) + mTargetPan(0.f, 0.f), + mCurPan(0.f, 0.f), + mStartPan(0.f, 0.f), + mMouseDown(0, 0), + mPanning(false), +// mUpdateNow( false ), +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + mUpdateObjectImage(false), + mUpdateParcelImage(false), +// [/SL:KB] + mObjectImageCenterGlobal( gAgentCamera.getCameraPositionGlobal() ), + mObjectRawImagep(), + mObjectImagep(), +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + mParcelImageCenterGlobal( gAgentCamera.getCameraPositionGlobal() ), + mParcelRawImagep(), + mParcelImagep(), +// [/SL:KB] + mClosestAgentToCursor(), + mPopupMenu(NULL) { - mScale = gSavedSettings.getF32("MiniMapScale"); mPixelsPerMeter = mScale / REGION_WIDTH_METERS; mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS); + setScale(gSavedSettings.getF32("MiniMapScale")); - mObjectImageCenterGlobal = gAgentCamera.getCameraPositionGlobal(); - + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_mini_map.xml"); +} + +LLNetMap::~LLNetMap() +{ + gSavedSettings.setF32("MiniMapScale", mScale); +} + +BOOL LLNetMap::postBuild() +{ // Register event listeners for popup menu (new LLScaleMap())->registerListener(this, "MiniMap.ZoomLevel"); (new LLCenterMap())->registerListener(this, "MiniMap.Center"); @@ -129,32 +162,26 @@ LLNetMap::LLNetMap(const std::string& name) : (new mmsetunmark())->registerListener(this, "MiniMap.setunmark"); (new mmenableunmark())->registerListener(this, "MiniMap.enableunmark"); (new LLToggleControl())->registerListener(this, "MiniMap.ToggleControl"); + (new OverlayToggle())->registerListener(this, "Minimap.ToggleOverlay"); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_mini_map.xml"); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + LLViewerParcelMgr::instance().setCollisionUpdateCallback(boost::bind(&LLNetMap::refreshParcelOverlay, this)); + LLViewerParcelOverlay::setUpdateCallback(boost::bind(&LLNetMap::refreshParcelOverlay, this)); +// [/SL:KB] updateMinorDirections(); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_mini_map.xml", this); - if (!menu) - { - menu = new LLMenuGL(LLStringUtil::null); - } - menu->setVisible(FALSE); - mPopupMenuHandle = menu->getHandle(); -} - -LLNetMap::~LLNetMap() -{ + mPopupMenu = LLUICtrlFactory::getInstance()->buildMenu("menu_mini_map.xml", this); + if (!mPopupMenu) mPopupMenu = new LLMenuGL(LLStringUtil::null); + mPopupMenu->setVisible(FALSE); + return TRUE; } void LLNetMap::setScale( F32 scale ) { + scale = llclamp(scale, MAP_SCALE_MIN, MAP_SCALE_MAX); + mCurPan *= scale / mScale; mScale = scale; - if (mScale == 0.f) - { - mScale = 0.1f; - } - gSavedSettings.setF32("MiniMapScale", mScale); if (mObjectImagep.notNull()) { @@ -174,20 +201,18 @@ void LLNetMap::setScale( F32 scale ) mPixelsPerMeter = mScale / REGION_WIDTH_METERS; mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS); - mUpdateNow = TRUE; -} - -void LLNetMap::translatePan( F32 delta_x, F32 delta_y ) -{ - mTargetPanX += delta_x; - mTargetPanY += delta_y; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + mUpdateObjectImage = true; + mUpdateParcelImage = true; +// [/SL:KB] +// mUpdateNow = true; } /////////////////////////////////////////////////////////////////////////////////// std::size_t hash_value(const LLUUID& uuid) { - return (std::size_t)uuid.getCRC32(); + return (std::size_t)uuid.getCRC32(); } boost::unordered_map mm_MarkerColors; @@ -198,7 +223,12 @@ void LLNetMap::mm_setcolor(LLUUID key,LLColor4 col) void LLNetMap::draw() { static LLFrameTimer map_timer; - + static LLUIColor map_track_color = gTrackColor; + static const LLCachedControl map_frustum_color(gColors, "NetMapFrustum", LLColor4::white); + static const LLCachedControl map_frustum_rotating_color(gColors, "NetMapFrustumRotating", LLColor4::white); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-08-17 (Catznip-3.3.0) + static const LLCachedControl map_property_line("MiniMapPropertyLine", LLColor4::white); +// [/SL:KB] static const LLCachedControl map_whisper_ring_color("MiniMapWhisperRingColor", LLColor4(0.f,1.f,0.f,0.5f)); static const LLCachedControl map_chat_ring_color("MiniMapChatRingColor", LLColor4(0.f,0.f,1.f,0.5f)); static const LLCachedControl map_shout_ring_color("MiniMapShoutRingColor", LLColor4(1.f,0.f,0.f,0.5f)); @@ -208,15 +238,22 @@ void LLNetMap::draw() createObjectImage(); } - if (gSavedSettings.getS32( "MiniMapCenter") != MAP_CENTER_NONE) +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + if (mParcelImagep.isNull()) { - mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); - mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); + createParcelImage(); + } +// [/SL:KB] + + static LLUICachedControl center("MiniMapCenter"); + if (center != MAP_CENTER_NONE) + { + mCurPan = lerp(mCurPan, mTargetPan, LLCriticalDamp::getInterpolant(0.1f)); } + // Prepare a scissor region F32 rotation = 0; - gGL.pushMatrix(); gGL.pushUIMatrix(); @@ -229,13 +266,10 @@ void LLNetMap::draw() gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]); gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); - // Prepare a scissor region { - LLGLEnable scissor(GL_SCISSOR_TEST); - + LLLocalClipRect clip(getLocalRect()); { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLLocalClipRect clip(getLocalRect()); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -249,13 +283,13 @@ void LLNetMap::draw() } // region 0,0 is in the middle - S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX); - S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY); + S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPan.mV[VX]); + S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPan.mV[VY]); gGL.pushMatrix(); gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); - + static LLCachedControl rotate_map("MiniMapRotate", true); if (rotate_map) { @@ -265,9 +299,9 @@ void LLNetMap::draw() } // figure out where agent is - LLColor4 this_region_color = gColors.getColor( "NetMapThisRegion" ); - LLColor4 live_region_color = gColors.getColor( "NetMapLiveRegion" ); - LLColor4 dead_region_color = gColors.getColor( "NetMapDeadRegion" ); + static const LLCachedControl this_region_color(gColors, "NetMapThisRegion"); + static const LLCachedControl live_region_color(gColors, "NetMapLiveRegion"); + static const LLCachedControl dead_region_color(gColors, "NetMapDeadRegion"); // Aurora Sim //S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters()); S32 region_width = REGION_WIDTH_UNITS; @@ -293,13 +327,51 @@ void LLNetMap::draw() F32 right = left + (regionp->getWidth() / REGION_WIDTH_METERS) * mScale ; // Aurora Sim - gGL.color4fv(regionp == gAgent.getRegion() ? this_region_color.mV : live_region_color.mV); - if (!regionp->isAlive()) + if (regionp == gAgent.getRegion()) { - gGL.color4fv(dead_region_color.mV); + gGL.color4fv(this_region_color().mV); + } + else + { + gGL.color4fv(live_region_color().mV); } + if (!regionp->isAlive()) + { + gGL.color4fv(dead_region_color().mV); + } +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-26 (Catznip-3.3) + static LLCachedControl s_fUseWorldMapTextures(gSavedSettings, "MiniMapWorldMapTextures"); + bool fRenderTerrain = true; + + if (s_fUseWorldMapTextures) + { + LLViewerTexture* pRegionImage = regionp->getWorldMapTile(); + if ( (pRegionImage) && (pRegionImage->hasGLTexture()) ) + { + gGL.getTexUnit(0)->bind(pRegionImage); + gGL.begin(LLRender::QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(left, top); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(left, bottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(right, bottom); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2f(right, top); + gGL.end(); + + pRegionImage->setBoostLevel(LLViewerTexture::BOOST_MAP_VISIBLE); + fRenderTerrain = false; + } + } +// [/SL:KB] + +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-26 (Catznip-3.3) + if (fRenderTerrain) + { +// [/SL:KB] // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); gGL.begin(LLRender::QUADS); @@ -332,43 +404,92 @@ void LLNetMap::draw() } } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-26 (Catznip-3.3) + } +// [/SL:KB] } // Redraw object layer periodically - if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) - { - mUpdateNow = false; +// if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) +// { +// mUpdateNow = false; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + // Locate the center + LLVector3 posCenter = globalPosToView(gAgentCamera.getCameraPositionGlobal()); + posCenter.mV[VX] -= mCurPan.mV[VX]; + posCenter.mV[VY] -= mCurPan.mV[VY]; + posCenter.mV[VZ] = 0.f; + LLVector3d posCenterGlobal = viewPosToGlobal(llfloor(posCenter.mV[VX]), llfloor(posCenter.mV[VY])); - // Locate the centre of the object layer, accounting for panning - LLVector3 new_center = globalPosToView(gAgentCamera.getCameraPositionGlobal(), rotate_map); - new_center.mV[VX] -= mCurPanX; - new_center.mV[VY] -= mCurPanY; - new_center.mV[VZ] = 0.f; - mObjectImageCenterGlobal = viewPosToGlobal(llround(new_center.mV[VX]), llround(new_center.mV[VY]), rotate_map); + static LLCachedControl s_fShowObjects(gSavedSettings, "ShowMiniMapObjects") ; + if ( (s_fShowObjects) && ((mUpdateObjectImage) || ((map_timer.getElapsedTimeF32() > 0.5f))) ) + { + mUpdateObjectImage = false; +// [/SL:KB] + +// // Locate the centre of the object layer, accounting for panning +// LLVector3 new_center = globalPosToView(gAgentCamera.getCameraPositionGlobal()); +// new_center.mV[VX] -= mCurPan.mV[VX]; +// new_center.mV[VY] -= mCurPan.mV[VY]; +// new_center.mV[VZ] = 0.f; +// mObjectImageCenterGlobal = viewPosToGlobal(llfloor(new_center.mV[VX]), llfloor(new_center.mV[VY])); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + mObjectImageCenterGlobal = posCenterGlobal; +// [/SL:KB] // Create the base texture. U8 *default_texture = mObjectRawImagep->getData(); memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); - if (gSavedSettings.getBOOL("ShowMiniMapObjects")) - { - gObjectList.renderObjectsForMap(*this); // Draw buildings. - } + // Draw objects + gObjectList.renderObjectsForMap(*this); mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); map_timer.reset(); } - LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); - map_center_agent -= gAgentCamera.getCameraPositionAgent(); - map_center_agent.mV[0] *= mScale/REGION_WIDTH_METERS; - map_center_agent.mV[1] *= mScale/REGION_WIDTH_METERS; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + static LLCachedControl s_fShowPropertyLines(gSavedSettings, "MiniMapPropertyLines") ; + if ( (s_fShowPropertyLines) && ((mUpdateParcelImage) || (dist_vec_squared2D(mParcelImageCenterGlobal, posCenterGlobal) > 9.0f)) ) + { + mUpdateParcelImage = false; + mParcelImageCenterGlobal = posCenterGlobal; - gGL.getTexUnit(0)->bind(mObjectImagep); + U8* pTextureData = mParcelRawImagep->getData(); + memset(pTextureData, 0, mParcelImagep->getWidth() * mParcelImagep->getHeight() * mParcelImagep->getComponents()); + + // Process each region + for (LLWorld::region_list_t::const_iterator itRegion = LLWorld::getInstance()->getRegionList().begin(); + itRegion != LLWorld::getInstance()->getRegionList().end(); ++itRegion) + { + const LLViewerRegion* pRegion = *itRegion; LLColor4U clrOverlay; + if (pRegion->isAlive()) + clrOverlay = map_property_line.get(); + else + clrOverlay = LLColor4U(255, 128, 128, 255); + renderPropertyLinesForRegion(pRegion, clrOverlay); + } + + mParcelImagep->setSubImage(mParcelRawImagep, 0, 0, mParcelImagep->getWidth(), mParcelImagep->getHeight()); + } +// [/SL:KB] + + LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); + LLVector3 camera_position = gAgentCamera.getCameraPositionAgent(); + map_center_agent -= camera_position; + map_center_agent.mV[VX] *= mScale/region_width; + map_center_agent.mV[VY] *= mScale/region_width; + +// gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-26 (Catznip-3.3) + if (s_fShowObjects) + { + gGL.getTexUnit(0)->bind(mObjectImagep); +// [/SL:KB] gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); @@ -379,134 +500,192 @@ void LLNetMap::draw() gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); gGL.end(); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-26 (Catznip-3.3) + } +// [/SL:KB] + +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + if (s_fShowPropertyLines) + { + map_center_agent = gAgent.getPosAgentFromGlobal(mParcelImageCenterGlobal) - camera_position; + map_center_agent.mV[VX] *= mScale / region_width; + map_center_agent.mV[VY] *= mScale / region_width; + + gGL.getTexUnit(0)->bind(mParcelImagep); + gGL.begin(LLRender::QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); + gGL.end(); + } +// [/SL:KB] gGL.popMatrix(); - LLVector3d pos_global; - LLVector3 pos_map; - // Mouse pointer in local coordinates S32 local_mouse_x; S32 local_mouse_y; + //localMouse(&local_mouse_x, &local_mouse_y); LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); mClosestAgentToCursor.setNull(); - F32 closest_dist = F32_MAX; - F32 min_pick_dist = mDotRadius * MIN_PICK_SCALE; + F32 closest_dist_squared = F32_MAX; // value will be overridden in the loop + F32 min_pick_dist_squared = (mDotRadius * MIN_PICK_SCALE) * (mDotRadius * MIN_PICK_SCALE); - // Draw avatars -// LLColor4 mapcolor = gAvatarMapColor; - - static const LLCachedControl standard_color("MapAvatar",LLColor4(0.f,1.f,0.f,1.f)); - static const LLCachedControl friend_color_stored("AscentFriendColor",LLColor4(1.f,1.f,0.f,1.f)); - static const LLCachedControl em_color("AscentEstateOwnerColor",LLColor4(1.f,0.6f,1.f,1.f)); - static const LLCachedControl linden_color("AscentLindenColor",LLColor4(0.f,0.f,1.f,1.f)); - static const LLCachedControl muted_color("AscentMutedColor",LLColor4(0.7f,0.7f,0.7f,1.f)); - - // Draw avatars + LLVector3 pos_map; // [RLVa:KB] - Version: 1.23.4 | Alternate: Snowglobe-1.2.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b - LLColor4 friend_color = (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? friend_color_stored : standard_color; + bool show_friends = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES); // [/RLVa:KB] - std::vector avatar_ids; + uuid_vec_t avatar_ids; std::vector positions; - LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); + + LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgentCamera.getCameraPositionGlobal()); + + // Get the selected ids from radar now, as they are loop invariant + uuid_vec_t gmSelected; + static const LLCachedControl radar_tracking_circle("MiniMapRadarTrackingCircles"); + if (radar_tracking_circle && LLFloaterAvatarList::instanceVisible()) + gmSelected = LLFloaterAvatarList::instance().getSelectedIDs(); + + // Draw avatars for(U32 i=0; i standard_color("MapAvatar",LLColor4(0.f,1.f,0.f,1.f)); + LLColor4 color = standard_color; // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. // just be careful to sort the avatar IDs along with the positions. -MG - pos_map = globalPosToView(pos, rotate_map); - if (pos.mdV[VZ] == 0.f) + pos_map = globalPosToView(positions[i]); + if (positions[i].mdV[VZ] == 0.f || positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z) { pos_map.mV[VZ] = 16000.f; } - std::string avName; - - gCacheName->getFullName(id, avName); - if(LLMuteList::getInstance()->isMuted(id)) + if(LLMuteList::getInstance()->isMuted(uuid)) { - avColor = muted_color; + static const LLCachedControl muted_color("AscentMutedColor",LLColor4(0.7f,0.7f,0.7f,1.f)); + color = muted_color; } - LLViewerRegion* avatar_region = LLWorld::getInstance()->getRegionFromPosGlobal(pos); - LLUUID estate_owner = avatar_region? avatar_region->getOwner() : LLUUID::null; + LLViewerRegion* avatar_region = LLWorld::getInstance()->getRegionFromPosGlobal(positions[i]); + LLUUID estate_owner = avatar_region ? avatar_region->getOwner() : LLUUID::null; // MOYMOD Minimap custom av colors. - boost::unordered_map::const_iterator it = mm_MarkerColors.find(id); + boost::unordered_map::const_iterator it = mm_MarkerColors.find(uuid); if(it != mm_MarkerColors.end()) { - avColor = it->second; + color = it->second; } //Lindens are always more Linden than your friend, make that take precedence - else if(LLMuteList::getInstance()->isLinden(id)) + else if (LLMuteList::getInstance()->isLinden(uuid)) { - avColor = linden_color; + static const LLCachedControl linden_color("AscentLindenColor",LLColor4(0.f,0.f,1.f,1.f)); + color = linden_color; } //check if they are an estate owner at their current position - else if(estate_owner.notNull() && id == estate_owner) + else if (estate_owner.notNull() && uuid == estate_owner) { - avColor = em_color; + static const LLCachedControl em_color("AscentEstateOwnerColor",LLColor4(1.f,0.6f,1.f,1.f)); + color = em_color; } //without these dots, SL would suck. - else if(LLAvatarActions::isFriend(id)) + else if (show_friends && LLAvatarActions::isFriend(uuid)) { - avColor = friend_color; + static const LLCachedControl friend_color("AscentFriendColor",LLColor4(1.f,1.f,0.f,1.f)); + color = friend_color; } LLWorldMapView::drawAvatar( - pos_map.mV[VX], pos_map.mV[VY], - avColor, - pos_map.mV[VZ], - mDotRadius); + pos_map.mV[VX], pos_map.mV[VY], + color, + pos_map.mV[VZ], mDotRadius); - F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); - if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist) + F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), + LLVector2(local_mouse_x,local_mouse_y)); + if(dist_to_cursor_squared < min_pick_dist_squared) { - closest_dist = dist_to_cursor; - mClosestAgentToCursor = id; - mClosestAgentPosition = pos; + if (dist_to_cursor_squared < closest_dist_squared) + { + closest_dist_squared = dist_to_cursor_squared; + mClosestAgentToCursor = uuid; + mClosestAgentPosition = positions[i]; + } + } + + if (!gmSelected.empty()) + if (uuid.notNull()) + { + bool selected = false; + uuid_vec_t::iterator sel_iter = gmSelected.begin(); + for (; sel_iter != gmSelected.end(); sel_iter++) + { + if(*sel_iter == uuid) + { + selected = true; + break; + } + } + if (selected) + { + if( (pos_map.mV[VX] < 0) || + (pos_map.mV[VY] < 0) || + (pos_map.mV[VX] >= getRect().getWidth()) || + (pos_map.mV[VY] >= getRect().getHeight()) ) + { + S32 x = llround( pos_map.mV[VX] ); + S32 y = llround( pos_map.mV[VY] ); + LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10); + } else + { + LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f); + } + } } } // Draw dot for autopilot target if (gAgent.getAutoPilot()) { - drawTracking(gAgent.getAutoPilotTargetGlobal(), rotate_map, gTrackColor); + drawTracking( gAgent.getAutoPilotTargetGlobal(), map_track_color ); } else { LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_AVATAR == tracking_status ) { - drawTracking(LLAvatarTracker::instance().getGlobalPos(), rotate_map, gTrackColor); + drawTracking( LLAvatarTracker::instance().getGlobalPos(), map_track_color ); } else if ( LLTracker::TRACKING_LANDMARK == tracking_status || LLTracker::TRACKING_LOCATION == tracking_status ) { - drawTracking(LLTracker::getTrackedPositionGlobal(), rotate_map, gTrackColor); + drawTracking( LLTracker::getTrackedPositionGlobal(), map_track_color ); } } // Draw dot for self avatar position - pos_global = gAgent.getPositionGlobal(); - pos_map = globalPosToView(pos_global, rotate_map); - LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; + LLVector3d pos_global = gAgent.getPositionGlobal(); + pos_map = globalPosToView(pos_global); S32 dot_width = llround(mDotRadius * 2.f); - you->draw( - llround(pos_map.mV[VX] - mDotRadius), - llround(pos_map.mV[VY] - mDotRadius), - dot_width, - dot_width); + LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; + if (you) + { + you->draw(llround(pos_map.mV[VX] - mDotRadius), + llround(pos_map.mV[VY] - mDotRadius), + dot_width, + dot_width); + } // Draw chat range ring(s) - static LLUICachedControl whisper_ring("MiniMapWhisperRing"); - static LLUICachedControl chat_ring("MiniMapChatRing"); - static LLUICachedControl shout_ring("MiniMapShoutRing"); + static LLCachedControl whisper_ring("MiniMapWhisperRing"); if(whisper_ring) drawRing(LFSimFeatureHandler::getInstance()->whisperRange(), pos_map, map_whisper_ring_color); + static LLCachedControl chat_ring("MiniMapChatRing"); if(chat_ring) drawRing(LFSimFeatureHandler::getInstance()->sayRange(), pos_map, map_chat_ring_color); + static LLCachedControl shout_ring("MiniMapShoutRing"); if(shout_ring) drawRing(LFSimFeatureHandler::getInstance()->shoutRange(), pos_map, map_shout_ring_color); @@ -531,7 +710,7 @@ void LLNetMap::draw() if (rotate_map) { - gGL.color4fv(gColors.getColor("NetMapFrustum").mV); + gGL.color4fv((map_frustum_color()).mV); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( ctr_x, ctr_y ); @@ -541,7 +720,7 @@ void LLNetMap::draw() } else { - gGL.color4fv(gColors.getColor("NetMapFrustumRotating").mV); + gGL.color4fv((map_frustum_rotating_color()).mV); // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); @@ -558,7 +737,7 @@ void LLNetMap::draw() gGL.popMatrix(); gGL.popUIMatrix(); - + // Rotation of 0 means that North is up setDirectionPos( getChild("e_label"), rotation); setDirectionPos( getChild("n_label"), rotation + F_PI_BY_TWO); @@ -570,19 +749,24 @@ void LLNetMap::draw() setDirectionPos( getChild("sw_label"), rotation + F_PI + F_PI_BY_TWO / 2); setDirectionPos( getChild("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2); - LLView::draw(); + LLUICtrl::draw(); } void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) { LLPanel::reshape(width, height, called_from_parent); createObjectImage(); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-28 (Catznip-3.3) + createParcelImage(); +// [/SL:KB] updateMinorDirections(); } -LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos, BOOL rotated) +LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos) { - LLVector3d relative_pos_global = global_pos - gAgentCamera.getCameraPositionGlobal(); + LLVector3d camera_position = gAgentCamera.getCameraPositionGlobal(); + + LLVector3d relative_pos_global = global_pos - camera_position; LLVector3 pos_local; pos_local.setVec(relative_pos_global); // convert to floats from doubles @@ -593,39 +777,39 @@ LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos, BOOL rotated) pos_local.mV[VY] *= mPixelsPerMeter; // leave Z component in meters - if( rotated ) + static LLUICachedControl rotate_map("MiniMapRotate", true); + if( rotate_map ) { F32 radians = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f)); pos_local.rotVec( rot ); } - pos_local.mV[VX] += getRect().getWidth() / 2 + mCurPanX; - pos_local.mV[VY] += getRect().getHeight() / 2 + mCurPanY; + pos_local.mV[VX] += getRect().getWidth() / 2 + mCurPan.mV[VX]; + pos_local.mV[VY] += getRect().getHeight() / 2 + mCurPan.mV[VY]; return pos_local; } void LLNetMap::drawRing(const F32 radius, const LLVector3 pos_map, const LLColor4& color) - { // Aurora Sim - F32 meters_to_pixels = mScale / LLWorld::getInstance()->getRegionWidthInMeters(); - //F32 meters_to_pixels = mScale / REGION_WIDTH_METERS; + F32 meters_to_pixels = mScale / LLWorld::getInstance()->getRegionWidthInMeters(); + //F32 meters_to_pixels = mScale / REGION_WIDTH_METERS; // Aurora Sim - F32 radius_pixels = radius * meters_to_pixels; + F32 radius_pixels = radius * meters_to_pixels; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.translatef((F32)pos_map.mV[VX], (F32)pos_map.mV[VY], 0.f); - gl_ring(radius_pixels, WIDTH_PIXELS, color, color, CIRCLE_STEPS, FALSE); - gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.translatef((F32)pos_map.mV[VX], (F32)pos_map.mV[VY], 0.f); + gl_ring(radius_pixels, WIDTH_PIXELS, color, color, CIRCLE_STEPS, FALSE); + gGL.popMatrix(); } -void LLNetMap::drawTracking(const LLVector3d& pos_global, BOOL rotated, - const LLColor4& color, BOOL draw_arrow ) +void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color, + BOOL draw_arrow ) { - LLVector3 pos_local = globalPosToView( pos_global, rotated ); + LLVector3 pos_local = globalPosToView(pos_global); if( (pos_local.mV[VX] < 0) || (pos_local.mV[VY] < 0) || (pos_local.mV[VX] >= getRect().getWidth()) || @@ -648,16 +832,17 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, BOOL rotated, } } -LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y, BOOL rotated ) +LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) { - x -= llround(getRect().getWidth() / 2 + mCurPanX); - y -= llround(getRect().getHeight() / 2 + mCurPanY); + x -= llround(getRect().getWidth() / 2 + mCurPan.mV[VX]); + y -= llround(getRect().getHeight() / 2 + mCurPan.mV[VY]); - LLVector3 pos_local( (F32)x, (F32)y, 0.f ); + LLVector3 pos_local( (F32)x, (F32)y, 0 ); F32 radians = - atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); - if( rotated ) + static LLUICachedControl rotate_map("MiniMapRotate", true); + if( rotate_map ) { LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f)); pos_local.rotVec( rot ); @@ -678,24 +863,41 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y, BOOL rotated ) BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in - F32 scale = mScale; - - scale *= pow(MAP_SCALE_ZOOM_FACTOR, -clicks); - setScale(llclamp(scale, MAP_SCALE_MIN, MAP_SCALE_MAX)); + F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); + F32 old_scale = mScale; + + setScale(new_scale); + + static LLUICachedControl center("MiniMapCenter"); + if (center == MAP_CENTER_NONE) + { + // Adjust pan to center the zoom on the mouse pointer + LLVector2 zoom_offset; + zoom_offset.mV[VX] = x - getRect().getWidth() / 2; + zoom_offset.mV[VY] = y - getRect().getHeight() / 2; + mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; + } return TRUE; } BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen ) { - BOOL handled = FALSE; if (gDisconnected) { return FALSE; } - LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(viewPosToGlobal(x, y, gSavedSettings.getBOOL( "MiniMapRotate" ))); + + LLRect sticky_rect; + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(viewPosToGlobal(x, y)); if( region ) { + // set sticky_rect + S32 SLOP = 4; + localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); + sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; + sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; + msg.assign(""); std::string fullname; if(mClosestAgentToCursor.notNull() && LLAvatarNameCache::getPNSName(mClosestAgentToCursor, fullname)) @@ -711,19 +913,12 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec if ( LLFloaterAvatarList::instanceExists() ) { - LLAvatarListEntry *ent = LLFloaterAvatarList::getInstance()->getAvatarEntry(mClosestAgentToCursor); - if ( NULL != ent ) - { - //position = LLFloaterAvatarList::AvatarPosition(mClosestAgentToCursor); + if (LLAvatarListEntry *ent = LLFloaterAvatarList::getInstance()->getAvatarEntry(mClosestAgentToCursor)) position = ent->getPosition(); - } } LLVector3d delta = position - mypos; F32 distance = (F32)delta.magVec(); - - //llinfos << distance << " - " << position << llendl; - msg.append( llformat("\n(Distance: %.02fm)\n\n",distance) ); } // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-0.2.0b @@ -731,31 +926,16 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec // [/RLVa:KB] //msg.append( region->getName() ); -//#ifndef LL_RELEASE_FOR_DOWNLOAD - std::string buffer; - msg.append("\n"); - buffer = region->getHost().getHostName(); - msg.append(buffer); - msg.append("\n"); - buffer = region->getHost().getString(); - msg.append(buffer); -//#endif - msg.append("\n"); - msg.append(getToolTip()); - - S32 SLOP = 4; - localPointToScreen( - x - SLOP, y - SLOP, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP; - sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP; - handled = TRUE; + msg.append("\n" + region->getHost().getHostName()); + msg.append("\n" + region->getHost().getString()); + msg.append("\n" + getToolTip()); } - if(!handled) + else { return LLPanel::handleToolTip(x, y, msg, sticky_rect_screen); } - return handled; + *sticky_rect_screen = sticky_rect; + return TRUE; } @@ -800,7 +980,7 @@ void LLNetMap::renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U & // DEV-17370 - megaprims of size > 4096 cause lag. (go figger.) const F32 MAX_RADIUS = 256.0f; F32 radius_clamped = llmin(radius_meters, MAX_RADIUS); - + S32 diameter_pixels = llround(2 * radius_clamped * mObjectMapTPM); renderPoint( local_pos, color, diameter_pixels ); } @@ -891,36 +1071,159 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color, } } -void LLNetMap::createObjectImage() +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +void LLNetMap::renderPropertyLinesForRegion(const LLViewerRegion* pRegion, const LLColor4U& clrOverlay) +{ + const S32 imgWidth = (S32)mParcelImagep->getWidth(); + const S32 imgHeight = (S32)mParcelImagep->getHeight(); + + const LLVector3 originLocal(pRegion->getOriginGlobal() - mParcelImageCenterGlobal); + const S32 originX = llround(originLocal.mV[VX] * mObjectMapTPM + imgWidth / 2); + const S32 originY = llround(originLocal.mV[VY] * mObjectMapTPM + imgHeight / 2); + + U32* pTextureData = (U32*)mParcelRawImagep->getData(); + + // + // Draw the north and east region borders + // + const S32 borderY = originY + llround(REGION_WIDTH_METERS * mObjectMapTPM); + if ( (borderY >= 0) && (borderY < imgHeight) ) + { + S32 curX = llclamp(originX, 0, imgWidth), endX = llclamp(originX + llround(REGION_WIDTH_METERS * mObjectMapTPM), 0, imgWidth - 1); + for (; curX <= endX; curX++) + pTextureData[borderY * imgWidth + curX] = clrOverlay.mAll; + } + const S32 borderX = originX + llround(REGION_WIDTH_METERS * mObjectMapTPM); + if ( (borderX >= 0) && (borderX < imgWidth) ) + { + S32 curY = llclamp(originY, 0, imgHeight), endY = llclamp(originY + llround(REGION_WIDTH_METERS * mObjectMapTPM), 0, imgHeight - 1); + for (; curY <= endY; curY++) + pTextureData[curY * imgWidth + borderX] = clrOverlay.mAll; + } + + // + // Render parcel lines + // + static const F32 GRID_STEP = PARCEL_GRID_STEP_METERS; + static const S32 GRIDS_PER_EDGE = REGION_WIDTH_METERS / GRID_STEP; + + const U8* pOwnership = pRegion->getParcelOverlay()->getOwnership(); + const U8* pCollision = (pRegion->getHandle() == LLViewerParcelMgr::instance().getCollisionRegionHandle()) ? LLViewerParcelMgr::instance().getCollisionBitmap() : NULL; + for (S32 idxRow = 0; idxRow < GRIDS_PER_EDGE; idxRow++) + { + for (S32 idxCol = 0; idxCol < GRIDS_PER_EDGE; idxCol++) + { + S32 overlay = pOwnership[idxRow * GRIDS_PER_EDGE + idxCol]; + S32 idxCollision = idxRow * GRIDS_PER_EDGE + idxCol; + bool fForSale = ((overlay & PARCEL_COLOR_MASK) == PARCEL_FOR_SALE); + bool fCollision = (pCollision) && (pCollision[idxCollision / 8] & (1 << (idxCollision % 8))); + if ( (!fForSale) && (!fCollision) && (0 == (overlay & (PARCEL_SOUTH_LINE | PARCEL_WEST_LINE))) ) + continue; + + const S32 posX = originX + llround(idxCol * GRID_STEP * mObjectMapTPM); + const S32 posY = originY + llround(idxRow * GRID_STEP * mObjectMapTPM); + + static LLCachedControl s_fForSaleParcels(gSavedSettings, "MiniMapForSaleParcels"); + static LLCachedControl s_fShowCollisionParcels(gSavedSettings, "MiniMapCollisionParcels"); + if ( ((s_fForSaleParcels) && (fForSale)) || ((s_fShowCollisionParcels) && (fCollision)) ) + { + S32 curY = llclamp(posY, 0, imgHeight), endY = llclamp(posY + llround(GRID_STEP * mObjectMapTPM), 0, imgHeight - 1); + for (; curY <= endY; curY++) + { + S32 curX = llclamp(posX, 0, imgWidth) , endX = llclamp(posX + llround(GRID_STEP * mObjectMapTPM), 0, imgWidth - 1); + for (; curX <= endX; curX++) + { + pTextureData[curY * imgWidth + curX] = (fForSale) ? LLColor4U(255, 255, 128, 192).mAll + : LLColor4U(255, 128, 128, 192).mAll; + } + } + } + if (overlay & PARCEL_SOUTH_LINE) + { + if ( (posY >= 0) && (posY < imgHeight) ) + { + S32 curX = llclamp(posX, 0, imgWidth), endX = llclamp(posX + llround(GRID_STEP * mObjectMapTPM), 0, imgWidth - 1); + for (; curX <= endX; curX++) + pTextureData[posY * imgWidth + curX] = clrOverlay.mAll; + } + } + if (overlay & PARCEL_WEST_LINE) + { + if ( (posX >= 0) && (posX < imgWidth) ) + { + S32 curY = llclamp(posY, 0, imgHeight), endY = llclamp(posY + llround(GRID_STEP * mObjectMapTPM), 0, imgHeight - 1); + for (; curY <= endY; curY++) + pTextureData[curY * imgWidth + posX] = clrOverlay.mAll; + } + } + } + } +} +// [/SL:KB] + +//void LLNetMap::createObjectImage() +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +bool LLNetMap::createImage(LLPointer& rawimagep) const +// [/SL:KB] { // Find the size of the side of a square that surrounds the circle that surrounds getRect(). // ... which is, the diagonal of the rect. - F32 width = getRect().getWidth(); - F32 height = getRect().getHeight(); + F32 width = (F32)getRect().getWidth(); + F32 height = (F32)getRect().getHeight(); S32 square_size = llround( sqrt(width*width + height*height) ); // Find the least power of two >= the minimum size. const S32 MIN_SIZE = 64; - const S32 MAX_SIZE = 256; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-28 (Catznip-3.3) + const S32 MAX_SIZE = 512; +// [/SL:KB] +// const S32 MAX_SIZE = 256; S32 img_size = MIN_SIZE; while( (img_size*2 < square_size ) && (img_size < MAX_SIZE) ) { img_size <<= 1; } - if( mObjectImagep.isNull() || - (mObjectImagep->getWidth() != img_size) || - (mObjectImagep->getHeight() != img_size) ) +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + if( rawimagep.isNull() || (rawimagep->getWidth() != img_size) || (rawimagep->getHeight() != img_size) ) { - mObjectRawImagep = new LLImageRaw(img_size, img_size, 4); - U8* data = mObjectRawImagep->getData(); + rawimagep = new LLImageRaw(img_size, img_size, 4); + U8* data = rawimagep->getData(); memset( data, 0, img_size * img_size * 4 ); - mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE); + return true; } - setScale(mScale); - mUpdateNow = TRUE; + return false; +// [/SL:KB] +// if( mObjectImagep.isNull() || +// (mObjectImagep->getWidth() != img_size) || +// (mObjectImagep->getHeight() != img_size) ) +// { +// mObjectRawImagep = new LLImageRaw(img_size, img_size, 4); +// U8* data = mObjectRawImagep->getData(); +// memset( data, 0, img_size * img_size * 4 ); +// mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE); +// } +// setScale(mScale); +// mUpdateNow = true; } +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +void LLNetMap::createObjectImage() +{ + if (createImage(mObjectRawImagep)) + mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE); + setScale(mScale); + mUpdateObjectImage = true; +} + +void LLNetMap::createParcelImage() +{ + if (createImage(mParcelRawImagep)) + mParcelImagep = LLViewerTextureManager::getLocalTexture( mParcelRawImagep.get(), FALSE); + mUpdateParcelImage = true; +} +// [/SL:KB] + BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask ) { if (!(mask & MASK_SHIFT)) return FALSE; @@ -928,10 +1231,9 @@ BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask ) // Start panning gFocusMgr.setMouseCapture(this); - mMouseDownPanX = llround(mCurPanX); - mMouseDownPanY = llround(mCurPanY); - mMouseDownX = x; - mMouseDownY = y; + mStartPan = mCurPan; + mMouseDown.mX = x; + mMouseDown.mY = y; return TRUE; } @@ -943,22 +1245,20 @@ BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask ) { // restore mouse cursor S32 local_x, local_y; - local_x = mMouseDownX + llfloor(mCurPanX - mMouseDownPanX); - local_y = mMouseDownY + llfloor(mCurPanY - mMouseDownPanY); + local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]); + local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]); LLRect clip_rect = getRect(); clip_rect.stretch(-8); - clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y); + clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y); LLUI::setMousePositionLocal(this, local_x, local_y); // finish the pan - mPanning = FALSE; + mPanning = false; - mMouseDownX = 0; - mMouseDownY = 0; + mMouseDown.set(0, 0); // auto centre - mTargetPanX = 0; - mTargetPanY = 0; + mTargetPan.setZero(); } gViewerWindow->showCursor(); gFocusMgr.setMouseCapture(NULL); @@ -967,8 +1267,68 @@ BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask ) return FALSE; } +// [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3.0) +bool LLNetMap::OverlayToggle::handleEvent(LLPointer event, const LLSD& sdParam) +{ + // Toggle the setting + const std::string strControl = sdParam.asString(); + BOOL fCurValue = gSavedSettings.getBOOL(strControl); + gSavedSettings.setBOOL(strControl, !fCurValue); + + // Force an overlay update + mPtr->mUpdateParcelImage = true; + return true; +} +// [/SL:KB] + +BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + mClosestAgentAtLastRightClick = mClosestAgentToCursor; + if (mPopupMenu) + { + mPopupMenu->buildDrawLabels(); + mPopupMenu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, mPopupMenu, x, y); + } + return TRUE; +} + +BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask ) +{ + LLVector3d pos_global = viewPosToGlobal(x, y); + + bool double_click_teleport = gSavedSettings.getBOOL("DoubleClickTeleport"); + bool double_click_show_world_map = gSavedSettings.getBOOL("DoubleClickShowWorldMap"); + + bool new_target = false; + if (double_click_teleport || double_click_show_world_map) + { + // If we're not tracking a beacon already, double-click will set one + if (!LLTracker::isTracking()) + { + LLFloaterWorldMap* world_map = gFloaterWorldMap; + if (world_map) + { + world_map->trackLocation(pos_global); + new_target = true; + } + } + } + + if (double_click_teleport) + { + // If DoubleClickTeleport is on, double clicking the minimap will teleport there + gAgent.teleportViaLocationLookAt(pos_global); + } + else if (double_click_show_world_map) + { + LLFloaterWorldMap::show(new_target); + } + return TRUE; +} + // static -BOOL LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop ) +bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop ) { S32 dx = x - start_x; S32 dy = y - start_y; @@ -980,23 +1340,21 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) { if (hasMouseCapture()) { - if (mPanning || outsideSlop(x, y, mMouseDownX, mMouseDownY, MOUSE_DRAG_SLOP)) + if (mPanning || outsideSlop(x, y, mMouseDown.mX, mMouseDown.mY, MOUSE_DRAG_SLOP)) { if (!mPanning) { // just started panning, so hide cursor - mPanning = TRUE; + mPanning = true; gViewerWindow->hideCursor(); } - F32 delta_x = (F32)(gViewerWindow->getCurrentMouseDX()); - F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY()); + LLVector2 delta(static_cast(gViewerWindow->getCurrentMouseDX()), + static_cast(gViewerWindow->getCurrentMouseDY())); // Set pan to value at start of drag + offset - mCurPanX += delta_x; - mCurPanY += delta_y; - mTargetPanX = mCurPanX; - mTargetPanY = mCurPanY; + mCurPan += delta; + mTargetPan = mCurPan; gViewerWindow->moveCursorToCenter(); } @@ -1020,41 +1378,6 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) return TRUE; } -BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - LLVector3d pos_global = viewPosToGlobal(x, y, gSavedSettings.getBOOL( "MiniMapRotate" )); - BOOL new_target = FALSE; - if (!LLTracker::isTracking()) - { - gFloaterWorldMap->trackLocation(pos_global); - new_target = TRUE; - } - - if (gSavedSettings.getBOOL("DoubleClickTeleport")) - { - gAgent.teleportViaLocationLookAt(pos_global); - } - else - { - LLFloaterWorldMap::show(new_target); - } - return TRUE; -} - -BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - mClosestAgentAtLastRightClick = mClosestAgentToCursor; - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); - if (menu) - { - menu->buildDrawLabels(); - menu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(this, menu, x, y); - } - return TRUE; -} - - // static bool LLNetMap::LLScaleMap::handleEvent(LLPointer event, const LLSD& userdata) { @@ -1165,11 +1488,11 @@ bool LLNetMap::LLChatRings::handleEvent(LLPointer event, const LLSD& us BOOL chat_enabled = gSavedSettings.getBOOL("MiniMapChatRing"); BOOL shout_enabled = gSavedSettings.getBOOL("MiniMapShoutRing"); BOOL all_enabled = whisper_enabled && chat_enabled && shout_enabled; - + gSavedSettings.setBOOL("MiniMapWhisperRing", !all_enabled); gSavedSettings.setBOOL("MiniMapChatRing", !all_enabled); gSavedSettings.setBOOL("MiniMapShoutRing", !all_enabled); - + return true; } @@ -1179,7 +1502,7 @@ bool LLNetMap::LLCheckChatRings::handleEvent(LLPointer event, const LLS BOOL chat_enabled = gSavedSettings.getBOOL("MiniMapChatRing"); BOOL shout_enabled = gSavedSettings.getBOOL("MiniMapShoutRing"); BOOL all_enabled = whisper_enabled && chat_enabled && shout_enabled; - + LLNetMap *self = mPtr; self->findControl(userdata["control"].asString())->setValue(all_enabled); return true; @@ -1237,4 +1560,3 @@ bool LLNetMap::LLToggleControl::handleEvent(LLPointer event, const LLSD gSavedSettings.setBOOL(control_name, !gSavedSettings.getBOOL(control_name)); return true; } - diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 82f48bc9a..2a4db214d 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -33,21 +33,31 @@ #ifndef LL_LLNETMAP_H #define LL_LLNETMAP_H +#include "llmath.h" #include "llpanel.h" #include "llmemberlistener.h" #include "v3math.h" #include "v3dmath.h" #include "v4color.h" -#include "llimage.h" +#include "llpointer.h" +#include "llcoord.h" + class LLTextBox; +class LLImageRaw; class LLViewerTexture; +class LLFloaterMap; +class LLMenuGL; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +class LLViewerRegion; +class LLAvatarName; +// [/SL:KB] -typedef enum e_minimap_center +enum EMiniMapCenter { MAP_CENTER_NONE = 0, MAP_CENTER_CAMERA = 1 -} EMiniMapCenter; +}; class LLNetMap : public LLPanel { @@ -55,77 +65,93 @@ public: LLNetMap(const std::string& name); virtual ~LLNetMap(); - virtual void draw(); - virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); - virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); - virtual BOOL handleHover( S32 x, S32 y, MASK mask ); - virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - virtual BOOL handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen ); + static const F32 MAP_SCALE_MIN; + static const F32 MAP_SCALE_MID; + static const F32 MAP_SCALE_MAX; - void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius ); + /*virtual*/ void draw(); + /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen ); + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); static void mm_setcolor(LLUUID key,LLColor4 col); //moymod -private: +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + void refreshParcelOverlay() { mUpdateParcelImage = true; } +// [/SL:KB] void setScale( F32 scale ); + void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius ); - // Not used at present - void translatePan( F32 delta_x, F32 delta_y ); - void setPan( F32 x, F32 y ) { mTargetPanX = x; mTargetPanY = y; } - +private: + const LLVector3d& getObjectImageCenterGlobal() { return mObjectImageCenterGlobal; } void renderPoint(const LLVector3 &pos, const LLColor4U &color, S32 diameter, S32 relative_height = 0); - LLVector3 globalPosToView(const LLVector3d& global_pos, BOOL rotated); - LLVector3d viewPosToGlobal(S32 x,S32 y, BOOL rotated); + + LLVector3 globalPosToView(const LLVector3d& global_pos); + LLVector3d viewPosToGlobal(S32 x,S32 y); void drawRing(const F32 radius, LLVector3 pos_map, const LLColor4& color); void drawTracking( const LLVector3d& pos_global, - BOOL rotated, const LLColor4& color, BOOL draw_arrow = TRUE); void setDirectionPos( LLTextBox* text_box, F32 rotation ); void updateMinorDirections(); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + bool createImage(LLPointer& rawimagep) const; void createObjectImage(); + void createParcelImage(); - LLHandle mPopupMenuHandle; + void renderPropertyLinesForRegion(const LLViewerRegion* pRegion, const LLColor4U& clrOverlay); +// [/SL:KB] +// void createObjectImage(); + + static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop); + +private: +// bool mUpdateNow; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + bool mUpdateObjectImage; +protected: + friend class OverlayToggle; + bool mUpdateParcelImage; +private: +// [/SL:KB] F32 mScale; // Size of a region in pixels F32 mPixelsPerMeter; // world meters to map pixels F32 mObjectMapTPM; // texels per meter on map F32 mObjectMapPixels; // Width of object map in pixels F32 mDotRadius; // Size of avatar markers - F32 mTargetPanX; - F32 mTargetPanY; - F32 mCurPanX; - F32 mCurPanY; - BOOL mPanning; // map has been dragged - S32 mMouseDownPanX; // value at start of drag - S32 mMouseDownPanY; // value at start of drag - S32 mMouseDownX; - S32 mMouseDownY; + bool mPanning; // map is being dragged + LLVector2 mTargetPan; + LLVector2 mCurPan; + LLVector2 mStartPan; // pan offset at start of drag + LLCoordGL mMouseDown; // pointer position at start of drag - BOOL mUpdateNow; LLVector3d mObjectImageCenterGlobal; LLPointer mObjectRawImagep; LLPointer mObjectImagep; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + LLVector3d mParcelImageCenterGlobal; + LLPointer mParcelRawImagep; + LLPointer mParcelImagep; +// [/SL:KB] -private: LLUUID mClosestAgentToCursor; LLVector3d mClosestAgentPosition; LLUUID mClosestAgentAtLastRightClick; - static BOOL sRotateMap; - static LLNetMap* sInstance; - static BOOL isAgentUnderCursor(void*) { return sInstance && sInstance->mClosestAgentToCursor.notNull(); } - static BOOL outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop); - static void showAgentProfile(void*); BOOL isAgentUnderCursor() { return mClosestAgentToCursor.notNull(); } @@ -183,10 +209,7 @@ private: /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata); }; - - //moymod - Custom minimap markers :o - class mmsetred : public LLMemberListener //moymod { public: @@ -224,9 +247,6 @@ private: }; - - - class LLEnableProfile : public LLMemberListener { public: @@ -238,7 +258,16 @@ private: public: /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata); }; - + +// [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3.0) + class OverlayToggle : public LLMemberListener + { + public: + /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata); + }; +// [/SL:KB] + + LLMenuGL* mPopupMenu; }; diff --git a/indra/newview/llpaneldisplay.cpp b/indra/newview/llpaneldisplay.cpp index 0f7184757..9fc9b96c9 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -334,6 +334,16 @@ BOOL LLPanelDisplay::postBuild() mVBOStream = getChild("vbo_stream"); + if(gGLManager.mIsATI) //AMD gpus don't go beyond 8x fsaa. + { + LLComboBox* fsaa = getChild("fsaa"); + fsaa->remove("16x"); + } + if(!gGLManager.mHasAdaptiveVsync) + { + LLComboBox* vsync = getChild("vsync"); + vsync->remove("VSyncAdaptive"); + } refresh(); @@ -447,8 +457,10 @@ void LLPanelDisplay::refresh() mGamma = gSavedSettings.getF32("RenderGamma"); mVideoCardMem = gSavedSettings.getS32("TextureMemory"); mFogRatio = gSavedSettings.getF32("RenderFogRatio"); + mVsyncMode = gSavedSettings.getS32("SHRenderVsyncMode"); childSetValue("fsaa", (LLSD::Integer) mFSAASamples); + childSetValue("vsync", (LLSD::Integer) mVsyncMode); refreshEnabledState(); } @@ -846,13 +858,22 @@ void LLPanelDisplay::cancel() gSavedSettings.setF32("RenderGamma", mGamma); gSavedSettings.setS32("TextureMemory", mVideoCardMem); gSavedSettings.setF32("RenderFogRatio", mFogRatio); + gSavedSettings.setS32("SHRenderVsyncMode", mVsyncMode); } void LLPanelDisplay::apply() { U32 fsaa_value = childGetValue("fsaa").asInteger(); + S32 vsync_value = childGetValue("vsync").asInteger(); + + if(vsync_value == -1 && !gGLManager.mHasAdaptiveVsync) + vsync_value = 0; + bool apply_fsaa_change = !gSavedSettings.getBOOL("RenderUseFBO") && (mFSAASamples != fsaa_value); + bool apply_vsync_change = vsync_value != mVsyncMode; + gSavedSettings.setU32("RenderFSAASamples", fsaa_value); + gSavedSettings.setS32("SHRenderVsyncMode", vsync_value); applyResolution(); @@ -865,7 +886,7 @@ void LLPanelDisplay::apply() // Hardware tab //Still do a bit of voodoo here. V2 forces restart to change FSAA with FBOs off. //Let's not do that, and instead do pre-V2 FSAA change handling for that particular case - if(apply_fsaa_change) + if(apply_fsaa_change || apply_vsync_change) { bool logged_in = (LLStartUp::getStartupState() >= STATE_STARTED); LLWindow* window = gViewerWindow->getWindow(); @@ -875,7 +896,7 @@ void LLPanelDisplay::apply() LLGLState::checkTextureChannels(); gViewerWindow->changeDisplaySettings(window->getFullscreen(), size, - gSavedSettings.getBOOL("DisableVerticalSync"), + vsync_value, logged_in); LLGLState::checkStates(); LLGLState::checkTextureChannels(); diff --git a/indra/newview/llpaneldisplay.h b/indra/newview/llpaneldisplay.h index 9b39ee555..1652b497b 100644 --- a/indra/newview/llpaneldisplay.h +++ b/indra/newview/llpaneldisplay.h @@ -194,6 +194,7 @@ protected: F32 mGamma; S32 mVideoCardMem; F32 mFogRatio; + S32 mVsyncMode; // if the quality radio buttons are changed void onChangeQuality(LLUICtrl* caller); diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 9e4ef15cc..92ce2545f 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -129,10 +129,7 @@ void LLPanelGroupTab::handleClickHelp() } } -static void copy_group_profile_uri(const LLUUID& id) -{ - gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring("secondlife:///app/group/"+id.asString()+"/about")); -} +void copy_profile_uri(const LLUUID& id, bool group); LLPanelGroup::LLPanelGroup(const LLUUID& group_id) : LLPanel("PanelGroup", LLRect(), FALSE), @@ -163,7 +160,7 @@ LLPanelGroup::LLPanelGroup(const LLUUID& group_id) LLGroupMgr::getInstance()->addObserver(this); - mCommitCallbackRegistrar.add("Group.CopyURI", boost::bind(copy_group_profile_uri, boost::ref(mID))); + mCommitCallbackRegistrar.add("Group.CopyURI", boost::bind(copy_profile_uri, boost::ref(mID), true)); // Pass on construction of this panel to the control factory. LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group.xml", &getFactoryMap()); } diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 2b1bbf804..5b58e6b76 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -828,6 +828,8 @@ void LLPanelGroupGeneral::updateMembers() } } +bool is_online_status_string(const std::string& status); + void LLPanelGroupGeneral::addMember(LLGroupMemberData* member) { // Owners show up in bold. @@ -845,9 +847,8 @@ void LLPanelGroupGeneral::addMember(LLGroupMemberData* member) item_params.columns.add().column("title").value(member->getTitle()).font/*.name*/("SANSSERIF_SMALL").font_style(style); static const LLCachedControl format(gSavedSettings, "ShortDateFormat"); - static const std::string online(LLTrans::getString("group_member_status_online")); item_params.columns.add().column("online").value(member->getOnlineStatus()) - .format(format).type(member->getOnlineStatus() == online ? "text" : "date") + .format(format).type(is_online_status_string(member->getOnlineStatus()) ? "text" : "date") .font/*.name*/("SANSSERIF_SMALL").font_style(style); /*LLScrollListItem* member_row =*/ mListVisibleMembers->addNameItemRow(item_params); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index d713ff9e8..e38bda37b 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1523,6 +1523,14 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc) } } +bool is_online_status_string(const std::string& status) +{ + static const std::string online(LLTrans::getString("group_member_status_online")); + if (status == online) return true; + static const std::string unknown(LLTrans::getString("group_member_status_unknown")); + return status == unknown; +} + void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data) { if (!data) return; @@ -1538,9 +1546,8 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data) .font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/; static const LLCachedControl format(gSavedSettings, "ShortDateFormat"); - static const std::string online(LLTrans::getString("group_member_status_online")); item_params.columns.add().column("online").value(data->getOnlineStatus()) - .format(format).type(data->getOnlineStatus() == online ? "text" : "date") + .format(format).type(is_online_status_string(data->getOnlineStatus()) ? "text" : "date") .font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/; mMembersList->addNameItemRow(item_params); diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp index 19d1a8d82..526ade3e9 100644 --- a/indra/newview/llpanelland.cpp +++ b/indra/newview/llpanelland.cpp @@ -52,10 +52,6 @@ #include "hippogridmanager.h" -// [RLVa:KB] -#include "rlvhandler.h" -// [/RLVa:KB] - LLPanelLandSelectObserver* LLPanelLandInfo::sObserver = NULL; LLPanelLandInfo* LLPanelLandInfo::sInstance = NULL; @@ -239,12 +235,6 @@ void LLPanelLandInfo::refresh() //static void LLPanelLandInfo::onClickClaim(void*) { -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) - { - return; - } -// [/RLVa:KB] LLViewerParcelMgr::getInstance()->startBuyLand(); } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index f0a950b40..a219868d3 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -159,32 +159,22 @@ LLLoginRefreshHandler gLoginRefreshHandler; //--------------------------------------------------------------------------- // Public methods //--------------------------------------------------------------------------- -LLPanelLogin::LLPanelLogin(const LLRect &rect, - void (*callback)(S32 option, void* user_data), - void *cb_data) -: LLPanel(std::string("panel_login"), LLRect(0,600,800,0), FALSE), // not bordered - mLogoImage(), - mCallback(callback), - mCallbackData(cb_data) +LLPanelLogin::LLPanelLogin(const LLRect& rect) +: LLPanel(std::string("panel_login"), rect, FALSE), // not bordered + mLogoImage(LLUI::getUIImage("startup_logo.j2c")) { setFocusRoot(TRUE); setBackgroundVisible(FALSE); setBackgroundOpaque(TRUE); - gViewerWindow->abortShowProgress(); //Kill previous instance. It might still be alive, and if so, its probably pending - //deletion via the progressviews idle callback. Kill it now and unregister said idle callback. - LLPanelLogin::sInstance = this; // add to front so we are the bottom-most child gViewerWindow->getRootView()->addChildInBack(this); - // Logo - mLogoImage = LLUI::getUIImage("startup_logo.j2c"); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_login.xml"); - + reshape(rect.getWidth(), rect.getHeight()); LLComboBox* username_combo(getChild("username_combo")); @@ -243,12 +233,12 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed } - childSetAction("connect_btn", onClickConnect, this); - setDefaultBtn("connect_btn"); // Also set default button for subpanels, otherwise hitting enter in text entry fields won't login { LLButton* connect_btn(findChild("connect_btn")); + connect_btn->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this)); + setDefaultBtn(connect_btn); findChild("name_panel")->setDefaultBtn(connect_btn); findChild("password_panel")->setDefaultBtn(connect_btn); findChild("grids_panel")->setDefaultBtn(connect_btn); @@ -287,6 +277,24 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, refreshLoginPage(); gHippoGridManager->setCurrentGridChangeCallback(boost::bind(&LLPanelLogin::onCurGridChange,this,_1,_2)); + + // Load login history + std::string login_hist_filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "saved_logins_sg2.xml"); + mLoginHistoryData = LLSavedLogins::loadFile(login_hist_filepath); + + const LLSavedLoginsList& saved_login_entries(mLoginHistoryData.getEntries()); + for (LLSavedLoginsList::const_reverse_iterator i = saved_login_entries.rbegin(); + i != saved_login_entries.rend(); ++i) + { + LLSD e = i->asLLSD(); + if (e.isMap() && gHippoGridManager->getGrid(i->getGrid())) + username_combo->add(getDisplayString(*i), e); + } + + if (saved_login_entries.size() > 0) + { + setFields(*saved_login_entries.rbegin()); + } } void LLPanelLogin::setSiteIsAlive( bool alive ) @@ -355,24 +363,6 @@ LLPanelLogin::~LLPanelLogin() } } -void LLPanelLogin::setLoginHistory(LLSavedLogins const& login_history) -{ - sInstance->mLoginHistoryData = login_history; - - LLComboBox* login_combo = sInstance->getChild("username_combo"); - llassert(login_combo); - login_combo->clear(); - - LLSavedLoginsList const& saved_login_entries(login_history.getEntries()); - for (LLSavedLoginsList::const_reverse_iterator i = saved_login_entries.rbegin(); - i != saved_login_entries.rend(); ++i) - { - LLSD e = i->asLLSD(); - if (e.isMap() && gHippoGridManager->getGrid(i->getGrid())) - login_combo->add(getDisplayString(*i), e); - } -} - // virtual void LLPanelLogin::draw() { @@ -449,12 +439,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask) } #endif - if (KEY_RETURN == key && MASK_NONE == mask) - { - // let the panel handle UICtrl processing: calls onClickConnect() - return LLPanel::handleKeyHere(key, mask); - } - return LLPanel::handleKeyHere(key, mask); } @@ -514,11 +498,10 @@ void LLPanelLogin::giveFocus() // static -void LLPanelLogin::show(const LLRect &rect, - void (*callback)(S32 option, void* user_data), - void* callback_data) +void LLPanelLogin::show() { - new LLPanelLogin(rect, callback, callback_data); + if (sInstance) sInstance->setVisible(true); + else new LLPanelLogin(gViewerWindow->getVirtualWindowRect()); if( !gFocusMgr.getKeyboardFocus() ) { @@ -664,7 +647,7 @@ void LLPanelLogin::updateLocationSelectorsVisibility() sInstance->getChildView("location_panel")->setVisible(show_start); - bool show_server = true; + bool show_server = gSavedSettings.getBOOL("ForceShowGrid"); sInstance->getChildView("grids_panel")->setVisible(show_server); } @@ -892,28 +875,24 @@ bool LLPanelLogin::getRememberLogin() //--------------------------------------------------------------------------- // static -void LLPanelLogin::onClickConnect(void *) +void LLPanelLogin::onClickConnect() { - if (sInstance && sInstance->mCallback) + // JC - Make sure the fields all get committed. + gFocusMgr.setKeyboardFocus(NULL); + + std::string first, last, password; + if (nameSplit(getChild("username_combo")->getTextEntry(), first, last)) { - - // JC - Make sure the fields all get committed. - gFocusMgr.setKeyboardFocus(NULL); - - std::string first, last, password; - if (nameSplit(sInstance->getChild("username_combo")->getTextEntry(), first, last)) - { - // has both first and last name typed - sInstance->mCallback(0, sInstance->mCallbackData); - } - else - { - if (gHippoGridManager->getCurrentGrid()->getRegisterUrl().empty()) { - LLNotificationsUtil::add("MustHaveAccountToLogInNoLinks"); - } else { - LLNotificationsUtil::add("MustHaveAccountToLogIn", LLSD(), LLSD(), - LLPanelLogin::newAccountAlertCallback); - } + // has both first and last name typed + LLStartUp::setStartupState(STATE_LOGIN_CLEANUP); + } + else + { + if (gHippoGridManager->getCurrentGrid()->getRegisterUrl().empty()) { + LLNotificationsUtil::add("MustHaveAccountToLogInNoLinks"); + } else { + LLNotificationsUtil::add("MustHaveAccountToLogIn", LLSD(), LLSD(), + LLPanelLogin::newAccountAlertCallback); } } } diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index b1a7ff935..05c4c3b18 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -49,18 +49,15 @@ class LLPanelLogin: { LOG_CLASS(LLPanelLogin); public: - LLPanelLogin(const LLRect &rect, - void (*callback)(S32 option, void* user_data), - void *callback_data); + LLPanelLogin(const LLRect& rect = LLRect()); ~LLPanelLogin(); virtual BOOL handleKeyHere(KEY key, MASK mask); virtual void draw(); virtual void setFocus( BOOL b ); - static void show(const LLRect &rect, - void (*callback)(S32 option, void* user_data), - void* callback_data); + static void show(); + static void hide() { if (sInstance) sInstance->setVisible(false); } // Remember password checkbox is set via gSavedSettings "RememberPassword" @@ -69,7 +66,6 @@ public: * @param firstname First name value. * @param lastname Last name value. * @param password Password, as plaintext or munged. - * @param is_secondlife True if First/Last refer to a SecondLife(tm) account. */ static void setFields(const std::string& firstname, const std::string& lastname, const std::string& password); @@ -110,7 +106,7 @@ private: void reshapeBrowser(); void onLocationSLURL(); - static void onClickConnect(void*); + void onClickConnect(); static void onClickNewAccount(); static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response); static void onClickGrids(void*); @@ -124,10 +120,6 @@ private: static void clearPassword(); public: - /** - * @brief Set the login history data. - */ - static void setLoginHistory(LLSavedLogins const& login_history); /** * @brief Returns the login history data. @@ -144,14 +136,9 @@ public: */ static bool getRememberLogin(); - //static void selectFirstElement(void); - private: LLPointer mLogoImage; - void (*mCallback)(S32 option, void *userdata); - void* mCallbackData; - std::string mIncomingPassword; std::string mMungedPassword; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index cd7b2ebd4..71b507ef6 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -30,6 +30,7 @@ #include "llagent.h" #include "llagentcamera.h" #include "lleconomy.h" +#include "llfirstuse.h" #include "llfiltereditor.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" @@ -444,6 +445,8 @@ void LLInventoryView::toggleVisibility() S32 count = sActiveViews.count(); if (0 == count) { + // We're using the inventory, possibly for the first time. + LLFirstUse::useInventory(); showAgentInventory(TRUE); } else if (1 == count) diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp index 7800eb791..2a19fea07 100644 --- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp @@ -83,7 +83,7 @@ void LLOutboxInventoryPanel::buildFolderView(/*const LLInventoryPanel::Params& p NULL, root_id); - mFolderRoot = createFolderView(new_listener, true/*params.use_label_suffix()*/); + mFolderRoot = createFolderView(new_listener, true/*params.use_label_suffix()*/)->getHandle(); } LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge) @@ -93,7 +93,7 @@ LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridg bridge->getIcon(), bridge->getOpenIcon(), LLUI::getUIImage("inv_link_overlay.tga"), - mFolderRoot, + mFolderRoot.get(), bridge); } @@ -105,7 +105,7 @@ LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge->getOpenIcon(), LLUI::getUIImage("inv_link_overlay.tga"), bridge->getCreationDate(), - mFolderRoot, + mFolderRoot.get(), bridge); } diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 77363270a..1cf09178e 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -552,6 +552,8 @@ void LLPanelObject::getState( ) mBtnCopySize->setEnabled( enable_scale ); mBtnPasteSize->setEnabled( enable_scale ); mBtnPasteSizeClip->setEnabled( enable_scale ); + mCtrlPosX->setMaxValue(objectp->getRegion()->getWidth()); + mCtrlPosY->setMaxValue(objectp->getRegion()->getWidth()); // Singu TODO: VarRegions, getLength() mCtrlPosZ->setMaxValue(gHippoLimits->getMaxHeight()); mCtrlScaleX->setMaxValue(gHippoLimits->getMaxPrimScale()); mCtrlScaleY->setMaxValue(gHippoLimits->getMaxPrimScale()); diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 6fc0ab438..99ff385ee 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -314,8 +314,8 @@ void LLPhysicsMotion::getString(std::ostringstream &oss) } } -LLPhysicsMotionController::LLPhysicsMotionController(const LLUUID &id) : - LLMotion(id), +LLPhysicsMotionController::LLPhysicsMotionController(LLUUID const& id, LLMotionController* controller) : + AIMaskedMotion(id, controller, ANIM_AGENT_PHYSICS_MOTION), mCharacter(NULL), mIsDefault(true) { @@ -332,15 +332,6 @@ LLPhysicsMotionController::~LLPhysicsMotionController() } } -BOOL LLPhysicsMotionController::onActivate() -{ - return TRUE; -} - -void LLPhysicsMotionController::onDeactivate() -{ -} - LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter *character) { mCharacter = character; @@ -889,4 +880,4 @@ void LLPhysicsMotion::reset() mCharacter->setVisualParamWeight((*iter).mParam,(*iter).mParam->getDefaultWeight()); } } -} \ No newline at end of file +} diff --git a/indra/newview/llphysicsmotion.h b/indra/newview/llphysicsmotion.h index 7412c9d88..2ce79b220 100644 --- a/indra/newview/llphysicsmotion.h +++ b/indra/newview/llphysicsmotion.h @@ -42,14 +42,14 @@ class LLPhysicsMotion; // class LLPhysicsMotion //----------------------------------------------------------------------------- class LLPhysicsMotionController : - public LLMotion + public AIMaskedMotion { public: std::string getString(); // Constructor - LLPhysicsMotionController(const LLUUID &id); + LLPhysicsMotionController(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLPhysicsMotionController(); @@ -61,7 +61,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLPhysicsMotionController(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLPhysicsMotionController(id, controller); } public: //------------------------------------------------------------------------- @@ -93,19 +93,11 @@ public: // must return true to indicate success and be available for activation virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - LLCharacter* getCharacter() { return mCharacter; } protected: diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index cbaa5d47e..23981e565 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -135,13 +135,6 @@ void LLProgressView::revealIntroPanel() gIdleCallbacks.addFunction(onIdle, this); } -void LLProgressView::abortShowProgress() -{ - mFadeFromLoginTimer.stop(); - LLPanelLogin::close(); - gIdleCallbacks.deleteFunction(onIdle, this); -} - void LLProgressView::setStartupComplete() { mStartupComplete = true; @@ -334,7 +327,7 @@ void LLProgressView::onIdle(void* user_data) self->mFadeFromLoginTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME) { self->mFadeFromLoginTimer.stop(); - LLPanelLogin::close(); + LLPanelLogin::hide(); // Nothing to do anymore. gIdleCallbacks.deleteFunction(onIdle, user_data); diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index 816305efd..bff970e29 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -62,7 +62,6 @@ public: void setMessage(const std::string& msg); void revealIntroPanel(); - void abortShowProgress(); void setStartupComplete(); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index f16409e32..976397931 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -94,6 +94,7 @@ #include "hippogridmanager.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) +#include "rlvactions.h" #include "rlvhandler.h" // [/RLVa:KB] @@ -661,7 +662,7 @@ bool LLSelectMgr::enableLinkObjects() } } // [RLVa:KB] - Checked: 2011-03-19 (RLVa-1.3.0f) | Modified: RLVa-0.2.0g - if ( (new_value) && ((rlv_handler_t::isEnabled()) && (!gRlvHandler.canStand())) ) + if ( (new_value) && ((rlv_handler_t::isEnabled()) && (!RlvActions::canStand())) ) { // Allow only if the avie isn't sitting on any of the selected objects LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); @@ -683,7 +684,7 @@ bool LLSelectMgr::enableUnlinkObjects() !first_editable_object->isAttachment() && !first_editable_object->isPermanentEnforced() && ((root_object == NULL) || !root_object->isPermanentEnforced()); // [RLVa:KB] - Checked: 2011-03-19 (RLVa-1.3.0f) | Modified: RLVa-0.2.0g - if ( (new_value) && ((rlv_handler_t::isEnabled()) && (!gRlvHandler.canStand())) ) + if ( (new_value) && ((rlv_handler_t::isEnabled()) && (!RlvActions::canStand())) ) { // Allow only if the avie isn't sitting on any of the selected objects LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); @@ -6505,7 +6506,7 @@ void LLSelectMgr::updateSelectionCenter() mSelectionCenterGlobal.clearVec(); mShowSelection = FALSE; mSelectionBBox = LLBBox(); - mPauseRequest = NULL; + mPauseRequests.clear(); resetAgentHUDZoom(); } @@ -6515,27 +6516,18 @@ void LLSelectMgr::updateSelectionCenter() if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) { - // Singu Note: Chalice Yao's pause agent on attachment selection - if (object->permYouOwner()) + // Freeze avatars with a selected attachment, and all avatars with synchronized motions, if any. + LLVOAvatar* avatar = object->getAvatar(); + // It is possible that 'avatar' is NULL despite this being an attachment because of some race condition. + // In that case just don't freeze the avatar. + if (avatar) { - mPauseRequest = gAgentAvatarp->requestPause(); - } - else if (LLViewerObject* objectp = mSelectedObjects->getPrimaryObject()) - { - while (objectp && !objectp->isAvatar()) - { - objectp = (LLViewerObject*)objectp->getParent(); - } - - if (objectp) - { - mPauseRequest = objectp->asAvatar()->requestPause(); - } + avatar->pauseAllSyncedCharacters(mPauseRequests); } } else { - mPauseRequest = NULL; + mPauseRequests.clear(); } if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid()) @@ -6733,6 +6725,24 @@ void LLSelectMgr::doDelete() selectDelete(); } +// Note: Allow Ctrl-A for select all linked prims +//----------------------------------------------------------------------------- +// canSelectAll() +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::canSelectAll() const +{ + return !mSelectedObjects->isEmpty(); +} + +//----------------------------------------------------------------------------- +// selectAll() +//----------------------------------------------------------------------------- +void LLSelectMgr::selectAll() +{ + promoteSelectionToRoot(); +} +// + //----------------------------------------------------------------------------- // canDeselect() //----------------------------------------------------------------------------- diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index ce16d0569..145c25005 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -389,6 +389,9 @@ public: virtual BOOL canDoDelete() const; virtual void doDelete(); + virtual void selectAll(); + virtual BOOL canSelectAll() const; + virtual void deselect(); virtual BOOL canDeselect() const; @@ -790,7 +793,7 @@ private: LLFrameTimer mEffectsTimer; BOOL mForceSelection; - LLAnimPauseRequest mPauseRequest; + std::vector mPauseRequests; // Selected avatar and all synchronized avatars. friend class LLObjectBackup; }; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index c2fb74365..9ad74f7a0 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -45,6 +45,7 @@ #include "llvolumeoctree.h" #include "llviewercamera.h" #include "llface.h" +#include "llfloaterinspect.h" #include "llfloatertools.h" #include "llviewercontrol.h" #include "llviewerregion.h" @@ -1528,6 +1529,7 @@ static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw"); void LLSpatialGroup::doOcclusion(LLCamera* camera) { + LLGLDisable stencil(GL_STENCIL_TEST); if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) { //static const LLCachedControl render_water_void_culling("RenderWaterVoidCulling", TRUE); @@ -3867,6 +3869,8 @@ public: return; } + LLGLDisable stencil(GL_STENCIL_TEST); + group->rebuildGeom(); group->rebuildMesh(); @@ -4372,7 +4376,7 @@ public: if (vobj->isAvatar()) { LLVOAvatar* avatar = (LLVOAvatar*) vobj; - if (avatar->isSelf() && gFloaterTools->getVisible()) + if (gFloaterTools->getVisible() || LLFloaterInspect::instanceExists()) { LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent); if (hit) diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 3ab2d2b68..8d2b5a47b 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -711,7 +711,7 @@ class LLVolumeGeometryManager: public LLGeometryManager virtual void rebuildGeom(LLSpatialGroup* group); virtual void rebuildMesh(LLSpatialGroup* group); virtual void getGeometry(LLSpatialGroup* group); - void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE); + void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE); void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); }; diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 0f15435dc..215e9f242 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -88,11 +88,11 @@ void LLSpeaker::lookupName() void LLSpeaker::onNameCache(const LLAvatarName& full_name) { - static const LLCachedControl legacy_name("LiruLegacySpeakerNames"); - if (legacy_name) + static const LLCachedControl name_system("SpeakerNameSystem"); + if (!name_system) mDisplayName = gCacheName->cleanFullName(full_name.getLegacyName()); else - LLAvatarNameCache::getPNSName(full_name, mDisplayName); + LLAvatarNameCache::getPNSName(full_name, mDisplayName, name_system); } bool LLSpeaker::isInVoiceChannel() diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 0cf590cd8..cc2cc300c 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -291,8 +291,7 @@ boost::scoped_ptr LLStartUp::sPhases(new LLViewerStats: // local function declaration // -void login_show(LLSavedLogins const& saved_logins); -void login_callback(S32 option, void* userdata); +void login_show(); void show_first_run_dialog(); bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); void set_startup_status(const F32 frac, const std::string& string, const std::string& msg); @@ -882,24 +881,17 @@ bool idle_startup() gViewerWindow->setShowProgress(FALSE); display_startup(); - // Load login history - std::string login_hist_filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "saved_logins_sg2.xml"); - LLSavedLogins login_history = LLSavedLogins::loadFile(login_hist_filepath); - display_startup(); - // Show the login dialog. - login_show(login_history); + login_show(); display_startup(); - if (login_history.size() > 0) - { - LLPanelLogin::setFields(*login_history.getEntries().rbegin()); - } - else + static bool sSetFields(LLPanelLogin::getLoginHistory().size() > 0); // If there were no entries to be loaded, use what's available + if (!sSetFields) { LLPanelLogin::setFields(firstname, lastname, password); + sSetFields = true; // Never reset the fields again! + display_startup(); + LLPanelLogin::giveFocus(); } - display_startup(); - LLPanelLogin::giveFocus(); gSavedSettings.setBOOL("FirstRunThisInstall", FALSE); @@ -1416,6 +1408,7 @@ bool idle_startup() // Yay, login! successful_login = true; Debug(if (gCurlIo) dc::curlio.off()); // Login succeeded: restore dc::curlio to original state. + LLPanelLogin::close(); // Singu Note: Actually destroy the login panel here, otherwise user interaction gets lost upon failed login. } else if(login_response == "indeterminate") { @@ -2712,59 +2705,17 @@ bool idle_startup() // local function definition // -void login_show(LLSavedLogins const& saved_logins) +void login_show() { LL_INFOS("AppInit") << "Initializing Login Screen" << LL_ENDL; // This creates the LLPanelLogin instance. - LLPanelLogin::show( gViewerWindow->getVirtualWindowRect(), - login_callback, NULL ); - - // Now that the LLPanelLogin instance is created, - // store the login history there. - LLPanelLogin::setLoginHistory(saved_logins); + LLPanelLogin::show(); // UI textures have been previously loaded in doPreloadImages() } -// Callback for when login screen is closed. Option 0 = connect, option 1 = quit. -void login_callback(S32 option, void *userdata) -{ - const S32 CONNECT_OPTION = 0; - const S32 QUIT_OPTION = 1; - - if (CONNECT_OPTION == option) - { - LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); - return; - } - else if (QUIT_OPTION == option) - { - // Make sure we don't save the password if the user is trying to clear it. - std::string first, last, password; - LLPanelLogin::getFields(&first, &last, &password); - if (!gSavedSettings.getBOOL("RememberPassword")) - { - // turn off the setting and write out to disk - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile") , TRUE ); - } - - // Next iteration through main loop should shut down the app cleanly. - LLAppViewer::instance()->userQuit(); - - if (LLAppViewer::instance()->quitRequested()) - { - LLPanelLogin::close(); - } - return; - } - else - { - LL_WARNS("AppInit") << "Unknown login button clicked" << LL_ENDL; - } -} - // static std::string LLStartUp::loadPasswordFromDisk() @@ -3504,7 +3455,7 @@ void LLStartUp::initNameCache() // capabilities for display name lookup LLAvatarNameCache::initClass(false); S32 phoenix_name_system = gSavedSettings.getS32("PhoenixNameSystem"); - if(phoenix_name_system <= 0 || phoenix_name_system > 2) LLAvatarNameCache::setUseDisplayNames(false); + if(phoenix_name_system <= 0 || phoenix_name_system > 3) LLAvatarNameCache::setUseDisplayNames(false); else LLAvatarNameCache::setUseDisplayNames(true); } diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 1bfc7ca9e..d15900993 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -95,7 +95,8 @@ #include "hippogridmanager.h" // [RLVa:KB] -#include "rlvhandler.h" +#include "rlvactions.h" +#include "rlvcommon.h" // [/RLVa:KB] // @@ -595,7 +596,7 @@ void LLStatusBar::refresh() } // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-1.0.0a - if ( (region) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) // region == NULL if we lose our connection to the grid + if ( (region) && (RlvActions::hasBehaviour(RLV_BHVR_SHOWLOC)) ) // region == NULL if we lose our connection to the grid { location_name = llformat("%s (%s) - %s", RlvStrings::getString(RLV_STRING_HIDDEN_REGION).c_str(), region->getSimAccessString().c_str(), @@ -922,13 +923,6 @@ static void onClickScripts(void*) static void onClickBuyLand(void*) { -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) - if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) - { - return; - } -// [/RLVa:KB] - LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); LLViewerParcelMgr::getInstance()->startBuyLand(); } diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index 985d27f15..5612088d8 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -35,29 +35,21 @@ #include "lltoolbar.h" -#include "llbutton.h" #include "llflyoutbutton.h" #include "llscrolllistitem.h" -#include "llui.h" #include "llagent.h" #include "llagentcamera.h" -#include "llagentwearables.h" -#include "llfirstuse.h" -#include "llviewerparcelmgr.h" -#include "llfloateravatarlist.h" #include "llfloaterchat.h" #include "llfloaterchatterbox.h" -#include "llfloatercustomize.h" #include "llfloaterfriends.h" #include "llfloaterinventory.h" #include "llfloatermute.h" -#include "llfloatersnapshot.h" #include "llimpanel.h" #include "llimview.h" -#include "llmenucommands.h" -#include "lltoolmgr.h" #include "lltoolgrab.h" +#include "lltoolmgr.h" +#include "llviewerparcelmgr.h" #include "llvoavatarself.h" // [RLVa:KB] @@ -66,24 +58,30 @@ #if LL_DARWIN - #include "llresizehandle.h" - #include "llviewerwindow.h" +#include "llresizehandle.h" +#include "llviewerwindow.h" - // This class draws like an LLResizeHandle but has no interactivity. - // It's just there to provide a cue to the user that the lower right corner of the window functions as a resize handle. - class LLFakeResizeHandle : public LLResizeHandle +// This class draws like an LLResizeHandle but has no interactivity. +// It's just there to provide a cue to the user that the lower right corner of the window functions as a resize handle. +class LLFakeResizeHandle : public LLResizeHandle +{ +public: + LLFakeResizeHandle(const LLResizeHandle::Params& p) : LLResizeHandle(p) {} + + virtual BOOL handleHover(S32 x, S32 y, MASK mask) { return false; } + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return false; } + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) { return false; } + virtual void reshape(S32 width, S32 height, BOOL called_from_parent) { - public: - LLFakeResizeHandle(const LLResizeHandle::Params& p) - : LLResizeHandle(p) - { - } + // Only when running in windowed mode on the Mac, leave room for a resize widget on the right edge of the bar. + if (gViewerWindow->getWindow()->getFullscreen()) + return setVisible(false); - virtual BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; }; - virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; }; - virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) { return FALSE; }; - - }; + setVisible(true); + const F32 wide(gViewerWindow->getWindowWidth() + 2); + setRect(LLRect(wide - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, wide, 0)); + } +}; #endif // LL_DARWIN @@ -102,56 +100,21 @@ F32 LLToolBar::sInventoryAutoOpenTime = 1.f; // // Functions // +void show_floater(const std::string& floater_name); LLToolBar::LLToolBar() : LLLayoutPanel() -#if LL_DARWIN - , mResizeHandle(NULL) -#endif // LL_DARWIN { setIsChrome(TRUE); setFocusRoot(TRUE); + mCommitCallbackRegistrar.add("ShowFloater", boost::bind(show_floater, _2)); } BOOL LLToolBar::postBuild() { - childSetCommitCallback("communicate_btn", onClickCommunicate, this); - - childSetAction("chat_btn", onClickChat, this); - childSetControlName("chat_btn", "ChatVisible"); - - //childSetAction("appearance_btn", onClickAppearance, this); - //childSetControlName("appearance_btn", ""); - - childSetAction("radar_list_btn", onClickRadarList, this); - childSetControlName("radar_list_btn", "ShowRadar"); - - childSetAction("fly_btn", onClickFly, this); - childSetControlName("fly_btn", "FlyBtnState"); - - //childSetAction("sit_btn", onClickSit, this); - //childSetControlName("sit_btn", "SitBtnState"); - - childSetAction("snapshot_btn", onClickSnapshot, this); - childSetControlName("snapshot_btn", "SnapshotBtnState"); - - childSetAction("directory_btn", onClickDirectory, this); - childSetControlName("directory_btn", "ShowDirectory"); - - childSetAction("build_btn", onClickBuild, this); - childSetControlName("build_btn", "BuildBtnState"); - - childSetAction("radar_btn", onClickRadar, this); - childSetControlName("radar_btn", "ShowMiniMap"); - - childSetAction("map_btn", onClickMap, this); - childSetControlName("map_btn", "ShowWorldMap"); - - childSetAction("inventory_btn", onClickInventory, this); - childSetControlName("inventory_btn", "ShowInventory"); - mCommunicateBtn.connect(this, "communicate_btn"); + mCommunicateBtn->setCommitCallback(boost::bind(&LLToolBar::onClickCommunicate, this, _2)); mFlyBtn.connect(this, "fly_btn"); mBuildBtn.connect(this, "build_btn"); mMapBtn.connect(this, "map_btn"); @@ -170,22 +133,16 @@ BOOL LLToolBar::postBuild() } #if LL_DARWIN - if(mResizeHandle == NULL) - { - LLResizeHandle::Params p; - p.rect(LLRect(0, 0, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT)); - p.name(std::string("")); - p.min_width(RESIZE_HANDLE_WIDTH); - p.min_height(RESIZE_HANDLE_HEIGHT); - p.corner(LLResizeHandle::RIGHT_BOTTOM); - mResizeHandle = new LLFakeResizeHandle(p); this->addChildInBack(mResizeHandle); - LLLayoutStack* toolbar_stack = getChild("toolbar_stack"); - toolbar_stack->reshape(toolbar_stack->getRect().getWidth() - RESIZE_HANDLE_WIDTH, toolbar_stack->getRect().getHeight()); - } + LLResizeHandle::Params p; + p.rect(LLRect(0, 0, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT)); + p.name(std::string("")); + p.min_width(RESIZE_HANDLE_WIDTH); + p.min_height(RESIZE_HANDLE_HEIGHT); + p.corner(LLResizeHandle::RIGHT_BOTTOM); + addChildInBack(new LLFakeResizeHandle(p)); + reshape(getRect().getWidth(), getRect().getHeight()); #endif // LL_DARWIN - layoutButtons(); - return TRUE; } @@ -201,18 +158,18 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EAcceptance* accept, std::string& tooltip_msg) { - LLButton* inventory_btn = getChild("inventory_btn"); - if (!inventory_btn) return FALSE; + LLButton* inventory_btn = mInventoryBtn; + if (!inventory_btn || !inventory_btn->getVisible()) return FALSE; LLInventoryView* active_inventory = LLInventoryView::getActiveInventory(); - if(active_inventory && active_inventory->getVisible()) + if (active_inventory && active_inventory->getVisible()) { - mInventoryAutoOpen = FALSE; + mInventoryAutoOpenTimer.stop(); } else if (inventory_btn->getRect().pointInRect(x, y)) { - if (mInventoryAutoOpen) + if (mInventoryAutoOpenTimer.getStarted()) { if (!(active_inventory && active_inventory->getVisible()) && mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime) @@ -222,105 +179,41 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, } else { - mInventoryAutoOpen = TRUE; - mInventoryAutoOpenTimer.reset(); + mInventoryAutoOpenTimer.start(); } } return LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); } -// static -void LLToolBar::toggle(void*) -{ - BOOL show = gSavedSettings.getBOOL("ShowToolBar"); - gSavedSettings.setBOOL("ShowToolBar", !show); - gToolBar->setVisible(!show); -} - - -// static -BOOL LLToolBar::visible(void*) -{ - return gToolBar->getVisible(); -} - - -void LLToolBar::layoutButtons() -{ -#if LL_DARWIN - const S32 FUDGE_WIDTH_OF_SCREEN = 4; - S32 width = gViewerWindow->getWindowWidth() + FUDGE_WIDTH_OF_SCREEN; - S32 pad = 2; - - // this function may be called before postBuild(), in which case mResizeHandle won't have been set up yet. - if(mResizeHandle != NULL) - { - if(!gViewerWindow->getWindow()->getFullscreen()) - { - // Only when running in windowed mode on the Mac, leave room for a resize widget on the right edge of the bar. - width -= RESIZE_HANDLE_WIDTH; - - LLRect r; - r.mLeft = width - pad; - r.mBottom = 0; - r.mRight = r.mLeft + RESIZE_HANDLE_WIDTH; - r.mTop = r.mBottom + RESIZE_HANDLE_HEIGHT; - mResizeHandle->setRect(r); - mResizeHandle->setVisible(TRUE); - } - else - { - mResizeHandle->setVisible(FALSE); - } - } -#endif // LL_DARWIN -} - - -// virtual -void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLPanel::reshape(width, height, called_from_parent); - - layoutButtons(); -} - // Per-frame updates of visibility void LLToolBar::refresh() { - if(!isAgentAvatarValid()) - return; - - static LLCachedControl show("ShowToolBar", true); - static LLCachedControl ascent_build_always_enabled("AscentBuildAlwaysEnabled", true); - BOOL mouselook = gAgentCamera.cameraMouselook(); - setVisible(show && !mouselook); - - BOOL sitting = FALSE; - static LLCachedControl continue_flying_on_unsit("LiruContinueFlyingOnUnsit"); - if (continue_flying_on_unsit) + static const LLCachedControl show_toolbar("ShowToolBar", true); + bool show = show_toolbar; + if (show && gAgentCamera.cameraMouselook()) { - sitting = false; - } - else if (gAgentAvatarp) - { - sitting = gAgentAvatarp->isSitting(); + static const LLCachedControl hidden("LiruMouselookHidesToolbar"); + show = !hidden; } + setVisible(show); + if (!show) return; // Everything below this point manipulates visible UI, anyway - mFlyBtn->setEnabled((gAgent.canFly() || gAgent.getFlying()) && !sitting ); - mBuildBtn->setEnabled((LLViewerParcelMgr::getInstance()->allowAgentBuild() || ascent_build_always_enabled)); + updateCommunicateList(); + + if (!isAgentAvatarValid()) return; + + static const LLCachedControl continue_flying_on_unsit("LiruContinueFlyingOnUnsit"); + mFlyBtn->setEnabled((gAgent.canFly() || gAgent.getFlying()) && (continue_flying_on_unsit || !gAgentAvatarp->isSitting())); + static const LLCachedControl ascent_build_always_enabled("AscentBuildAlwaysEnabled", true); + mBuildBtn->setEnabled(ascent_build_always_enabled || LLViewerParcelMgr::getInstance()->allowAgentBuild()); // Check to see if we're in build mode - BOOL build_mode = LLToolMgr::getInstance()->inEdit(); // And not just clicking on a scripted object - if (LLToolGrab::getInstance()->getHideBuildHighlight()) - { - build_mode = FALSE; - } + bool build_mode = LLToolMgr::getInstance()->inEdit() && !LLToolGrab::getInstance()->getHideBuildHighlight(); static LLCachedControl build_btn_state("BuildBtnState",false); - if(build_btn_state!=(bool)build_mode) + if (build_btn_state != build_mode) build_btn_state = build_mode; // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-10 (RLVa-1.0.0g) @@ -336,64 +229,40 @@ void LLToolBar::refresh() mInventoryBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWINV)); } // [/RLVa:KB] +} - if (isInVisibleChain()) - { - updateCommunicateList(); - } +void bold_if_equal(const LLFloater* f1, const LLFloater* f2, LLScrollListItem* itemp) +{ + if (f1 != f2) return; + static_cast(itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD); } void LLToolBar::updateCommunicateList() { - LLFlyoutButton* communicate_button = mCommunicateBtn; - LLSD selected = communicate_button->getValue(); + if (!mCommunicateBtn->getVisible()) return; - communicate_button->removeall(); + LLSD selected = mCommunicateBtn->getValue(); - LLFloater* frontmost_floater = LLFloaterChatterBox::getInstance()->getActiveFloater(); - LLScrollListItem* itemp = NULL; + mCommunicateBtn->removeall(); - itemp = communicate_button->add(LLFloaterMyFriends::getInstance()->getShortTitle(), LLSD("contacts"), ADD_TOP); - if (LLFloaterMyFriends::getInstance() == frontmost_floater) + const LLFloater* frontmost_floater = LLFloaterChatterBox::getInstance()->getActiveFloater(); + bold_if_equal(LLFloaterMyFriends::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterMyFriends::getInstance()->getShortTitle(), LLSD("contacts"), ADD_TOP)); + bold_if_equal(LLFloaterChat::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterChat::getInstance()->getShortTitle(), LLSD("local chat"), ADD_TOP)); + mCommunicateBtn->addSeparator(ADD_TOP); + mCommunicateBtn->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP); + mCommunicateBtn->addSeparator(ADD_TOP); + bold_if_equal(LLFloaterMute::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterMute::getInstance()->getShortTitle(), LLSD("mute list"), ADD_TOP)); + + if (gIMMgr->getIMFloaterHandles().size() > 0) mCommunicateBtn->addSeparator(ADD_TOP); + for(std::set >::const_iterator floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it) { - ((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD); - // make sure current tab is selected in list - if (selected.isUndefined()) + if (LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)floater_handle_it->get()) { - selected = itemp->getValue(); - } - } - itemp = communicate_button->add(LLFloaterChat::getInstance()->getShortTitle(), LLSD("local chat"), ADD_TOP); - if (LLFloaterChat::getInstance() == frontmost_floater) - { - ((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD); - if (selected.isUndefined()) - { - selected = itemp->getValue(); - } - } - communicate_button->addSeparator(ADD_TOP); - communicate_button->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP); - communicate_button->addSeparator(ADD_TOP); - communicate_button->add(LLFloaterMute::getInstance()->getShortTitle(), LLSD("mute list"), ADD_TOP); - - std::set >::const_iterator floater_handle_it; - - if (gIMMgr->getIMFloaterHandles().size() > 0) - { - communicate_button->addSeparator(ADD_TOP); - } - - for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it) - { - LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)floater_handle_it->get(); - if (im_floaterp) - { - static LLCachedControl show_counts("ShowUnreadIMsCounts", true); - S32 count = im_floaterp->getNumUnreadMessages(); + const S32 count = im_floaterp->getNumUnreadMessages(); std::string floater_title; if (count > 0) floater_title = "*"; floater_title.append(im_floaterp->getShortTitle()); + static const LLCachedControl show_counts("ShowUnreadIMsCounts", true); if (show_counts && count > 0) { floater_title += " - "; @@ -408,32 +277,19 @@ void LLToolBar::updateCommunicateList() floater_title += getString("IM"); } } - - itemp = communicate_button->add(floater_title, im_floaterp->getSessionID(), ADD_TOP); - if (im_floaterp == frontmost_floater) - { - ((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD); - if (selected.isUndefined()) - { - selected = itemp->getValue(); - } - } + bold_if_equal(im_floaterp, frontmost_floater, mCommunicateBtn->add(floater_title, im_floaterp->getSessionID(), ADD_TOP)); } } - communicate_button->setToggleState(gSavedSettings.getBOOL("ShowCommunicate")); - communicate_button->setValue(selected); + static const LLCachedControl show_comm("ShowCommunicate", true); + mCommunicateBtn->setToggleState(show_comm); + if (!selected.isUndefined()) mCommunicateBtn->setValue(selected); } // static -void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, void* user_data) +void LLToolBar::onClickCommunicate(const LLSD& selected_option) { - LLToolBar* toolbar = (LLToolBar*)user_data; - LLFlyoutButton* communicate_button = toolbar->getChild("communicate_btn"); - - LLSD selected_option = communicate_button->getValue(); - if (selected_option.asString() == "contacts") { LLFloaterMyFriends::showInstance(); @@ -484,104 +340,3 @@ void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, void* user_data) LLFloaterChatterBox::showInstance(selected_option); } } - - -// static -void LLToolBar::onClickChat(void* user_data) -{ - handle_chat(NULL); -} - -// static -void LLToolBar::onClickAppearance(void*) -{ - if (gAgentWearables.areWearablesLoaded()) - { - LLFloaterCustomize::show(); - } -} - -// static -void LLToolBar::onClickRadarList(void*) -{ - LLFloaterAvatarList::toggle(0); -} - - -// static -void LLToolBar::onClickFly(void*) -{ - gAgent.toggleFlying(); -} - - -// static -void LLToolBar::onClickSit(void*) -{ - if (!(gAgent.getControlFlags() & AGENT_CONTROL_SIT_ON_GROUND)) - { - // sit down - gAgent.setFlying(FALSE); - gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); - - // Might be first sit - LLFirstUse::useSit(); - } - else - { -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) - // NOTE-RLVa: dead code? - if (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) - { - return; - } -// [/RLVa:KB] - - // stand up - gAgent.setFlying(FALSE); - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); - } -} - - -// static -void LLToolBar::onClickSnapshot(void*) -{ - LLFloaterSnapshot::show (0); -} - - -// static -void LLToolBar::onClickDirectory(void*) -{ - handle_find(NULL); -} - - -// static -void LLToolBar::onClickBuild(void*) -{ - LLToolMgr::getInstance()->toggleBuildMode(); -} - - -// static -void LLToolBar::onClickRadar(void*) -{ - handle_mini_map(NULL); -} - - -// static -void LLToolBar::onClickMap(void*) -{ - handle_map(NULL); -} - - -// static -void LLToolBar::onClickInventory(void*) -{ - handle_inventory(NULL); -} - diff --git a/indra/newview/lltoolbar.h b/indra/newview/lltoolbar.h index 28fcba9df..958c0b4bc 100644 --- a/indra/newview/lltoolbar.h +++ b/indra/newview/lltoolbar.h @@ -41,10 +41,6 @@ // "Constants" loaded from settings.xml at start time extern S32 TOOL_BAR_HEIGHT; -#if LL_DARWIN - class LLFakeResizeHandle; -#endif // LL_DARWIN - class LLFlyoutButton; class LLToolBar @@ -62,44 +58,20 @@ public: EAcceptance* accept, std::string& tooltip_msg); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); - - static void toggle(void*); - static BOOL visible(void*); - - // Move buttons to appropriate locations based on rect. - void layoutButtons(); - // Per-frame refresh call void refresh(); // callbacks - static void onClickCommunicate(LLUICtrl*, void*); - static void onClickChat(void* data); - static void onClickAppearance(void* data); - static void onClickFly(void*); - static void onClickSit(void*); - static void onClickSnapshot(void* data); - static void onClickDirectory(void* data); - static void onClickBuild(void* data); - static void onClickRadar(void* data); - static void onClickMap(void* data); - static void onClickInventory(void* data); - static void onClickRadarList(void* data); + void onClickCommunicate(const LLSD& selected); static F32 sInventoryAutoOpenTime; private: void updateCommunicateList(); - private: - BOOL mInventoryAutoOpen; LLFrameTimer mInventoryAutoOpenTimer; S32 mNumUnreadIMs; -#if LL_DARWIN - LLFakeResizeHandle *mResizeHandle; -#endif // LL_DARWIN CachedUICtrl mCommunicateBtn; CachedUICtrl mFlyBtn; diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 3f3470e04..2c442069e 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -50,7 +50,6 @@ #include "llagent.h" #include "llagentcamera.h" #include "llfloatertools.h" -#include "qtoolalign.h" #include "llviewercontrol.h" @@ -278,20 +277,13 @@ BOOL LLToolCompTranslate::handleMouseUp(S32 x, S32 y, MASK mask) LLTool* LLToolCompTranslate::getOverrideTool(MASK mask) { - if (gKeyboard->getKeyDown('A') && mask & MASK_CONTROL) + if (mask == MASK_CONTROL) { - return QToolAlign::getInstance(); + return LLToolCompRotate::getInstance(); } - else + else if (mask == (MASK_CONTROL | MASK_SHIFT)) { - if (mask == MASK_CONTROL) - { - return LLToolCompRotate::getInstance(); - } - else if (mask == (MASK_CONTROL | MASK_SHIFT)) - { - return LLToolCompScale::getInstance(); - } + return LLToolCompScale::getInstance(); } return LLToolComposite::getOverrideTool(mask); } @@ -404,11 +396,7 @@ BOOL LLToolCompScale::handleMouseUp(S32 x, S32 y, MASK mask) LLTool* LLToolCompScale::getOverrideTool(MASK mask) { - if (gKeyboard->getKeyDown('A') && mask & MASK_CONTROL) - { - return QToolAlign::getInstance(); - } - else if (mask == MASK_CONTROL) + if (mask == MASK_CONTROL) { return LLToolCompRotate::getInstance(); } @@ -607,11 +595,7 @@ BOOL LLToolCompRotate::handleMouseUp(S32 x, S32 y, MASK mask) LLTool* LLToolCompRotate::getOverrideTool(MASK mask) { - if (gKeyboard->getKeyDown('A') && mask & MASK_CONTROL) - { - return QToolAlign::getInstance(); - } - else if (mask == (MASK_CONTROL | MASK_SHIFT)) + if (mask == (MASK_CONTROL | MASK_SHIFT)) { return LLToolCompScale::getInstance(); } @@ -780,7 +764,11 @@ void LLToolCompGun::handleSelect() void LLToolCompGun::handleDeselect() { LLToolComposite::handleDeselect(); - LLViewerCamera::getInstance()->loadDefaultFOV(); // Singu Note: Load Default FOV in case we were zoomed in + if (mRightMouseButton || mTimerFOV.getStarted()) // Singu Note: Load Default FOV if we were zoomed in + { + LLViewerCamera::getInstance()->loadDefaultFOV(); + mRightMouseButton = false; + } setMouseCapture(FALSE); } diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp index 1eedb7b22..07629eefc 100644 --- a/indra/newview/lltoolgun.cpp +++ b/indra/newview/lltoolgun.cpp @@ -60,10 +60,17 @@ LLToolGun::LLToolGun( LLToolComposite* composite ) void LLToolGun::handleSelect() { - gViewerWindow->hideCursor(); - gViewerWindow->moveCursorToCenter(); - gViewerWindow->getWindow()->setMouseClipping(TRUE); - mIsSelected = TRUE; +// [RLVa:KB] - Checked: 2014-02-24 (RLVa-1.4.10) + if (gFocusMgr.getAppHasFocus()) + { +// [/RLVa:KB] + gViewerWindow->hideCursor(); + gViewerWindow->moveCursorToCenter(); + gViewerWindow->getWindow()->setMouseClipping(TRUE); + mIsSelected = TRUE; +// [RLVa:KB] - Checked: 2014-02-24 (RLVa-1.4.10) + } +// [/RLVa:KB] } void LLToolGun::handleDeselect() @@ -137,11 +144,14 @@ BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask) void LLToolGun::draw() { - if( gSavedSettings.getBOOL("ShowCrosshairs") ) + static const LLCachedControl show("ShowCrosshairs"); + if (show) { LLUIImagePtr crosshair = LLUI::getUIImage("UIImgCrosshairsUUID"); + static const LLCachedControl color("LiruCrosshairColor"); crosshair->draw( ( gViewerWindow->getWorldViewRectScaled().getWidth() - crosshair->getWidth() ) / 2, - ( gViewerWindow->getWorldViewRectScaled().getHeight() - crosshair->getHeight() ) / 2); + ( gViewerWindow->getWorldViewRectScaled().getHeight() - crosshair->getHeight() ) / 2, + color); } } diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index 24dc16383..7e204c0e6 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -427,7 +427,7 @@ const std::string& LLTracker::getTrackedLocationName() return instance()->mTrackedLocationName; } -F32 pulse_func(F32 t, F32 z) +F32 pulse_func(F32 t, F32 z, bool down) { if (!LLTracker::sCheesyBeacon) { @@ -435,7 +435,14 @@ F32 pulse_func(F32 t, F32 z) } t *= F_PI; - z -= t*64.f - 256.f; + if (down) + { + z += t*64.f - 256.f; + } + else + { + z -= t*64.f - 256.f; + } F32 a = cosf(z*F_PI/512.f)*10.0f; a = llmax(a, 9.9f); @@ -489,6 +496,74 @@ void draw_shockwave(F32 center_z, F32 t, S32 steps, LLColor4 color) gGL.end(); } +void draw_beacon(LLVector3 pos_agent, bool down, LLColor4 fogged_color, F32 dist) +{ + const U32 BEACON_VERTS = 256; + F32 step; + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + + if (down) + { + gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]); + draw_shockwave(1024.f, gRenderStartTime.getElapsedTimeF32(), 32, fogged_color); + step = (8192.0f - pos_agent.mV[2]) / BEACON_VERTS; + } + else + { + gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], 0); + step = pos_agent[2] / BEACON_VERTS; + } + + gGL.color4fv(fogged_color.mV); + + LLVector3 x_axis = LLViewerCamera::getInstance()->getLeftAxis(); + F32 t = gRenderStartTime.getElapsedTimeF32(); + F32 dr = dist/LLViewerCamera::getInstance()->getFar(); + + for (U32 i = 0; i < BEACON_VERTS; i++) + { + F32 x = x_axis.mV[0]; + F32 y = x_axis.mV[1]; + + F32 z = i * step; + F32 z_next = (i+1)*step; + + F32 a = pulse_func(t, z, down); + F32 an = pulse_func(t, z_next, down); + + LLColor4 c_col = fogged_color + LLColor4(a,a,a,a); + LLColor4 col_next = fogged_color + LLColor4(an,an,an,an); + LLColor4 col_edge = fogged_color * LLColor4(a,a,a,0.0f); + LLColor4 col_edge_next = fogged_color * LLColor4(an,an,an,0.0f); + + a *= 2.f; + a += 1.0f+dr; + + an *= 2.f; + an += 1.0f+dr; + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.color4fv(col_edge.mV); + gGL.vertex3f(-x*a, -y*a, z); + gGL.color4fv(col_edge_next.mV); + gGL.vertex3f(-x*an, -y*an, z_next); + + gGL.color4fv(c_col.mV); + gGL.vertex3f(0, 0, z); + gGL.color4fv(col_next.mV); + gGL.vertex3f(0, 0, z_next); + + gGL.color4fv(col_edge.mV); + gGL.vertex3f(x*a,y*a,z); + gGL.color4fv(col_edge_next.mV); + gGL.vertex3f(x*an,y*an,z_next); + + gGL.end(); + } + gGL.popMatrix(); +} // static void LLTracker::renderBeacon(LLVector3d pos_global, @@ -496,6 +571,7 @@ void LLTracker::renderBeacon(LLVector3d pos_global, LLHUDText* hud_textp, const std::string& label ) { + const LLColor4& color_under(LLColor4::blue); sCheesyBeacon = gSavedSettings.getBOOL("CheesyBeacon"); LLVector3d to_vec = pos_global - gAgentCamera.getCameraPositionGlobal(); @@ -512,9 +588,11 @@ void LLTracker::renderBeacon(LLVector3d pos_global, } LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getFogColor(); + LLColor4 fogged_color_under = color_frac * color_under + (1 - color_frac) * gSky.getFogColor(); F32 FADE_DIST = 3.f; fogged_color.mV[3] = llmax(0.2f, llmin(0.5f,(dist-FADE_DIST)/FADE_DIST)); + fogged_color_under.mV[3] = llmax(0.2f, llmin(0.5f,(dist-FADE_DIST)/FADE_DIST)); LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(pos_global); @@ -523,64 +601,8 @@ void LLTracker::renderBeacon(LLVector3d pos_global, LLGLDisable cull_face(GL_CULL_FACE); LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - { - gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]); - - draw_shockwave(1024.f, gRenderStartTime.getElapsedTimeF32(), 32, fogged_color); - - gGL.color4fv(fogged_color.mV); - const U32 BEACON_VERTS = 256; - const F32 step = 1024.0f/BEACON_VERTS; - - LLVector3 x_axis = LLViewerCamera::getInstance()->getLeftAxis(); - F32 t = gRenderStartTime.getElapsedTimeF32(); - F32 dr = dist/LLViewerCamera::getInstance()->getFar(); - - for (U32 i = 0; i < BEACON_VERTS; i++) - { - F32 x = x_axis.mV[0]; - F32 y = x_axis.mV[1]; - - F32 z = i * step; - F32 z_next = (i+1)*step; - - F32 a = pulse_func(t, z); - F32 an = pulse_func(t, z_next); - - LLColor4 c_col = fogged_color + LLColor4(a,a,a,a); - LLColor4 col_next = fogged_color + LLColor4(an,an,an,an); - LLColor4 col_edge = fogged_color * LLColor4(a,a,a,0.0f); - LLColor4 col_edge_next = fogged_color * LLColor4(an,an,an,0.0f); - - a *= 2.f; - a += 1.0f+dr; - - an *= 2.f; - an += 1.0f+dr; - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.color4fv(col_edge.mV); - gGL.vertex3f(-x*a, -y*a, z); - gGL.color4fv(col_edge_next.mV); - gGL.vertex3f(-x*an, -y*an, z_next); - - gGL.color4fv(c_col.mV); - gGL.vertex3f(0, 0, z); - gGL.color4fv(col_next.mV); - gGL.vertex3f(0, 0, z_next); - - gGL.color4fv(col_edge.mV); - gGL.vertex3f(x*a,y*a,z); - gGL.color4fv(col_edge_next.mV); - gGL.vertex3f(x*an,y*an,z_next); - - gGL.end(); - } - } - gGL.popMatrix(); + draw_beacon(pos_agent, true, fogged_color, dist); + draw_beacon(pos_agent, false, fogged_color_under, dist); std::string text; text = llformat( "%.0f m", to_vec.magVec()); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index c8f2d4c9a..d87d82ad5 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -204,6 +204,12 @@ bool handleRenderAvatarComplexityLimitChanged(const LLSD& newvalue) bool handleRenderTransparentWaterChanged(const LLSD& newvalue) { + LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && gSavedSettings.getBOOL("VertexShaderEnable"); + if (gPipeline.isInit()) //If water is opaque then distortion/reflection fbos will not be needed. + { + gPipeline.releaseGLBuffers(); + gPipeline.createGLBuffers(); + } LLWorld::getInstance()->updateWaterObjects(); return true; } @@ -614,7 +620,7 @@ bool handleAscentAvatarModifier(const LLSD& newvalue) static bool handlePhoenixNameSystemChanged(const LLSD& newvalue) { S32 dnval = (S32)newvalue.asInteger(); - if (dnval <= 0 || dnval > 2) LLAvatarNameCache::setUseDisplayNames(false); + if (dnval <= 0 || dnval > 3) LLAvatarNameCache::setUseDisplayNames(false); else LLAvatarNameCache::setUseDisplayNames(true); LLVOAvatar::invalidateNameTags(); return true; @@ -679,6 +685,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("SHUseRMSEAutoMask")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("SHAutoMaskMaxRMSE")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + gSavedSettings.getControl("SHAltBatching")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); //See LL jira VWR-3258 comment section. Implemented by LL in 2.1 -Shyotl diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 1c8b3b629..8c899a4ae 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -61,14 +61,11 @@ const F32 YAW_NUDGE_RATE = 0.05f; // fraction of normal speed LLViewerKeyboard gViewerKeyboard; -bool isCrouch = false; //Shouldn't start crouched. - void agent_jump( EKeystate s ) { if( KEYSTATE_UP == s ) return; F32 time = gKeyboard->getCurKeyElapsedTime(); S32 frame_count = llround(gKeyboard->getCurKeyElapsedFrameCount()); - isCrouch = false; if( time < FLY_TIME || frame_count <= FLY_FRAMES || gAgent.upGrabbed() @@ -86,18 +83,17 @@ void agent_toggle_down( EKeystate s ) { if(KEYSTATE_UP == s) return; - gAgent.moveUp(-1); if(KEYSTATE_DOWN == s && !gAgent.getFlying() && gSavedSettings.getBOOL("SGShiftCrouchToggle")) { - isCrouch = !isCrouch; + gAgent.toggleCrouch(); } + gAgent.moveUp(-1); } void agent_push_down( EKeystate s ) { if( KEYSTATE_UP == s ) return; gAgent.moveUp(-1); - isCrouch = false; } static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode) @@ -247,7 +243,6 @@ void agent_toggle_fly( EKeystate s ) if (KEYSTATE_DOWN == s ) { gAgent.toggleFlying(); - isCrouch = false; } } diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h index e3ef315b5..2be702fee 100644 --- a/indra/newview/llviewerkeyboard.h +++ b/indra/newview/llviewerkeyboard.h @@ -93,6 +93,5 @@ protected: }; extern LLViewerKeyboard gViewerKeyboard; -extern bool isCrouch; void agent_push_forward(EKeystate s); #endif // LL_LLVIEWERKEYBOARD_H diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ca85a2ac2..52812a7ff 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -42,130 +42,88 @@ #include "llfeaturemanager.h" #include "llsecondlifeurls.h" // -#include "llfloaterexploreanimations.h" -#include "llfloaterexploresounds.h" #include "llfloaterblacklist.h" // #include "statemachine/aifilepicker.h" // newview includes +#include "lfsimfeaturehandler.h" #include "llagent.h" #include "llagentcamera.h" #include "llappearancemgr.h" #include "llagentwearables.h" -#include "jcfloaterareasearch.h" -#include "lfsimfeaturehandler.h" #include "llagentpilot.h" +#include "llavatarpropertiesprocessor.h" +#include "llcallingcard.h" #include "llcompilequeue.h" #include "llconsole.h" #include "lldebugview.h" #include "llenvmanager.h" #include "llfirstuse.h" -#include "llfloaterabout.h" -#include "llfloateractivespeakers.h" -#include "llfloateravatarlist.h" #include "llfloateravatartextures.h" -#include "llfloaterbeacons.h" -#include "llfloaterbuildoptions.h" -#include "llfloaterbump.h" #include "llfloaterbuy.h" #include "llfloaterbuycontents.h" #include "llfloaterbuycurrency.h" #include "llfloaterbuyland.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" -#include "llfloaterdaycycle.h" #include "llfloaterdirectory.h" #include "llfloatereditui.h" -#include "llfloaterchatterbox.h" #include "llfloaterfonttest.h" -#include "llfloatergesture.h" #include "llfloatergodtools.h" #include "llfloaterhtmlcurrency.h" -#include "llfloaterhud.h" -#include "llfloaterinspect.h" -#include "llfloaterinventory.h" -#include "llfloaterlagmeter.h" #include "llfloaterland.h" -#include "llfloaterlandholdings.h" -#include "llfloatermap.h" #include "llfloatermute.h" #include "llfloateropenobject.h" -#include "llfloateroutbox.h" #include "llfloaterpathfindingcharacters.h" #include "llfloaterpathfindinglinksets.h" -#include "llfloaterperms.h" -#include "llfloaterpostprocess.h" -#include "llfloaterpreference.h" #include "llfloaterregiondebugconsole.h" #include "llfloaterregioninfo.h" #include "llfloaterreporter.h" -#include "llfloaterscriptdebug.h" -#include "llfloaterscriptlimits.h" #include "llfloatersettingsdebug.h" - -#include "llfloaterenvsettings.h" -#include "llfloaterstats.h" -#include "llfloaterteleporthistory.h" #include "llfloatertest.h" #include "llfloatertools.h" -#include "llfloatervoiceeffect.h" -#include "llfloaterwater.h" -#include "llfloaterwebcontent.h" -#include "llfloaterwindlight.h" #include "llfloaterworldmap.h" #include "llfloatermemleak.h" #include "llframestats.h" -#include "llgivemoney.h" #include "llavataractions.h" +#include "llgivemoney.h" #include "llgroupmgr.h" #include "llhoverview.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" -#include "llimview.h" -#include "llinventorybridge.h" -#include "llinventorydefines.h" #include "llinventoryfunctions.h" -#include "llmakeoutfitdialog.h" #include "llmimetypes.h" -#include "llmenucommands.h" #include "llmenuoptionpathfindingrebakenavmesh.h" -#include "llmoveview.h" #include "llmutelist.h" #include "llnotify.h" -#include "llpanellogin.h" #include "llparcel.h" #include "llregioninfomodel.h" #include "llselectmgr.h" #include "llstatusbar.h" #include "lltextureview.h" -#include "lltoolbar.h" #include "lltoolcomp.h" +#include "lltoolgrab.h" #include "lltoolmgr.h" #include "lltoolpie.h" #include "lltoolselectland.h" +#include "lltrans.h" #include "lluictrlfactory.h" -#include "lluserauth.h" #include "llvelocitybar.h" #include "llviewercamera.h" #include "llviewergenericmessage.h" +#include "llviewerjoystick.h" #include "llviewertexturelist.h" // gTextureList #include "llviewermenufile.h" // init_menu_file() #include "llviewermessage.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" -#include "llviewerstats.h" #include "llvoavatarself.h" #include "llworld.h" #include "llworldmap.h" #include "pipeline.h" -#include "llviewerjoystick.h" -#include "llwaterparammanager.h" -#include "llwlanimator.h" -#include "llwlparammanager.h" -#include "llfloatercamera.h" #include "llfloaternotificationsconsole.h" // @@ -176,12 +134,8 @@ // #include "scriptcounter.h" -#include "llfloaterdisplayname.h" -#include "floaterao.h" -#include "slfloatermediafilter.h" #include "llviewerobjectbackup.h" #include "llagentui.h" -#include "lltoolgrab.h" #include "llpathfindingmanager.h" #include @@ -191,8 +145,6 @@ #include "hippogridmanager.h" #include "wlfPanel_AdvSettings.h" -void toggle_search_floater(); - using namespace LLOldEvents; using namespace LLAvatarAppearanceDefines; void init_client_menu(LLMenuGL* menu); @@ -207,9 +159,10 @@ void init_debug_rendering_menu(LLMenuGL* menu); void init_debug_ui_menu(LLMenuGL* menu); void init_debug_xui_menu(LLMenuGL* menu); void init_debug_avatar_menu(LLMenuGL* menu); -// [RLVa:KB] +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) +#include "rlvactions.h" #include "rlvhandler.h" -#include "rlvfloaterbehaviour.h" +#include "rlvfloaters.h" #include "rlvlocks.h" void init_debug_rlva_menu(LLMenuGL* menu); // [/RLVa:KB] @@ -239,6 +192,7 @@ extern BOOL gDebugTextEditorTips; extern BOOL gShowOverlayTitle; extern BOOL gOcclusionCull; extern AIHTTPView* gHttpView; +extern LLMenuGL* sScrollListMenus[1]; // // Globals // @@ -520,6 +474,10 @@ void region_change(); void parse_simulator_features(); void custom_selected(void* user_data); + +void advanced_toggle_wireframe(void*); +BOOL advanced_check_wireframe(void*); + void reset_vertex_buffers(void *user_data) { gPipeline.clearRebuildGroups(); @@ -781,6 +739,10 @@ void init_menus() gMenuHolder->addChild(gLoginMenuBarView); + // Singu Note: Initialize common ScrollListMenus here + sScrollListMenus[0] = LLUICtrlFactory::getInstance()->buildMenu("menu_avs_list.xml", gMenuHolder); + //sScrollListMenus[1] = LLUICtrlFactory::getInstance()->buildMenu("menu_groups_list.xml"); // Singu TODO + LLView* ins = gMenuBarView->getChildView("insert_world", true, false); ins->setVisible(false); ins = gMenuBarView->getChildView("insert_agent", true, false); @@ -845,7 +807,7 @@ void init_client_menu(LLMenuGL* menu) } sub->addChild(new LLMenuItemCheckGL("HTTP Console", - &AIHTTPView::toggle_visibility, + &toggle_visibility, NULL, &get_visibility, (void*)gHttpView, @@ -960,15 +922,13 @@ void init_client_menu(LLMenuGL* menu) menu->addChild(sub_menu); // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1b | OK - #ifdef RLV_ADVANCED_MENU - sub_menu = new LLMenuGL("RLVa Embedded"); - init_debug_rlva_menu(sub_menu); - menu->addChild(sub_menu); - // Top Level Menu as well - sub_menu = new LLMenuGL("RLVa Main"); - init_debug_rlva_menu(sub_menu); - gMenuBarView->addChild(sub_menu); - #endif // RLV_ADVANCED_MENU + sub_menu = new LLMenuGL("RLVa Embedded"); + init_debug_rlva_menu(sub_menu); + menu->addChild(sub_menu); + // Top Level Menu as well + sub_menu = new LLMenuGL("RLVa Main"); + init_debug_rlva_menu(sub_menu); + gMenuBarView->addChild(sub_menu); // [/RLVa:KB] sub_menu = new LLMenuGL("UI"); @@ -1095,10 +1055,8 @@ void init_client_menu(LLMenuGL* menu) (void*)"ShowConsoleWindow")); // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-1.0.0e | OK - #ifdef RLV_ADVANCED_TOGGLE_RLVA - if (gSavedSettings.controlExists(RLV_SETTING_MAIN)) - menu->addChild(new LLMenuItemCheckGL("RestrainedLove API", &rlvMenuToggleEnabled, NULL, &rlvMenuCheckEnabled, NULL)); - #endif // RLV_ADVANCED_TOGGLE_RLVA + if (gSavedSettings.controlExists(RLV_SETTING_MAIN)) + menu->addChild(new LLMenuItemCheckGL("RestrainedLove API", &rlvMenuToggleEnabled, NULL, &rlvMenuCheckEnabled, NULL)); // [/RLVa:KB] if(gSavedSettings.getBOOL("QAMode")) @@ -1469,8 +1427,7 @@ void init_debug_rendering_menu(LLMenuGL* menu) menu->addChild(new LLMenuItemCallGL("Selected Texture Info", handle_selected_texture_info, NULL, NULL, 'T', MASK_CONTROL|MASK_SHIFT|MASK_ALT)); //menu->addChild(new LLMenuItemCallGL("Dump Image List", handle_dump_image_list, NULL, NULL, 'I', MASK_CONTROL|MASK_SHIFT)); - menu->addChild(new LLMenuItemToggleGL("Wireframe", &gUseWireframe, - 'R', MASK_CONTROL|MASK_SHIFT)); + menu->addChild(new LLMenuItemCheckGL("Wireframe", advanced_toggle_wireframe, NULL, advanced_check_wireframe, NULL, 'R', MASK_CONTROL|MASK_SHIFT)); LLMenuItemCheckGL* item; item = new LLMenuItemCheckGL("Object-Object Occlusion", menu_toggle_control, NULL, menu_check_control, (void*)"UseOcclusion", 'O', MASK_CONTROL|MASK_SHIFT); @@ -1521,16 +1478,8 @@ void init_debug_rendering_menu(LLMenuGL* menu) item = new LLMenuItemCheckGL("Audit Texture", menu_toggle_control, NULL, menu_check_control, (void*)"AuditTexture"); menu->addChild(item); -#ifndef LL_RELEASE_FOR_DOWNLOAD menu->addSeparator(); menu->addChild(new LLMenuItemCallGL("Memory Leaking Simulation", LLFloaterMemLeak::show, NULL, NULL)); -#else - if(gSavedSettings.getBOOL("QAMode")) - { - menu->addSeparator(); - menu->addChild(new LLMenuItemCallGL("Memory Leaking Simulation", LLFloaterMemLeak::show, NULL, NULL)); - } -#endif menu->createJumpKeys(); } @@ -1634,16 +1583,14 @@ void init_debug_rlva_menu(LLMenuGL* menu) menu->addChild(new LLMenuItemCheckGL("Enable Shared Wear", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_ENABLESHAREDWEAR)); menu->addSeparator(); - #ifdef RLV_EXTENSION_HIDELOCKED - if ( (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDLAYER)) && - (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDATTACH)) ) - { - menu->addChild(new LLMenuItemCheckGL("Hide Locked Layers", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDLAYER)); - menu->addChild(new LLMenuItemCheckGL("Hide Locked Attachments", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDATTACH)); - //sub_menu->addChild(new LLMenuItemToggleGL("Hide locked inventory", &rlv_handler_t::fHideLockedInventory)); - menu->addSeparator(); - } - #endif // RLV_EXTENSION_HIDELOCKED + if ( (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDLAYER)) && + (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDATTACH)) ) + { + menu->addChild(new LLMenuItemCheckGL("Hide Locked Layers", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDLAYER)); + menu->addChild(new LLMenuItemCheckGL("Hide Locked Attachments", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDATTACH)); + //sub_menu->addChild(new LLMenuItemToggleGL("Hide locked inventory", &rlv_handler_t::fHideLockedInventory)); + menu->addSeparator(); + } if (gSavedSettings.controlExists(RLV_SETTING_FORBIDGIVETORLV)) menu->addChild(new LLMenuItemCheckGL("Forbid Give to #RLV", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_FORBIDGIVETORLV)); @@ -1651,11 +1598,9 @@ void init_debug_rlva_menu(LLMenuGL* menu) menu->addChild(new LLMenuItemCheckGL("Show Name Tags", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_SHOWNAMETAGS)); menu->addSeparator(); - #ifdef RLV_EXTENSION_FLOATER_RESTRICTIONS - // TODO-RLVa: figure out a way to tell if floater_rlv_behaviour.xml exists - menu->addChild(new LLMenuItemCheckGL("Restrictions...", &RlvFloaterBehaviours::toggle, NULL, &RlvFloaterBehaviours::visible, NULL)); - menu->addChild(new LLMenuItemCheckGL("Locks...", &RlvFloaterLocks::toggle, NULL, &RlvFloaterLocks::visible, NULL)); - #endif // RLV_EXTENSION_FLOATER_RESTRICTIONS + menu->addChild(new LLMenuItemCheckGL("Restrictions...", &RlvFloaterBehaviours::toggle, NULL, &RlvFloaterBehaviours::visible, NULL)); + menu->addChild(new LLMenuItemCheckGL("Locks...", &RlvFloaterLocks::toggle, NULL, &RlvFloaterLocks::visible, NULL)); + menu->addChild(new LLMenuItemCheckGL("Strings...", &RlvFloaterStrings::toggle, NULL, &RlvFloaterStrings::visible, NULL)); } // [/RLVa:KB] @@ -1733,6 +1678,46 @@ void init_server_menu(LLMenuGL* menu) menu->createJumpKeys(); } +////////////////////// +// TOGGLE WIREFRAME // +////////////////////// + +/* +class LLAdvancedToggleWireframe : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) +*/ + void advanced_toggle_wireframe(void*) + { +// [RLVa:KB] - Checked: 2013-05-11 (RLVa-1.4.9) + bool fRlvBlockWireframe = gRlvAttachmentLocks.hasLockedHUD(); + if ( (!gUseWireframe) && (fRlvBlockWireframe) ) + { + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_WIREFRAME); + } + gUseWireframe = (!gUseWireframe) && (!fRlvBlockWireframe); +// [/RLVa:KB] +// gUseWireframe = !(gUseWireframe); +// gWindowResized = TRUE; // Singu Note: We don't use this (yet?) + LLPipeline::updateRenderDeferred(); + gPipeline.resetVertexBuffers(); +// return true; + } +/* +}; + +class LLAdvancedCheckWireframe : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) +*/ + BOOL advanced_check_wireframe(void*) + { + bool new_value = gUseWireframe; + return new_value; + } +//}; + + //----------------------------------------------------------------------------- // cleanup_menus() //----------------------------------------------------------------------------- @@ -1943,23 +1928,6 @@ class LLViewCheckJoystickFlycam : public view_listener_t } }; -class LLViewCommunicate : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - static LLCachedControl only_comm("CommunicateSpecificShortcut"); - if (!only_comm && LLFloaterChatterBox::getInstance()->getFloaterCount() == 0) - { - LLFloaterMyFriends::toggleInstance(); - } - else - { - LLFloaterChatterBox::toggleInstance(); - } - return true; - } -}; - void handle_toggle_flycam() { @@ -2087,15 +2055,6 @@ void handle_attachment_edit(const LLUUID& idItem) } // [/SL:KB] -class LLObjectInspect : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloaterInspect::showInstance(); - return true; - } -}; - // Derenderizer. Originally by Phox. class LLObjectDerender : public view_listener_t { @@ -2842,19 +2801,6 @@ class LLObjectPFLinksetsSelected : public view_listener_t } }; -class LLAvatarAnims : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar) - { - new LLFloaterExploreAnimations(avatar->getID()); //temporary - } - return true; - } -}; - // bool handle_go_to() @@ -3978,7 +3924,7 @@ class LLLandSit : public view_listener_t bool handleEvent(LLPointer event, const LLSD& userdata) { // [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f - if ( (rlv_handler_t::isEnabled()) && ((!gRlvHandler.canStand()) || (gRlvHandler.hasBehaviour(RLV_BHVR_SIT))) ) + if ( (rlv_handler_t::isEnabled()) && ((!RlvActions::canStand()) || (gRlvHandler.hasBehaviour(RLV_BHVR_SIT))) ) return true; // [/RLVa:KB] @@ -4179,22 +4125,6 @@ class LLViewLookAtLastChatter : public view_listener_t } }; -class LLViewMouselook : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - if (!gAgentCamera.cameraMouselook()) - { - gAgentCamera.changeCameraToMouselook(); - } - else - { - gAgentCamera.changeCameraToDefault(); - } - return true; - } -}; - class LLViewFullscreen : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -4261,6 +4191,7 @@ void handle_duplicate_in_place(void*) } /* dead code 30-apr-2008 +#include "llviewerstats.h" void handle_deed_object_to_group(void*) { LLUUID group_id; @@ -4674,7 +4605,7 @@ void handle_take_copy() if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; // [RLVa:KB] - Checked: 2010-03-07 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a - if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStand()) ) + if ( (rlv_handler_t::isEnabled()) && (!RlvActions::canStand()) ) { // Allow only if the avie isn't sitting on any of the selected objects LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); @@ -5619,15 +5550,6 @@ bool enable_object_delete() return new_value; } -class LLEditSearch : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - toggle_search_floater(); - return true; - } -}; - class LLObjectsReturnPackage { public: @@ -5728,15 +5650,6 @@ class LLViewEnableLastChatter : public view_listener_t } }; -class LLViewToggleRadar: public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloaterAvatarList::toggle(0); - return true; - } -}; - class LLEditEnableDeselect : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -5965,55 +5878,17 @@ class LLWorldTeleportHome : public view_listener_t } }; -class LLWorldAlwaysRun : public view_listener_t +void toggle_sit() { - bool handleEvent(LLPointer event, const LLSD& userdata) - { - // as well as altering the default walk-vs-run state, - // we also change the *current* walk-vs-run state. - if (gAgent.getAlwaysRun()) - { - gAgent.clearAlwaysRun(); -// gAgent.clearRunning(); - } - else - { - gAgent.setAlwaysRun(); -// gAgent.setRunning(); - } - - // tell the simulator. -// gAgent.sendWalkRun(gAgent.getAlwaysRun()); - - return true; - } -}; - -class LLWorldCheckAlwaysRun : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - bool new_value = gAgent.getAlwaysRun(); - gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); - return true; - } -}; + if (!gAgentAvatarp) return; + gAgent.setControlFlags(gAgentAvatarp->isSitting() ? AGENT_CONTROL_STAND_UP : AGENT_CONTROL_SIT_ON_GROUND); +} class LLWorldSitOnGround : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if (gAgentAvatarp) - { - if(!gAgentAvatarp->isSitting()) - { - gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); - } - else - { - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); - } - } + toggle_sit(); return true; } }; @@ -6105,7 +5980,7 @@ class LLWorldCreateLandmark : public view_listener_t create_inventory_item(gAgent.getID(), gAgent.getSessionID(), folder_id, LLTransactionID::tnull, - pos_string, pos_string, // name, desc + pos_string, agent_parcel->getDesc(), // name, desc, // name, desc LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, NOT_WEARABLE, PERM_ALL, @@ -6283,7 +6158,7 @@ bool enable_object_stand_up() // 'Object Stand Up' menu item is enabled when agent is sitting on selection // return sitting_on_selection(); // [RLVa:KB] - Checked: 2010-07-24 (RLVa-1.2.0g) | Added: RLVa-1.2.0g - return sitting_on_selection() && ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.canStand()) ); + return sitting_on_selection() && ( (!rlv_handler_t::isEnabled()) || (RlvActions::canStand()) ); // [/RLVa:KB] } @@ -6408,160 +6283,23 @@ void handle_viewer_disable_message_log(void*) gMessageSystem->stopLogging(); } -struct MenuFloaterDict : public LLSingleton -{ - typedef std::map, boost::function > > menu_floater_map_t; - menu_floater_map_t mEntries; - MenuFloaterDict() - { - registerFloater("about", boost::bind(&LLFloaterAbout::show,(void*)NULL)); - //registerFloater("about region", boost::bind(&LLFloaterRegionInfo::showInstance,LLSD())); - registerFloater("buy currency", boost::bind(&LLFloaterBuyCurrency::buyCurrency)); - registerFloater("displayname", boost::bind(&LLFloaterDisplayName::show)); - //registerFloater("friends", boost::bind(&LLFloaterMyFriends::toggleInstance,0), boost::bind(&LLFloaterMyFriends::instanceVisible,0)); - registerFloater("gestures", boost::bind(&LLFloaterGesture::toggleVisibility), boost::bind(&LLFloaterGesture::instanceVisible)); - registerFloater("grid options", boost::bind(&LLFloaterBuildOptions::show,(void*)NULL)); - registerFloater("help tutorial",boost::bind(&LLFloaterHUD::showHUD)); - registerFloater("im", boost::bind(&LLFloaterChatterBox::toggleInstance,LLSD()), boost::bind(&LLFloaterMyFriends::instanceVisible,0)); - //registerFloater("lag meter", boost::bind(&LLFloaterLagMeter::showInstance,LLSD())); - registerFloater("my land", boost::bind(&LLFloaterLandHoldings::show,(void*)NULL)); - registerFloater("preferences", boost::bind(&LLFloaterPreference::show,(void*)NULL)); - registerFloater("script errors",boost::bind(&LLFloaterScriptDebug::show,LLUUID::null)); - //registerFloater("script info", boost::bind(&LLFloaterScriptLimits::showInstance,LLSD())); - // Phoenix: Wolfspirit: Enabled Show Floater out of viewer menu - registerFloater("toolbar", boost::bind(&LLToolBar::toggle,(void*)NULL), boost::bind(&LLToolBar::visible,(void*)NULL)); - registerFloater("world map", boost::bind(&LLFloaterWorldMap::toggle)); - registerFloater("sound_explorer", boost::bind(&LLFloaterExploreSounds::toggle), boost::bind(&LLFloaterExploreSounds::visible)); - registerFloater("asset_blacklist", boost::bind(&LLFloaterBlacklist::toggle), boost::bind(&LLFloaterBlacklist::visible)); - - registerFloater ("about land"); - registerFloater ("about region"); - registerFloater ("active speakers"); - registerFloater ("areasearch"); - registerFloater ("beacons"); - registerFloater ("camera controls"); - registerFloater ("chat history"); - registerFloater ("communicate"); - registerFloater ("friends",0); - registerFloater ("lag meter"); - registerFloater ("media filter"); - registerFloater ("mini map"); - registerFloater ("movement controls"); - registerFloater ("mute list"); - registerFloater ("outbox"); - registerFloater ("perm prefs"); - registerFloater ("script info"); - registerFloater ("stat bar"); - registerFloater ("teleport history"); - registerFloater ("voice effect"); - registerFloater ("pathfinding_characters"); - registerFloater ("pathfinding_linksets"); - - } - void registerFloater(const std::string& name, boost::function show, boost::function visible = NULL) - { - mEntries.insert( std::make_pair( name, std::make_pair( show, visible ) ) ); - } - template - void registerFloater(const std::string& name, const LLSD& key = LLSD()) - { - registerFloater(name, boost::bind(&T::toggleInstance,key), boost::bind(&T::instanceVisible,key)); - } - -}; - // TomY TODO: Move! +void show_floater(const std::string& floater_name); class LLShowFloater : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - std::string floater_name = userdata.asString(); - if (floater_name.empty()) return false; - MenuFloaterDict::menu_floater_map_t::iterator it = MenuFloaterDict::instance().mEntries.find(floater_name); - if(it != MenuFloaterDict::instance().mEntries.end() && it->second.first != NULL) - { - it->second.first(); - } - else if (floater_name == "appearance") - { - if (gAgentWearables.areWearablesLoaded()) - { - LLFloaterCustomize::show(); - } - } - else if (floater_name == "outfit") - { - new LLMakeOutfitDialog(false); - } - else if (floater_name == "inventory") - { - LLInventoryView::toggleVisibility(NULL); - } - else if (floater_name == "buy land") - { -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) - { - return true; - } -// [/RLVa:KB] - if (LLViewerParcelMgr::getInstance()->selectionEmpty()) - { - LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); - } - LLViewerParcelMgr::getInstance()->startBuyLand(); - } - - //Singu TODO: Re-implement f1 help. - /*else if (floater_name == "help f1") - { - llinfos << "Spawning HTML help window" << llendl; - gViewerHtmlHelp.show(); - }*/ - - else if (floater_name == "complaint reporter") - { - // Prevent menu from appearing in screen shot. - gMenuHolder->hideMenus(); - LLFloaterReporter::showFromMenu(COMPLAINT_REPORT); - } - else if (floater_name == "mean events") - { - if (!gNoRender) - { - LLFloaterBump::show(NULL); - } - } - else // Simple codeless floater - { - LLFloater* floater = LLUICtrlFactory::getInstance()->getBuiltFloater(floater_name); - if (floater) - gFloaterView->bringToFront(floater); - else - LLUICtrlFactory::getInstance()->buildFloater(new LLFloater(), floater_name); - } + show_floater(userdata.asString()); return true; } }; +bool floater_visible(const std::string& floater_name); class LLFloaterVisible : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - std::string control_name = userdata["control"].asString(); - std::string floater_name = userdata["data"].asString(); - bool new_value = false; - MenuFloaterDict::menu_floater_map_t::iterator it = MenuFloaterDict::instance().mEntries.find(floater_name); - if(it != MenuFloaterDict::instance().mEntries.end() && it->second.second != NULL) - { - new_value = it->second.second(); - } - else if (floater_name == "inventory") - { - LLInventoryView* iv = LLInventoryView::getActiveInventory(); - new_value = (NULL != iv && TRUE == iv->getVisible()); - } - gMenuHolder->findControl(control_name)->setValue(new_value); + gMenuHolder->findControl(userdata["control"].asString())->setValue(floater_visible(userdata["data"].asString())); return true; } }; @@ -6674,15 +6412,6 @@ class LLShowAgentProfile : public view_listener_t } }; -class LLShowAgentGroups : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloaterMyFriends::toggleInstance(1); - return true; - } -}; - class LLLandEdit : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -8965,15 +8694,6 @@ class LLEditTakeOff : public view_listener_t } }; -class LLWorldChat : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - handle_chat(NULL); - return true; - } -}; - class LLToolsSelectTool : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -9014,22 +8734,6 @@ class LLWorldEnvSettings : public view_listener_t // [/RLVa:KB] std::string tod = userdata.asString(); - - if (tod == "editor") - { - // if not there or is hidden, show it - if( !LLFloaterEnvSettings::isOpen() || - !LLFloaterEnvSettings::instance()->getVisible()) - { - LLFloaterEnvSettings::show(); - } - else - { - // otherwise, close it button acts like a toggle - LLFloaterEnvSettings::instance()->close(); - } - return true; - } if (tod == "sunrise") { @@ -9056,60 +8760,6 @@ class LLWorldEnvSettings : public view_listener_t } }; -/// Water Menu callbacks -class LLWorldWaterSettings : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) - { - return true; - } -// [/RLVa:KB] - - // if not there or is hidden, show it - if( !LLFloaterWater::isOpen() || - !LLFloaterWater::instance()->getVisible()) { - LLFloaterWater::show(); - - // otherwise, close it button acts like a toggle - } - else - { - LLFloaterWater::instance()->close(); - } - return true; - } -}; - -/// Post-Process callbacks -class LLWorldPostProcess : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloaterPostProcess::show(); - return true; - } -}; - -/// Day Cycle callbacks -class LLWorldDayCycle : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) - { - return true; - } -// [/RLVa:KB] - - LLFloaterDayCycle::show(); - return true; - } -}; - class SinguCloseAllDialogs : public view_listener_t { @@ -9120,16 +8770,6 @@ class SinguCloseAllDialogs : public view_listener_t } }; -class SinguAnimationOverride : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloaterAO::show(NULL); - - return true; - } -}; - class SinguNimble : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -9150,36 +8790,6 @@ class SinguCheckNimble : public view_listener_t } }; -class SinguAssetBlacklist : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloaterBlacklist::toggle(); - - return true; - } -}; - -class SinguStreamingAudioDisplay : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - handle_ticker_toggle(NULL); - - return true; - } -}; - -class SinguCheckStreamingAudioDisplay : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - gMenuHolder->findControl(userdata["control"].asString())->setValue(handle_singleton_check(NULL)); - - return true; - } -}; - class SinguEnableStreamingAudioDisplay : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -9216,33 +8826,12 @@ class SinguRebake : public view_listener_t } }; -class SinguDebugConsole : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - handle_singleton_toggle(NULL); - return true; - } -}; - -class SinguCheckDebugConsole : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - gMenuHolder->findControl(userdata["control"].asString())->setValue(handle_singleton_check(NULL)); - return true; - } -}; - class SinguVisibleDebugConsole : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if (LLViewerRegion* region = gAgent.getRegion()) - { - if (LLView* item = gMenuBarView->getChildView("Region Debug Console", true, false)) - item->setVisible(!(region->getCapability("SimConsoleAsync").empty() || region->getCapability("SimConsole").empty())); - } + LLViewerRegion* region = gAgent.getRegion(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(region && !(region->getCapability("SimConsoleAsync").empty() || region->getCapability("SimConsole").empty())); return true; } }; @@ -9284,6 +8873,18 @@ const uuid_vec_t get_focused_list_ids_selected() return uuid_vec_t(); } +const LLWString get_slurl_for(const LLUUID& id, bool group) +{ + std::string str("secondlife:///app/"); + str += group ? "group/" : "agent/"; + return utf8str_to_wstring(str + id.asString() + "/about"); +} + +void copy_profile_uri(const LLUUID& id, bool group) +{ + gViewerWindow->getWindow()->copyTextToClipboard(get_slurl_for(id, group)); +} + class ListEnableAnySelected : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -9371,6 +8972,15 @@ class ListVisibleWebProfile : public view_listener_t } }; +class ListCopySLURL : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + copy_profile_uri(get_focused_list_id_selected(), false); + return true; + } +}; + class ListCopyUUIDs : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -9620,7 +9230,6 @@ void initialize_menus() addMenu(new LLEditCopy(), "Edit.Copy"); addMenu(new LLEditPaste(), "Edit.Paste"); addMenu(new LLEditDelete(), "Edit.Delete"); - addMenu(new LLEditSearch(), "Edit.Search"); addMenu(new LLEditSelectAll(), "Edit.SelectAll"); addMenu(new LLEditDeselect(), "Edit.Deselect"); addMenu(new LLEditDuplicate(), "Edit.Duplicate"); @@ -9640,9 +9249,7 @@ void initialize_menus() addMenu(new LLEditEnableChangeDisplayname(), "Edit.EnableChangeDisplayname"); // View menu - addMenu(new LLViewMouselook(), "View.Mouselook"); addMenu(new LLViewJoystickFlycam(), "View.JoystickFlycam"); - addMenu(new LLViewCommunicate(), "View.Communicate"); addMenu(new LLViewResetView(), "View.ResetView"); addMenu(new LLViewResetPresetAngles(), "View.ResetPresetAngles"); addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter"); @@ -9659,7 +9266,6 @@ void initialize_menus() addMenu(new LLViewEnableMouselook(), "View.EnableMouselook"); addMenu(new LLViewEnableJoystickFlycam(), "View.EnableJoystickFlycam"); addMenu(new LLViewEnableLastChatter(), "View.EnableLastChatter"); - addMenu(new LLViewToggleRadar(), "View.ToggleAvatarList"); addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam"); addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips"); @@ -9668,8 +9274,6 @@ void initialize_menus() addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); // World menu - addMenu(new LLWorldChat(), "World.Chat"); - addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun"); addMenu(new LLWorldSitOnGround(), "World.SitOnGround"); addMenu(new LLWorldEnableSitOnGround(), "World.EnableSitOnGround"); addMenu(new LLWorldFly(), "World.Fly"); @@ -9685,13 +9289,7 @@ void initialize_menus() addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation"); addMenu(new LLWorldEnableTeleportHome(), "World.EnableTeleportHome"); addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand"); - - addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun"); - (new LLWorldEnvSettings())->registerListener(gMenuHolder, "World.EnvSettings"); - (new LLWorldWaterSettings())->registerListener(gMenuHolder, "World.WaterSettings"); - (new LLWorldPostProcess())->registerListener(gMenuHolder, "World.PostProcess"); - (new LLWorldDayCycle())->registerListener(gMenuHolder, "World.DayCycle"); // Tools menu @@ -9715,7 +9313,6 @@ void initialize_menus() addMenu(new LLToolsLookAtSelection(), "Tools.LookAtSelection"); addMenu(new LLToolsBuyOrTake(), "Tools.BuyOrTake"); addMenu(new LLToolsTakeCopy(), "Tools.TakeCopy"); - addMenu(new LLToolsTakeCopy(), "Tools.TakeCopy"); // addMenu(new LLToolsEnableAdminDelete(), "Tools.EnableAdminDelete"); @@ -9765,7 +9362,6 @@ void initialize_menus() addMenu(new LLAvatarEject(), "Avatar.Eject"); addMenu(new LLAvatarSendIM(), "Avatar.SendIM"); addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse"); - addMenu(new LLAvatarAnims(),"Avatar.Anims"); addMenu(new LLObjectEnableMute(), "Avatar.EnableMute"); addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend"); addMenu(new LLAvatarEnableFreezeEject(), "Avatar.EnableFreezeEject"); @@ -9796,7 +9392,6 @@ void initialize_menus() addMenu(new LLObjectMute(), "Object.Mute"); addMenu(new LLObjectBuy(), "Object.Buy"); addMenu(new LLObjectEdit(), "Object.Edit"); - addMenu(new LLObjectInspect(), "Object.Inspect"); // Visual mute, originally by Phox. addMenu(new LLObjectDerender(), "Object.DERENDER"); addMenu(new LLAvatarReloadTextures(), "Avatar.ReloadTextures"); @@ -9843,7 +9438,6 @@ void initialize_menus() addMenu(new LLShowFloater(), "ShowFloater"); addMenu(new LLPromptShowURL(), "PromptShowURL"); addMenu(new LLShowAgentProfile(), "ShowAgentProfile"); - addMenu(new LLShowAgentGroups(), "ShowAgentGroups"); addMenu(new LLToggleControl(), "ToggleControl"); addMenu(new LLGoToObject(), "GoToObject"); @@ -9866,17 +9460,12 @@ void initialize_menus() // Singularity menu addMenu(new SinguCloseAllDialogs(), "CloseAllDialogs"); // ---- Fake away handled elsewhere - addMenu(new SinguAnimationOverride(), "AnimationOverride"); addMenu(new SinguNimble(), "Nimble"); addMenu(new SinguCheckNimble(), "CheckNimble"); - addMenu(new SinguStreamingAudioDisplay(), "StreamingAudioDisplay"); addMenu(new SinguEnableStreamingAudioDisplay(), "EnableStreamingAudioDisplay"); - addMenu(new SinguCheckStreamingAudioDisplay(), "CheckStreamingAudioDisplay"); addMenu(new SinguPoseStand(), "PoseStand"); addMenu(new SinguCheckPoseStand(), "CheckPoseStand"); addMenu(new SinguRebake(), "Rebake"); - addMenu(new SinguDebugConsole(), "RegionDebugConsole"); - addMenu(new SinguCheckDebugConsole(), "CheckRegionDebugConsole"); addMenu(new SinguVisibleDebugConsole(), "VisibleRegionDebugConsole"); // [RLVa:KB] - Checked: 2010-01-18 (RLVa-1.1.0m) | Added: RLVa-1.1.0m | OK @@ -9898,6 +9487,7 @@ void initialize_menus() addMenu(new ListEnableMute(), "List.EnableMute"); addMenu(new ListEnableOfferTeleport(), "List.EnableOfferTeleport"); addMenu(new ListVisibleWebProfile(), "List.VisibleWebProfile"); + addMenu(new ListCopySLURL(), "List.CopySLURL"); addMenu(new ListCopyUUIDs(), "List.CopyUUIDs"); addMenu(new ListInviteToGroup(), "List.InviteToGroup"); addMenu(new ListOfferTeleport(), "List.OfferTeleport"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 5eb158997..877bfdce3 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -62,7 +62,6 @@ #include "lltrans.h" #include "llfloaterbuycurrency.h" // -#include "floaterlocalassetbrowse.h" #include "llassettype.h" #include "llinventorytype.h" // @@ -517,15 +516,6 @@ class LLFileMinimizeAllWindows : public view_listener_t return true; } }; - -class LLFileLocalAssetBrowser : public view_listener_t -{ - bool handleEvent(LLPointer, const LLSD&) - { - FloaterLocalAssetBrowser::show(0); - return true; - } -}; // class LLFileSavePreview : public view_listener_t @@ -541,15 +531,6 @@ class LLFileSavePreview : public view_listener_t } }; -class LLFileTakeSnapshot : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloaterSnapshot::show(NULL); - return true; - } -}; - class LLFileTakeSnapshotToDisk : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -979,21 +960,21 @@ void temp_upload_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt { LLUUID item_id; item_id.generate(); - LLPermissions* perms = new LLPermissions(); - perms->set(LLPermissions::DEFAULT); - perms->setOwnerAndGroup(gAgentID, gAgentID, gAgentID, false); + LLPermissions perms; + perms.set(LLPermissions::DEFAULT); + perms.setOwnerAndGroup(gAgentID, gAgentID, gAgentID, false); - perms->setMaskBase(PERM_ALL); - perms->setMaskOwner(PERM_ALL); - perms->setMaskEveryone(PERM_ALL); - perms->setMaskGroup(PERM_ALL); - perms->setMaskNext(PERM_ALL); + perms.setMaskBase(PERM_ALL); + perms.setMaskOwner(PERM_ALL); + perms.setMaskEveryone(PERM_ALL); + perms.setMaskGroup(PERM_ALL); + perms.setMaskNext(PERM_ALL); LLViewerInventoryItem* item = new LLViewerInventoryItem( item_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE), - *perms, + perms, uuid, (LLAssetType::EType)data->mAssetInfo.mType, (LLInventoryType::EType)data->mInventoryType, @@ -1368,10 +1349,8 @@ void init_menu_file() (new LLFileEnableCloseAllWindows())->registerListener(gMenuHolder, "File.EnableCloseAllWindows"); // (new LLFileMinimizeAllWindows())->registerListener(gMenuHolder, "File.MinimizeAllWindows"); - (new LLFileLocalAssetBrowser())->registerListener(gMenuHolder, "File.LocalAssetBrowser"); // (new LLFileSavePreview())->registerListener(gMenuHolder, "File.SavePreview"); - (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot"); (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk"); (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit"); (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a27bbedb4..ceea596b0 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -38,6 +38,7 @@ #include "llaudioengine.h" #include "llavataractions.h" #include "llavatarnamecache.h" +#include "llbase64.h" #include "../lscript/lscript_byteformat.h" //Need LSCRIPTRunTimePermissionBits and SCRIPT_PERMISSION_* #include "lleconomy.h" #include "llfocusmgr.h" @@ -111,7 +112,7 @@ #include "llviewerregion.h" // [RLVa:KB] - Checked: 2010-03-09 (RLVa-1.2.0a) -#include "llfloateravatarinfo.h" // Checked: 2009-07-08 (RLVa-1.0.0e) +#include "rlvactions.h" #include "rlvhandler.h" #include "rlvinventory.h" #include "rlvui.h" @@ -1493,7 +1494,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& bool busy = gAgent.getBusy(); -// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1e) | Added: RLVa-1.2.1e +// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1) bool fRlvNotifyAccepted = false; // [/RLVa:KB] switch(button) @@ -1504,25 +1505,23 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // group_notice_inventory is 1 greater than the offer integer value. // [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1e) | Modified: RLVa-1.2.1e - // Only change the inventory offer's destination folder to the shared root if: + // Only treat the offer as 'Give to #RLV' if: // - the user has enabled the feature // - the inventory offer came from a script (and specifies a folder) // - the name starts with the prefix - mDesc format: '[OBJECTNAME]' ( http://slurl.com/... ) - if ( (rlv_handler_t::isEnabled()) && - (IM_TASK_INVENTORY_OFFERED == mIM) && (LLAssetType::AT_CATEGORY == mType) && (mDesc.find(RLV_PUTINV_PREFIX) == 1) ) + if ( (rlv_handler_t::isEnabled()) && (IM_TASK_INVENTORY_OFFERED == mIM) && (LLAssetType::AT_CATEGORY == mType) && (mDesc.find(RLV_PUTINV_PREFIX) == 1) ) { fRlvNotifyAccepted = true; if (!RlvSettings::getForbidGiveToRLV()) { - const LLViewerInventoryCategory* pRlvRoot = RlvInventory::instance().getSharedRoot(); - if (pRlvRoot) - { - fRlvNotifyAccepted = false; // "accepted_in_rlv" is sent from RlvGiveToRLVTaskOffer *after* we have the folder - mFolderID = pRlvRoot->getUUID(); + const LLUUID& idRlvRoot = RlvInventory::instance().getSharedRootID(); + if (idRlvRoot.notNull()) + mFolderID = idRlvRoot; - RlvGiveToRLVTaskOffer* pOfferObserver = new RlvGiveToRLVTaskOffer(mTransactionID); - gInventory.addObserver(pOfferObserver); - } + fRlvNotifyAccepted = false; // "accepted_in_rlv" is sent from RlvGiveToRLVTaskOffer *after* we have the folder + + RlvGiveToRLVTaskOffer* pOfferObserver = new RlvGiveToRLVTaskOffer(mTransactionID); + gInventory.addObserver(pOfferObserver); } } // [/RLVa:KB] @@ -1535,7 +1534,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // send the message msg->sendReliable(mHost); -// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1e) | Added: RLVa-1.2.1e +// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1) if (fRlvNotifyAccepted) { std::string::size_type idxToken = mDesc.find("' ( http://"); @@ -1562,9 +1561,8 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // This is an offer from an agent. In this case, the back // end has already copied the items into your inventory, // so we can fetch it out of our inventory. -// [RLVa:KB] - Checked: 2010-04-18 (RLVa-1.2.0e) | Modified: RLVa-1.2.0e - if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getForbidGiveToRLV()) && (LLAssetType::AT_CATEGORY == mType) && - (RlvInventory::instance().getSharedRoot()) && (mDesc.find(RLV_PUTINV_PREFIX) == 0) ) +// [RLVa:KB] - Checked: 2010-04-18 (RLVa-1.2.0) + if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getForbidGiveToRLV()) && (LLAssetType::AT_CATEGORY == mType) && (mDesc.find(RLV_PUTINV_PREFIX) == 0) ) { RlvGiveToRLVAgentOffer* pOfferObserver = new RlvGiveToRLVAgentOffer(mObjectID); pOfferObserver->startFetch(); @@ -1628,6 +1626,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& args["[NAME]"] = mFromName; LLFloaterChat::addChatHistory(LLTrans::getString("InvOfferAcceptSilent", args)); } + break; case IOR_BUSY: @@ -1688,7 +1687,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& } if (busy && (!mFromGroup && !mFromObject)) { - busy_message(msg,mFromID); + send_do_not_disturb_message(msg,mFromID); } break; } @@ -1706,6 +1705,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& return false; } +void script_msg_api(const std::string& msg); bool is_spam_filtered(const EInstantMessage& dialog, bool is_friend, bool is_owned_by_me) { // First, check the master filter @@ -1775,6 +1775,8 @@ void inventory_offer_handler(LLOfferInfo* info) return; } + if (!info->mFromGroup) script_msg_api(info->mFromID.asString() + ", 1"); + // If the user wants to, accept all offers of any kind if (gSavedSettings.getBOOL("AutoAcceptAllNewInventory")) { @@ -2246,7 +2248,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) llinfos << "RegionID: " << region_id.asString() << llendl; // - BOOL is_busy = gAgent.getBusy(); + BOOL is_do_not_disturb = gAgent.getBusy(); BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat) // object IMs contain sender object id in session_id (STORM-1209) || dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id); @@ -2315,7 +2317,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // do nothing -- don't distract newbies in // Prelude with global IMs } -// [RLVa:KB] - Checked: 2011-05-28 (RLVa-1.4.0a) | Modified: RLVa-1.4.0a +// [RLVa:KB] - Checked: 2011-05-28 (RLVa-1.4.0) else if ( (rlv_handler_t::isEnabled()) && (offline == IM_ONLINE) && ("@version" == message) && (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) ) { @@ -2325,25 +2327,35 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) gIMMgr->processIMTypingStop(im_info); } // [/RLVa:KB] -// else if (offline == IM_ONLINE && !is_linden && !is_muted && is_busy && name != SYSTEM_FROM) -// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - else if ( (offline == IM_ONLINE && !is_linden && !is_muted && is_busy && name != SYSTEM_FROM) && (gRlvHandler.canReceiveIM(from_id)) ) +// else if (offline == IM_ONLINE +// && is_do_not_disturb +// && !is_muted // Singu Note: Never if muted +// && from_id.notNull() //not a system message +// && to_id.notNull()) //not global message +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0) + else if (offline == IM_ONLINE + && is_do_not_disturb + && !is_muted // Singu Note: Never if muted + && from_id.notNull() //not a system message + && to_id.notNull() //not global message + && RlvActions::canReceiveIM(from_id)) // [/RLVa:KB] { - // return a standard "busy" message, but only do it to online IM + // return a standard "do not disturb" message, but only do it to online IM // (i.e. not other auto responses and not store-and-forward IM) if (!gIMMgr->hasSession(session_id) || gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat")) { // if the user wants to repeat responses over and over or // if there is not a panel for this conversation (i.e. it is a new IM conversation // initiated by the other party) then... - if (to_id.notNull()) busy_message(msg, from_id); + send_do_not_disturb_message(msg, from_id, session_id); } // now store incoming IM in chat history buffer = separator_string + message.substr(message_offset); LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL; + script_msg_api(from_id.asString() + ", 0"); // add to IM panel, but do not bother the user gIMMgr->addMessage( session_id, @@ -2361,9 +2373,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) chat.mText = std::string("IM: ") + name + separator_string + message.substr(message_offset); LLFloaterChat::addChat(chat, true, true); } -// else if (to_id.notNull() && offline == IM_ONLINE && !is_linden && (is_autorespond || is_autorespond_nonfriends || is_autorespond_muted) && name != SYSTEM_FROM) -// [RLVa:LF] - Same as above: Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - else if (to_id.notNull() && offline == IM_ONLINE && !is_linden && (is_autorespond || is_autorespond_nonfriends || is_autorespond_muted) && name != SYSTEM_FROM && gRlvHandler.canReceiveIM(from_id)) +// else if (offline == IM_ONLINE && (is_autorespond || is_autorespond_nonfriends || is_autorespond_muted) && from_id.notNull() && to_id.notNull()) +// [RLVa:LF] - Same as above: Checked: 2010-11-30 (RLVa-1.3.0) + else if (offline == IM_ONLINE && (is_autorespond || is_autorespond_nonfriends || is_autorespond_muted) && from_id.notNull() && to_id.notNull() && RlvActions::canReceiveIM(from_id) && RlvActions::canSendIM(from_id)) // [/RLVa:LF] { // now store incoming IM in chat history @@ -2371,6 +2383,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) buffer = separator_string + message.substr(message_offset); LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL; + if (!is_muted) script_msg_api(from_id.asString() + ", 0"); bool send_autoresponse = !gIMMgr->hasSession(session_id) || gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat"); // add to IM panel, but do not bother the user @@ -2475,16 +2488,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) mute_im = true; } -// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - // Don't block offline IMs, or IMs from Lindens - if ( (rlv_handler_t::isEnabled()) && (offline != IM_OFFLINE) && (!is_linden) && (!gRlvHandler.canReceiveIM(from_id)) ) - { - if (!mute_im) - RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM_REMOTE), session_id); - message = message.substr(0, message_offset) + RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); - } -// [/RLVa:KB] - std::string saved; if(offline == IM_OFFLINE) { @@ -2492,6 +2495,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) args["[LONG_TIMESTAMP]"] = formatted_time(timestamp); saved = LLTrans::getString("Saved_message", args); } + else if (!mute_im) script_msg_api(from_id.asString() + ", 0"); buffer = separator_string + saved + message.substr(message_offset); LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL; @@ -2510,6 +2514,17 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) mute_im = true; } */ + +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0) + // Don't block offline IMs, or IMs from Lindens + if ( (rlv_handler_t::isEnabled()) && (offline != IM_OFFLINE) && (!RlvActions::canReceiveIM(from_id)) && (!is_linden) ) + { + if (!mute_im) + RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM_REMOTE), session_id); + message = RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); + } +// [/RLVa:KB] + if (!mute_im || is_linden) { gIMMgr->addMessage( @@ -2562,7 +2577,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_TYPING_START: { // Don't announce that someone has started messaging, if they're muted or when in busy mode - if (!is_muted && (!accept_im_from_only_friend || is_friend) && !is_busy && !gIMMgr->hasSession(computed_session_id) && gSavedSettings.getBOOL("AscentInstantMessageAnnounceIncoming")) + if (!is_muted && (!accept_im_from_only_friend || is_friend) && !is_do_not_disturb && !gIMMgr->hasSession(computed_session_id) && gSavedSettings.getBOOL("AscentInstantMessageAnnounceIncoming")) { std::string pns_name; if (!LLAvatarNameCache::getPNSName(from_id, pns_name)) pns_name = name; @@ -2579,6 +2594,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) position, false); + // This block is very similar to the one above, but is necessary, since a session is opened to announce incoming message.. // In order to prevent doubling up on the first response, We neglect to send this if Repeat for each message is on. if ((is_autorespond_nonfriends || is_autorespond) && !gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat")) @@ -2622,6 +2638,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } LLPointer im_info = new LLIMInfo(gMessageSystem); gIMMgr->processIMTypingStart(im_info); + script_msg_api(from_id.asString() + ", 4"); } break; @@ -2629,6 +2646,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { LLPointer im_info = new LLIMInfo(gMessageSystem); gIMMgr->processIMTypingStop(im_info); + script_msg_api(from_id.asString() + ", 5"); } break; @@ -2737,7 +2755,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) payload["sender_name"] = name; payload["group_id"] = group_id; payload["inventory_name"] = item_name; - payload["inventory_offer"] = info ? info->asLLSD() : LLSD(); + if(info && info->asLLSD()) + { + payload["inventory_offer"] = info->asLLSD(); + } LLSD args; args["SUBJECT"] = subj; @@ -2758,12 +2779,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) break; case IM_GROUP_INVITATION: { - //if (!is_linden && (is_busy || is_muted)) + //if (is_do_not_disturb || is_muted) if (is_muted) return; - if (is_busy) + if (is_do_not_disturb) { LLMessageSystem *msg = gMessageSystem; - busy_message(msg,from_id); + send_do_not_disturb_message(msg,from_id); } else { @@ -2850,7 +2871,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) info->mFromName = name; info->mDesc = message; info->mHost = msg->getSender(); - //if (((is_busy && !is_owned_by_me) || is_muted)) + //if (((is_do_not_disturb && !is_owned_by_me) || is_muted)) if (is_muted) { // Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331) @@ -2862,9 +2883,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) info->forceResponse(IOR_DECLINE); } /* Singu Note: Handle this inside inventory_offer_handler so if the user wants to autoaccept offers, they can while busy. - else if (is_busy && dialog != IM_TASK_INVENTORY_OFFERED) // busy mode must not affect interaction with objects (STORM-565) + // old logic: busy mode must not affect interaction with objects (STORM-565) + // new logic: inventory offers from in-world objects should be auto-declined (CHUI-519) + // Singu Note: We should use old logic + else if (is_do_not_disturb && dialog != IM_TASK_INVENTORY_OFFERED) // busy mode must not affect interaction with objects (STORM-565) { - // Until throttling is implemented, busy mode should reject inventory instead of silently + // Until throttling is implemented, do not disturb mode should reject inventory instead of silently // accepting it. SEE SL-39554 info->forceResponse(IOR_DECLINE); } @@ -2920,7 +2944,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_SESSION_SEND: { - if (!is_linden && is_busy) + if (!is_linden && is_do_not_disturb) { return; } @@ -2938,16 +2962,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) return; } - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIMFROM)) ) + if (from_id != gAgentID && (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM) || gRlvHandler.hasBehaviour(RLV_BHVR_RECVIMFROM))) { switch (pIMFloater->getSessionType()) { case LLFloaterIMPanel::GROUP_SESSION: // Group chat - if ( (from_id != gAgent.getID()) && (!gRlvHandler.canReceiveIM(session_id)) ) + if (!RlvActions::canReceiveIM(session_id)) return; break; case LLFloaterIMPanel::ADHOC_SESSION: // Conference chat - if ( (from_id != gAgent.getID()) && (!gRlvHandler.canReceiveIM(from_id)) ) + if (!RlvActions::canReceiveIM(from_id)) message = RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); break; default: @@ -2996,7 +3020,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_FROM_TASK: { - if (is_busy && !is_owned_by_me) + if (is_do_not_disturb && !is_owned_by_me) { return; } @@ -3004,7 +3028,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) chat.mFromName = name; // Build a link to open the object IM info window. - std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size); + std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size-1); if (session_id.notNull()) { @@ -3032,6 +3056,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) chat.mFromID = LLUUID::null; chat.mSourceType = CHAT_SOURCE_SYSTEM; } + else script_msg_api(chat.mFromID.asString() + ", 6"); // IDEVO Some messages have embedded resident names message = clean_name_from_task_im(message, from_group); @@ -3075,8 +3100,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLFloaterChat::addChat(chat, FALSE, FALSE); } break; + case IM_FROM_TASK_AS_ALERT: - if (is_busy && !is_owned_by_me) + if (is_do_not_disturb && !is_owned_by_me) { return; } @@ -3090,38 +3116,35 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_BUSY_AUTO_RESPONSE: if (is_muted) { - LL_DEBUGS("Messaging") << "Ignoring busy response from " << from_id << LL_ENDL; + LL_DEBUGS("Messaging") << "Ignoring do-not-disturb response from " << from_id << LL_ENDL; return; } else { - // TODO: after LLTrans hits release, get "busy response" into translatable file - buffer = llformat("%s (%s): %s", name.c_str(), "busy response", message.substr(message_offset).c_str()); - gIMMgr->addMessage(session_id, from_id, name, buffer); + gIMMgr->addMessage(session_id, from_id, name, message); } break; case IM_LURE_USER: case IM_TELEPORT_REQUEST: { -// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c - // If the lure sender is a specific @accepttp exception they will override muted and busy status - bool fRlvSummon = (rlv_handler_t::isEnabled()) && (gRlvHandler.isException(RLV_BHVR_ACCEPTTP, from_id)); +// [RLVa:KB] - Checked: 2013-11-08 (RLVa-1.4.9) + // If we auto-accept the offer/request then this will override DnD status (but we'll still let the other party know later) + bool fRlvAutoAccept = (rlv_handler_t::isEnabled()) && + ( ((IM_LURE_USER == dialog) && (RlvActions::autoAcceptTeleportOffer(from_id))) || + ((IM_TELEPORT_REQUEST == dialog) && (RlvActions::autoAcceptTeleportRequest(from_id))) ); // [/RLVa:KB] -// if (is_muted) -// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c - if ( (is_muted) && (!fRlvSummon) ) -// [/RLVa:KB] + if (is_muted) { return; } -// else if (is_busy) -// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c - else if ( (is_busy) && (!fRlvSummon) ) +// else if (is_do_not_disturb) +// [RLVa:KB] - Checked: 2013-11-08 (RLVa-1.4.9) + else if ( (is_do_not_disturb) && (!fRlvAutoAccept) ) // [/RLVa:KB] { - busy_message(msg,from_id); + send_do_not_disturb_message(msg, from_id); } else { @@ -3178,19 +3201,20 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } } -// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c +// [RLVa:KB] - Checked: 2013-11-08 (RLVa-1.4.9) if (rlv_handler_t::isEnabled()) { - if (IM_TELEPORT_REQUEST != dialog && !gRlvHandler.canTeleportViaLure(from_id)) + if ( ((IM_LURE_USER == dialog) && (!RlvActions::canAcceptTpOffer(from_id))) || + ((IM_TELEPORT_REQUEST == dialog) && (!RlvActions::canAcceptTpRequest(from_id))) ) { - RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_TPLURE_REMOTE)); - if (is_busy) - busy_message(msg,from_id); + RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_TPLUREREQ_REMOTE)); + if (is_do_not_disturb) + send_do_not_disturb_message(msg, from_id); return; } - // Censor lure message if: 1) restricted from receiving IMs from the sender, or 2) @showloc=n restricted - if ( (!gRlvHandler.canReceiveIM(from_id)) || (IM_TELEPORT_REQUEST != dialog && gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) + // Censor lure message if: 1) restricted from receiving IMs from the sender, or 2) teleport offer and @showloc=n restricted + if ( (!RlvActions::canReceiveIM(from_id)) || ((IM_LURE_USER == dialog) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))) ) { message = RlvStrings::getString(RLV_STRING_HIDDEN); } @@ -3209,17 +3233,26 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) payload["lure_id"] = session_id; payload["godlike"] = FALSE; payload["region_maturity"] = region_access; - //LLNotificationsUtil::add("TeleportOffered", args, payload); -// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c - if ( IM_TELEPORT_REQUEST != dialog && (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTP)) || (fRlvSummon)) ) + /* Singu TODO: Figure if we should use these + if (!canUserAccessDstRegion) { - gRlvHandler.setCanCancelTp(false); - if (is_busy) - busy_message(msg,from_id); - LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); + LLNotification::Params params("TeleportOffered_MaturityBlocked"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add( params, from_id, false); + send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id); + send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id); + } + else if (doesUserRequireMaturityIncrease) + { + LLNotification::Params params("TeleportOffered_MaturityExceeded"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add( params, from_id, false); } else + */ { /* Singu Note: No default constructor for LLNotification::Params LLNotification::Params params; @@ -3238,14 +3271,29 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) params.substitutions = args; params.payload = payload; - LLNotifications::instance().add(params); - // - if (IM_LURE_USER == dialog) - gAgent.showLureDestination(name, region_handle, pos.mV[VX], pos.mV[VY], pos.mV[VZ]); - // - } + +// [RLVa:KB] - Checked: 20103-11-08 (RLVa-1.4.9) + if ( (rlv_handler_t::isEnabled()) && (fRlvAutoAccept) ) + { + if (IM_LURE_USER == dialog) + gRlvHandler.setCanCancelTp(false); + if (is_do_not_disturb) + send_do_not_disturb_message(msg, from_id); + LLNotifications::instance().forceResponse(LLNotification::Params(params.name).payload(payload), 0); + } + else + { + LLNotifications::instance().add(params); + + // + if (IM_LURE_USER == dialog) + gAgent.showLureDestination(name, region_handle, pos.mV[VX], pos.mV[VY], pos.mV[VZ]); + script_msg_api(from_id.asString().append(IM_LURE_USER == dialog ? ", 2" : ", 3")); + // + } // [/RLVa:KB] - //LLNotificationsUtil::add("TeleportOffered", args, payload); +// LLNotifications::instance().add(params); + } } } break; @@ -3355,17 +3403,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) payload["online"] = (offline == IM_ONLINE); payload["sender"] = msg->getSender().getIPandPort(); - if (!is_muted && is_busy) - { - busy_message(msg, from_id); - LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1); - } - else if (is_muted) + if (is_muted) { LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1); } else { + if (is_do_not_disturb) + { + send_do_not_disturb_message(msg, from_id); + } args["[NAME]"] = name; if(message.empty()) { @@ -3395,12 +3442,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) args["NAME"] = name; LLSD payload; payload["from_id"] = from_id; - LLAvatarNameCache::get(from_id, boost::bind(¬ification_display_name_callback, - _1, - _2, - "FriendshipAccepted", - args, - payload)); + LLAvatarNameCache::get(from_id, boost::bind(¬ification_display_name_callback, _1, _2, "FriendshipAccepted", args, payload)); } break; @@ -3418,7 +3460,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } } -void busy_message (LLMessageSystem* msg, LLUUID from_id) +void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id) { if (gAgent.getBusy()) { @@ -3429,7 +3471,7 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id) from_name = LLCacheName::cleanFullName(from_name); std::string response = gSavedPerAccountSettings.getString("BusyModeResponse"); pack_instant_message( - gMessageSystem, + msg, gAgent.getID(), FALSE, gAgent.getSessionID(), @@ -3487,7 +3529,7 @@ bool callingcard_offer_callback(const LLSD& notification, const LLSD& response) msg->nextBlockFast(_PREHASH_TransactionBlock); msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID()); msg->sendReliable(LLHost(notification["payload"]["sender"].asString())); - busy_message(msg, notification["payload"]["source_id"].asUUID()); + send_do_not_disturb_message(msg, notification["payload"]["source_id"].asUUID()); break; default: // close button probably, possibly timed out @@ -3654,6 +3696,17 @@ void check_translate_chat(const std::string &mesg, LLChat &chat, const BOOL hist // defined in llchatbar.cpp, but not declared in any header void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel); +void script_msg_api(const std::string& msg) +{ + static const LLCachedControl channel("ScriptMessageAPI"); + if (!channel) return; + static const LLCachedControl key("ScriptMessageAPIKey"); + std::string str; + for (size_t i = 0, keysize = key().size(); i != msg.size(); ++i) + str += msg[i] ^ key()[i%keysize]; + send_chat_from_viewer(LLBase64::encode(reinterpret_cast(str.c_str()), str.size()), CHAT_TYPE_WHISPER, channel); +} + class AuthHandler : public LLHTTPClient::ResponderWithCompleted { protected: @@ -3748,7 +3801,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) chat.mFromName = from_name; } - BOOL is_busy = gAgent.getBusy(); + BOOL is_do_not_disturb = gAgent.getBusy(); BOOL is_muted = FALSE; BOOL is_linden = FALSE; @@ -3866,7 +3919,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) // record last audible utterance if (is_audible - && (is_linden || (!is_muted && !is_busy))) + && (is_linden || (!is_muted && !is_do_not_disturb))) { if (chat.mChatType != CHAT_TYPE_START && chat.mChatType != CHAT_TYPE_STOP) @@ -3950,10 +4003,10 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) // Filtering "rules": // avatar => filter all avie text (unless it's this avie or they're an exemption) - // objects => filter everything except attachments this avie owns (never filter llOwnerSay chat) + // objects => filter everything except attachments this avie owns (never filter llOwnerSay or llRegionSayTo chat) if ( ( (CHAT_SOURCE_AGENT == chat.mSourceType) && (from_id != gAgent.getID()) ) || ( (CHAT_SOURCE_OBJECT == chat.mSourceType) && ((!is_owned_by_me) || (!is_attachment)) && - (CHAT_TYPE_OWNER != chat.mChatType) ) ) + (CHAT_TYPE_OWNER != chat.mChatType) && (CHAT_TYPE_DIRECT != chat.mChatType) ) ) { bool fIsEmote = RlvUtil::isEmote(mesg); if ((!fIsEmote) && @@ -4057,7 +4110,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE); static_cast(chatter)->stopTyping(); - if (!is_muted /*&& !is_busy*/) + if (!is_muted /*&& !is_do_not_disturb*/) { static const LLCachedControl use_chat_bubbles("UseChatBubbles",false); visible_in_chat_bubble = use_chat_bubbles; @@ -4200,7 +4253,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } chat.mMuted = is_muted && !is_linden; - bool only_history = visible_in_chat_bubble || (!is_linden && !is_owned_by_me && is_busy); + bool only_history = visible_in_chat_bubble || (!is_linden && !is_owned_by_me && is_do_not_disturb); #if 0 // Google translate doesn't work anymore if (!chat.mMuted) { @@ -5719,7 +5772,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data) } } - if (num_blocks) + //if (num_blocks) Singu note: commented out; having blocks or not is totally irrelevant! { avatarp->processAnimationStateChanges(); } @@ -6319,6 +6372,7 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) // make notification loggable payload["from_id"] = source_id; + if (!is_source_group) script_msg_api(source_id.asString() + ", 7"); } // Despite using SLURLs, wait until the name is available before @@ -7590,14 +7644,14 @@ void send_lures(const LLSD& notification, const LLSD& response) LLAgentUI::buildSLURL(slurl); text.append("\r\n").append(slurl.getSLURLString()); -// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) ) +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0) + if ( (RlvActions::hasBehaviour(RLV_BHVR_SENDIM)) || (RlvActions::hasBehaviour(RLV_BHVR_SENDIMTO)) ) { // Filter the lure message if one of the recipients of the lure can't be sent an IM to for (LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray(); it != notification["payload"]["ids"].endArray(); ++it) { - if (!gRlvHandler.canSendIM(it->asUUID())) + if (!RlvActions::canSendIM(it->asUUID())) { text = RlvStrings::getString(RLV_STRING_HIDDEN); break; diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index a31b7f486..ea3275cd7 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -70,7 +70,6 @@ enum InventoryOfferResponse BOOL can_afford_transaction(S32 cost); void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE, S32 trx_type = TRANS_GIFT, const std::string& desc = LLStringUtil::null); -void busy_message (LLMessageSystem* msg, LLUUID from_id); void process_logout_reply(LLMessageSystem* msg, void**); void process_layer_data(LLMessageSystem *mesgsys, void **user_data); @@ -160,6 +159,8 @@ void send_group_notice(const LLUUID& group_id, const std::string& message, const LLInventoryItem* item); +void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id = LLUUID::null); + void handle_lure(const LLUUID& invitee); void handle_lure(const uuid_vec_t& ids); diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index 98f08007e..b93cd6b2c 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -855,9 +855,9 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) if (prim_llsd.has("sculpt")) { - LLSculptParams* sculpt = new LLSculptParams(); - sculpt->fromLLSD(prim_llsd["sculpt"]); - LLUUID orig = sculpt->getSculptTexture(); + LLSculptParams sculpt; + sculpt.fromLLSD(prim_llsd["sculpt"]); + LLUUID orig = sculpt.getSculptTexture(); bool alreadyseen = false; for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) { @@ -913,10 +913,10 @@ LLVector3 LLObjectBackup::offsetAgent(LLVector3 offset) void LLObjectBackup::rezAgentOffset(LLVector3 offset) { // This will break for a sitting agent - LLToolPlacer* mPlacer = new LLToolPlacer(); - mPlacer->setObjectType(LL_PCODE_CUBE); + LLToolPlacer mPlacer; + mPlacer.setObjectType(LL_PCODE_CUBE); //LLVector3 pos = offsetAgent(offset); - mPlacer->placeObject((S32)offset.mV[0], (S32)offset.mV[1], MASK_NONE); + mPlacer.placeObject((S32)offset.mV[0], (S32)offset.mV[1], MASK_NONE); } void LLObjectBackup::importFirstObject() @@ -1004,32 +1004,32 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) if (prim_llsd.has("sculpt")) { - LLSculptParams* sculpt = new LLSculptParams(); - sculpt->fromLLSD(prim_llsd["sculpt"]); + LLSculptParams sculpt; + sculpt.fromLLSD(prim_llsd["sculpt"]); // TODO: check if map is valid and only set texture if map is valid and changes - if (mAssetMap[sculpt->getSculptTexture()].notNull()) + if (mAssetMap[sculpt.getSculptTexture()].notNull()) { - LLUUID replacment = mAssetMap[sculpt->getSculptTexture()]; - sculpt->setSculptTexture(replacment); + LLUUID replacment = mAssetMap[sculpt.getSculptTexture()]; + sculpt.setSculptTexture(replacment); } - object->setParameterEntry(LLNetworkData::PARAMS_SCULPT,(LLNetworkData&)(*sculpt), true); + object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt, true); } if (prim_llsd.has("light")) { - LLLightParams* light = new LLLightParams(); - light->fromLLSD(prim_llsd["light"]); - object->setParameterEntry(LLNetworkData::PARAMS_LIGHT,(LLNetworkData&)(*light), true); + LLLightParams light; + light.fromLLSD(prim_llsd["light"]); + object->setParameterEntry(LLNetworkData::PARAMS_LIGHT, light, true); } if (prim_llsd.has("flexible")) { - LLFlexibleObjectData* flex = new LLFlexibleObjectData(); - flex->fromLLSD(prim_llsd["flexible"]); - object->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE,(LLNetworkData&)(*flex), true); + LLFlexibleObjectData flex; + flex.fromLLSD(prim_llsd["flexible"]); + object->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, flex, true); } // Textures diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 57037a871..977d8fede 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -2,31 +2,25 @@ * @file llviewerparcelmgr.cpp * @brief Viewer-side representation of owned land * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -75,6 +69,7 @@ #include "lloverlaybar.h" #include "roles_constants.h" #include "llweb.h" +#include "rlvactions.h" const F32 PARCEL_COLLISION_DRAW_SECS = 1.f; @@ -130,6 +125,10 @@ LLViewerParcelMgr::LLViewerParcelMgr() mRenderSelection(TRUE), mCollisionBanned(0), mCollisionTimer(), +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + mCollisionRegionHandle(0), + mCollisionUpdateSignal(NULL), +// [/SL:KB] mMediaParcelId(0), mMediaRegionId(0), mHighlightSegments(NULL), @@ -152,6 +151,11 @@ LLViewerParcelMgr::LLViewerParcelMgr() mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)]; resetSegments(mHighlightSegments); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + mCollisionBitmap = new U8[getCollisionBitmapSize()]; + memset(mCollisionBitmap, 0, getCollisionBitmapSize()); +// [/SL:KB] + mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)]; resetSegments(mCollisionSegments); @@ -208,6 +212,11 @@ LLViewerParcelMgr::~LLViewerParcelMgr() delete[] mHighlightSegments; mHighlightSegments = NULL; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + delete[] mCollisionBitmap; + mCollisionBitmap = NULL; +// [/SL:KB] + delete[] mCollisionSegments; mCollisionSegments = NULL; @@ -1741,18 +1750,31 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } - S32 bitmap_size = parcel_mgr.mParcelsPerEdge - * parcel_mgr.mParcelsPerEdge - / 8; - U8* bitmap = new U8[ bitmap_size ]; - msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size); +// S32 bitmap_size = parcel_mgr.mParcelsPerEdge +// * parcel_mgr.mParcelsPerEdge +// / 8; +// U8* bitmap = new U8[ bitmap_size ]; +// msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, parcel_mgr.mCollisionBitmap, parcel_mgr.getCollisionBitmapSize()); +// [/SL:KB] parcel_mgr.resetSegments(parcel_mgr.mCollisionSegments); - parcel_mgr.writeSegmentsFromBitmap( bitmap, parcel_mgr.mCollisionSegments ); +// parcel_mgr.writeSegmentsFromBitmap( bitmap, parcel_mgr.mCollisionSegments ); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + parcel_mgr.writeSegmentsFromBitmap(parcel_mgr.mCollisionBitmap, parcel_mgr.mCollisionSegments); +// [/SL:KB] - delete[] bitmap; - bitmap = NULL; +// delete[] bitmap; +// bitmap = NULL; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + LLViewerRegion* pRegion = LLWorld::getInstance()->getRegion(msg->getSender()); + parcel_mgr.mCollisionRegionHandle = (pRegion) ? pRegion->getHandle() : 0; + + if (parcel_mgr.mCollisionUpdateSignal) + (*parcel_mgr.mCollisionUpdateSignal)(pRegion); +// [/SL:KB] } else if (sequence_id == HOVERED_PARCEL_SEQ_ID) { @@ -1770,7 +1792,10 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - // look for music. + // Check for video + LLViewerParcelMedia::update(parcel); + + // Then check for music if (gAudiop) { if (parcel) @@ -1818,9 +1843,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use gAudiop->stopInternetStream(); } }//if gAudiop - - // now check for video - LLViewerParcelMedia::update( parcel ); }; } @@ -1828,9 +1850,6 @@ void optionally_start_music(LLParcel* parcel) { if (gSavedSettings.getBOOL("AudioStreamingMusic")) { - - - // Make the user click the start button on the overlay bar. JC // llinfos << "Starting parcel music " << parcel->getMusicURL() << llendl; @@ -2208,6 +2227,12 @@ bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const void LLViewerParcelMgr::startBuyLand(BOOL is_for_group) { +// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) + if (RlvActions::isRlvEnabled() && !RlvActions::canShowLocation()) + return; +// [/RLVa:KB] + if (selectionEmpty()) selectParcelAt(gAgent.getPositionGlobal()); + LLFloaterBuyLand::buyLand(getSelectionRegion(), mCurrentParcelSelection, is_for_group == TRUE); } @@ -2571,3 +2596,12 @@ void LLViewerParcelMgr::onTeleportFailed() { mTeleportFailedSignal(); } + +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +boost::signals2::connection LLViewerParcelMgr::setCollisionUpdateCallback(const collision_update_signal_t::slot_type & cb) +{ + if (!mCollisionUpdateSignal) + mCollisionUpdateSignal = new collision_update_signal_t(); + return mCollisionUpdateSignal->connect(cb); +} +// [/SL:KB] diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 022465a97..1e0ea2c83 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -2,31 +2,25 @@ * @file llviewerparcelmgr.h * @brief Viewer-side representation of owned land * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,10 +30,13 @@ #include "v3dmath.h" #include "lldarray.h" #include "llframetimer.h" -#include "llmemory.h" +#include "llsingleton.h" #include "llparcelselection.h" #include "llui.h" +#include +#include + class LLUUID; class LLMessageSystem; class LLParcel; @@ -169,6 +166,14 @@ public: LLParcel* getHoverParcel() const; LLParcel* getCollisionParcel() const; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + const U8* getCollisionBitmap() const { return mCollisionBitmap; } + size_t getCollisionBitmapSize() const { return mParcelsPerEdge * mParcelsPerEdge / 8; } + U64 getCollisionRegionHandle() const { return mCollisionRegionHandle; } + + typedef boost::signals2::signal collision_update_signal_t; + boost::signals2::connection setCollisionUpdateCallback(const collision_update_signal_t::slot_type & cb); +// [/SL:KB] // Can this agent build on the parcel he is on? // Used for parcel property icons in nav bar. @@ -361,6 +366,11 @@ private: // Watch for pending collisions with a parcel you can't access. // If it's coming, draw the parcel's boundaries. LLParcel* mCollisionParcel; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + U8* mCollisionBitmap; + U64 mCollisionRegionHandle; + collision_update_signal_t* mCollisionUpdateSignal; +// [/SL:KB] U8* mCollisionSegments; BOOL mRenderCollision; BOOL mRenderSelection; diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 6eb83a9f7..7bdc24f0a 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -2,31 +2,25 @@ * @file llviewerparceloverlay.cpp * @brief LLViewerParcelOverlay class implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -54,8 +48,13 @@ #include "llglheaders.h" #include "pipeline.h" + const U8 OVERLAY_IMG_COMPONENTS = 4; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +LLViewerParcelOverlay::update_signal_t* LLViewerParcelOverlay::mUpdateSignal = NULL; +// [/SL:KB] + LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters) : mRegion( region ), mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ), @@ -858,6 +857,10 @@ void LLViewerParcelOverlay::idleUpdate(bool force_update) { updateOverlayTexture(); updatePropertyLines(); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + if (mUpdateSignal) + (*mUpdateSignal)(mRegion); +// [/SL:KB] mTimeSinceLastUpdate.reset(); } } @@ -929,6 +932,7 @@ S32 LLViewerParcelOverlay::renderPropertyLines () S32 drawn = 0; F32* vertexp; U8* colorp; + bool render_hidden = LLSelectMgr::sRenderHiddenSelections && gFloaterTools && gFloaterTools->getVisible(); const F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f; @@ -970,7 +974,7 @@ S32 LLViewerParcelOverlay::renderPropertyLines () gGL.end(); - if (LLSelectMgr::sRenderHiddenSelections && gFloaterTools && gFloaterTools->getVisible()) + if (render_hidden) { LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); @@ -1005,3 +1009,12 @@ S32 LLViewerParcelOverlay::renderPropertyLines () return drawn; } + +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +boost::signals2::connection LLViewerParcelOverlay::setUpdateCallback(const update_signal_t::slot_type & cb) +{ + if (!mUpdateSignal) + mUpdateSignal = new update_signal_t(); + return mUpdateSignal->connect(cb); +} +// [/SL:KB] diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index d53a4c15f..3f629fda9 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -2,31 +2,25 @@ * @file llviewerparceloverlay.h * @brief LLViewerParcelOverlay class header file * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -73,6 +67,9 @@ public: BOOL isBuildCameraAllowed(const LLVector3& pos) const; F32 getOwnedRatio() const; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + const U8* getOwnership() const { return mOwnership; } +// [/SL:KB] // Returns the number of vertices drawn S32 renderPropertyLines(); @@ -88,6 +85,11 @@ public: void idleUpdate(bool update_now = false); void updateGL(); +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + typedef boost::signals2::signal update_signal_t; + static boost::signals2::connection setUpdateCallback(const update_signal_t::slot_type & cb); +// [/SL:KB] + private: // This is in parcel rows and columns, not grid rows and columns // Stored in bottom three bits. @@ -129,6 +131,10 @@ private: S32 mVertexCount; F32* mVertexArray; U8* mColorArray; + +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + static update_signal_t* mUpdateSignal; +// [/SL:KB] }; #endif diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 0754d1d2e..7103a7ede 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -48,6 +48,7 @@ #include "v3math.h" #include "v4math.h" +#include "lfsimfeaturehandler.h" #include "llagent.h" #include "llagentcamera.h" #include "llcallingcard.h" @@ -222,7 +223,7 @@ public: virtual ~BaseCapabilitiesComplete() { } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + void error(U32 statusNum, const std::string& reason) { LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL; LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); @@ -232,7 +233,7 @@ public: } } - /*virtual*/ void result(const LLSD& content) + void result(const LLSD& content) { LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); if(!regionp) //region was removed @@ -422,6 +423,14 @@ LLViewerRegion::~LLViewerRegion() delete mImpl; mImpl = NULL; + +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-26 (Catznip-3.3) + if (mWorldMapTile) + { + mWorldMapTile->setBoostLevel(LLViewerTexture::BOOST_NONE); + mWorldMapTile = NULL; + } +// [/SL:KB] } LLEventPump& LLViewerRegion::getCapAPI() const @@ -1087,7 +1096,28 @@ F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos) return mImpl->mLandp->resolveHeightRegion( region_pos ); } -bool LLViewerRegion::isAlive() +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +LLViewerTexture* LLViewerRegion::getWorldMapTile() const +{ + if (!mWorldMapTile) + { + U32 gridX, gridY; + grid_from_region_handle(mHandle, &gridX, &gridY); + // Singu Note: We must obey the override on certain grids! + std::string simOverrideMap = LFSimFeatureHandler::instance().mapServerURL(); + std::string strImgURL = (simOverrideMap.empty() ? gSavedSettings.getString("MapServerURL") : simOverrideMap) + llformat("map-1-%d-%d-objects.jpg", gridX, gridY); + + mWorldMapTile = LLViewerTextureManager::getFetchedTextureFromUrl(strImgURL, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mWorldMapTile->setBoostLevel(LLViewerTexture::BOOST_MAP); + } + return mWorldMapTile; +} +// [/SL:KB] + +//bool LLViewerRegion::isAlive() +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) +bool LLViewerRegion::isAlive() const +// [/SL:KB] { return mAlive; } @@ -1281,7 +1311,7 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) std::stringstream str; LLSDSerialize::toPrettyXML(sim_features, str); - llinfos << str.str() << llendl; + LL_DEBUGS("SimFeatures") << "\n" << str.str() << LL_ENDL; mSimulatorFeatures = sim_features; mFeaturesReceived = true; @@ -1817,13 +1847,13 @@ public: { } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + void error(U32 statusNum, const std::string& reason) { LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL; retry(); } - /*virtual*/ void result(const LLSD& content) + void result(const LLSD& content) { LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); if(!regionp) //region is removed or responder is not created. @@ -2044,6 +2074,7 @@ void LLViewerRegion::getNeighboringRegionsStatus( std::vector& regions ) { mImpl->mLandp->getNeighboringRegionsStatus( regions ); } + void LLViewerRegion::showReleaseNotes() { std::string url = this->getCapability("ServerReleaseNotes"); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index f5d2d2eae..1b6eee985 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -75,6 +75,9 @@ class LLDataPacker; class LLDataPackerBinaryBuffer; class LLHost; class LLBBox; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-26 (Catznip-3.3) +class LLViewerTexture; +// [/SL:KB] class LLViewerRegionImpl; @@ -143,7 +146,12 @@ public: inline BOOL getRestrictPushObject() const; inline BOOL getReleaseNotesRequested() const; - bool isAlive(); // can become false if circuit disconnects +// bool isAlive(); // can become false if circuit disconnects +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3.0) + bool isAlive() const; // can become false if circuit disconnects + + LLViewerTexture* getWorldMapTile() const; +// [/SL:KB] void setWaterHeight(F32 water_level); F32 getWaterHeight() const; @@ -455,6 +463,10 @@ private: LLDynamicArray mCacheMissFull; LLDynamicArray mCacheMissCRC; +// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-26 (Catznip-3.3) + mutable LLPointer mWorldMapTile; +// [/SL:KB] + bool mAlive; // can become false if circuit disconnects bool mCapabilitiesReceived; bool mFeaturesReceived; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index b5a819032..453a1e076 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -190,7 +190,7 @@ LLGLSLShader gDeferredWaterProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calc LLGLSLShader gDeferredUnderWaterProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED);//Not in mShaderList LLGLSLShader gDeferredDiffuseAlphaMaskProgram(LLViewerShaderMgr::SHADER_DEFERRED); -LLGLSLShader gDeferredNonIndexedDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED); +//LLGLSLShader gDeferredNonIndexedDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredSkinnedDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED); @@ -552,6 +552,7 @@ void LLViewerShaderMgr::setShaders() else { LLGLSLShader::sNoFixedFunction = false; + LLGLSLShader::sIndexedTextureChannels = 1; gPipeline.mVertexShadersEnabled = FALSE; gPipeline.mVertexShadersLoaded = 0; for (S32 i = 0; i < SHADER_COUNT; i++) @@ -569,6 +570,7 @@ void LLViewerShaderMgr::setShaders() else { LLGLSLShader::sNoFixedFunction = false; + LLGLSLShader::sIndexedTextureChannels = 1; gPipeline.mVertexShadersEnabled = FALSE; gPipeline.mVertexShadersLoaded = 0; for (S32 i = 0; i < SHADER_COUNT; i++) @@ -673,14 +675,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // (in order of shader function call depth for reference purposes, deepest level first) shaders.clear(); - S32 ch = 1; - - if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) - { //use indexed texture rendering for GLSL >= 1.30 - static const LLCachedControl no_texture_indexing("ShyotlUseLegacyTextureBatching",false); - if(!no_texture_indexing) - ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); - } + S32 ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); std::vector index_channels; index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); @@ -1078,7 +1073,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL); } - if (success) + /*if (success) { gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader"; gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear(); @@ -1086,7 +1081,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredNonIndexedDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL); - } + }*/ if (success) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 99374c31a..feea7cfbc 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -300,7 +300,7 @@ extern LLGLSLShader gDeferredDiffuseProgram; extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; -extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; +//extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; extern LLGLSLShader gDeferredSkinnedDiffuseProgram; extern LLGLSLShader gDeferredSkinnedBumpProgram; extern LLGLSLShader gDeferredSkinnedAlphaProgram; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 4728f0ffd..62dba3ca5 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -878,8 +878,9 @@ void send_stats() llinfos << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << llendl; llinfos << "Misc Stats: string_1: " << misc["string_1"] << " string_2: " << misc["string_2"] << llendl; - body["DisplayNamesEnabled"] = gSavedSettings.getS32("PhoenixNameSystem") == 1 || gSavedSettings.getS32("PhoenixNameSystem") == 2; - body["DisplayNamesShowUsername"] = gSavedSettings.getS32("PhoenixNameSystem") == 1; + const S32 namesys = gSavedSettings.getS32("PhoenixNameSystem"); + body["DisplayNamesEnabled"] = namesys > 0 && namesys < 4; + body["DisplayNamesShowUsername"] = namesys == 1 || namesys == 3; body["MinimalSkin"] = false; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 4f2e5c931..1e77f7b43 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1640,12 +1640,18 @@ LLViewerWindow::LLViewerWindow( LLViewerWindow::sMovieBaseName = "SLmovie"; resetSnapshotLoc(); + S32 vsync_mode = gSavedSettings.getS32("SHRenderVsyncMode"); + if(vsync_mode == -1 && !gGLManager.mHasAdaptiveVsync) + { + vsync_mode = 0; //Disable vsync if adaptive is desired yet isn't supported. + } + // create window mWindow = LLWindowManager::createWindow(this, title, name, x, y, width, height, 0, fullscreen, gNoRender, - gSavedSettings.getBOOL("DisableVerticalSync"), + vsync_mode, !gNoRender, ignore_pixel_depth, gSavedSettings.getBOOL("RenderUseFBO") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled @@ -4436,14 +4442,20 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height) BORDERHEIGHT = size.mY- y; LLCoordScreen new_size(new_width + BORDERWIDTH, new_height + BORDERHEIGHT); - BOOL disable_sync = gSavedSettings.getBOOL("DisableVerticalSync"); + + S32 vsync_mode = gSavedSettings.getS32("SHRenderVsyncMode"); + if(vsync_mode == -1 && !gGLManager.mHasAdaptiveVsync) + { + vsync_mode = 0; //Disable vsync if adaptive is desired yet isn't supported. + } + if (gViewerWindow->getWindow()->getFullscreen()) { LLGLState::checkStates(); LLGLState::checkTextureChannels(); gViewerWindow->changeDisplaySettings(FALSE, new_size, - disable_sync, + vsync_mode, TRUE); LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -5137,14 +5149,6 @@ void LLViewerWindow::revealIntroPanel() } } -void LLViewerWindow::abortShowProgress() -{ - if (mProgressView) - { - mProgressView->abortShowProgress(); - } -} - void LLViewerWindow::setShowProgress(const BOOL show) { if (mProgressView) @@ -5429,9 +5433,16 @@ BOOL LLViewerWindow::checkSettings() LLGLState::checkStates(); LLGLState::checkTextureChannels(); + + S32 vsync_mode = gSavedSettings.getS32("SHRenderVsyncMode"); + if(vsync_mode == -1 && !gGLManager.mHasAdaptiveVsync) + { + vsync_mode = 0; //Disable vsync if adaptive is desired yet isn't supported. + } + changeDisplaySettings(TRUE, desired_screen_size, - gSavedSettings.getBOOL("DisableVerticalSync"), + vsync_mode, mShowFullscreenProgress); LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -5472,7 +5483,7 @@ void LLViewerWindow::restartDisplay(BOOL show_progress_bar) } } -BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar) +BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, const S32 vsync_mode, BOOL show_progress_bar) { BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized"); mWantFullscreen = fullscreen; @@ -5491,6 +5502,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); U32 old_fsaa = mWindow->getFSAASamples(); + // going from windowed to windowed if (!old_fullscreen && !fullscreen) { @@ -5500,7 +5512,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, mWindow->setSize(size); } - if (fsaa == old_fsaa) + if (fsaa == old_fsaa && vsync_mode == mWindow->getFSAASamples()) { return TRUE; } @@ -5539,13 +5551,14 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, } mWindow->setFSAASamples(fsaa); + mWindow->setVsyncMode(vsync_mode); - result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync, &new_pos); + result_first_try = mWindow->switchContext(fullscreen, size, vsync_mode, &new_pos); if (!result_first_try) { // try to switch back mWindow->setFSAASamples(old_fsaa); - result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync, &new_pos); + result_second_try = mWindow->switchContext(old_fullscreen, old_size, vsync_mode, &new_pos); if (!result_second_try) { diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 7ec0f3ec3..7e47a1a1b 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -386,7 +386,7 @@ public: void requestResolutionUpdate(bool fullscreen_checked); BOOL checkSettings(); void restartDisplay(BOOL show_progress_bar); - BOOL changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar); + BOOL changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, const S32 vsync_mode, BOOL show_progress_bar); BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; } F32 getDisplayAspectRatio() const; const LLVector2& getDisplayScale() const { return mDisplayScale; } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 453525da9..901340a57 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -145,18 +145,106 @@ using namespace LLAvatarAppearanceDefines; //----------------------------------------------------------------------------- // Global constants //----------------------------------------------------------------------------- -const LLUUID ANIM_AGENT_BODY_NOISE = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise" -const LLUUID ANIM_AGENT_BREATHE_ROT = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot" -const LLUUID ANIM_AGENT_EDITING = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing" -const LLUUID ANIM_AGENT_EYE = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye" -const LLUUID ANIM_AGENT_FLY_ADJUST = LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e"); //"fly_adjust" -const LLUUID ANIM_AGENT_HAND_MOTION = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion" -const LLUUID ANIM_AGENT_HEAD_ROT = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"); //"head_rot" -const LLUUID ANIM_AGENT_PELVIS_FIX = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b"); //"pelvis_fix" -const LLUUID ANIM_AGENT_TARGET = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55"); //"target" -const LLUUID ANIM_AGENT_WALK_ADJUST = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust" -const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df440d987"); //"physics_motion" +const LLUUID ANIM_AGENT_BODY_NOISE_ID = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise" +const LLUUID ANIM_AGENT_BREATHE_ROT_ID = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot" +const LLUUID ANIM_AGENT_PHYSICS_MOTION_ID = LLUUID("7360e029-3cb8-ebc4-863e-212df440d987"); //"physics_motion" +const LLUUID ANIM_AGENT_EDITING_ID = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing" +const LLUUID ANIM_AGENT_EYE_ID = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye" +const LLUUID ANIM_AGENT_FLY_ADJUST_ID = LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e"); //"fly_adjust" +const LLUUID ANIM_AGENT_HAND_MOTION_ID = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion" +const LLUUID ANIM_AGENT_HEAD_ROT_ID = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"); //"head_rot" +const LLUUID ANIM_AGENT_PELVIS_FIX_ID = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b"); //"pelvis_fix" +const LLUUID ANIM_AGENT_TARGET_ID = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55"); //"target" +const LLUUID ANIM_AGENT_WALK_ADJUST_ID = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust" +// +// This must be in the same order as ANIM_AGENT_BODY_NOISE through ANIM_AGENT_WALK_ADJUST (see llmotion.h)! +static LLUUID const* lookup[] = { + &ANIM_AGENT_BODY_NOISE_ID, + &ANIM_AGENT_BREATHE_ROT_ID, + &ANIM_AGENT_PHYSICS_MOTION_ID, + &ANIM_AGENT_EDITING_ID, + &ANIM_AGENT_EYE_ID, + &ANIM_AGENT_FLY_ADJUST_ID, + &ANIM_AGENT_HAND_MOTION_ID, + &ANIM_AGENT_HEAD_ROT_ID, + &ANIM_AGENT_PELVIS_FIX_ID, + &ANIM_AGENT_TARGET_ID, + &ANIM_AGENT_WALK_ADJUST_ID +}; + +LLUUID const& mask2ID(U32 bit) +{ + int const lookupsize = sizeof(lookup) / sizeof(LLUUID const*); + int i = lookupsize - 1; + U32 mask = 1 << i; + for(;;) + { + if (bit == mask) + { + return *lookup[i]; + } + --i; + mask >>= 1; + llassert_always(i >= 0); + } +} + +#ifdef CWDEBUG +static char const* strlookup[] = { + "ANIM_AGENT_BODY_NOISE", + "ANIM_AGENT_BREATHE_ROT", + "ANIM_AGENT_PHYSICS_MOTION", + "ANIM_AGENT_EDITING", + "ANIM_AGENT_EYE", + "ANIM_AGENT_FLY_ADJUST", + "ANIM_AGENT_HAND_MOTION", + "ANIM_AGENT_HEAD_ROT", + "ANIM_AGENT_PELVIS_FIX", + "ANIM_AGENT_TARGET", + "ANIM_AGENT_WALK_ADJUST" +}; + +char const* mask2str(U32 bit) +{ + int const lookupsize = sizeof(lookup) / sizeof(LLUUID const*); + int i = lookupsize - 1; + U32 mask = 1 << i; + do + { + if (bit == mask) + { + return strlookup[i]; + } + --i; + mask >>= 1; + } + while(i >= 0); + return ""; +} +#endif + +// stopMotion(ANIM_AGENT_WALK_ADJUST) is called every frame, and for every avatar on the radar. +// That can be like 1000 times per second, so... speed that up a bit and lets not lookup the same LLUUID 1000 times +// per second in a std::map. Added the rest of the animations while I was at it. +void LLVOAvatar::startMotion(U32 bit, F32 time_offset) +{ + if (!isMotionActive(bit)) + { + mMotionController.disable_syncing(); // Don't attempt to synchronize AIMaskedMotion. + startMotion(mask2ID(bit), time_offset); + mMotionController.enable_syncing(); + } +} + +void LLVOAvatar::stopMotion(U32 bit, BOOL stop_immediate) +{ + if (isMotionActive(bit)) + { + stopMotion(mask2ID(bit), stop_immediate); + } +} +// //----------------------------------------------------------------------------- // Constants @@ -257,12 +345,12 @@ struct LLTextureMaskData // class LLBodyNoiseMotion //----------------------------------------------------------------------------- class LLBodyNoiseMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLBodyNoiseMotion(const LLUUID &id) - : LLMotion(id) + LLBodyNoiseMotion(LLUUID const& id, LLMotionController* controller) + : AIMaskedMotion(id, controller, ANIM_AGENT_BODY_NOISE) { mName = "body_noise"; mTorsoState = new LLJointState; @@ -277,7 +365,7 @@ public: //------------------------------------------------------------------------- // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLBodyNoiseMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLBodyNoiseMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -320,11 +408,6 @@ public: return STATUS_SUCCESS; } - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() { return TRUE; } - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. @@ -348,9 +431,6 @@ public: return TRUE; } - // called when a motion is deactivated - virtual void onDeactivate() {} - private: //------------------------------------------------------------------------- // joint states to be animated @@ -362,12 +442,12 @@ private: // class LLBreatheMotionRot //----------------------------------------------------------------------------- class LLBreatheMotionRot : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLBreatheMotionRot(const LLUUID &id) : - LLMotion(id), + LLBreatheMotionRot(LLUUID const& id, LLMotionController* controller) : + AIMaskedMotion(id, controller, ANIM_AGENT_BREATHE_ROT), mBreatheRate(1.f), mCharacter(NULL) { @@ -384,7 +464,7 @@ public: //------------------------------------------------------------------------- // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLBreatheMotionRot(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLBreatheMotionRot(id, controller); } public: //------------------------------------------------------------------------- @@ -437,11 +517,6 @@ public: } } - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() { return TRUE; } - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. @@ -456,9 +531,6 @@ public: return TRUE; } - // called when a motion is deactivated - virtual void onDeactivate() {} - private: //------------------------------------------------------------------------- // joint states to be animated @@ -472,12 +544,12 @@ private: // class LLPelvisFixMotion //----------------------------------------------------------------------------- class LLPelvisFixMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLPelvisFixMotion(const LLUUID &id) - : LLMotion(id), mCharacter(NULL) + LLPelvisFixMotion(LLUUID const& id, LLMotionController* controller) + : AIMaskedMotion(id, controller, ANIM_AGENT_PELVIS_FIX), mCharacter(NULL) { mName = "pelvis_fix"; @@ -493,7 +565,7 @@ public: //------------------------------------------------------------------------- // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID& id) { return new LLPelvisFixMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLPelvisFixMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -538,11 +610,6 @@ public: return STATUS_SUCCESS; } - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() { return TRUE; } - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. @@ -553,9 +620,6 @@ public: return TRUE; } - // called when a motion is deactivated - virtual void onDeactivate() {} - private: //------------------------------------------------------------------------- // joint states to be animated @@ -1438,17 +1502,17 @@ void LLVOAvatar::deleteCachedImages(bool clearAll) //------------------------------------------------------------------------ void LLVOAvatar::initClass() { - gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise"); - gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot"); - gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion"); - gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING,"editing"); - gAnimLibrary.animStateSetString(ANIM_AGENT_EYE,"eye"); - gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST,"fly_adjust"); - gAnimLibrary.animStateSetString(ANIM_AGENT_HAND_MOTION,"hand_motion"); - gAnimLibrary.animStateSetString(ANIM_AGENT_HEAD_ROT,"head_rot"); - gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX,"pelvis_fix"); - gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET,"target"); - gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST,"walk_adjust"); + gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE_ID,"body_noise"); + gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT_ID,"breathe_rot"); + gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION_ID,"physics_motion"); + gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING_ID,"editing"); + gAnimLibrary.animStateSetString(ANIM_AGENT_EYE_ID,"eye"); + gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST_ID,"fly_adjust"); + gAnimLibrary.animStateSetString(ANIM_AGENT_HAND_MOTION_ID,"hand_motion"); + gAnimLibrary.animStateSetString(ANIM_AGENT_HEAD_ROT_ID,"head_rot"); + gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX_ID,"pelvis_fix"); + gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET_ID,"target"); + gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST_ID,"walk_adjust"); SHClientTagMgr::instance(); //Instantiate. Parse. Will fetch a new tag file if AscentUpdateTagsOnLoad is true. } @@ -1506,19 +1570,19 @@ void LLVOAvatar::initInstance(void) registerMotion( ANIM_AGENT_WALK_NEW, LLKeyframeWalkMotion::create ); //v2 // motions without a start/stop bit - registerMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create ); - registerMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create ); - registerMotion( ANIM_AGENT_PHYSICS_MOTION, LLPhysicsMotionController::create ); - registerMotion( ANIM_AGENT_EDITING, LLEditingMotion::create ); - registerMotion( ANIM_AGENT_EYE, LLEyeMotion::create ); - registerMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create ); - registerMotion( ANIM_AGENT_HAND_MOTION, LLHandMotion::create ); - registerMotion( ANIM_AGENT_HEAD_ROT, LLHeadRotMotion::create ); - registerMotion( ANIM_AGENT_PELVIS_FIX, LLPelvisFixMotion::create ); - registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create ); - registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create ); - registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create ); + registerMotion( ANIM_AGENT_BODY_NOISE_ID, LLBodyNoiseMotion::create ); + registerMotion( ANIM_AGENT_BREATHE_ROT_ID, LLBreatheMotionRot::create ); + registerMotion( ANIM_AGENT_PHYSICS_MOTION_ID, LLPhysicsMotionController::create ); + registerMotion( ANIM_AGENT_EDITING_ID, LLEditingMotion::create ); + registerMotion( ANIM_AGENT_EYE_ID, LLEyeMotion::create ); + registerMotion( ANIM_AGENT_FLY_ADJUST_ID, LLFlyAdjustMotion::create ); + registerMotion( ANIM_AGENT_HAND_MOTION_ID, LLHandMotion::create ); + registerMotion( ANIM_AGENT_HEAD_ROT_ID, LLHeadRotMotion::create ); + registerMotion( ANIM_AGENT_PELVIS_FIX_ID, LLPelvisFixMotion::create ); + registerMotion( ANIM_AGENT_TARGET_ID, LLTargetingMotion::create ); + registerMotion( ANIM_AGENT_WALK_ADJUST_ID, LLWalkAdjustMotion::create ); + registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create ); } LLAvatarAppearance::initInstance(); @@ -3312,7 +3376,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - bool show_display_names = phoenix_name_system == 1 || phoenix_name_system == 2; + bool show_display_names = phoenix_name_system > 0 || phoenix_name_system < 4; bool show_usernames = phoenix_name_system != 2; if (show_display_names && LLAvatarNameCache::useDisplayNames()) { @@ -3332,7 +3396,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) // Might be blank if name not available yet, that's OK if (show_display_names) { - firstnameText=av_name.mDisplayName; //Defer for later formatting + firstnameText = phoenix_name_system == 3 ? av_name.mUsername : av_name.mDisplayName; //Defer for later formatting //addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL, // LLFontGL::getFontSansSerif()); } @@ -3341,7 +3405,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) { firstnameText.push_back(' '); firstnameText.push_back('('); - firstnameText.append(av_name.mUsername); //Defer for later formatting + firstnameText.append(phoenix_name_system == 3 ? av_name.mDisplayName : av_name.mUsername); //Defer for later formatting firstnameText.push_back(')'); // *HACK: Desaturate the color //LLColor4 username_color = name_tag_color * 0.83f; @@ -3748,6 +3812,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) if (LLVOAvatar::sShowAnimationDebug) { + addDebugText(llformat("at=%.1f", mMotionController.getAnimTime())); for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); iter != mMotionController.getActiveMotions().end(); ++iter) { @@ -3767,6 +3832,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) motionp->getName().c_str(), (U32)motionp->getPriority()); } + if (motionp->server()) + { +#ifdef SHOW_ASSERT + output += llformat(" rt=%.1f r=%d s=0x%xl", motionp->getRuntime(), motionp->mReadyEvents, motionp->server()); +#else + output += llformat(" rt=%.1f s=0x%xl", motionp->getRuntime(), motionp->server()); +#endif + } addDebugText(output); } } @@ -3884,7 +3957,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) getOffObject(); // //Singu note: this appears to be a safety catch: - // when getParent() is NULL and we're note playing ANIM_AGENT_SIT_GROUND_CONSTRAINED then we aren't sitting! + // when getParent() is NULL and we're not playing ANIM_AGENT_SIT_GROUND_CONSTRAINED then we aren't sitting! // The previous call existed in an attempt to fix this inconsistent state by standing up from an object. // However, since getParent() is NULL that function would crash! // Since we never got crash reports regarding to this, that apparently never happened, except, I discovered @@ -5437,6 +5510,7 @@ void LLVOAvatar::processAnimationStateChanges() } // clear all current animations + BOOL const AOEnabled = gSavedSettings.getBOOL("AOEnabled"); // Singu note: put this outside the loop. AnimIterator anim_it; for (anim_it = mPlayingAnimations.begin(); anim_it != mPlayingAnimations.end();) { @@ -5446,9 +5520,9 @@ void LLVOAvatar::processAnimationStateChanges() if (found_anim == mSignaledAnimations.end()) { - if (isSelf()) + if (AOEnabled && isSelf()) { - if ((gSavedSettings.getBOOL("AOEnabled")) && LLFloaterAO::stopMotion(anim_it->first, FALSE)) // if the AO replaced this anim serverside then stop it serverside + if (LLFloaterAO::stopMotion(anim_it->first, FALSE)) // if the AO replaced this anim serverside then stop it serverside { // return TRUE; //no local stop needed } @@ -5456,7 +5530,7 @@ void LLVOAvatar::processAnimationStateChanges() processSingleAnimationStateChange(anim_it->first, FALSE); // - LLFloaterExploreAnimations::stopAnim(getID(), anim_it->first); + LLFloaterExploreAnimations::processAnim(getID(), anim_it->first, false); // mPlayingAnimations.erase(anim_it++); continue; @@ -5474,11 +5548,11 @@ void LLVOAvatar::processAnimationStateChanges() if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second) { // - LLFloaterExploreAnimations::startAnim(getID(), anim_it->first); + LLFloaterExploreAnimations::processAnim(getID(), anim_it->first, true); // if (processSingleAnimationStateChange(anim_it->first, TRUE)) { - if (isSelf() && gSavedSettings.getBOOL("AOEnabled")) // AO is only for ME + if (AOEnabled && isSelf()) // AO is only for ME { LLFloaterAO::startMotion(anim_it->first, 0,FALSE); // AO overrides the anim if needed } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 891fae7d9..ded74c50b 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -54,6 +54,9 @@ #include "llavatarname.h" +// +#if 0 +// Hide these: should be using the bit masks everywhere. extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; extern const LLUUID ANIM_AGENT_PHYSICS_MOTION; @@ -65,6 +68,8 @@ extern const LLUUID ANIM_AGENT_HEAD_ROT; extern const LLUUID ANIM_AGENT_PELVIS_FIX; extern const LLUUID ANIM_AGENT_TARGET; extern const LLUUID ANIM_AGENT_WALK_ADJUST; +#endif +// class LLAPRFile; class LLViewerWearable; @@ -230,6 +235,10 @@ public: /*virtual*/ LLUUID remapMotionID(const LLUUID& id); /*virtual*/ BOOL startMotion(const LLUUID& id, F32 time_offset = 0.f); /*virtual*/ BOOL stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE); + // + void startMotion(U32 bit, F32 start_offset = 0.f); + void stopMotion(U32 bit, BOOL stop_immediate = FALSE); + // virtual void stopMotionFromSource(const LLUUID& source_id); virtual void requestStopMotion(LLMotion* motion); LLMotion* findMotion(const LLUUID& id) const; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index e01998284..c3ead99db 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -897,9 +897,9 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp) //virtual void LLVOAvatarSelf::idleUpdateTractorBeam() { - - - if(gSavedSettings.getBOOL("DisablePointAtAndBeam")) + // + static LLCachedControl disable_pointat_effect("DisablePointAtAndBeam"); + if (disable_pointat_effect) { return; } @@ -978,6 +978,7 @@ void LLVOAvatarSelf::idleUpdateTractorBeam() } } } + //----------------------------------------------------------------------------- // restoreMeshData() //----------------------------------------------------------------------------- @@ -1226,7 +1227,6 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view gRlvAttachmentLocks.updateLockedHUD(); } // [/RLVa:KB] - } return attachment; @@ -1239,24 +1239,20 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) // [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0a) | Added: RLVa-1.2.0a // NOTE: RLVa event handlers should be invoked *before* LLVOAvatar::detachObject() calls LLViewerJointAttachment::removeObject() - + if (rlv_handler_t::isEnabled()) { for (attachment_map_t::const_iterator itAttachPt = mAttachmentPoints.begin(); itAttachPt != mAttachmentPoints.end(); ++itAttachPt) { const LLViewerJointAttachment* pAttachPt = itAttachPt->second; if (pAttachPt->isObjectAttached(viewer_object)) { - if (rlv_handler_t::isEnabled()) - { - RlvAttachmentLockWatchdog::instance().onDetach(viewer_object, pAttachPt); - gRlvHandler.onDetach(viewer_object, pAttachPt); - } - if (mAttachmentSignal) - { - (*mAttachmentSignal)(viewer_object, pAttachPt, ACTION_DETACH); - } + RlvAttachmentLockWatchdog::instance().onDetach(viewer_object, pAttachPt); + gRlvHandler.onDetach(viewer_object, pAttachPt); + } + if (mAttachmentSignal) + { + (*mAttachmentSignal)(viewer_object, pAttachPt, ACTION_DETACH); } - break; } } // [/RLVa:KB] @@ -1525,6 +1521,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset return FALSE; } + BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const { const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); @@ -3122,6 +3119,7 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const return success; } + //------------------------------------------------------------------------ // needsRenderBeam() //------------------------------------------------------------------------ @@ -3257,14 +3255,6 @@ LLVector3 LLVOAvatarSelf::getLegacyAvatarOffset() const static LLCachedControl z_off("AscentAvatarZModifier"); LLVector3 offset(x_off,y_off,z_off); -// [RLVa:KB] Custom blah blah - if(rlv_handler_t::isEnabled()) - { - F32 rlva_z_offs = RlvSettings::getAvatarOffsetZ(); - if(fabs(rlva_z_offs) > F_APPROXIMATELY_ZERO) - offset.mV[VZ] = rlva_z_offs; - } -// [/RLVa:KB] if(on_pose_stand) offset.mV[VZ] += 7.5f; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index dd1b7c662..f3709450d 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -540,6 +540,7 @@ void LLVoiceClient::setMuteMic(bool muted) { mMuteMic = muted; updateMicMuteLogic(); + mMicroChangedSignal(); } @@ -550,6 +551,7 @@ void LLVoiceClient::setUserPTTState(bool ptt) { mUserPTTState = ptt; updateMicMuteLogic(); + mMicroChangedSignal(); } bool LLVoiceClient::getUserPTTState() @@ -711,14 +713,7 @@ BOOL LLVoiceClient::isParticipantAvatar(const LLUUID& id) BOOL LLVoiceClient::isOnlineSIP(const LLUUID& id) { - if (mVoiceModule) - { - return mVoiceModule->isOnlineSIP(id); - } - else - { return FALSE; - } } BOOL LLVoiceClient::getIsSpeaking(const LLUUID& id) diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 761a1a768..b8cf474cc 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -198,7 +198,6 @@ public: //@{ virtual BOOL getVoiceEnabled(const LLUUID& id)=0; // true if we've received data for this avatar virtual std::string getDisplayName(const LLUUID& id)=0; - virtual BOOL isOnlineSIP(const LLUUID &id)=0; virtual BOOL isParticipantAvatar(const LLUUID &id)=0; virtual BOOL getIsSpeaking(const LLUUID& id)=0; virtual BOOL getIsModeratorMuted(const LLUUID& id)=0; @@ -302,6 +301,9 @@ public: LLVoiceClient(); ~LLVoiceClient(); + typedef boost::signals2::signal micro_changed_signal_t; + micro_changed_signal_t mMicroChangedSignal; + void init(LLPumpIO *pump); // Call this once at application startup (creates connector) void terminate(); // Call this to clean up during shutdown @@ -400,6 +402,8 @@ public: void keyUp(KEY key, MASK mask); void middleMouseState(bool down); + boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); } + ///////////////////////////// // Accessors for data related to nearby speakers @@ -455,6 +459,7 @@ protected: LLVoiceModuleInterface* mVoiceModule; LLPumpIO *m_servicePump; + LLCachedControl mVoiceEffectEnabled; LLCachedControl mVoiceEffectDefault; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index edfecf681..58f8dbcf0 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -177,17 +177,10 @@ class LLVivoxVoiceClientMuteListObserver : public LLMuteListObserver /* virtual */ void onChange() { LLVivoxVoiceClient::getInstance()->muteListChanged();} }; -class LLVivoxVoiceClientFriendsObserver : public LLFriendObserver -{ -public: - /* virtual */ void changed(U32 mask) { LLVivoxVoiceClient::getInstance()->updateFriends(mask);} -}; static LLVivoxVoiceClientMuteListObserver mutelist_listener; static bool sMuteListListener_listening = false; -static LLVivoxVoiceClientFriendsObserver *friendslist_listener = NULL; - /////////////////////////////////////////////////////////////////////////////////////////////// class LLVivoxVoiceClientCapResponder : public LLHTTPClient::ResponderWithResult @@ -424,7 +417,6 @@ void LLVivoxVoiceClient::terminate() void LLVivoxVoiceClient::cleanUp() { deleteAllSessions(); - deleteAllBuddies(); deleteAllVoiceFonts(); deleteVoiceFontTemplates(); } @@ -510,10 +502,10 @@ void LLVivoxVoiceClient::connectorCreate() std::string savedLogLevel = gSavedSettings.getString("VivoxDebugLevel"); - if(savedLogLevel != "-1") + if(savedLogLevel != "-0") { LL_DEBUGS("Voice") << "creating connector with logging enabled" << LL_ENDL; - loglevel = "10"; + loglevel = "0"; } stream @@ -845,11 +837,24 @@ void LLVivoxVoiceClient::stateMachine() // SLIM SDK: these arguments are no longer necessary. // std::string args = " -p tcp -h -c"; std::string loglevel = gSavedSettings.getString("VivoxDebugLevel"); + if(loglevel.empty()) + { + loglevel = "0"; // turn logging off completely + } - // If we allow multiple instances of the viewer to start the voice - // daemon, set TEMPORARY random voice port + args += " -ll "; +// Singu Note: hard code log level to -1 for Linux, as we are using 2.x version of the SDK there +// Singu TODO: Remove this when the Vivox SDK 4.x is working on Linux +#if LL_LINUX + args += "-1"; +#else + args += loglevel; +#endif + + // If we allow multiple instances of the viewer to start the voicedaemon if (gSavedSettings.getBOOL("VoiceMultiInstance")) { + // Set TEMPORARY random voice port LLControlVariable* voice_port = gSavedSettings.getControl("VoicePort"); if (voice_port) { @@ -857,19 +862,7 @@ void LLVivoxVoiceClient::stateMachine() S32 port_nr = 30000 + ll_rand(20000); voice_port->setValue(LLSD(port_nr), DO_NOT_PERSIST); } - } - - if(loglevel.empty()) - { - loglevel = "-1"; // turn logging off completely - } - - args += " -ll "; - args += loglevel; - - // Tell voice gateway to listen to a specific port - if (gSavedSettings.getBOOL("VoiceMultiInstance")) - { + // Tell voice gateway to listen to a specific port args += llformat(" -i 127.0.0.1:%u", gSavedSettings.getU32("VoicePort")); } @@ -1338,12 +1331,6 @@ void LLVivoxVoiceClient::stateMachine() setState(stateVoiceFontsReceived); } - // request the current set of block rules (we'll need them when updating the friends list) - accountListBlockRulesSendMessage(); - - // request the current set of auto-accept rules - accountListAutoAcceptRulesSendMessage(); - // Set up the mute list observer if it hasn't been set up already. if((!sMuteListListener_listening)) { @@ -1351,13 +1338,6 @@ void LLVivoxVoiceClient::stateMachine() sMuteListListener_listening = true; } - // Set up the friends list observer if it hasn't been set up already. - if(friendslist_listener == NULL) - { - friendslist_listener = new LLVivoxVoiceClientFriendsObserver; - LLAvatarTracker::instance().addObserver(friendslist_listener); - } - // Set the initial state of mic mute, local speaker volume, etc. { std::ostringstream stream; @@ -1427,9 +1407,7 @@ void LLVivoxVoiceClient::stateMachine() case stateNoChannel: LL_DEBUGS("Voice") << "State No Channel" << LL_ENDL; mSpatialJoiningNum = 0; - // Do this here as well as inside sendPositionalUpdate(). - // Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync. - sendFriendsListUpdates(); + if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized)) { @@ -1626,7 +1604,6 @@ void LLVivoxVoiceClient::stateMachine() mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS); sendPositionalUpdate(); } - mIsInitialized = true; } break; @@ -1801,7 +1778,7 @@ void LLVivoxVoiceClient::loginSendMessage() << "" << mAccountName << "" << "" << mAccountPassword << "" << "VerifyAnswer" - << "true" + << "false" << "Application" << "5" << (autoPostCrashDumps?"true":"") @@ -1837,42 +1814,6 @@ void LLVivoxVoiceClient::logoutSendMessage() } } -void LLVivoxVoiceClient::accountListBlockRulesSendMessage() -{ - if(!mAccountHandle.empty()) - { - std::ostringstream stream; - - LL_DEBUGS("Voice") << "requesting block rules" << LL_ENDL; - - stream - << "" - << "" << mAccountHandle << "" - << "" - << "\n\n\n"; - - writeString(stream.str()); - } -} - -void LLVivoxVoiceClient::accountListAutoAcceptRulesSendMessage() -{ - if(!mAccountHandle.empty()) - { - std::ostringstream stream; - - LL_DEBUGS("Voice") << "requesting auto-accept rules" << LL_ENDL; - - stream - << "" - << "" << mAccountHandle << "" - << "" - << "\n\n\n"; - - writeString(stream.str()); - } -} - void LLVivoxVoiceClient::sessionGroupCreateSendMessage() { if(!mAccountHandle.empty()) @@ -2708,9 +2649,6 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void) writeString(stream.str()); } - // Friends list updates can be huge, especially on the first voice login of an account with lots of friends. - // Batching them all together can choke SLVoice, so send them in separate writes. - sendFriendsListUpdates(); } void LLVivoxVoiceClient::buildSetCaptureDevice(std::ostringstream &stream) @@ -2808,275 +2746,6 @@ void LLVivoxVoiceClient::buildLocalAudioUpdates(std::ostringstream &stream) } -void LLVivoxVoiceClient::checkFriend(const LLUUID& id) -{ - buddyListEntry *buddy = findBuddy(id); - - // Make sure we don't add a name before it's been looked up. - LLAvatarName av_name; - if(LLAvatarNameCache::get(id, &av_name)) - { - // *NOTE: We feed legacy names to Vivox because we don't know if their service - // can support a mix of new and old clients with different sorts of names. - std::string name = av_name.getLegacyName(); - - if(buddy) - { - // This buddy is already in both lists (vivox buddies and avatar cache). - // Trust the avatar cache more for the display name (vivox display name are notoriously wrong) - buddy->mDisplayName = name; - } - else - { - // This buddy was not in the vivox list, needs to be added. - buddy = addBuddy(sipURIFromID(id), name); - buddy->mUUID = id; - } - - const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); - buddy->mCanSeeMeOnline = (relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)); - // In all the above cases, the buddy is in the SL friends list and tha name has been resolved (which is how we got here). - buddy->mNameResolved = true; - buddy->mInSLFriends = true; - } - else - { - // This name hasn't been looked up yet in the avatar cache. Don't do anything with this buddy list entry until it has. - if(buddy) - { - buddy->mNameResolved = false; - } - // Initiate a lookup. - // The "lookup completed" callback will ensure that the friends list is rechecked after it completes. - lookupName(id); - } -} - -void LLVivoxVoiceClient::clearAllLists() -{ - // FOR TESTING ONLY - - // This will send the necessary commands to delete ALL buddies, autoaccept rules, and block rules SLVoice tells us about. - buddyListMap::iterator buddy_it; - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end();) - { - buddyListEntry *buddy = buddy_it->second; - buddy_it++; - - std::ostringstream stream; - - if(buddy->mInVivoxBuddies) - { - // delete this entry from the vivox buddy list - buddy->mInVivoxBuddies = false; - LL_DEBUGS("Voice") << "delete " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "\n\n\n"; - } - - if(buddy->mHasBlockListEntry) - { - // Delete the associated block list entry (so the block list doesn't fill up with junk) - buddy->mHasBlockListEntry = false; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "\n\n\n"; - } - if(buddy->mHasAutoAcceptListEntry) - { - // Delete the associated auto-accept list entry (so the auto-accept list doesn't fill up with junk) - buddy->mHasAutoAcceptListEntry = false; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "\n\n\n"; - } - - writeString(stream.str()); - - } -} - -void LLVivoxVoiceClient::sendFriendsListUpdates() -{ - if(mBuddyListMapPopulated && mBlockRulesListReceived && mAutoAcceptRulesListReceived && mFriendsListDirty) - { - mFriendsListDirty = false; - - if(0) - { - // FOR TESTING ONLY -- clear all buddy list, block list, and auto-accept list entries. - clearAllLists(); - return; - } - - LL_INFOS("Voice") << "Checking vivox buddy list against friends list..." << LL_ENDL; - - buddyListMap::iterator buddy_it; - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++) - { - // reset the temp flags in the local buddy list - buddy_it->second->mInSLFriends = false; - } - - // correlate with the friends list - { - LLCollectAllBuddies collect; - LLAvatarTracker::instance().applyFunctor(collect); - LLCollectAllBuddies::buddy_map_t::const_iterator it = collect.mOnline.begin(); - LLCollectAllBuddies::buddy_map_t::const_iterator end = collect.mOnline.end(); - - for ( ; it != end; ++it) - { - checkFriend(it->second); - } - it = collect.mOffline.begin(); - end = collect.mOffline.end(); - for ( ; it != end; ++it) - { - checkFriend(it->second); - } - } - - LL_INFOS("Voice") << "Sending friend list updates..." << LL_ENDL; - - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end();) - { - buddyListEntry *buddy = buddy_it->second; - buddy_it++; - - // Ignore entries that aren't resolved yet. - if(buddy->mNameResolved) - { - std::ostringstream stream; - - if(buddy->mInSLFriends && !buddy->mInVivoxBuddies) - { - if(mNumberOfAliases > 0) - { - // Add (or update) this entry in the vivox buddy list - buddy->mInVivoxBuddies = true; - LL_DEBUGS("Voice") << "add/update " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL; - stream - << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "" << buddy->mDisplayName << "" - << "" // Without this, SLVoice doesn't seem to parse the command. - << "0" - << "\n\n\n"; - } - } - else if(!buddy->mInSLFriends) - { - // This entry no longer exists in your SL friends list. Remove all traces of it from the Vivox buddy list. - if(buddy->mInVivoxBuddies) - { - // delete this entry from the vivox buddy list - buddy->mInVivoxBuddies = false; - LL_DEBUGS("Voice") << "delete " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "\n\n\n"; - } - - if(buddy->mHasBlockListEntry) - { - // Delete the associated block list entry, if any - buddy->mHasBlockListEntry = false; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "\n\n\n"; - } - if(buddy->mHasAutoAcceptListEntry) - { - // Delete the associated auto-accept list entry, if any - buddy->mHasAutoAcceptListEntry = false; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "\n\n\n"; - } - } - - if(buddy->mInSLFriends) - { - - if(buddy->mCanSeeMeOnline) - { - // Buddy should not be blocked. - - // If this buddy doesn't already have either a block or autoaccept list entry, we'll update their status when we receive a SubscriptionEvent. - - // If the buddy has a block list entry, delete it. - if(buddy->mHasBlockListEntry) - { - buddy->mHasBlockListEntry = false; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "\n\n\n"; - - - // If we just deleted a block list entry, add an auto-accept entry. - if(!buddy->mHasAutoAcceptListEntry) - { - buddy->mHasAutoAcceptListEntry = true; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "0" - << "\n\n\n"; - } - } - } - else - { - // Buddy should be blocked. - - // If this buddy doesn't already have either a block or autoaccept list entry, we'll update their status when we receive a SubscriptionEvent. - - // If this buddy has an autoaccept entry, delete it - if(buddy->mHasAutoAcceptListEntry) - { - buddy->mHasAutoAcceptListEntry = false; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "\n\n\n"; - - // If we just deleted an auto-accept entry, add a block list entry. - if(!buddy->mHasBlockListEntry) - { - buddy->mHasBlockListEntry = true; - stream << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "1" - << "\n\n\n"; - } - } - } - - if(!buddy->mInSLFriends && !buddy->mInVivoxBuddies) - { - // Delete this entry from the local buddy list. This should NOT invalidate the iterator, - // since it has already been incremented to the next entry. - deleteBuddy(buddy->mURI); - } - - } - writeString(stream.str()); - } - } - } -} - ///////////////////////////// // Response/Event handlers @@ -3879,83 +3548,6 @@ void LLVivoxVoiceClient::participantUpdatedEvent( } } -void LLVivoxVoiceClient::buddyPresenceEvent( - std::string &uriString, - std::string &alias, - std::string &statusString, - std::string &applicationString) -{ - buddyListEntry *buddy = findBuddy(uriString); - - if(buddy) - { - LL_DEBUGS("Voice") << "Presence event for " << buddy->mDisplayName << " status \"" << statusString << "\", application \"" << applicationString << "\""<< LL_ENDL; - LL_DEBUGS("Voice") << "before: mOnlineSL = " << (buddy->mOnlineSL?"true":"false") << ", mOnlineSLim = " << (buddy->mOnlineSLim?"true":"false") << LL_ENDL; - - if(applicationString.empty()) - { - // This presence event is from a client that doesn't set up the Application string. Do things the old-skool way. - // NOTE: this will be needed to support people who aren't on the 3010-class SDK yet. - - if ( stricmp("Unknown", statusString.c_str())== 0) - { - // User went offline with a non-SLim-enabled viewer. - buddy->mOnlineSL = false; - } - else if ( stricmp("Online", statusString.c_str())== 0) - { - // User came online with a non-SLim-enabled viewer. - buddy->mOnlineSL = true; - } - else - { - // If the user is online through SLim, their status will be "Online-slc", "Away", or something else. - // NOTE: we should never see this unless someone is running an OLD version of SLim -- the versions that should be in use now all set the application string. - buddy->mOnlineSLim = true; - } - } - else if(applicationString.find("SecondLifeViewer") != std::string::npos) - { - // This presence event is from a viewer that sets the application string - if ( stricmp("Unknown", statusString.c_str())== 0) - { - // Viewer says they're offline - buddy->mOnlineSL = false; - } - else - { - // Viewer says they're online - buddy->mOnlineSL = true; - } - } - else - { - // This presence event is from something which is NOT the SL viewer (assume it's SLim). - if ( stricmp("Unknown", statusString.c_str())== 0) - { - // SLim says they're offline - buddy->mOnlineSLim = false; - } - else - { - // SLim says they're online - buddy->mOnlineSLim = true; - } - } - - LL_DEBUGS("Voice") << "after: mOnlineSL = " << (buddy->mOnlineSL?"true":"false") << ", mOnlineSLim = " << (buddy->mOnlineSLim?"true":"false") << LL_ENDL; - - // HACK -- increment the internal change serial number in the LLRelationship (without changing the actual status), so the UI notices the change. - LLAvatarTracker::instance().setBuddyOnline(buddy->mUUID,LLAvatarTracker::instance().isBuddyOnline(buddy->mUUID)); - - notifyFriendObservers(); - } - else - { - LL_DEBUGS("Voice") << "Presence for unknown buddy " << uriString << LL_ENDL; - } -} - void LLVivoxVoiceClient::messageEvent( std::string &sessionHandle, std::string &uriString, @@ -4145,70 +3737,12 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st } } -void LLVivoxVoiceClient::subscriptionEvent(std::string &buddyURI, std::string &subscriptionHandle, std::string &alias, std::string &displayName, std::string &applicationString, std::string &subscriptionType) -{ - buddyListEntry *buddy = findBuddy(buddyURI); - - if(!buddy) - { - // Couldn't find buddy by URI, try converting the alias... - if(!alias.empty()) - { - LLUUID id; - if(IDFromName(alias, id)) - { - buddy = findBuddy(id); - } - } - } - - if(buddy) - { - std::ostringstream stream; - - if(buddy->mCanSeeMeOnline) - { - // Sending the response will create an auto-accept rule - buddy->mHasAutoAcceptListEntry = true; - } - else - { - // Sending the response will create a block rule - buddy->mHasBlockListEntry = true; - } - - if(buddy->mInSLFriends) - { - buddy->mInVivoxBuddies = true; - } - - stream - << "" - << "" << mAccountHandle << "" - << "" << buddy->mURI << "" - << "" << (buddy->mCanSeeMeOnline?"Allow":"Hide") << "" - << ""<< (buddy->mInSLFriends?"1":"0")<< "" - << "" << subscriptionHandle << "" - << "" - << "\n\n\n"; - - writeString(stream.str()); - } -} - void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy) { LL_DEBUGS("Voice") << "got energy " << energy << LL_ENDL; mTuningEnergy = energy; } -void LLVivoxVoiceClient::buddyListChanged() -{ - // This is called after we receive a BuddyAndGroupListChangedEvent. - mBuddyListMapPopulated = true; - mFriendsListDirty = true; -} - void LLVivoxVoiceClient::muteListChanged() { // The user's mute list has been updated. Go through the current participant list and sync it with the mute list. @@ -4227,15 +3761,6 @@ void LLVivoxVoiceClient::muteListChanged() } } -void LLVivoxVoiceClient::updateFriends(U32 mask) -{ - if(mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::POWERS)) - { - // Just resend the whole friend list to the daemon - mFriendsListDirty = true; - } -} - ///////////////////////////// // Managing list of participants LLVivoxVoiceClient::participantState::participantState(const std::string &uri) : @@ -4835,34 +4360,6 @@ bool LLVivoxVoiceClient::answerInvite(std::string &sessionHandle) return false; } -BOOL LLVivoxVoiceClient::isOnlineSIP(const LLUUID &id) -{ - bool result = false; - buddyListEntry *buddy = findBuddy(id); - if(buddy) - { - result = buddy->mOnlineSLim; - LL_DEBUGS("Voice") << "Buddy " << buddy->mDisplayName << " is SIP " << (result?"online":"offline") << LL_ENDL; - } - - if(!result) - { - // This user isn't on the buddy list or doesn't show online status through the buddy list, but could be a participant in an existing session if they initiated a text IM. - sessionState *session = findSession(id); - if(session && !session->mHandle.empty()) - { - if((session->mTextStreamState != streamStateUnknown) || (session->mMediaStreamState > streamStateIdle)) - { - LL_DEBUGS("Voice") << "Open session with " << id << " found, returning SIP online state" << LL_ENDL; - // we have a p2p text session open with this user, so by definition they're online. - result = true; - } - } - } - - return result; -} - bool LLVivoxVoiceClient::isVoiceWorking() const { //Added stateSessionTerminated state to avoid problems with call in parcels with disabled voice (EXT-4758) @@ -5970,224 +5467,6 @@ void LLVivoxVoiceClient::verifySessionState(void) } } -LLVivoxVoiceClient::buddyListEntry::buddyListEntry(const std::string &uri) : - mURI(uri) -{ - mOnlineSL = false; - mOnlineSLim = false; - mCanSeeMeOnline = true; - mHasBlockListEntry = false; - mHasAutoAcceptListEntry = false; - mNameResolved = false; - mInVivoxBuddies = false; - mInSLFriends = false; -} - -void LLVivoxVoiceClient::processBuddyListEntry(const std::string &uri, const std::string &displayName) -{ - buddyListEntry *buddy = addBuddy(uri, displayName); - buddy->mInVivoxBuddies = true; -} - -LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::string &uri) -{ - std::string empty; - buddyListEntry *buddy = addBuddy(uri, empty); - if(buddy->mDisplayName.empty()) - { - buddy->mNameResolved = false; - } - return buddy; -} - -LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::string &uri, const std::string &displayName) -{ - buddyListEntry *result = NULL; - buddyListMap::iterator iter = mBuddyListMap.find(uri); - - if(iter != mBuddyListMap.end()) - { - // Found a matching buddy already in the map. - LL_DEBUGS("Voice") << "adding existing buddy " << uri << LL_ENDL; - result = iter->second; - } - - if(!result) - { - // participant isn't already in one list or the other. - LL_DEBUGS("Voice") << "adding new buddy " << uri << LL_ENDL; - result = new buddyListEntry(uri); - result->mDisplayName = displayName; - - if (!IDFromName(uri, result->mUUID)) - { - LL_DEBUGS("Voice") << "Couldn't find ID for buddy " << uri << " (\"" << displayName << "\")" << LL_ENDL; - } - - mBuddyListMap.insert(buddyListMap::value_type(result->mURI, result)); - } - - return result; -} - -LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::findBuddy(const std::string &uri) -{ - buddyListEntry *result = NULL; - buddyListMap::iterator iter = mBuddyListMap.find(uri); - if(iter != mBuddyListMap.end()) - { - result = iter->second; - } - - return result; -} - -LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::findBuddy(const LLUUID &id) -{ - buddyListEntry *result = NULL; - buddyListMap::iterator iter; - - for(iter = mBuddyListMap.begin(); iter != mBuddyListMap.end(); iter++) - { - if(iter->second->mUUID == id) - { - result = iter->second; - break; - } - } - - return result; -} - -LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::findBuddyByDisplayName(const std::string &name) -{ - buddyListEntry *result = NULL; - buddyListMap::iterator iter; - - for(iter = mBuddyListMap.begin(); iter != mBuddyListMap.end(); iter++) - { - if(iter->second->mDisplayName == name) - { - result = iter->second; - break; - } - } - - return result; -} - -void LLVivoxVoiceClient::deleteBuddy(const std::string &uri) -{ - buddyListMap::iterator iter = mBuddyListMap.find(uri); - if(iter != mBuddyListMap.end()) - { - LL_DEBUGS("Voice") << "deleting buddy " << uri << LL_ENDL; - buddyListEntry *buddy = iter->second; - mBuddyListMap.erase(iter); - delete buddy; - } - else - { - LL_DEBUGS("Voice") << "attempt to delete nonexistent buddy " << uri << LL_ENDL; - } - -} - -void LLVivoxVoiceClient::deleteAllBuddies(void) -{ - while(!mBuddyListMap.empty()) - { - deleteBuddy(mBuddyListMap.begin()->first); - } - - // Don't want to correlate with friends list when we've emptied the buddy list. - mBuddyListMapPopulated = false; - - // Don't want to correlate with friends list when we've reset the block rules. - mBlockRulesListReceived = false; - mAutoAcceptRulesListReceived = false; -} - -void LLVivoxVoiceClient::deleteAllBlockRules(void) -{ - // Clear the block list entry flags from all local buddy list entries - buddyListMap::iterator buddy_it; - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++) - { - buddy_it->second->mHasBlockListEntry = false; - } -} - -void LLVivoxVoiceClient::deleteAllAutoAcceptRules(void) -{ - // Clear the auto-accept list entry flags from all local buddy list entries - buddyListMap::iterator buddy_it; - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++) - { - buddy_it->second->mHasAutoAcceptListEntry = false; - } -} - -void LLVivoxVoiceClient::addBlockRule(const std::string &blockMask, const std::string &presenceOnly) -{ - buddyListEntry *buddy = NULL; - - // blockMask is the SIP URI of a friends list entry - buddyListMap::iterator iter = mBuddyListMap.find(blockMask); - if(iter != mBuddyListMap.end()) - { - LL_DEBUGS("Voice") << "block list entry for " << blockMask << LL_ENDL; - buddy = iter->second; - } - - if(buddy == NULL) - { - LL_DEBUGS("Voice") << "block list entry for unknown buddy " << blockMask << LL_ENDL; - buddy = addBuddy(blockMask); - } - - if(buddy != NULL) - { - buddy->mHasBlockListEntry = true; - } -} - -void LLVivoxVoiceClient::addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy) -{ - buddyListEntry *buddy = NULL; - - // blockMask is the SIP URI of a friends list entry - buddyListMap::iterator iter = mBuddyListMap.find(autoAcceptMask); - if(iter != mBuddyListMap.end()) - { - LL_DEBUGS("Voice") << "auto-accept list entry for " << autoAcceptMask << LL_ENDL; - buddy = iter->second; - } - - if(buddy == NULL) - { - LL_DEBUGS("Voice") << "auto-accept list entry for unknown buddy " << autoAcceptMask << LL_ENDL; - buddy = addBuddy(autoAcceptMask); - } - - if(buddy != NULL) - { - buddy->mHasAutoAcceptListEntry = true; - } -} - -void LLVivoxVoiceClient::accountListBlockRulesResponse(int statusCode, const std::string &statusString) -{ - // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done. - mBlockRulesListReceived = true; -} - -void LLVivoxVoiceClient::accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString) -{ - // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done. - mAutoAcceptRulesListReceived = true; -} - void LLVivoxVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) { mParticipantObservers.insert(observer); @@ -6336,11 +5615,6 @@ void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id, void LLVivoxVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name) { - // If the avatar whose name just resolved is on our friends list, resync the friends list. - if(LLAvatarTracker::instance().getBuddyInfo(id) != NULL) - { - mFriendsListDirty = true; - } // Iterate over all sessions. for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++) { @@ -6859,7 +6133,6 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceEffectObserver* observer) { mVoiceFontObservers.erase(observer); } - void LLVivoxVoiceClient::notifyVoiceFontObservers() { LL_DEBUGS("Voice") << "Notifying voice effect observers. Lists changed: " << mVoiceFontListDirty << LL_ENDL; @@ -7248,18 +6521,6 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) { deviceString.clear(); } - else if (!stricmp("Buddies", tag)) - { - LLVivoxVoiceClient::getInstance()->deleteAllBuddies(); - } - else if (!stricmp("BlockRules", tag)) - { - LLVivoxVoiceClient::getInstance()->deleteAllBlockRules(); - } - else if (!stricmp("AutoAcceptRules", tag)) - { - LLVivoxVoiceClient::getInstance()->deleteAllAutoAcceptRules(); - } else if (!stricmp("SessionFont", tag)) { id = 0; @@ -7391,24 +6652,10 @@ void LLVivoxProtocolParser::EndTag(const char *tag) { LLVivoxVoiceClient::getInstance()->addRenderDevice(deviceString); } - else if (!stricmp("Buddy", tag)) - { - // NOTE : Vivox does *not* give reliable display name for Buddy tags - // We don't take those very seriously as a result... - LLVivoxVoiceClient::getInstance()->processBuddyListEntry(uriString, displayNameString); - } - else if (!stricmp("BlockRule", tag)) - { - LLVivoxVoiceClient::getInstance()->addBlockRule(blockMask, presenceOnly); - } else if (!stricmp("BlockMask", tag)) blockMask = string; else if (!stricmp("PresenceOnly", tag)) presenceOnly = string; - else if (!stricmp("AutoAcceptRule", tag)) - { - LLVivoxVoiceClient::getInstance()->addAutoAcceptRule(autoAcceptMask, autoAddAsBuddy); - } else if (!stricmp("AutoAcceptMask", tag)) autoAcceptMask = string; else if (!stricmp("AutoAddAsBuddy", tag)) @@ -7640,16 +6887,6 @@ void LLVivoxProtocolParser::processResponse(std::string tag) LLVivoxVoiceClient::getInstance()->auxAudioPropertiesEvent(energy); } - else if (!stricmp(eventTypeCstr, "BuddyPresenceEvent")) - { - LLVivoxVoiceClient::getInstance()->buddyPresenceEvent(uriString, alias, statusString, applicationString); - } - else if (!stricmp(eventTypeCstr, "BuddyAndGroupListChangedEvent")) - { - // The buddy list was updated during parsing. - // Need to recheck against the friends list. - LLVivoxVoiceClient::getInstance()->buddyListChanged(); - } else if (!stricmp(eventTypeCstr, "BuddyChangedEvent")) { /* @@ -7672,10 +6909,6 @@ void LLVivoxProtocolParser::processResponse(std::string tag) { LLVivoxVoiceClient::getInstance()->sessionNotificationEvent(sessionHandle, uriString, notificationType); } - else if (!stricmp(eventTypeCstr, "SubscriptionEvent")) - { - LLVivoxVoiceClient::getInstance()->subscriptionEvent(uriString, subscriptionHandle, alias, displayNameString, applicationString, subscriptionType); - } else if (!stricmp(eventTypeCstr, "SessionUpdatedEvent")) { /* @@ -7739,14 +6972,6 @@ void LLVivoxProtocolParser::processResponse(std::string tag) { LLVivoxVoiceClient::getInstance()->connectorShutdownResponse(statusCode, statusString); } - else if (!stricmp(actionCstr, "Account.ListBlockRules.1")) - { - LLVivoxVoiceClient::getInstance()->accountListBlockRulesResponse(statusCode, statusString); - } - else if (!stricmp(actionCstr, "Account.ListAutoAcceptRules.1")) - { - LLVivoxVoiceClient::getInstance()->accountListAutoAcceptRulesResponse(statusCode, statusString); - } else if (!stricmp(actionCstr, "Session.Set3DPosition.1")) { // We don't need to process these, but they're so spammy we don't want to log them. diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index e9c233993..03811e4e1 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -163,7 +163,6 @@ public: //@{ virtual BOOL getVoiceEnabled(const LLUUID& id); // true if we've received data for this avatar virtual std::string getDisplayName(const LLUUID& id); - virtual BOOL isOnlineSIP(const LLUUID &id); virtual BOOL isParticipantAvatar(const LLUUID &id); virtual BOOL getIsSpeaking(const LLUUID& id); virtual BOOL getIsModeratorMuted(const LLUUID& id); @@ -470,14 +469,10 @@ protected: void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString); void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy); void auxAudioPropertiesEvent(F32 energy); - void buddyPresenceEvent(std::string &uriString, std::string &alias, std::string &statusString, std::string &applicationString); void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString); void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string ¬ificationType); - void subscriptionEvent(std::string &buddyURI, std::string &subscriptionHandle, std::string &alias, std::string &displayName, std::string &applicationString, std::string &subscriptionType); - void buddyListChanged(); void muteListChanged(); - void updateFriends(U32 mask); ///////////////////////////// // Sending updates of current state @@ -568,24 +563,6 @@ protected: typedef std::map buddyListMap; - // This should be called when parsing a buddy list entry sent by SLVoice. - void processBuddyListEntry(const std::string &uri, const std::string &displayName); - - buddyListEntry *addBuddy(const std::string &uri); - buddyListEntry *addBuddy(const std::string &uri, const std::string &displayName); - buddyListEntry *findBuddy(const std::string &uri); - buddyListEntry *findBuddy(const LLUUID &id); - buddyListEntry *findBuddyByDisplayName(const std::string &name); - void deleteBuddy(const std::string &uri); - void deleteAllBuddies(void); - - void deleteAllBlockRules(void); - void addBlockRule(const std::string &blockMask, const std::string &presenceOnly); - void deleteAllAutoAcceptRules(void); - void addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy); - void accountListBlockRulesResponse(int statusCode, const std::string &statusString); - void accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString); - ///////////////////////////// // session control messages @@ -754,8 +731,7 @@ private: void buildSetCaptureDevice(std::ostringstream &stream); void buildSetRenderDevice(std::ostringstream &stream); - void clearAllLists(); - void checkFriend(const LLUUID& id); + void sendFriendsListUpdates(); // start a text IM session with the specified user diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 371c23580..a94d9e856 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -40,6 +40,7 @@ #include "llviewercontrol.h" #include "lldir.h" #include "llflexibleobject.h" +#include "llfloaterinspect.h" #include "llfloatertools.h" #include "llmaterialid.h" #include "llmaterialtable.h" @@ -3643,7 +3644,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& if (mDrawable->isState(LLDrawable::RIGGED)) { static const LLCachedControl allow_mesh_picking("SGAllowRiggedMeshSelection"); - if (allow_mesh_picking && gFloaterTools->getVisible() && getAvatar()->isSelf()) + if (allow_mesh_picking && (gFloaterTools->getVisible() || LLFloaterInspect::instanceExists())) { updateRiggedVolume(); //genBBoxes(FALSE); @@ -3825,10 +3826,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& bool LLVOVolume::treatAsRigged() { - return gFloaterTools->getVisible() && + return (gFloaterTools->getVisible() || LLFloaterInspect::instanceExists()) && isAttachment() && - getAvatar() && - getAvatar()->isSelf() && mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED); } @@ -4063,8 +4062,12 @@ LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) mSlopRatio = 0.25f; } -bool can_batch_texture(LLFace* facep) +bool can_batch_texture(const LLFace* facep) { + static const LLCachedControl alt_batching("SHAltBatching",true); + + if(!alt_batching) + { if (facep->getTextureEntry()->getBumpmap()) { //bump maps aren't worked into texture batching yet return false; @@ -4084,6 +4087,30 @@ bool can_batch_texture(LLFace* facep) { //texture animation breaks batches return false; } + } + else + { + + if (facep->getPoolType() == LLDrawPool::POOL_BUMP && (facep->getTextureEntry()->getBumpmap() > 0 && facep->getTextureEntry()->getBumpmap() < 18)) + { //bump maps aren't worked into texture batching yet + return false; + } + + if (LLPipeline::sRenderDeferred && (facep->getPoolType() == LLDrawPool::POOL_ALPHA || facep->getPoolType() == LLDrawPool::POOL_MATERIALS) && facep->getTextureEntry()->getMaterialParams().notNull()) + { //materials don't work with texture batching yet + return false; + } + + if (facep->getPoolType() != LLDrawPool::POOL_ALPHA && facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA) + { //can't batch invisiprims + return false; + } + + if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) + { //texture animation breaks batches + return false; + } + } return true; } @@ -4093,10 +4120,10 @@ static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face"); void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) { LLFastTimer t(FTM_REGISTER_FACE); - if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)) - { - LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; - } + //if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)) + //{ + // LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; + //} // if (facep->getViewerObject()->isSelected() && gHideSelectedObjects) // [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c @@ -4115,11 +4142,21 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, S32 idx = draw_vec.size()-1; - BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || + static const LLCachedControl alt_batching("SHAltBatching",true); + BOOL fullbright; + if(!alt_batching) + { + fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || (type == LLRenderPass::PASS_INVISIBLE) || (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || (facep->getTextureEntry()->getFullbright()); + } + else + { + fullbright = facep->isState(LLFace::FULLBRIGHT); + } + if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL)) { @@ -4152,21 +4189,30 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); - U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0; + LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); + + U32 pool_type = facep->getPoolType(); + + bool cmp_bump = (type == LLRenderPass::PASS_BUMP) || (type == LLRenderPass::PASS_POST_BUMP); + bool cmp_mat = (!alt_batching) || LLPipeline::sRenderDeferred && /*facep->getTextureEntry()->getColor().mV[3] >= 0.999f &&*/ + ((pool_type == LLDrawPool::POOL_MATERIALS) || (pool_type == LLDrawPool::POOL_ALPHA)); + bool cmp_shiny = (!alt_batching) ? !!mat : (mat && cmp_mat); + bool cmp_fullbright = !alt_batching || cmp_shiny || pool_type == LLDrawPool::POOL_ALPHA; + + U8 bump = facep->getTextureEntry()->getBumpmap(); U8 shiny = facep->getTextureEntry()->getShiny(); LLViewerTexture* tex = facep->getTexture(); U8 index = facep->getTextureIndex(); - LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); - LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID(); + //LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); bool batchable = false; U32 shader_mask = 0xFFFFFFFF; //no shader - if (mat) + if (mat && cmp_mat) { if (type == LLRenderPass::PASS_ALPHA) { @@ -4178,10 +4224,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } } - if (index < 255 && idx >= 0) { - if (mat || draw_vec[idx]->mMaterial) + if (cmp_mat && (mat || draw_vec[idx]->mMaterial)) { //can't batch textures when materials are present (yet) batchable = false; } @@ -4202,7 +4247,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, batchable = true; } } - + if (idx >= 0 && draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && @@ -4211,14 +4256,15 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && #endif - draw_vec[idx]->mMaterial == mat && - draw_vec[idx]->mMaterialID == mat_id && - draw_vec[idx]->mFullbright == fullbright && - draw_vec[idx]->mBump == bump && - (!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different + (!cmp_mat || draw_vec[idx]->mMaterial == mat) && + //draw_vec[idx]->mMaterialID == mat_id && + (!cmp_fullbright || draw_vec[idx]->mFullbright == fullbright) && + (!cmp_bump || draw_vec[idx]->mBump == bump) && + (!cmp_shiny || draw_vec[idx]->mShiny == shiny) && + //(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different draw_vec[idx]->mTextureMatrix == tex_mat && draw_vec[idx]->mModelMatrix == model_mat && - draw_vec[idx]->mShaderMask == shader_mask) + (!cmp_mat || draw_vec[idx]->mShaderMask == shader_mask)) { draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); @@ -4265,9 +4311,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mMaterial = mat; draw_info->mShaderMask = shader_mask; - if (mat) + if (cmp_mat && mat) { - draw_info->mMaterialID = mat_id; + //draw_info->mMaterialID = mat_id; // We have a material. Update our draw info accordingly. @@ -4288,7 +4334,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); } - else + else { if (type == LLRenderPass::PASS_GRASS) { @@ -4312,6 +4358,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mTextureList.resize(index+1); draw_info->mTextureList[index] = tex; } + draw_info->validate(); } } @@ -4491,10 +4538,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) vobj->isMesh() && gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); - bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); + //bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); bool is_rigged = false; + static const LLCachedControl alt_batching("SHAltBatching",true); + //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -4603,7 +4652,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } LLMaterial* mat = te->getMaterialParams().get(); - + + if(!alt_batching) + { if (mat && LLPipeline::sRenderDeferred) { U8 alpha_mode = mat->getDiffuseAlphaMode(); @@ -4716,6 +4767,68 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } } + } + else + { + if(type == LLDrawPool::POOL_ALPHA) + { + if(te->getColor().mV[3] > 0.f) + { + U32 mask = te->getFullbright() ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA; + if (mat && LLPipeline::sRenderDeferred && te->getColor().mV[3] >= 0.999f ) + { + if(mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) + mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND); + else + mask = mat->getShaderMask(); + } + pool->addRiggedFace(facep, mask); + } + } + else if(!LLPipeline::sRenderDeferred) + { + if(type == LLDrawPool::POOL_FULLBRIGHT || type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); + } + else if(type == LLDrawPool::POOL_SIMPLE || type == LLDrawPool::POOL_ALPHA_MASK) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else if(type == LLDrawPool::POOL_BUMP) //Either shiny, or bump (which isn't used in non-deferred) + { + if(te->getShiny()) + pool->addRiggedFace(facep, te->getFullbright() ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY); + else + pool->addRiggedFace(facep, te->getFullbright() ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + } + + else + { + if( type == LLDrawPool::POOL_FULLBRIGHT || type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); + } + //Annoying exception to the rule. getPoolTypeFromTE will return POOL_ALPHA_MASK for legacy bumpmaps, but there is no POOL_ALPHA_MASK in deferred. + else if(type == LLDrawPool::POOL_MATERIALS || (type == LLDrawPool::POOL_ALPHA_MASK && mat)) + { + pool->addRiggedFace(facep, mat->getShaderMask()); + } + else if (type == LLDrawPool::POOL_BUMP && te->getBumpmap()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + } + } + } } continue; @@ -4760,18 +4873,64 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } + bool force_fullbright = group->isHUDGroup(); BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); U32 type = gPipeline.getPoolTypeFromTE(te, tex); + + if(!alt_batching) + { if (type != LLDrawPool::POOL_ALPHA && force_simple) { type = LLDrawPool::POOL_SIMPLE; } + } + else + { + if (force_fullbright || te->getFullbright()) + facep->setState(LLFace::FULLBRIGHT); + + if ( type == LLDrawPool::POOL_ALPHA ) + { + if(facep->canRenderAsMask()) + { + if (facep->isState(LLFace::FULLBRIGHT)) + { + type = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK; + } + else + { + type = LLDrawPool::POOL_ALPHA_MASK; + } + } + } + else if (force_fullbright) //Hud is done in a forward render. Fullbright cannot be shared with simple. + { + if(type == LLDrawPool::POOL_ALPHA_MASK) + type = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK; + else + type = LLDrawPool::POOL_FULLBRIGHT; + } + else if(force_simple && type != LLDrawPool::POOL_FULLBRIGHT && type != LLDrawPool::POOL_ALPHA_MASK && type != LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) + { + type = LLDrawPool::POOL_SIMPLE; + } + } + facep->setPoolType(type); + if(!alt_batching) + { if (vobj->isHUDAttachment()) { facep->setState(LLFace::FULLBRIGHT); } + } + /*LLColor4 clr = facep->getFaceColor(); + LLColor4U clru = LLColor4U(llround(clr.mV[0] * 255.f), llround(clr.mV[0] * 255.f), llround(clr.mV[0] * 255.f), llround(clr.mV[0] * 255.f)); + if(clru.mV[0] == 164 && clru.mV[1] == 106 && clr.mV[2] == 65) + { + llinfos << "Facepool = " << type << " alpha = " << clr.mV[3] << llendl; + }*/ if (vobj->mTextureAnimp && vobj->mTexAnimMode) { @@ -4797,8 +4956,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - if (type == LLDrawPool::POOL_ALPHA) + if(!alt_batching) { + if (type == LLDrawPool::POOL_ALPHA) + { if (facep->canRenderAsMask()) { //can be treated as alpha mask if (simple_count < MAX_FACE_COUNT) @@ -4824,7 +4985,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { facep->mLastUpdateTime = gFrameTimeSeconds; } - if (gPipeline.canUseWindLightShadersOnObjects() && LLPipeline::sRenderBump) { @@ -4832,7 +4992,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) // If we did check, then genDrawInfo would be more lenient than rebuildGeom on deciding if a face verts should have material-related attributes, // which would result in a face with a vertex buffer that fails to meet shader attribute requirements. if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() /* && !te->getMaterialID().isNull()*/) - { + { LLMaterial* mat = te->getMaterialParams().get(); if (mat->getNormalID().notNull()) { @@ -4864,7 +5024,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { simple_faces[simple_count++] = facep; } - } + } } else if (te->getBumpmap()) { //needs normal + tangent @@ -4899,7 +5059,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } else if ((te->getShiny() && LLPipeline::sRenderBump) || - !(te->getFullbright() || bake_sunlight)) + !(te->getFullbright())) { //needs normal if (simple_count < MAX_FACE_COUNT) { @@ -4916,6 +5076,132 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } } + } + else + { + LLFace*** cur_type = NULL; + U32* cur_count = NULL; + + if (type == LLDrawPool::POOL_ALPHA) + { + cur_type = &alpha_faces; + cur_count = &alpha_count; + + if (te->getColor().mV[3] > 0.f) + { //only treat as alpha in the pipeline if < 100% transparent + drawablep->setState(LLDrawable::HAS_ALPHA); + } + + LLMaterial* mat = te->getMaterialParams().get(); + if(mat && LLPipeline::sRenderDeferred) + { + if (mat->getNormalID().notNull()) + { + if (mat->getSpecularID().notNull()) + { //has normal and specular maps (needs texcoord1, texcoord2, and tangent) + cur_type = &normspec_faces; + cur_count = &normspec_count; + } + else + { //has normal map (needs texcoord1 and tangent) + cur_type = &norm_faces; + cur_count = &norm_count; + } + } + else if (mat->getSpecularID().notNull()) + { //has specular map but no normal map, needs texcoord2 + cur_type = &spec_faces; + cur_count = &spec_count; + } + } + } + else if(type == LLDrawPool::POOL_ALPHA_MASK) + { + cur_type = &simple_faces; + cur_count = &simple_count; + } + else if(type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) + { + cur_type = &fullbright_faces; + cur_count = &fullbright_count; + } + else + { + if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) + { + facep->mLastUpdateTime = gFrameTimeSeconds; + } + + if (type == LLDrawPool::POOL_BUMP) + { //needs normal + tangent + if(te->getBumpmap() > 0 && te->getBumpmap() < 18) + { + cur_type = &bump_faces; + cur_count = &bump_count; + } + else if(te->getShiny()) + { + cur_type = &simple_faces; + cur_count = &simple_count; + } + } + else if (type == LLDrawPool::POOL_SIMPLE) + { //needs normal + tangent + cur_type = &simple_faces; + cur_count = &simple_count; + } + else if (type == LLDrawPool::POOL_FULLBRIGHT) + { //doesn't need normal... + if(LLPipeline::sRenderBump && te->getShiny()) //unless it's shiny.. + { + cur_type = &simple_faces; + cur_count = &simple_count; + } + else + { + cur_type = &fullbright_faces; + cur_count = &fullbright_count; + } + } + /*Singu Note: Don't check the materials ID, as doing such causes a mismatch between rebuildGeom and genDrawInfo. + If we did check, then genDrawInfo would be more lenient than rebuildGeom on deciding if a face verts should have material-related attributes, + which would result in a face with a vertex buffer that fails to meet shader attribute requirements.*/ + else if(type == LLDrawPool::POOL_MATERIALS) + { + LLMaterial* mat = te->getMaterialParams().get(); + if (mat->getNormalID().notNull()) + { + if (mat->getSpecularID().notNull()) + { //has normal and specular maps (needs texcoord1, texcoord2, and tangent) + cur_type = &normspec_faces; + cur_count = &normspec_count; + } + else + { //has normal map (needs texcoord1 and tangent) + cur_type = &norm_faces; + cur_count = &norm_count; + } + } + else if (mat->getSpecularID().notNull()) + { //has specular map but no normal map, needs texcoord2 + cur_type = &spec_faces; + cur_count = &spec_count; + } + else + { //has neither specular map nor normal map, only needs texcoord0 + cur_type = &simple_faces; + cur_count = &simple_count; + } + } + else + { + llerrs << "Unknown pool type: " << type << llendl; + } + } + llassert_always(cur_type); + if(*cur_count < MAX_FACE_COUNT) + (*cur_type)[(*cur_count)++] = facep; + } } else { //face has no renderable geometry @@ -4946,7 +5232,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //PROCESS NON-ALPHA FACES U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO - U32 bump_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1; + U32 bump_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; @@ -4964,23 +5250,21 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE; } - BOOL batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; + BOOL batch_textures = gPipeline.getUseVertexShaders(); - if (batch_textures) - { - bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; - simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; - alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; - fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; - } + U32 additional_flags = 0x0; + if(batch_textures) + additional_flags |= LLVertexBuffer::MAP_TEXTURE_INDEX; + if(emissive) + additional_flags |= LLVertexBuffer::MAP_EMISSIVE; - genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, simple_count, FALSE, batch_textures, FALSE); - genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, fullbright_count, FALSE, batch_textures); - genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, alpha_count, TRUE, batch_textures); - genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, bump_count, FALSE, FALSE); - genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, norm_count, FALSE, FALSE); - genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, spec_count, FALSE, FALSE); - genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, normspec_count, FALSE, FALSE); + genDrawInfo(group, simple_mask | additional_flags, simple_faces, simple_count, FALSE, batch_textures); + genDrawInfo(group, fullbright_mask | additional_flags, fullbright_faces, fullbright_count, FALSE, batch_textures); + genDrawInfo(group, alpha_mask | additional_flags, alpha_faces, alpha_count, TRUE, batch_textures); + genDrawInfo(group, bump_mask | additional_flags, bump_faces, bump_count, FALSE); + genDrawInfo(group, norm_mask | additional_flags, norm_faces, norm_count, FALSE); + genDrawInfo(group, spec_mask | additional_flags, spec_faces, spec_count, FALSE); + genDrawInfo(group, normspec_mask | additional_flags, normspec_faces, normspec_count, FALSE); if (!LLPipeline::sDelayVBUpdate) { @@ -5132,29 +5416,76 @@ struct CompareBatchBreakerModified { bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) { + static const LLCachedControl alt_batching("SHAltBatching",true); + if(!alt_batching) + { + const LLTextureEntry* lte = lhs->getTextureEntry(); + const LLTextureEntry* rte = rhs->getTextureEntry(); + + if (lte->getBumpmap() != rte->getBumpmap()) + { + return lte->getBumpmap() < rte->getBumpmap(); + } + else if (lte->getFullbright() != rte->getFullbright()) + { + return lte->getFullbright() < rte->getFullbright(); + } + else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams()) + { + return lte->getMaterialParams() < rte->getMaterialParams(); + } + else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny())) + { + return lte->getShiny() < rte->getShiny(); + } + else + { + return lhs->getTexture() < rhs->getTexture(); + } + } + else + { + const LLTextureEntry* lte = lhs->getTextureEntry(); const LLTextureEntry* rte = rhs->getTextureEntry(); - if (lte->getBumpmap() != rte->getBumpmap()) + bool batch_left = can_batch_texture(lhs); + bool batch_right = can_batch_texture(rhs); + + if (lhs->getPoolType() != rhs->getPoolType()) + { + return lhs->getPoolType() < rhs->getPoolType(); + } + else if(batch_left != batch_right) //Move non-batchable faces together. + { + return !(batch_left < batch_right); + } + + static const LLCachedControl sh_fullbright_deferred("SHFullbrightDeferred",true); + bool batch_shiny = (!LLPipeline::sRenderDeferred || (sh_fullbright_deferred && lhs->isState(LLFace::FULLBRIGHT))) && lhs->getPoolType() == LLDrawPool::POOL_BUMP; + bool batch_fullbright = sh_fullbright_deferred || !LLPipeline::sRenderDeferred && lhs->getPoolType() == LLDrawPool::POOL_ALPHA; + + if (batch_fullbright && lhs->isState(LLFace::FULLBRIGHT) != rhs->isState(LLFace::FULLBRIGHT)) + { + return lhs->isState(LLFace::FULLBRIGHT) < rhs->isState(LLFace::FULLBRIGHT); + } + else if(batch_shiny && !lte->getShiny() != !rte->getShiny()) + { + return !lte->getShiny() < !rte->getShiny(); + } + else if(lhs->getPoolType() == LLDrawPool::POOL_MATERIALS && lte->getMaterialParams().get() != rte->getMaterialParams().get()) + { + return lte->getMaterialParams().get() < rte->getMaterialParams().get(); + } + else if(lhs->getPoolType() == LLDrawPool::POOL_BUMP && lte->getBumpmap() != rte->getBumpmap()) { return lte->getBumpmap() < rte->getBumpmap(); } - else if (lte->getFullbright() != rte->getFullbright()) - { - return lte->getFullbright() < rte->getFullbright(); - } - else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams()) - { - return lte->getMaterialParams() < rte->getMaterialParams(); - } - else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny())) - { - return lte->getShiny() < rte->getShiny(); - } else { return lhs->getTexture() < rhs->getTexture(); } + } } }; @@ -5168,7 +5499,7 @@ static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials) +void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures) { LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); @@ -5203,41 +5534,20 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater()); } } - + bool hud_group = group->isHUDGroup() ; LLFace** face_iter = faces; LLFace** end_faces = faces+face_count; LLSpatialGroup::buffer_map_t buffer_map; - LLViewerTexture* last_tex = NULL; - S32 buffer_index = 0; - - if (distance_sort) - { - buffer_index = -1; - } - - S32 texture_index_channels = 1; - - if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) - { - static const LLCachedControl no_texture_indexing("ShyotlUseLegacyTextureBatching",false); - if(!no_texture_indexing) - texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity; - } + S32 texture_index_channels = llmax(LLGLSLShader::sIndexedTextureChannels-1,1); //always reserve one for shiny for now just for simplicity if (LLPipeline::sRenderDeferred && distance_sort) { texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; } - static const LLCachedControl max_texture_index("RenderMaxTextureIndex",1); - texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index.get()); - - //NEVER use more than 16 texture index channels (workaround for prevalent driver bug) - texture_index_channels = llmin(texture_index_channels, 16); - bool flexi = false; while (face_iter != end_faces) @@ -5247,23 +5557,14 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac LLViewerTexture* tex = facep->getTexture(); LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams(); - if (distance_sort) + //bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic(); + + static const LLCachedControl alt_batching("SHAltBatching",true); + if (!alt_batching && distance_sort) { tex = NULL; } - if (last_tex == tex) - { - buffer_index++; - } - else - { - last_tex = tex; - buffer_index = 0; - } - - bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic(); - U32 index_count = facep->getIndicesCount(); U32 geom_count = facep->getGeomCount(); @@ -5272,7 +5573,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac //sum up vertices needed for this render batch LLFace** i = face_iter; ++i; - + + if(!alt_batching) + { const U32 MAX_TEXTURE_COUNT = 32; static LLViewerTexture* texture_list[MAX_TEXTURE_COUNT]; @@ -5389,6 +5692,95 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac } } + } + else + { + LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE); + + if (batch_textures) + { + facep->setTextureIndex(0); + + if(can_batch_texture(facep)) + { + static const U8 MAX_TEXTURE_COUNT = 32; + static LLViewerTexture* texture_list[MAX_TEXTURE_COUNT]; + U8 texture_count = 1; + U8 cur_tex = 0; + texture_list[0] = tex; + U8 pool = facep->getPoolType(); + + while (i != end_faces) + { + facep = *i; + if ( !can_batch_texture(facep) || !(facep) || (geom_count + facep->getGeomCount() > max_vertices) || pool != facep->getPoolType() ) + { //cut batches on geom count too big + break; + } + else + { + if(facep->getTexture() != tex) + { + bool reused = false; + if(distance_sort) //Alpha faces aren't sorted by batch criteria, but rather distance WRT camera. + { + for(U8 j = 0; j < texture_count; ++j) + { + if(texture_list[j] == facep->getTexture()) + { + tex = facep->getTexture(); + cur_tex = j; + reused = true; + break; + } + } + } + if(!reused) + { + if(++texture_count > llmin((U8)texture_index_channels,MAX_TEXTURE_COUNT)) + break; + cur_tex = texture_count - 1; + tex = facep->getTexture(); + texture_list[cur_tex] = tex; + } + } + facep->setTextureIndex(cur_tex); + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); + } + ++i; + } + } + } + else + { + //face has no texture index + facep->mDrawInfo = NULL; + facep->setTextureIndex(255); + + while (i != end_faces && + (LLPipeline::sTextureBindTest || + (distance_sort || + ((*i)->getTexture() == tex && + ((*i)->getTextureEntry()->getMaterialParams() == mat))))) + { + facep = *i; + + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut batches on geom count too big + break; + } + //face has no texture index + facep->mDrawInfo = NULL; + facep->setTextureIndex(255); + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); + ++i; + } + } + } if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB) { @@ -5398,14 +5790,19 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac // Singu Note: Catch insufficient vbos right when they are created. Easier to debug. if(gDebugGL) { - const LLTextureEntry* te = facep->getTextureEntry(); - if (mat && LLPipeline::sRenderDeferred && !hud_group && - !no_materials && - !te->getFullbright() && - !(te->getColor().mV[3] < 0.999f) && - !(te->getBumpmap() && (te->getBumpmap() < 18) && (mat->getNormalID().isNull()))) + if (LLPipeline::sRenderDeferred && + (*face_iter)->getTextureEntry()->getMaterialParams().get() && + ((*face_iter)->getPoolType() == LLDrawPool::POOL_ALPHA || + (*face_iter)->getPoolType() == LLDrawPool::POOL_MATERIALS )) { - U32 shader_mask = mat->getShaderMask(); + LLMaterial* mat = (*face_iter)->getTextureEntry()->getMaterialParams().get(); + + U32 shader_mask; + if((*face_iter)->getPoolType() == LLDrawPool::POOL_ALPHA) + shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND); + else + shader_mask = mat->getShaderMask(); + if(shader_mask != 1 && shader_mask != 5 && shader_mask != 9 && shader_mask != 13) { LLGLSLShader* shader = &(gDeferredMaterialProgram[shader_mask]); @@ -5493,8 +5890,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac index_offset += facep->getGeomCount(); indices_index += facep->getIndicesCount(); + static const LLCachedControl alt_batching("SHAltBatching",true); + //append face to appropriate render batch + if(!alt_batching) + { BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) @@ -5563,10 +5964,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac } } } - else if (no_materials) + /*else if (no_materials) { registerFace(group, facep, LLRenderPass::PASS_SIMPLE); - } + }*/ else if (!opaque) //Just use opaque instead of te->getColorblahblah { registerFace(group, facep, LLRenderPass::PASS_ALPHA); @@ -5708,7 +6109,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac { //invisiprim registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); } - else if (fullbright || bake_sunlight) + else if (fullbright) { //fullbright if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { @@ -5764,11 +6165,145 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac registerFace(group, facep, LLRenderPass::PASS_BUMP); } } - if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f) { registerFace(group, facep, LLRenderPass::PASS_GLOW); } + } + else + { + const LLTextureEntry* te = facep->getTextureEntry(); + tex = facep->getTexture(); + + bool is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA; + bool is_shiny_shader = facep->getPoolType() == LLDrawPool::POOL_BUMP && gPipeline.canUseVertexShaders() && te->getShiny(); + bool is_shiny_fixed = facep->getPoolType() == LLDrawPool::POOL_BUMP && !gPipeline.canUseVertexShaders() && te->getShiny(); + bool is_fullbright = facep->isState(LLFace::FULLBRIGHT); + + if (facep->getPoolType() == LLDrawPool::POOL_MATERIALS) + { + U32 pass[] = + { + LLRenderPass::PASS_MATERIAL, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA, + LLRenderPass::PASS_MATERIAL_ALPHA_MASK, + LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, + LLRenderPass::PASS_SPECMAP, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND, + LLRenderPass::PASS_SPECMAP_MASK, + LLRenderPass::PASS_SPECMAP_EMISSIVE, + LLRenderPass::PASS_NORMMAP, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND, + LLRenderPass::PASS_NORMMAP_MASK, + LLRenderPass::PASS_NORMMAP_EMISSIVE, + LLRenderPass::PASS_NORMSPEC, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND, + LLRenderPass::PASS_NORMSPEC_MASK, + LLRenderPass::PASS_NORMSPEC_EMISSIVE, + }; + + U32 mask = mat->getShaderMask(); + + llassert(mask < sizeof(pass)/sizeof(U32)); + + mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1)); + + registerFace(group, facep, pass[mask]); + } + else if (facep->getPoolType() == LLDrawPool::POOL_ALPHA) + { + // can we safely treat this as an alpha mask? + if (facep->getFaceColor().mV[3] <= 0.f) + { //100% transparent, don't render unless we're highlighting transparent + registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + } + else if (facep->getPoolType() == LLDrawPool::POOL_ALPHA_MASK) + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); + } + else if (facep->getPoolType() == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + } + else + { + if (tex->getPrimaryFormat() == GL_ALPHA) + { + if(is_shiny_shader && facep->getPoolType() == LLDrawPool::POOL_BUMP) + { + registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); + } + registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + } + else if (facep->getPoolType() == LLDrawPool::POOL_SIMPLE) + { + registerFace(group, facep, LLRenderPass::PASS_SIMPLE); + } + else if (facep->getPoolType() == LLDrawPool::POOL_FULLBRIGHT) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); + } + else if (facep->getPoolType() == LLDrawPool::POOL_BUMP) + { + llassert_always(mask & LLVertexBuffer::MAP_NORMAL); + + bool is_bump = te->getBumpmap() > 0 && te->getBumpmap() < 18; + + if(is_bump) + { + llassert_always(mask & LLVertexBuffer::MAP_TANGENT); + } + if(is_shiny_shader || is_shiny_fixed) + { + llassert_always(mask & LLVertexBuffer::MAP_NORMAL); + } + + if(LLPipeline::sRenderDeferred) + { + static const LLCachedControl sh_fullbright_deferred("SHFullbrightDeferred",true); + if(sh_fullbright_deferred && is_fullbright) + { + registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_FULLBRIGHT); + if(is_bump) + { + registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); + } + } + else + { + //is_bump should always be true. + registerFace(group, facep, is_bump ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_SIMPLE); + } + } + else + { + if (is_fullbright ) + { + registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_FULLBRIGHT); + } + else + { + registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_SHINY : LLRenderPass::PASS_SIMPLE); + } + + if(is_bump) + registerFace(group, facep, LLRenderPass::PASS_BUMP); + + if(is_shiny_fixed) + registerFace(group, facep, LLRenderPass::PASS_SHINY); + } + } + } + if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f) + { + registerFace(group, facep, LLRenderPass::PASS_GLOW); + } + } ++face_iter; } diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index c4e73d90b..b4ab34d36 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -166,7 +166,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) static const LLCachedControl render_transparent_water("RenderTransparentWater",false); static const LLCachedControl water_subdiv("SianaVoidWaterSubdivision", 16); - const S32 size = (render_transparent_water && LLGLSLShader::sNoFixedFunction) ? water_subdiv : 1; + const S32 size = ((render_transparent_water || LLPipeline::sRenderDeferred) && LLGLSLShader::sNoFixedFunction) ? water_subdiv : 1; const S32 num_quads = size * size; face->setSize(vertices_per_quad * num_quads, indices_per_quad * num_quads); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 5dd82bc4a..2593391be 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -660,7 +660,17 @@ void LLPipeline::resizeScreenTexture() GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) +// [RLVa:KB] - Checked: 2014-02-23 (RLVa-1.4.10) + U32 resMod = gSavedSettings.getU32("RenderResolutionDivisor"), resAdjustedX = resX, resAdjustedY = resY; + if ( (resMod > 1) && (resMod < resX) && (resMod < resY) ) + { + resAdjustedX /= resMod; + resAdjustedY /= resMod; + } + + if ( (resAdjustedX != mScreen.getWidth()) || (resAdjustedY != mScreen.getHeight()) ) +// [/RLVa:KB] +// if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) { releaseScreenBuffers(); if (!allocateScreenBuffer(resX,resY)) @@ -1526,24 +1536,28 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima { alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2); } - + if (alpha && mat) { switch (mat->getDiffuseAlphaMode()) { - case 1: + case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. break; - case 0: //alpha mode set to none, never go to alpha pool - case 3: //alpha mode set to emissive, never go to alpha pool + case LLMaterial::DIFFUSE_ALPHA_MODE_NONE: //alpha mode set to none, never go to alpha pool + case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: //alpha mode set to emissive, never go to alpha pool alpha = color_alpha; break; default: //alpha mode set to "mask", go to alpha pool if fullbright - alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool. + alpha = color_alpha; // Material's alpha mode is set to mask, or default. Toss it into the opaque material draw pool. break; } } + static const LLCachedControl alt_batching("SHAltBatching",true); + + if(!alt_batching) + { if (alpha) { return LLDrawPool::POOL_ALPHA; @@ -1560,6 +1574,54 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima { return LLDrawPool::POOL_SIMPLE; } + } + else + { + static const LLCachedControl sh_fullbright_deferred("SHFullbrightDeferred",true); + + //Bump goes into bump pool unless using deferred and there's a normal map that takes precedence. + bool legacy_bump = (!LLPipeline::sRenderDeferred || !mat || mat->getNormalID().isNull()) && LLPipeline::sRenderBump && te->getBumpmap() && te->getBumpmap() < 18; + if (alpha) + { + return LLDrawPool::POOL_ALPHA; + } + else if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + if(!LLPipeline::sRenderDeferred || legacy_bump) + { + return te->getFullbright() ? LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK : LLDrawPool::POOL_ALPHA_MASK; + } + else if(te->getFullbright() && !mat->getEnvironmentIntensity() && !te->getShiny()) + { + return LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK; + } + return LLDrawPool::POOL_MATERIALS; + } + else if (legacy_bump) + { + return LLDrawPool::POOL_BUMP; + } + else if(LLPipeline::sRenderDeferred && mat) + { + if(te->getFullbright() && !mat->getEnvironmentIntensity() && !te->getShiny()) + { + return sh_fullbright_deferred ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE; + } + return LLDrawPool::POOL_MATERIALS; + } + else if((sh_fullbright_deferred || !LLPipeline::sRenderDeferred) && te->getFullbright()) + { + return (LLPipeline::sRenderBump && te->getShiny()) ? LLDrawPool::POOL_BUMP : LLDrawPool::POOL_FULLBRIGHT; + } + else if (!LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getShiny()) + { + return LLDrawPool::POOL_BUMP; //Shiny goes into bump pool when not using deferred rendering. + } + else + { + return LLDrawPool::POOL_SIMPLE; + } + } } @@ -2282,6 +2344,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDisable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); + LLGLDisable stencil(GL_STENCIL_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -2497,15 +2560,13 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d { mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); mDeferredVB->allocateBuffer(8, 0, true); - } - - LLStrider vert; - mDeferredVB->getVertexStrider(vert); - LLStrider tc0; + LLStrider vert; + mDeferredVB->getVertexStrider(vert); - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); + vert[0].set(-1,1,0); + vert[1].set(-1,-3,0); + vert[2].set(3,1,0); + } if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE) { @@ -4706,6 +4767,8 @@ void LLPipeline::renderDebug() if(!mRenderDebugMask) return; + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); + // Debug stuff. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -7908,15 +7971,14 @@ void LLPipeline::renderDeferredLighting() { mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); mDeferredVB->allocateBuffer(8, 0, true); + LLStrider vert; + mDeferredVB->getVertexStrider(vert); + + vert[0].set(-1,1,0); + vert[1].set(-1,-3,0); + vert[2].set(3,1,0); } - LLStrider vert; - mDeferredVB->getVertexStrider(vert); - - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); - { setupHWLights(NULL); //to set mSunDir; LLVector4 dir(mSunDir, 0.f); @@ -8338,12 +8400,6 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSpotLightProgram); } - //reset mDeferredVB to fullscreen triangle - mDeferredVB->getVertexStrider(vert); - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); - { LLGLDepthTest depth(GL_FALSE); @@ -8456,14 +8512,10 @@ void LLPipeline::renderDeferredLighting() { LLGLDepthTest depth(GL_FALSE, GL_FALSE); - LLVector2 tc1(0,0); - LLVector2 tc2((F32) mScreen.getWidth()*2, - (F32) mScreen.getHeight()*2); - mScreen.bindTarget(); // Apply gamma correction to the frame here. gDeferredPostGammaCorrectProgram.bind(); - //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); S32 channel = 0; channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); if (channel > -1) @@ -8474,21 +8526,7 @@ void LLPipeline::renderDeferredLighting() gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight()); - //F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); - - //gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); gGL.getTexUnit(channel)->unbind(mScreen.getUsage()); gDeferredPostGammaCorrectProgram.unbind(); @@ -8509,10 +8547,10 @@ void LLPipeline::renderDeferredLighting() pushRenderTypeMask(); andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, LLPipeline::RENDER_TYPE_FULLBRIGHT, - //LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_VOLUME, LLPipeline::RENDER_TYPE_GLOW, LLPipeline::RENDER_TYPE_BUMP, - /*LLPipeline::RENDER_TYPE_PASS_SIMPLE, //These aren't used. + LLPipeline::RENDER_TYPE_PASS_SIMPLE, LLPipeline::RENDER_TYPE_PASS_ALPHA, LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, LLPipeline::RENDER_TYPE_PASS_BUMP, @@ -8524,7 +8562,7 @@ void LLPipeline::renderDeferredLighting() LLPipeline::RENDER_TYPE_PASS_GRASS, LLPipeline::RENDER_TYPE_PASS_SHINY, LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,*/ + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_ALPHA_MASK, LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, @@ -9132,10 +9170,10 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) pushRenderTypeMask(); andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, LLPipeline::RENDER_TYPE_FULLBRIGHT, - //LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_VOLUME, LLPipeline::RENDER_TYPE_GLOW, LLPipeline::RENDER_TYPE_BUMP, - /*LLPipeline::RENDER_TYPE_PASS_SIMPLE, //These aren't used. + LLPipeline::RENDER_TYPE_PASS_SIMPLE, LLPipeline::RENDER_TYPE_PASS_ALPHA, LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, LLPipeline::RENDER_TYPE_PASS_BUMP, @@ -9147,7 +9185,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) LLPipeline::RENDER_TYPE_PASS_GRASS, LLPipeline::RENDER_TYPE_PASS_SHINY, LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,*/ + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_ALPHA_MASK, LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, @@ -9352,7 +9390,8 @@ inline float sgn(float a) void LLPipeline::generateWaterReflection(LLCamera& camera_in) { - if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) + static const LLCachedControl render_transparent_water("RenderTransparentWater",false); + if ((render_transparent_water || LLPipeline::sRenderDeferred) && LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) { BOOL skip_avatar_update = FALSE; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) diff --git a/indra/newview/qtoolalign.cpp b/indra/newview/qtoolalign.cpp index 6afa97f07..2b09c7cf2 100644 --- a/indra/newview/qtoolalign.cpp +++ b/indra/newview/qtoolalign.cpp @@ -1,5 +1,5 @@ /** - * @file lltoolface.cpp + * @file qtoolalign.cpp * @brief A tool to align objects */ @@ -13,14 +13,11 @@ #include "v3math.h" // Viewer includes -#include "llagent.h" #include "llagentcamera.h" #include "llbox.h" #include "llcylinder.h" #include "llfloatertools.h" -#include "llmanip.h" #include "llselectmgr.h" -#include "lltoolcomp.h" #include "llviewercamera.h" #include "llviewercontrol.h" #include "llviewerobject.h" @@ -33,7 +30,7 @@ const F32 MANIPULATOR_SELECT_SIZE = 20.0; QToolAlign::QToolAlign() -: LLToolComposite(std::string("Align")) +: LLTool(std::string("Align")) { } @@ -48,51 +45,16 @@ BOOL QToolAlign::handleMouseDown(S32 x, S32 y, MASK mask) { if (mHighlightedAxis != -1) { - align(); + align(); } else { gViewerWindow->pickAsync(x, y, mask, pickCallback); } - + return TRUE; } -BOOL QToolAlign::handleMouseUp(S32 x, S32 y, MASK mask) -{ - // first, perform normal processing in case this was a quick-click - handleHover(x, y, mask); - LLSelectMgr::getInstance()->updateSelectionCenter(); - BOOL handled = FALSE; - if( hasMouseCapture() ) - { - handled = TRUE; - setMouseCapture( FALSE ); - } - return handled; -} - -BOOL QToolAlign::handleDoubleClick(S32 x, S32 y, MASK mask) -{ - return FALSE; -} - -LLTool* QToolAlign::getOverrideTool(MASK mask) -{ - if (!gKeyboard->getKeyDown('A')) - { - if (mask == MASK_CONTROL) - { - return LLToolCompRotate::getInstance(); - } - else if (mask == (MASK_CONTROL | MASK_SHIFT)) - { - return LLToolCompScale::getInstance(); - } - } - return LLToolComposite::getOverrideTool(mask); -} - void QToolAlign::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* object = pick_info.getObject(); @@ -140,9 +102,8 @@ void QToolAlign::handleSelect() { // no parts, please - //llwarns << "in select" << llendl; + LL_DEBUGS("ALIGNTOOL") << "in select" << LL_ENDL; LLSelectMgr::getInstance()->promoteSelectionToRoot(); - LLSelectMgr::getInstance()->updateSelectionCenter(); gFloaterTools->setStatusText("align"); } @@ -151,6 +112,7 @@ void QToolAlign::handleDeselect() { } + BOOL QToolAlign::findSelectedManipulator(S32 x, S32 y) { mHighlightedAxis = -1; @@ -182,8 +144,9 @@ BOOL QToolAlign::findSelectedManipulator(S32 x, S32 y) } - F32 half_width = (F32)gViewerWindow->getWindowWidth() / 2.f; - F32 half_height = (F32)gViewerWindow->getWindowHeight() / 2.f; + LLRect world_view_rect = gViewerWindow->getWorldViewRectScaled(); + F32 half_width = (F32)world_view_rect.getWidth() / 2.f; + F32 half_height = (F32)world_view_rect.getHeight() / 2.f; LLVector2 manip2d; LLVector2 mousePos((F32)x - half_width, (F32)y - half_height); LLVector2 delta; @@ -416,25 +379,24 @@ void QToolAlign::render() LLColor4 default_normal_color( 0.7f, 0.7f, 0.7f, 0.1f ); gGL.color4fv( default_normal_color.mV ); - + // LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getEditSelection(); - BOOL can_move = selection->getObjectCount() != 0; - if (can_move) + if (selection->getObjectCount() == 0) return; + struct F : public LLSelectedObjectFunctor { - struct f : public LLSelectedObjectFunctor + virtual bool apply(LLViewerObject* objectp) { - virtual bool apply(LLViewerObject* objectp) - { - return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); - } - } func; - can_move = selection->applyToObjects(&func); - } - if (can_move) - { - render_bbox(mBBox); - renderManipulators(); - } + if (!objectp->permMove()) return false; + if (objectp->permModify()) return true; + static const LLCachedControl edit_linked("EditLinkedParts"); + return !edit_linked; + } + } f; + if (!selection->applyToObjects(&f)) return; + // + + render_bbox(mBBox); + renderManipulators(); } // only works for our specialized (AABB, position centered) bboxes @@ -564,7 +526,7 @@ void QToolAlign::align() // check to see if it overlaps the previously placed objects BOOL overlap = FALSE; - llwarns << "i=" << i << " j=" << j << llendl; + LL_DEBUGS("ALIGNTOOL") << "i=" << i << " j=" << j << LL_ENDL; if (!mForce) // well, don't check if in force mode { @@ -577,8 +539,8 @@ void QToolAlign::align() if (overlaps_this) { - llwarns << "overlap" << new_bbox.getCenterAgent() << other_bbox.getCenterAgent() << llendl; - llwarns << "extent" << new_bbox.getExtentLocal() << other_bbox.getExtentLocal() << llendl; + LL_DEBUGS("ALIGNTOOL") << "overlap" << new_bbox.getCenterAgent() << other_bbox.getCenterAgent() << LL_ENDL; + LL_DEBUGS("ALIGNTOOL") << "extent" << new_bbox.getExtentLocal() << other_bbox.getExtentLocal() << LL_ENDL; } overlap = (overlap || overlaps_this); diff --git a/indra/newview/qtoolalign.h b/indra/newview/qtoolalign.h index 1bef073ba..da70b34af 100644 --- a/indra/newview/qtoolalign.h +++ b/indra/newview/qtoolalign.h @@ -8,14 +8,13 @@ #include "lltool.h" #include "llbbox.h" -#include "lltoolcomp.h" class LLViewerObject; class LLPickInfo; class LLToolSelectRect; class QToolAlign -: public LLToolComposite, public LLSingleton +: public LLTool, public LLSingleton { public: QToolAlign(); @@ -24,13 +23,9 @@ public: virtual void handleSelect(); virtual void handleDeselect(); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); - virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); - virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual void render(); - virtual LLTool* getOverrideTool(MASK mask); - static void pickCallback(const LLPickInfo& pick_info); private: diff --git a/indra/newview/res/singularity.icns b/indra/newview/res/singularity_icon.icns similarity index 100% rename from indra/newview/res/singularity.icns rename to indra/newview/res/singularity_icon.icns diff --git a/indra/newview/res/viewerRes.rc.in b/indra/newview/res/viewerRes.rc.in index 0ca054f5a..0119f9fd9 100644 --- a/indra/newview/res/viewerRes.rc.in +++ b/indra/newview/res/viewerRes.rc.in @@ -61,8 +61,8 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_LL_ICON ICON "singularity_icon.ico" -IDI_LCD_LL_ICON ICON "singularity_icon.ico" +IDI_LL_ICON ICON "${VIEWER_BRANDING_ID}_icon.ico" +IDI_LCD_LL_ICON ICON "${VIEWER_BRANDING_ID}_icon.ico" ///////////////////////////////////////////////////////////////////////////// // @@ -74,7 +74,7 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE FONT 8, "MS Sans Serif" BEGIN ICON IDI_LL_ICON,IDC_STATIC,7,7,20,20 - LTEXT "Loading Second Life...",666,36,13,91,8 + LTEXT "Loading ${VIEWER_CHANNEL}...",666,36,13,91,8 END diff --git a/indra/newview/res/viewerRes_bc.rc.in b/indra/newview/res/viewerRes_bc.rc.in index a9bdd7c8d..3413cf937 100644 --- a/indra/newview/res/viewerRes_bc.rc.in +++ b/indra/newview/res/viewerRes_bc.rc.in @@ -61,8 +61,8 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_LL_ICON ICON "singularity_icon_bc.ico" -IDI_LCD_LL_ICON ICON "singularity_icon_bc.ico" +IDI_LL_ICON ICON "${VIEWER_BRANDING_ID}_icon_bc.ico" +IDI_LCD_LL_ICON ICON "${VIEWER_BRANDING_ID}_icon_bc.ico" ///////////////////////////////////////////////////////////////////////////// // @@ -74,7 +74,7 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE FONT 8, "MS Sans Serif" BEGIN ICON IDI_LL_ICON,IDC_STATIC,7,7,20,20 - LTEXT "Loading Second Life...",666,36,13,91,8 + LTEXT "Loading ${VIEWER_CHANNEL}...",666,36,13,91,8 END diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp new file mode 100644 index 000000000..2ea2646cb --- /dev/null +++ b/indra/newview/rlvactions.cpp @@ -0,0 +1,125 @@ +/** + * + * Copyright (c) 2009-2013, Kitty Barnett + * + * The source code in this file is provided to you under the terms of the + * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt + * + * By copying, modifying or distributing this software, you acknowledge that + * you have read and understood your obligations described above, and agree to + * abide by those obligations. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llimview.h" +#include "llvoavatarself.h" +#include "rlvactions.h" +#include "rlvhandler.h" + +// ============================================================================ +// RlvActions member functions +// + +// Checked: 2010-11-30 (RLVa-1.3.0) +bool RlvActions::canReceiveIM(const LLUUID& idSender) +{ + // User can receive an IM from "sender" (could be an agent or a group) if: + // - not generally restricted from receiving IMs (or the sender is an exception) + // - not specifically restricted from receiving an IM from the sender + return + (!rlv_handler_t::isEnabled()) || + ( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) || (gRlvHandler.isException(RLV_BHVR_RECVIM, idSender)) ) && + ( (!gRlvHandler.hasBehaviour(RLV_BHVR_RECVIMFROM)) || (!gRlvHandler.isException(RLV_BHVR_RECVIMFROM, idSender)) ) ); +} + +// Checked: 2010-11-30 (RLVa-1.3.0) +bool RlvActions::canSendIM(const LLUUID& idRecipient) +{ + // User can send an IM to "recipient" (could be an agent or a group) if: + // - not generally restricted from sending IMs (or the recipient is an exception) + // - not specifically restricted from sending an IM to the recipient + return + (!rlv_handler_t::isEnabled()) || + ( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.isException(RLV_BHVR_SENDIM, idRecipient)) ) && + ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) || (!gRlvHandler.isException(RLV_BHVR_SENDIMTO, idRecipient)) ) ); +} + +// Checked: 2011-04-12 (RLVa-1.3.0) +bool RlvActions::canStartIM(const LLUUID& idRecipient) +{ + // User can start an IM session with "recipient" (could be an agent or a group) if: + // - not generally restricted from starting IM sessions (or the recipient is an exception) + // - not specifically restricted from starting an IM session with the recipient + return + (!rlv_handler_t::isEnabled()) || + ( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIM)) || (gRlvHandler.isException(RLV_BHVR_STARTIM, idRecipient)) ) && + ( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIMTO)) || (!gRlvHandler.isException(RLV_BHVR_STARTIMTO, idRecipient)) ) ); +} + +// Checked: 2010-12-11 (RLVa-1.2.2) +bool RlvActions::canAcceptTpOffer(const LLUUID& idSender) +{ + return ((!gRlvHandler.hasBehaviour(RLV_BHVR_TPLURE)) || (gRlvHandler.isException(RLV_BHVR_TPLURE, idSender))) && (canStand()); +} + +// Checked: 2013-11-08 (RLVa-1.4.9) +bool RlvActions::autoAcceptTeleportOffer(const LLUUID& idSender) +{ + return ((idSender.notNull()) && (gRlvHandler.isException(RLV_BHVR_ACCEPTTP, idSender))) || (gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTP)); +} + +// Checked: 2013-11-08 (RLVa-1.4.9) +bool RlvActions::canAcceptTpRequest(const LLUUID& idSender) +{ + return (!gRlvHandler.hasBehaviour(RLV_BHVR_TPREQUEST)) || (gRlvHandler.isException(RLV_BHVR_TPREQUEST, idSender)); +} + +// Checked: 2013-11-08 (RLVa-1.4.9) +bool RlvActions::autoAcceptTeleportRequest(const LLUUID& idRequester) +{ + return ((idRequester.notNull()) && (gRlvHandler.isException(RLV_BHVR_ACCEPTTPREQUEST, idRequester))) || (gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTPREQUEST)); +} + +// Checked: 2010-03-07 (RLVa-1.2.0) +bool RlvActions::canStand() +{ + // NOTE: return FALSE only if we're @unsit=n restricted and the avie is currently sitting on something and TRUE for everything else + return (!gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || ((isAgentAvatarValid()) && (!gAgentAvatarp->isSitting())); +} + +// Checked: 2014-02-24 (RLVa-1.4.10) +bool RlvActions::canShowLocation() +{ + return !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC); +} + +// Checked: 2013-05-10 (RLVa-1.4.9) +bool RlvActions::hasBehaviour(ERlvBehaviour eBhvr) +{ + return gRlvHandler.hasBehaviour(eBhvr); +} + +// Checked: 2013-05-09 (RLVa-1.4.9) +bool RlvActions::hasOpenP2PSession(const LLUUID& idAgent) +{ + const LLUUID idSession = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, idAgent); + return (idSession.notNull()) && (LLIMMgr::instance().hasSession(idSession)); +} + +// Checked: 2013-05-09 (RLVa-1.4.9) +bool RlvActions::hasOpenGroupSession(const LLUUID& idGroup) +{ + return (idGroup.notNull()) && (LLIMMgr::instance().hasSession(idGroup)); +} + +// Checked: 2013-11-08 (RLVa-1.4.9) +bool RlvActions::isRlvEnabled() +{ + return RlvHandler::isEnabled(); +} + +// ============================================================================ diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h new file mode 100644 index 000000000..58d90780a --- /dev/null +++ b/indra/newview/rlvactions.h @@ -0,0 +1,111 @@ +/** + * + * Copyright (c) 2009-2013, Kitty Barnett + * + * The source code in this file is provided to you under the terms of the + * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt + * + * By copying, modifying or distributing this software, you acknowledge that + * you have read and understood your obligations described above, and agree to + * abide by those obligations. + * + */ + +#ifndef RLV_ACTIONS_H +#define RLV_ACTIONS_H + +#include "rlvdefines.h" + +// ============================================================================ +// RlvActions class declaration - developer-friendly non-RLVa code facing class, use in lieu of RlvHandler whenever possible +// + +class RlvActions +{ + // ============= + // Communication + // ============= +public: + /* + * Returns true if the user is allowed to receive IMs from the specified sender (can be an avatar or a group) + */ + static bool canReceiveIM(const LLUUID& idSender); + + /* + * Returns true if the user is allowed to send IMs to the specified recipient (can be an avatar or a group) + */ + static bool canSendIM(const LLUUID& idRecipient); + + /* + * Returns true if the user is allowed to start a - P2P or group - conversation with the specified UUID. + */ + static bool canStartIM(const LLUUID& idRecipient); // @startim and @startimto + + // ======== + // Movement + // ======== +public: + /* + * Returns true if the user can accept an incoming teleport offer from the specified avatar + */ + static bool canAcceptTpOffer(const LLUUID& idSender); + + /* + * Returns true if a teleport offer from the specified avatar should be auto-accepted + * (pass the null UUID to check if all teleport offers should be auto-accepted regardless of sender) + */ + static bool autoAcceptTeleportOffer(const LLUUID& idSender); + + /* + * Returns true if the user can accept an incoming teleport request from the specified avatar + */ + static bool canAcceptTpRequest(const LLUUID& idSender); + + /* + * Returns true if a teleport request from the specified avatar should be auto-accepted + * (pass the null UUID to check if all teleport requests should be auto-accepted regardless of requester) + */ + static bool autoAcceptTeleportRequest(const LLUUID& idRequester); + + // ================= + // World interaction + // ================= +public: + /* + * Returns true if the user can stand up (returns true if the user isn't currently sitting) + */ + static bool canStand(); + + /* + * Returns true if the user can see their in-world location + */ + static bool canShowLocation(); + + // ================ + // Helper functions + // ================ +public: + /* + * Convenience function to check for a behaviour without having to include rlvhandler.h. + * Do NOT call this function if speed is important (i.e. per-frame) + */ + static bool hasBehaviour(ERlvBehaviour eBhvr); + + /* + * Returns true if a - P2P or group - IM session is open with the specified UUID. + */ + static bool hasOpenP2PSession(const LLUUID& idAgent); + static bool hasOpenGroupSession(const LLUUID& idGroup); + + /* + * Convenience function to check if RLVa is enabled without having to include rlvhandler.h + */ + static bool isRlvEnabled(); +}; + +// ============================================================================ + +#endif // RLV_ACTIONS_H diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index e24c5f3d8..e736193ef 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -18,17 +18,18 @@ #include "llagent.h" #include "llagentui.h" #include "llavatarnamecache.h" +#include "llinstantmessage.h" #include "llnotificationsutil.h" +#include "llsdserialize.h" #include "lluictrlfactory.h" -#include "sgversion.h" #include "llviewermenu.h" #include "llviewerparcelmgr.h" #include "llviewermenu.h" #include "llviewerregion.h" #include "llviewerstats.h" -#include "llvoavatar.h" #include "llworld.h" +#include "rlvactions.h" #include "rlvcommon.h" #include "rlvhelper.h" #include "rlvhandler.h" @@ -37,44 +38,16 @@ #include "../lscript/lscript_byteformat.h" //Need LSCRIPTRunTimePermissionBits and SCRIPT_PERMISSION_* #include -using namespace LLOldEvents; - // ============================================================================ // RlvNotifications // -#ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR -// Checked: 2009-12-05 (RLVa-1.1.0h) | Added: RLVa-1.1.0h -/*void RlvNotifications::notifyBehaviour(ERlvBehaviour eBhvr, ERlvParamType eType) -{ - const std::string& strMsg = RlvStrings::getBehaviourNotificationString(eBhvr, eType); - if (!strMsg.empty()) - { - LLSD argsNotify; - argsNotify["MESSAGE"] = strMsg; - LLNotificationsUtil::add("SystemMessageTip", argsNotify); - } -}*/ -#endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR - -// Checked: 2009-11-11 (RLVa-1.1.0a) | Added: RLVa-1.1.0a/ -/*void RlvNotifications::notifyBlockedViewXXX(const char* pstrAssetType) -{ - LLStringUtil::format_map_t argsMsg; std::string strMsg = RlvStrings::getString(RLV_STRING_BLOCKED_VIEWXXX); - argsMsg["[TYPE]"] = pstrAssetType; - LLStringUtil::format(strMsg, argsMsg); - - LLSD argsNotify; - argsNotify["MESSAGE"] = strMsg; - LLNotificationsUtil::add("SystemMessageTip", argsNotify); -} -*/ // Checked: 2009-11-13 (RLVa-1.1.0b) | Modified: RLVa-1.1.0b /* void RlvNotifications::warnGiveToRLV() { if ( (gSavedSettings.getWarning(RLV_SETTING_FIRSTUSE_GIVETORLV)) && (RlvSettings::getForbidGiveToRLV()) ) - LLNotifications::instance().add(RLV_SETTING_FIRSTUSE_GIVETORLV, LLSD(), LLSD(), &RlvUtil::onGiveToRLVConfirmation); + LLNotifications::instance().add(RLV_SETTING_FIRSTUSE_GIVETORLV, LLSD(), LLSD(), &RlvNotifications::onGiveToRLVConfirmation); } */ @@ -131,9 +104,6 @@ void RlvSettings::initClass() gSavedPerAccountSettings.getControl(RLV_SETTING_LOGINLASTLOCATION)->setHiddenFromSettingsEditor(true); #endif // RLV_EXTENSION_STARTLOCATION - if (gSavedSettings.controlExists(RLV_SETTING_AVATAROFFSET_Z)) - gSavedSettings.getControl(RLV_SETTING_AVATAROFFSET_Z)->getSignal()->connect(boost::bind(&onChangedAvatarOffset, _2)); - if (gSavedSettings.controlExists(RLV_SETTING_TOPLEVELMENU)) gSavedSettings.getControl(RLV_SETTING_TOPLEVELMENU)->getSignal()->connect(boost::bind(&onChangedMenuLevel)); @@ -147,7 +117,7 @@ void RlvSettings::initClass() { if ( (!LLApp::isQuitting()) && (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION)) ) { - BOOL fValue = (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) || (!gRlvHandler.canStand()); + BOOL fValue = (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) || (!RlvActions::canStand()); if (gSavedPerAccountSettings.getBOOL(RLV_SETTING_LOGINLASTLOCATION) != fValue) { gSavedPerAccountSettings.setBOOL(RLV_SETTING_LOGINLASTLOCATION, fValue); @@ -187,67 +157,32 @@ bool RlvSettings::onChangedSettingBOOL(const LLSD& sdValue, bool* pfSetting) // std::vector RlvStrings::m_Anonyms; -std::map RlvStrings::m_StringMap; -#ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR -/*std::map RlvStrings::m_BhvrAddMap; -std::map RlvStrings::m_BhvrRemMap;*/ -#endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR +RlvStrings::string_map_t RlvStrings::m_StringMap; +std::string RlvStrings::m_StringMapPath; -// Checked: 2010-03-09 (RLVa-1.2.0a) | Added: RLVa-1.1.0h +// Checked: 2011-11-08 (RLVa-1.5.0) void RlvStrings::initClass() { static bool fInitialized = false; if (!fInitialized) { - LLXMLNodePtr xmlRoot; - if ( (!LLUICtrlFactory::getLayeredXMLNode("rlva_strings.xml", xmlRoot)) || (xmlRoot.isNull()) || (!xmlRoot->hasName("rlva_strings")) ) + // Load the default string values + /* Singu TODO: findSkinnedFilenames/LLDir update + std::vector files = gDirUtilp->findSkinnedFilenames(LLDir::XUI, RLV_STRINGS_FILE, LLDir::ALL_SKINS); + m_StringMapPath = (!files.empty()) ? files.front() : LLStringUtil::null; + for (auto itFile = files.cbegin(); itFile != files.cend(); ++itFile) + */ + std::string itFile = gDirUtilp->findSkinnedFilename(LLUICtrlFactory::getXUIPaths().front(), RLV_STRINGS_FILE); + if (!itFile.empty()) { - RLV_ERRS << "Problem reading RLVa string XML file" << RLV_ENDL; - return; + loadFromFile(itFile, false); } + m_StringMapPath = itFile; // Singu TODO: Remove this when updating to the above LLDir impl. - for (LLXMLNode* pNode = xmlRoot->getFirstChild(); pNode != NULL; pNode = pNode->getNextSibling()) - { - if (pNode->hasName("strings")) - { - std::string strName; - for (LLXMLNode* pStringNode = pNode->getFirstChild(); pStringNode != NULL; pStringNode = pStringNode->getNextSibling()) - { - if ( (!pStringNode->hasName("string")) || (!pStringNode->getAttributeString("name", strName)) ) - continue; - m_StringMap[strName] = pStringNode->getTextContents(); - } - } - else if (pNode->hasName("anonyms")) - { - for (LLXMLNode* pAnonymNode = pNode->getFirstChild(); pAnonymNode != NULL; pAnonymNode = pAnonymNode->getNextSibling()) - { - if (!pAnonymNode->hasName("anonym")) - continue; - m_Anonyms.push_back(pAnonymNode->getTextContents()); - } - } - #ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR - /*else if (pNode->hasName("behaviour-notifications")) - { - std::string strBhvr, strType; ERlvBehaviour eBhvr; - for (LLXMLNode* pNotifyNode = pNode->getFirstChild(); pNotifyNode != NULL; pNotifyNode = pNotifyNode->getNextSibling()) - { - if ( (!pNotifyNode->hasName("notification")) || (!pNotifyNode->getAttributeString("type", strType)) || - (!pNotifyNode->getAttributeString("behaviour", strBhvr)) || - ((eBhvr = RlvCommand::getBehaviourFromString(strBhvr)) == RLV_BHVR_UNKNOWN) ) - { - continue; - } - if ("add" == strType) - m_BhvrAddMap.insert(std::pair(eBhvr, pNotifyNode->getTextContents())); - else if ("rem" == strType) - m_BhvrRemMap.insert(std::pair(eBhvr, pNotifyNode->getTextContents())); - } - }*/ - #endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR - } + // Load the custom string overrides + loadFromFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, RLV_STRINGS_FILE), true); + // Sanity check if ( (m_StringMap.empty()) || (m_Anonyms.empty()) ) { RLV_ERRS << "Problem parsing RLVa string XML file" << RLV_ENDL; @@ -258,6 +193,68 @@ void RlvStrings::initClass() } } +// Checked: 2011-11-08 (RLVa-1.5.0) +void RlvStrings::loadFromFile(const std::string& strFilePath, bool fUserOverride) +{ + llifstream fileStream(strFilePath, std::ios::binary); LLSD sdFileData; + if ( (!fileStream.is_open()) || (!LLSDSerialize::fromXMLDocument(sdFileData, fileStream)) ) + return; + fileStream.close(); + + if (sdFileData.has("strings")) + { + const LLSD& sdStrings = sdFileData["strings"]; + for (LLSD::map_const_iterator itString = sdStrings.beginMap(); itString != sdStrings.endMap(); ++itString) + { + if ( (!itString->second.has("value")) || ((fUserOverride) && (!hasString(itString->first))) ) + continue; + + std::list& listValues = m_StringMap[itString->first]; + if (!fUserOverride) + { + if (listValues.size() > 0) + listValues.pop_front(); + listValues.push_front(itString->second["value"].asString()); + } + else + { + while (listValues.size() > 1) + listValues.pop_back(); + listValues.push_back(itString->second["value"].asString()); + } + } + } + if (sdFileData.has("anonyms")) + { + const LLSD& sdAnonyms = sdFileData["anonyms"]; + for (LLSD::array_const_iterator itAnonym = sdAnonyms.beginArray(); itAnonym != sdAnonyms.endArray(); ++itAnonym) + { + m_Anonyms.push_back((*itAnonym).asString()); + } + } +} + +// Checked: 2011-11-08 (RLVa-1.5.0) +void RlvStrings::saveToFile(const std::string& strFilePath) +{ + LLSD sdFileData; + + LLSD& sdStrings = sdFileData["strings"]; + for (string_map_t::const_iterator itString = m_StringMap.begin(); itString != m_StringMap.end(); ++itString) + { + const std::list& listValues = itString->second; + if (listValues.size() > 1) + sdStrings[itString->first]["value"] = listValues.back(); + } + + llofstream fileStream(strFilePath); + if (!fileStream.good()) + return; + + LLSDSerialize::toPrettyXML(sdFileData, fileStream); + fileStream.close(); +} + // Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a const std::string& RlvStrings::getAnonym(const std::string& strName) { @@ -270,30 +267,12 @@ const std::string& RlvStrings::getAnonym(const std::string& strName) return m_Anonyms[nHash % m_Anonyms.size()]; } -#ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR -// Checked: 2009-12-05 (RLVa-1.1.0h) | Added: RLVa-1.1.0h -/*const std::string& RlvStrings::getBehaviourNotificationString(ERlvBehaviour eBhvr, ERlvParamType eType) -{ - if (RLV_TYPE_ADD == eType) - { - std::map::const_iterator itString = m_BhvrAddMap.find(eBhvr); - return (itString != m_BhvrAddMap.end()) ? itString->second : LLStringUtil::null; - } - else if (RLV_TYPE_REMOVE == eType) - { - std::map::const_iterator itString = m_BhvrRemMap.find(eBhvr); - return (itString != m_BhvrRemMap.end()) ? itString->second : LLStringUtil::null; - } - return LLStringUtil::null; -}*/ -#endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR - -// Checked: 2009-11-11 (RLVa-1.1.0a) | Added: RLVa-1.1.0a +// Checked: 2011-11-08 (RLVa-1.5.0) const std::string& RlvStrings::getString(const std::string& strStringName) { static const std::string strMissing = "(Missing RLVa string)"; string_map_t::const_iterator itString = m_StringMap.find(strStringName); - return (itString != m_StringMap.end()) ? itString->second : strMissing; + return (itString != m_StringMap.end()) ? itString->second.back() : strMissing; } // Checked: 2009-11-25 (RLVa-1.1.0f) | Added: RLVa-1.1.0f @@ -322,6 +301,8 @@ const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet) return "unknown command"; case RLV_RET_FAILED_NOSHAREDROOT: return "missing #RLV"; + case RLV_RET_DEPRECATED: + return "deprecated"; // The following are identified by the chat verb case RLV_RET_RETAINED: case RLV_RET_SUCCESS: @@ -354,15 +335,29 @@ std::string RlvStrings::getVersionAbout() } // Checked: 2010-03-27 (RLVa-1.4.0a) | Modified: RLVa-1.1.0a -std::string RlvStrings::getVersionNum() +std::string RlvStrings::getVersionNum() { return llformat("%d%02d%02d%02d", RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, RLV_VERSION_BUILD); } -// Checked: 2010-05-26 (RLVa-1.2.0h) | Added: RLVa-1.2.0g -bool RlvStrings::hasString(const std::string& strStringName) +// Checked: 2011-11-08 (RLVa-1.5.0) +bool RlvStrings::hasString(const std::string& strStringName, bool fCheckCustom) { - return m_StringMap.find(strStringName) != m_StringMap.end(); + string_map_t::const_iterator itString = m_StringMap.find(strStringName); + return (itString != m_StringMap.end()) && ((!fCheckCustom) || (itString->second.size() > 0)); +} + +// Checked: 2011-11-08 (RLVa-1.5.0) +void RlvStrings::setCustomString(const std::string& strStringName, const std::string& strStringValue) +{ + if (!hasString(strStringName)) + return; + + std::list& listValues = m_StringMap[strStringName]; + while (listValues.size() > 1) + listValues.pop_back(); + if (!strStringValue.empty()) + listValues.push_back(strStringValue); } // ============================================================================ @@ -396,27 +391,25 @@ void RlvUtil::filterNames(std::string& strUTF8Text, bool fFilterLegacy) LLAvatarName avName; if (LLAvatarNameCache::get(idAgents[idxAgent], &avName)) { - const std::string& strAnonym = RlvStrings::getAnonym(avName.mDisplayName); - - // NOTE: if the legacy first and last name are empty we get a legacy name of " " which would replace all spaces in the string - std::string strLegacyName; - if ( (fFilterLegacy) && (!avName.mLegacyFirstName.empty()) && - ((!avName.mIsDisplayNameDefault) || (LLCacheName::getDefaultLastName() == avName.mLegacyLastName)) ) - { - strLegacyName = avName.getLegacyName(); - } + const std::string& strDisplayName = avName.mDisplayName; + bool fFilterDisplay = (strDisplayName.length() > 2); + const std::string& strLegacyName = avName.getLegacyName(); + fFilterLegacy &= (strLegacyName.length() > 2); + const std::string& strAnonym = RlvStrings::getAnonym(avName); // If the display name is a subset of the legacy name we need to filter that first, otherwise it's the other way around - if (boost::icontains(strLegacyName, avName.mDisplayName)) + if (boost::icontains(strLegacyName, strDisplayName)) { - if (!strLegacyName.empty()) + if (fFilterLegacy) boost::ireplace_all(strUTF8Text, strLegacyName, strAnonym); - boost::ireplace_all(strUTF8Text, avName.mDisplayName, strAnonym); + if (fFilterDisplay) + boost::ireplace_all(strUTF8Text, strDisplayName, strAnonym); } else { - boost::ireplace_all(strUTF8Text, avName.mDisplayName, strAnonym); - if (!strLegacyName.empty()) + if (fFilterDisplay) + boost::ireplace_all(strUTF8Text, strDisplayName, strAnonym); + if (fFilterLegacy) boost::ireplace_all(strUTF8Text, strLegacyName, strAnonym); } } @@ -693,7 +686,7 @@ bool rlvPredCanNotWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWea } // Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a -bool rlvPredCanRemoveItem(const LLInventoryItem* pItem) +bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem) { if ( (pItem) && (RlvForceWear::isWearableItem(pItem)) ) { @@ -716,7 +709,7 @@ bool rlvPredCanRemoveItem(const LLInventoryItem* pItem) } // Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a -bool rlvPredCanNotRemoveItem(const LLInventoryItem* pItem) +bool rlvPredCanNotRemoveItem(const LLViewerInventoryItem* pItem) { return !rlvPredCanRemoveItem(pItem); } diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index a767ed445..a4411f146 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -46,6 +46,7 @@ class LLInventoryItem; class LLViewerInventoryCategory; class LLViewerInventoryItem; class LLViewerJointAttachment; +class LLViewerWearable; class LLWearable; // @@ -79,7 +80,6 @@ template inline T rlvGetPerUserSetting(const std::string& strSetting class RlvSettings { public: - static F32 getAvatarOffsetZ() { return rlvGetSetting(RLV_SETTING_AVATAROFFSET_Z, 0.0); } static bool getDebug() { return rlvGetSetting(RLV_SETTING_DEBUG, false); } static bool getCanOOC() { return fCanOOC; } static bool getForbidGiveToRLV() { return rlvGetSetting(RLV_SETTING_FORBIDGIVETORLV, true); } @@ -128,21 +128,25 @@ class RlvStrings { public: static void initClass(); + static void loadFromFile(const std::string& strFilePath, bool fDefault); + static void saveToFile(const std::string& strFilePath); static const std::string& getAnonym(const LLAvatarName& avName); // @shownames static const std::string& getAnonym(const std::string& strName); // @shownames - static const std::string& getBehaviourNotificationString(ERlvBehaviour eBhvr, ERlvParamType eType); static const std::string& getString(const std::string& strStringName); static const char* getStringFromReturnCode(ERlvCmdRet eRet); + static const std::string& getStringMapPath() { return m_StringMapPath; } static std::string getVersion(bool fLegacy = false); // @version static std::string getVersionAbout(); // Shown in Help / About static std::string getVersionNum(); // @versionnum - static bool hasString(const std::string& strStringName); + static bool hasString(const std::string& strStringName, bool fCheckCustom = false); + static void setCustomString(const std::string& strStringName, const std::string& strStringValue); protected: static std::vector m_Anonyms; - typedef std::map string_map_t; + typedef std::map > string_map_t; static string_map_t m_StringMap; + static std::string m_StringMapPath; }; // ============================================================================ @@ -239,8 +243,8 @@ protected: bool rlvPredCanWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask); bool rlvPredCanNotWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask); -bool rlvPredCanRemoveItem(const LLInventoryItem* pItem); -bool rlvPredCanNotRemoveItem(const LLInventoryItem* pItem); +bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem); +bool rlvPredCanNotRemoveItem(const LLViewerInventoryItem* pItem); struct RlvPredCanWearItem { @@ -258,6 +262,18 @@ protected: ERlvWearMask m_eWearMask; }; +struct RlvPredCanRemoveItem +{ + RlvPredCanRemoveItem() {} + bool operator()(const LLViewerInventoryItem* pItem) { return rlvPredCanRemoveItem(pItem); } +}; + +struct RlvPredCanNotRemoveItem +{ + RlvPredCanNotRemoveItem() {} + bool operator()(const LLViewerInventoryItem* pItem) { return rlvPredCanNotRemoveItem(pItem); } +}; + struct RlvPredIsEqualOrLinkedItem { RlvPredIsEqualOrLinkedItem(const LLViewerInventoryItem* pItem) : m_pItem(pItem) {} diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 9e000ddbd..3aa90e168 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -3,10 +3,10 @@ * Copyright (c) 2009-2011, Kitty Barnett * * The source code in this file is provided to you under the terms of the - * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY; + * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt - * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt * * By copying, modifying or distributing this software, you acknowledge that * you have read and understood your obligations described above, and agree to @@ -21,20 +21,10 @@ // Extensions // -// Comment out if you don't want the Advanced / RLVa menu (may prevent enabling some extensions or experimental features - see below) -#define RLV_ADVANCED_MENU -// Comment out if you provide your own way to enable/disable RLVa -#define RLV_ADVANCED_TOGGLE_RLVA - -// Provides access to "advanced" features through the RLVa debug menu -#define RLV_EXTENSION_FLOATER_RESTRICTIONS // Enables the Advanced / RLVa / Restrictions... floater -#define RLV_EXTENSION_HIDELOCKED // "Hide locked layers", "Hide locked attachments" and "Hide locked inventory" - // Extensions #define RLV_EXTENSION_CMD_GETSETDEBUG_EX // Extends the debug variables accessible through @getdebug_xxx/@setdebug_xxx #define RLV_EXTENSION_CMD_FINDFOLDERS // @findfolders: