diff --git a/.gitignore b/.gitignore index ead4b749f..7c302ed85 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,9 @@ qtcreator-build/ /indra/newview/res/viewerRes.rc /indra/newview/res/viewerRes_bc.rc /indra/newview/English.lproj/InfoPlist.strings +/indra/newview/linux_tools/handle_secondlifeprotocol.sh +/indra/newview/linux_tools/install.sh +/indra/newview/linux_tools/refresh_desktop_app_entry.sh +/indra/newview/linux_tools/wrapper.sh + + diff --git a/LICENSES/LEGAL-intel_matrixlib.txt b/LICENSES/LEGAL-intel_matrixlib.txt new file mode 100644 index 000000000..7ab64f595 --- /dev/null +++ b/LICENSES/LEGAL-intel_matrixlib.txt @@ -0,0 +1,29 @@ +INTEL LICENSE AGREEMENT + +IMPORTANT - READ BEFORE COPYING OR USING. +Do not use or load this library and any associated materials (collectively, +the "Software") until you have read the following terms and conditions. By +loading or using the Software, you agree to the terms of this Agreement. If +you do not wish to so agree, do not use the Software. + +LICENSE: Subject to the restrictions below, Intel Corporation ("Intel") +grants to you the permission to use, copy, distribute and prepare derivative +works of this Software for any purpose and without fee, provided, that +Intel's copyright notice appear in all copies of the Software files. +The distribution of derivative works of the Software is also subject to the +following limitations: you (i) are solely responsible to your customers for +any liability which may arise from the distribution, (ii) do not make any +statement that your product is "certified", or that its performance is +guaranteed, by Intel, and (iii) do not use Intel's name or trademarks to +market your product without written permission. + +EXCLUSION OF ALL WARRANTIES. The Software is provided "AS IS" without any +express or implies warranty of any kind including warranties of +merchantability, noninfringement, or fitness for a particular purpose. +Intel does not warrant or assume responsibility for the accuracy or +completeness of any information contained within the Software. +As this Software is given free of charge, in no event shall Intel be liable +for any damages whatsoever arising out of the use of or inability to use the +Software, even if Intel has been adviced of the possibility of such damages. +Intel does not assume any responsibility for any errors which may appear in +this Software nor any responsibility to update it. diff --git a/indra/aistatemachine/aistatemachine.cpp b/indra/aistatemachine/aistatemachine.cpp index fcdb2d9c8..fe7b4a3bd 100644 --- a/indra/aistatemachine/aistatemachine.cpp +++ b/indra/aistatemachine/aistatemachine.cpp @@ -293,7 +293,36 @@ void AIEngine::add(AIStateMachine* state_machine) } } -extern void print_statemachine_diagnostics(U64 total_clocks, U64 max_delta, AIEngine::queued_type::const_reference slowest_state_machine); +#if STATE_MACHINE_PROFILING +// Called from AIStateMachine::mainloop +void print_statemachine_diagnostics(U64 total_clocks, AIStateMachine::StateTimerBase::TimeData& slowest_timer, AIEngine::queued_type::const_reference slowest_element) +{ + AIStateMachine const& slowest_state_machine = slowest_element.statemachine(); + F64 const tfactor = 1000 / calc_clock_frequency(); + std::ostringstream msg; + + U64 max_delta = slowest_timer.GetDuration(); + + if (total_clocks > max_delta) + { + msg << "AIStateMachine::mainloop did run for " << (total_clocks * tfactor) << " ms. The slowest "; + } + else + { + msg << "AIStateMachine::mainloop: A "; + } + msg << "state machine " << "(" << slowest_state_machine.getName() << ") " << "ran for " << (max_delta * tfactor) << " ms"; + if (slowest_state_machine.getRuntime() > max_delta) + { + msg << " (" << (slowest_state_machine.getRuntime() * tfactor) << " ms in total now)"; + } + msg << ".\n"; + + AIStateMachine::StateTimerBase::DumpTimers(msg); + + llwarns << msg.str() << llendl; +} +#endif // MAIN-THREAD void AIEngine::mainloop(void) @@ -305,28 +334,33 @@ void AIEngine::mainloop(void) queued_element = engine_state_w->list.begin(); } U64 total_clocks = 0; -#ifndef LL_RELEASE_FOR_DOWNLOAD - U64 max_delta = 0; +#if STATE_MACHINE_PROFILING queued_type::value_type slowest_element(NULL); + AIStateMachine::StateTimerRoot::TimeData slowest_timer; #endif while (queued_element != end) { AIStateMachine& state_machine(queued_element->statemachine()); - U64 start = get_clock_count(); - if (!state_machine.sleep(start)) + AIStateMachine::StateTimerBase::TimeData time_data; + if (!state_machine.sleep(get_clock_count())) { - state_machine.multiplex(AIStateMachine::normal_run); + AIStateMachine::StateTimerRoot timer(state_machine.getName()); + state_machine.multiplex(AIStateMachine::normal_run); + time_data = timer.GetTimerData(); } - U64 delta = get_clock_count() - start; - state_machine.add(delta); - total_clocks += delta; -#ifndef LL_RELEASE_FOR_DOWNLOAD - if (delta > max_delta) + if (U64 delta = time_data.GetDuration()) { - max_delta = delta; - slowest_element = *queued_element; - } + state_machine.add(delta); + total_clocks += delta; +#if STATE_MACHINE_PROFILING + if (delta > slowest_timer.GetDuration()) + { + slowest_element = *queued_element; + slowest_timer = time_data; + } #endif + } + bool active = state_machine.active(this); // This locks mState shortly, so it must be called before locking mEngineState because add() locks mEngineState while holding mState. engine_state_type_wat engine_state_w(mEngineState); if (!active) @@ -340,8 +374,8 @@ void AIEngine::mainloop(void) } if (total_clocks >= sMaxCount) { -#ifndef LL_RELEASE_FOR_DOWNLOAD - print_statemachine_diagnostics(total_clocks, max_delta, slowest_element); +#if STATE_MACHINE_PROFILING + print_statemachine_diagnostics(total_clocks, slowest_timer, slowest_element); #endif Dout(dc::statemachine, "Sorting " << engine_state_w->list.size() << " state machines."); engine_state_w->list.sort(QueueElementComp()); @@ -752,6 +786,22 @@ void AIStateMachine::multiplex(event_type event) } } +#if STATE_MACHINE_PROFILING +std::vector AIStateMachine::StateTimerBase::mTimerStack; +AIStateMachine::StateTimerBase::TimeData AIStateMachine::StateTimerBase::TimeData::sRoot(""); +void AIStateMachine::StateTimer::TimeData::DumpTimer(std::ostringstream& msg, std::string prefix) +{ + F64 const tfactor = 1000 / calc_clock_frequency(); + msg << prefix << mName << " " << (mEnd - mStart)*tfactor << "ms" << std::endl; + prefix.push_back(' '); + std::vector::iterator it; + for (it = mChildren.begin(); it != mChildren.end(); ++it) + { + it->DumpTimer(msg, prefix); + } +} +#endif + AIStateMachine::state_type AIStateMachine::begin_loop(base_state_type base_state) { DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::begin_loop(" << state_str(base_state) << ") [" << (void*)this << "]"); diff --git a/indra/aistatemachine/aistatemachine.h b/indra/aistatemachine/aistatemachine.h index a9ac33d68..8c80cc01f 100644 --- a/indra/aistatemachine/aistatemachine.h +++ b/indra/aistatemachine/aistatemachine.h @@ -36,6 +36,7 @@ #include "aithreadsafe.h" #include +#include "lltimer.h" #include #include @@ -98,11 +99,140 @@ class AIEngine extern AIEngine gMainThreadEngine; extern AIEngine gStateMachineThreadEngine; +#ifndef STATE_MACHINE_PROFILING +#define STATE_MACHINE_PROFILING (LL_RELEASE_FOR_DOWNLOAD) +#endif + class AIStateMachine : public LLThreadSafeRefCount { public: typedef U32 state_type; //!< The type of run_state + // A simple timer class that will calculate time delta between ctor and GetTimerData call. + // Time data is stored as a nested TimeData object. + // If STATE_MACHINE_PROFILING is defined then a stack of all StateTimers from root is maintained for debug output. + class StateTimerBase + { + public: + class TimeData + { + friend class StateTimerBase; + public: + TimeData() : mStart(-1), mEnd(-1) {} + U64 GetDuration() { return mEnd - mStart; } + private: + U64 mStart, mEnd; + +#if !STATE_MACHINE_PROFILING + TimeData(const std::string& name) : mStart(get_clock_count()), mEnd(get_clock_count()) {} +#else + TimeData(const std::string& name) : mName(name), mStart(get_clock_count()), mEnd(get_clock_count()) {} + void DumpTimer(std::ostringstream& msg, std::string prefix); + std::vector mChildren; + std::string mName; + static TimeData sRoot; +#endif + }; + protected: +#if !STATE_MACHINE_PROFILING + StateTimerBase(const std::string& name) : mData(name) {} + ~StateTimerBase() {} + TimeData mData; + // Return a copy of the underlying timer data. + // This allows the data live beyond the scope of the state timer. + public: + const TimeData GetTimerData() + { + mData.mEnd = get_clock_count(); //set mEnd to current time, since GetTimerData() will always be called before the dtor, obv. + return mData; + } +#else + // Ctors/dtors are hidden. Only StateTimerRoot and StateTimer are permitted to access them. + StateTimerBase() : mData(NULL) {} + ~StateTimerBase() + { + // If mData is null then the timer was not registered due to being in the wrong thread or the root timer wasn't in the expected state. + if (!mData) + return; + mData->mEnd = get_clock_count(); + mTimerStack.pop_back(); + } + + // Also hide internals from everything except StateTimerRoot and StateTimer + bool AddAsRoot(const std::string& name) + { + + if (!is_main_thread()) + return true; //Ignoring this timer, but pretending it was added. + if (!mTimerStack.empty()) + return false; + TimeData::sRoot = TimeData(name); + mData = &TimeData::sRoot; + mData->mChildren.clear(); + mTimerStack.push_back(this); + return true; + } + bool AddAsChild(const std::string& name) + { + if (!is_main_thread()) + return true; //Ignoring this timer, but pretending it was added. + if (mTimerStack.empty()) + return false; + mTimerStack.back()->mData->mChildren.push_back(TimeData(name)); + mData = &mTimerStack.back()->mData->mChildren.back(); + mTimerStack.push_back(this); + return true; + } + + TimeData* mData; + static std::vector mTimerStack; + + public: + // Debug spew + static void DumpTimers(std::ostringstream& msg) + { + TimeData::sRoot.DumpTimer(msg, ""); + } + + // Return a copy of the underlying timer data. + // This allows the data live beyond the scope of the state timer. + const TimeData GetTimerData() const + { + if (mData) + { + TimeData ret = *mData; + ret.mEnd = get_clock_count(); //set mEnd to current time, since GetTimerData() will always be called before the dtor, obv. + return ret; + } + return TimeData(); + } +#endif + }; +public: +#if !STATE_MACHINE_PROFILING + typedef StateTimerBase StateTimerRoot; + typedef StateTimerBase StateTimer; +#else + class StateTimerRoot : public StateTimerBase + { //A StateTimerRoot can become a child if a root already exists. + public: + StateTimerRoot(const std::string& name) + { + if(!AddAsRoot(name)) + AddAsChild(name); + } + }; + class StateTimer : public StateTimerBase + { //A StateTimer can never become a root + public: + StateTimer(const std::string& name) + { + AddAsChild(name); + } + }; +#endif + + protected: // The type of event that causes multiplex() to be called. enum event_type { @@ -302,6 +432,9 @@ class AIStateMachine : public LLThreadSafeRefCount void add(U64 count) { mRuntime += count; } U64 getRuntime(void) const { return mRuntime; } + // For diagnostics. Every derived class must override this. + virtual const char* getName() const = 0; + protected: virtual void initialize_impl(void) = 0; virtual void multiplex_impl(state_type run_state) = 0; diff --git a/indra/aistatemachine/aistatemachinethread.h b/indra/aistatemachine/aistatemachinethread.h index d2ca65c8d..58b1e812a 100644 --- a/indra/aistatemachine/aistatemachinethread.h +++ b/indra/aistatemachine/aistatemachinethread.h @@ -232,6 +232,13 @@ class AIStateMachineThread : public AIStateMachineThreadBase { // Accessor. THREAD_IMPL& thread_impl(void) { return mThreadImpl; } + /*virtual*/ const char* getName() const + { +#define STRIZE(arg) #arg + return "AIStateMachineThread<"STRIZE(THREAD_IMPL)">"; +#undef STRIZE + } + protected: /*virtual*/ AIThreadImpl& impl(void) { return mThreadImpl; } }; diff --git a/indra/aistatemachine/aitimer.h b/indra/aistatemachine/aitimer.h index a8aeb8ca6..f3623c1d9 100644 --- a/indra/aistatemachine/aitimer.h +++ b/indra/aistatemachine/aitimer.h @@ -98,6 +98,8 @@ class AITimer : public AIStateMachine { */ F64 getInterval(void) const { return mInterval; } + /*virtual*/ const char* getName() const { return "AITimer"; } + protected: // Call finish() (or abort()), not delete. /*virtual*/ ~AITimer() { DoutEntering(dc::statemachine(mSMDebug), "~AITimer() [" << (void*)this << "]"); mFrameTimer.cancel(); } diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake index d2981fcd3..2f983b261 100644 --- a/indra/cmake/BuildVersion.cmake +++ b/indra/cmake/BuildVersion.cmake @@ -52,6 +52,29 @@ if (DARWIN) ) endif (DARWIN) +if (LINUX) + configure_file( + ${CMAKE_SOURCE_DIR}/newview/linux_tools/wrapper.sh.in + ${CMAKE_SOURCE_DIR}/newview/linux_tools/wrapper.sh + @ONLY + ) + configure_file( + ${CMAKE_SOURCE_DIR}/newview/linux_tools/handle_secondlifeprotocol.sh.in + ${CMAKE_SOURCE_DIR}/newview/linux_tools/handle_secondlifeprotocol.sh + @ONLY + ) + configure_file( + ${CMAKE_SOURCE_DIR}/newview/linux_tools/install.sh.in + ${CMAKE_SOURCE_DIR}/newview/linux_tools/install.sh + @ONLY + ) + configure_file( + ${CMAKE_SOURCE_DIR}/newview/linux_tools/refresh_desktop_app_entry.sh.in + ${CMAKE_SOURCE_DIR}/newview/linux_tools/refresh_desktop_app_entry.sh + @ONLY + ) +endif (LINUX) + # Compose the version. set(viewer_VERSION "${vMAJOR}.${vMINOR}.${vPATCH}.${vBUILD}") if (viewer_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$") diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp index cff862a20..5153debff 100644 --- a/indra/llappearance/llavatarjoint.cpp +++ b/indra/llappearance/llavatarjoint.cpp @@ -105,8 +105,9 @@ void LLAvatarJoint::setValid( BOOL valid, BOOL recursive ) for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); ++iter) { - LLAvatarJoint* joint = (LLAvatarJoint*)(*iter); - joint->setValid(valid, TRUE); + LLAvatarJoint* joint = dynamic_cast(*iter); + if (joint) + joint->setValid(valid, TRUE); } } @@ -138,8 +139,9 @@ void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive) for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); ++iter) { - LLAvatarJoint* joint = (LLAvatarJoint*)(*iter); - joint->setVisible(visible, recursive); + LLAvatarJoint* joint = dynamic_cast(*iter); + if(joint) + joint->setVisible(visible, recursive); } } } @@ -260,7 +262,7 @@ void LLAvatarJointCollisionVolume::renderCollision() updateWorldMatrix(); gGL.pushMatrix(); - gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] ); + gGL.multMatrix( mXform.getWorldMatrix() ); gGL.diffuseColor3f( 0.f, 0.f, 1.f ); diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp index 4a5cff1dc..5099e5481 100644 --- a/indra/llappearance/llavatarjointmesh.cpp +++ b/indra/llappearance/llavatarjointmesh.cpp @@ -366,8 +366,9 @@ void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin(); iter != current_joint->mChildren.end(); ++iter) { - LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); - setupJoint(child_joint); + LLAvatarJoint* child_joint = dynamic_cast(*iter); + if(child_joint) + setupJoint(child_joint); } } diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp index d588d687d..fd2a845c4 100644 --- a/indra/llappearance/llpolymesh.cpp +++ b/indra/llappearance/llpolymesh.cpp @@ -231,9 +231,9 @@ BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices ) mBaseCoords = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); mBaseNormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); mBaseBinormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); - mTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); - mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); - mWeights = (F32*) ll_aligned_malloc_16(numVertices*sizeof(F32)); + mTexCoords = (LLVector2*) ll_aligned_malloc_16((numVertices+numVertices%2)*sizeof(LLVector2)); + mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16((numVertices+numVertices%2)*sizeof(LLVector2)); + mWeights = (F32*) ll_aligned_malloc_16(((numVertices)*sizeof(F32)+0xF) & ~0xF); for (i = 0; i < numVertices; i++) { mBaseCoords[i].clear(); diff --git a/indra/llappearance/llpolymesh.h b/indra/llappearance/llpolymesh.h index 87f421f33..d006e389c 100644 --- a/indra/llappearance/llpolymesh.h +++ b/indra/llappearance/llpolymesh.h @@ -146,10 +146,10 @@ public: class LLJointRenderData { public: - LLJointRenderData(const LLMatrix4* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {} + LLJointRenderData(const LLMatrix4a* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {} ~LLJointRenderData(){} - const LLMatrix4* mWorldMatrix; + const LLMatrix4a* mWorldMatrix; LLSkinJoint* mSkinJoint; }; diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp index efdf5c577..3157cc965 100644 --- a/indra/llappearance/llpolyskeletaldistortion.cpp +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -154,13 +154,13 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin(); iter != joint->mChildren.end(); ++iter) { - LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); - if (child_joint->inheritScale()) - { - LLVector3 childDeformation = LLVector3(child_joint->getScale()); - childDeformation.scaleVec(bone_info->mScaleDeformation); - mJointScales[child_joint] = childDeformation; - } + LLAvatarJoint* child_joint = dynamic_cast(*iter); + if (child_joint && child_joint->inheritScale()) + { + LLVector3 childDeformation = LLVector3(child_joint->getScale()); + childDeformation.scaleVec(bone_info->mScaleDeformation); + mJointScales[child_joint] = childDeformation; + } } if (bone_info->mHasPositionDeformation) diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h index a9b843af6..0e2f6e05d 100644 --- a/indra/llappearance/llpolyskeletaldistortion.h +++ b/indra/llappearance/llpolyskeletaldistortion.h @@ -68,7 +68,16 @@ class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo { friend class LLPolySkeletalDistortion; public: - + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLPolySkeletalDistortionInfo(); /*virtual*/ ~LLPolySkeletalDistortionInfo() {}; @@ -77,12 +86,12 @@ public: protected: typedef std::vector bone_info_list_t; bone_info_list_t mBoneInfoList; -}; - +} LL_ALIGN_POSTFIX(16); //----------------------------------------------------------------------------- // LLPolySkeletalDeformation // A set of joint scale data for deforming the avatar mesh //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLPolySkeletalDistortion : public LLViewerVisualParam { public: diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 12960ac01..2b2a193d9 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -72,21 +72,11 @@ LLCharacter::~LLCharacter() delete param; } - U32 i ; - U32 size = sInstances.size() ; - for(i = 0 ; i < size ; i++) - { - if(sInstances[i] == this) - { - break ; - } - } + bool erased = vector_replace_with_last(sInstances,this); - llassert_always(i < size) ; + llassert_always(erased) ; llassert_always(sAllowInstancesChange) ; - sInstances[i] = sInstances[size - 1] ; - sInstances.pop_back() ; } diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index f2900d4a5..e8bf2b0c5 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -312,19 +312,15 @@ void LLJoint::setWorldPosition( const LLVector3& pos ) return; } - LLMatrix4 temp_matrix = getWorldMatrix(); - temp_matrix.mMatrix[VW][VX] = pos.mV[VX]; - temp_matrix.mMatrix[VW][VY] = pos.mV[VY]; - temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ]; + LLMatrix4a temp_matrix = getWorldMatrix(); + temp_matrix.setTranslate_affine(pos); - LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix(); - LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert(); + LLMatrix4a invParentWorldMatrix = mParent->getWorldMatrix(); + invParentWorldMatrix.invert(); - temp_matrix *= invParentWorldMatrix; + invParentWorldMatrix.mul(temp_matrix); - LLVector3 localPos( temp_matrix.mMatrix[VW][VX], - temp_matrix.mMatrix[VW][VY], - temp_matrix.mMatrix[VW][VZ] ); + LLVector3 localPos( invParentWorldMatrix.getRow().getF32ptr() ); setPosition( localPos ); } @@ -383,19 +379,19 @@ void LLJoint::setWorldRotation( const LLQuaternion& rot ) this->setRotation( rot ); return; } + + LLMatrix4a parentWorldMatrix = mParent->getWorldMatrix(); + LLQuaternion2 rota(rot); + LLMatrix4a temp_mat(rota); - LLMatrix4 temp_mat(rot); + LLMatrix4a invParentWorldMatrix = mParent->getWorldMatrix(); + invParentWorldMatrix.setTranslate_affine(LLVector3(0.f)); - LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix(); - parentWorldMatrix.mMatrix[VW][VX] = 0; - parentWorldMatrix.mMatrix[VW][VY] = 0; - parentWorldMatrix.mMatrix[VW][VZ] = 0; + invParentWorldMatrix.invert(); - LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert(); + invParentWorldMatrix.mul(temp_mat); - temp_mat *= invParentWorldMatrix; - - setRotation(LLQuaternion(temp_mat)); + setRotation(LLQuaternion(LLMatrix4(invParentWorldMatrix.getF32ptr()))); } @@ -425,7 +421,7 @@ void LLJoint::setScale( const LLVector3& scale ) //-------------------------------------------------------------------- // getWorldMatrix() //-------------------------------------------------------------------- -const LLMatrix4 &LLJoint::getWorldMatrix() +const LLMatrix4a &LLJoint::getWorldMatrix() { updateWorldMatrixParent(); diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index cb55e6ca7..f633fc32d 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -162,7 +162,7 @@ public: void setScale( const LLVector3& scale ); // get/set world matrix - const LLMatrix4 &getWorldMatrix(); + const LLMatrix4a &getWorldMatrix(); void setWorldMatrix( const LLMatrix4& mat ); void updateWorldMatrixChildren(); diff --git a/indra/llcharacter/lljointsolverrp3.cpp b/indra/llcharacter/lljointsolverrp3.cpp index 6599a76b1..8ce737afb 100644 --- a/indra/llcharacter/lljointsolverrp3.cpp +++ b/indra/llcharacter/lljointsolverrp3.cpp @@ -171,12 +171,14 @@ void LLJointSolverRP3::solve() //------------------------------------------------------------------------- // get the poleVector in world space //------------------------------------------------------------------------- - LLMatrix4 worldJointAParentMat; + LLVector3 poleVec = mPoleVector; if ( mJointA->getParent() ) { - worldJointAParentMat = mJointA->getParent()->getWorldMatrix(); + LLVector4a pole_veca; + pole_veca.load3(mPoleVector.mV); + mJointA->getParent()->getWorldMatrix().rotate(pole_veca,pole_veca); + poleVec.set(pole_veca.getF32ptr()); } - LLVector3 poleVec = rotate_vector( mPoleVector, worldJointAParentMat ); //------------------------------------------------------------------------- // compute the following: diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index bccc714f1..43675a4c8 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -286,40 +286,38 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) //------------------------------------------------------------------------- if ( mTrackAnkles ) { - LLVector4 dirLeft4 = mAnkleLeftJoint.getWorldMatrix().getFwdRow4(); - LLVector4 dirRight4 = mAnkleRightJoint.getWorldMatrix().getFwdRow4(); - LLVector3 dirLeft = vec4to3( dirLeft4 ); - LLVector3 dirRight = vec4to3( dirRight4 ); + const LLVector4a& dirLeft4 = mAnkleLeftJoint.getWorldMatrix().getRow(); + const LLVector4a& dirRight4 = mAnkleRightJoint.getWorldMatrix().getRow(); - LLVector3 up; - LLVector3 dir; - LLVector3 left; + LLVector4a up; + LLVector4a dir; + LLVector4a left; - up = mNormalLeft; - up.normVec(); + up.load3(mNormalLeft.mV); + up.normalize3fast(); if (mFlipFeet) { - up *= -1.0f; + up.negate(); } - dir = dirLeft; - dir.normVec(); - left = up % dir; - left.normVec(); - dir = left % up; - mRotationLeft = LLQuaternion( dir, left, up ); + dir = dirLeft4; + dir.normalize3fast(); + left.setCross3(up,dir); + left.normalize3fast(); + dir.setCross3(left,up); + mRotationLeft = LLQuaternion( LLVector3(dir.getF32ptr()), LLVector3(left.getF32ptr()), LLVector3(up.getF32ptr())); - up = mNormalRight; - up.normVec(); + up.load3(mNormalRight.mV); + up.normalize3fast(); if (mFlipFeet) { - up *= -1.0f; + up.negate(); } - dir = dirRight; - dir.normVec(); - left = up % dir; - left.normVec(); - dir = left % up; - mRotationRight = LLQuaternion( dir, left, up ); + dir = dirRight4; + dir.normalize3fast(); + left.setCross3(up,dir); + left.normalize3fast(); + dir.setCross3(left,up); + mRotationRight = LLQuaternion( LLVector3(dir.getF32ptr()), LLVector3(left.getF32ptr()), LLVector3(up.getF32ptr())); } mAnkleLeftJoint.setWorldRotation( mRotationLeft ); mAnkleRightJoint.setWorldRotation( mRotationRight ); diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 121268ad6..8bc8553e3 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -254,7 +254,6 @@ set(llcommon_HEADER_FILES metapropertyt.h reflective.h reflectivet.h - roles_constants.h stdenums.h stdtypes.h string_table.h diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index ec98bb911..5afd5dc61 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -239,14 +239,14 @@ inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_ty // //Singu note: This has been generalized to support a broader range of sequence containers template -inline typename T::iterator vector_replace_with_last(T& invec, typename T::iterator& iter) +inline typename T::iterator vector_replace_with_last(T& invec, typename T::iterator iter) { - typename T::iterator last = invec.end(); --last; + typename T::iterator last = invec.end(); if (iter == invec.end()) { return iter; } - else if (iter == last) + else if (iter == --last) { invec.pop_back(); return invec.end(); diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h index 16a4ee854..6cb15e68b 100644 --- a/indra/llcommon/stdenums.h +++ b/indra/llcommon/stdenums.h @@ -118,16 +118,6 @@ enum EAddPosition ADD_BOTTOM }; -enum LLGroupChange -{ - GC_PROPERTIES, - GC_MEMBER_DATA, - GC_ROLE_DATA, - GC_ROLE_MEMBER_DATA, - GC_TITLES, - GC_ALL -}; - //---------------------------------------------------------------------------- // DEPRECATED - create new, more specific files for shared enums/constants //---------------------------------------------------------------------------- diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index deb25c74c..66a0f0278 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -178,7 +178,7 @@ BOOL LLInventoryObject::importLegacyStream(std::istream& input_stream) while(input_stream.good()) { input_stream.getline(buffer, MAX_STRING); - sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */ + if (sscanf(buffer, " %254s %254s", keyword, valuestr) < 1) continue; if(0 == strcmp("{",keyword)) { continue; @@ -610,7 +610,7 @@ BOOL LLInventoryItem::importFile(LLFILE* fp) buffer[0] = '\0'; } - sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */ + if (sscanf(buffer, " %254s %254s", keyword, valuestr) < 1) continue; if(0 == strcmp("{",keyword)) { continue; @@ -813,10 +813,10 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream) while(success && input_stream.good()) { input_stream.getline(buffer, MAX_STRING); - sscanf( /* Flawfinder: ignore */ + if (sscanf( buffer, " %254s %254s", - keyword, valuestr); + keyword, valuestr) < 1) continue; if(0 == strcmp("{",keyword)) { continue; @@ -1489,10 +1489,10 @@ BOOL LLInventoryCategory::importFile(LLFILE* fp) buffer[0] = '\0'; } - sscanf( /* Flawfinder: ignore */ + if (sscanf( buffer, " %254s %254s", - keyword, valuestr); + keyword, valuestr) < 1) continue; if(0 == strcmp("{",keyword)) { continue; @@ -1568,10 +1568,10 @@ BOOL LLInventoryCategory::importLegacyStream(std::istream& input_stream) while(input_stream.good()) { input_stream.getline(buffer, MAX_STRING); - sscanf( /* Flawfinder: ignore */ + if (sscanf( buffer, " %254s %254s", - keyword, valuestr); + keyword, valuestr) < 1) continue; if(0 == strcmp("{",keyword)) { continue; diff --git a/indra/llmath/camera.h b/indra/llmath/camera.h index ce41f8781..c8fa4c3af 100644 --- a/indra/llmath/camera.h +++ b/indra/llmath/camera.h @@ -2,31 +2,25 @@ * @file camera.h * @brief Legacy wrapper header. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/coordframe.h b/indra/llmath/coordframe.h index b8a1c14ab..d078e4a73 100644 --- a/indra/llmath/coordframe.h +++ b/indra/llmath/coordframe.h @@ -2,31 +2,25 @@ * @file coordframe.h * @brief Legacy wrapper header. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/llbbox.cpp b/indra/llmath/llbbox.cpp index 0aea7190b..9fd21514c 100644 --- a/indra/llmath/llbbox.cpp +++ b/indra/llmath/llbbox.cpp @@ -2,36 +2,28 @@ * @file llbbox.cpp * @brief General purpose bounding box class (Not axis aligned) * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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$ - * */ - #include "linden_common.h" // self include diff --git a/indra/llmath/llbbox.h b/indra/llmath/llbbox.h index 685704ccf..ede5e3142 100644 --- a/indra/llmath/llbbox.h +++ b/indra/llmath/llbbox.h @@ -2,36 +2,28 @@ * @file llbbox.h * @brief General purpose bounding box class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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$ - * */ - #ifndef LL_BBOX_H #define LL_BBOX_H diff --git a/indra/llmath/llbboxlocal.cpp b/indra/llmath/llbboxlocal.cpp index 3d0dbb076..2582003b3 100644 --- a/indra/llmath/llbboxlocal.cpp +++ b/indra/llmath/llbboxlocal.cpp @@ -2,31 +2,25 @@ * @file llbboxlocal.cpp * @brief General purpose bounding box class (Not axis aligned). * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ diff --git a/indra/llmath/llbboxlocal.h b/indra/llmath/llbboxlocal.h index 0d1e5a3ae..6ad2a2785 100644 --- a/indra/llmath/llbboxlocal.h +++ b/indra/llmath/llbboxlocal.h @@ -2,31 +2,25 @@ * @file llbboxlocal.h * @brief General purpose bounding box class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index 55cc9db53..721503443 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -2,31 +2,25 @@ * @file llcamera.cpp * @brief Implementation of the LLCamera class. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ @@ -189,8 +183,30 @@ static const LLVector4a sFrustumScaler[] = LLVector4a( 1, 1, 1) // 8 entries }; -S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) +bool LLCamera::isChanged() { + bool changed = false; + for (U32 i = 0; i < mPlaneCount; i++) +{ + U8 mask = mPlaneMask[i]; + if (mask != 0xff && !changed) + { + changed = !mAgentPlanes[i].equal(mLastAgentPlanes[i]); + } + mLastAgentPlanes[i].set(mAgentPlanes[i]); + } + + return changed; +} + +S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius, const LLPlane* planes) +{ + if(!planes) + { + //use agent space + planes = mAgentPlanes; + } + U8 mask = 0; bool result = false; LLVector4a rscale, maxp, minp; @@ -201,7 +217,7 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) mask = mPlaneMask[i]; if (mask < PLANE_MASK_NUM) { - const LLPlane& p(mAgentPlanes[i]); + const LLPlane& p(planes[i]); p.getAt<3>(d); rscale.setMul(radius, sFrustumScaler[mask]); minp.setSub(center, rscale); @@ -222,9 +238,21 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) return result?1:2; } - -S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius) +//exactly same as the function AABBInFrustum(...) +//except uses mRegionPlanes instead of mAgentPlanes. +S32 LLCamera::AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius) { + return AABBInFrustum(center, radius, mRegionPlanes); +} + +S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes) +{ + if(!planes) + { + //use agent space + planes = mAgentPlanes; + } + U8 mask = 0; bool result = false; LLVector4a rscale, maxp, minp; @@ -235,7 +263,7 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& mask = mPlaneMask[i]; if ((i != 5) && (mask < PLANE_MASK_NUM)) { - const LLPlane& p(mAgentPlanes[i]); + const LLPlane& p(planes[i]); p.getAt<3>(d); rscale.setMul(radius, sFrustumScaler[mask]); minp.setSub(center, rscale); @@ -256,6 +284,13 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& return result?1:2; } +//exactly same as the function AABBInFrustumNoFarClip(...) +//except uses mRegionPlanes instead of mAgentPlanes. +S32 LLCamera::AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius) +{ + return AABBInFrustumNoFarClip(center, radius, mRegionPlanes); +} + int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius) { LLVector3 dist = sphere_center-mFrustCenter; @@ -592,6 +627,47 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) } } +//calculate regional planes from mAgentPlanes. +//vector "shift" is the vector of the region origin in the agent space. +void LLCamera::calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance) +{ + F32 far_w; + { + LLVector3 p = getOrigin(); + LLVector3 n(mAgentPlanes[5][0], mAgentPlanes[5][1], mAgentPlanes[5][2]); + F32 dd = n * p; + if(dd + mAgentPlanes[5][3] < 0) //signed distance + { + far_w = -far_clip_distance - dd; + } + else + { + far_w = far_clip_distance - dd; + } + far_w += n * shift; + } + + F32 d; + LLVector3 n; + for(S32 i = 0 ; i < 7; i++) + { + if (mPlaneMask[i] != 0xff) + { + n.setVec(mAgentPlanes[i][0], mAgentPlanes[i][1], mAgentPlanes[i][2]); + + if(i != 5) + { + d = mAgentPlanes[i][3] + n * shift; + } + else + { + d = far_w; + } + mRegionPlanes[i].setVec(n, d); + } + } +} + void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom) { LLVector3 a, b, c; diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 8a1e32db7..aed99de28 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -2,31 +2,25 @@ * @file llcamera.h * @brief Header file for the LLCamera class. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ @@ -55,7 +49,7 @@ const F32 MIN_FAR_PLANE = 0.2f; // Min/Max FOV values for square views. Call getMin/MaxView to get extremes based on current aspect ratio. static const F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD; -static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD; +static const F32 MAX_FIELD_OF_VIEW = 320.f * DEG_TO_RAD; // An LLCamera is an LLCoorFrame with a view frustum. // This means that it has several methods for moving it around @@ -128,6 +122,8 @@ public: private: LL_ALIGN_16(LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + LL_ALIGN_16(LLPlane mRegionPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in a local region space, derived from mAgentPlanes + LL_ALIGN_16(LLPlane mLastAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]); U8 mPlaneMask[PLANE_MASK_NUM]; // 8 for alignment F32 mView; // angle between top and bottom frustum planes in radians. @@ -156,6 +152,7 @@ public: LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane); virtual ~LLCamera(); + bool isChanged(); //check if mAgentPlanes changed since last frame. void setUserClipPlane(const LLPlane& plane); void disableUserClipPlane(); @@ -197,6 +194,7 @@ public: // Return number of bytes copied. size_t readFrustumFromBuffer(const char *buffer); void calcAgentFrustumPlanes(LLVector3* frust); + void calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance); //calculate regional planes from mAgentPlanes. void ignoreAgentFrustumPlane(S32 idx); // Returns 1 if partly in, 2 if fully in. @@ -205,8 +203,10 @@ public: S32 sphereInFrustum(const LLVector3 ¢er, const F32 radius) const; S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); } S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); } - S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius); - S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius); + S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL); + S32 AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius); + S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL); + S32 AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius); //does a quick 'n dirty sphere-sphere check S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius); diff --git a/indra/llmath/llcoordframe.cpp b/indra/llmath/llcoordframe.cpp index 673a8f2b0..962f593e1 100644 --- a/indra/llmath/llcoordframe.cpp +++ b/indra/llmath/llcoordframe.cpp @@ -2,31 +2,25 @@ * @file llcoordframe.cpp * @brief LLCoordFrame class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/llcoordframe.h b/indra/llmath/llcoordframe.h index 89b5d8bef..81e17030a 100644 --- a/indra/llmath/llcoordframe.h +++ b/indra/llmath/llcoordframe.h @@ -2,31 +2,25 @@ * @file llcoordframe.h * @brief LLCoordFrame class header file. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/llinterp.h b/indra/llmath/llinterp.h index 485c7a3a6..12956ce28 100644 --- a/indra/llmath/llinterp.h +++ b/indra/llmath/llinterp.h @@ -1,31 +1,25 @@ /** * @file llinterp.h * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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. + * + * 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$ */ diff --git a/indra/llmath/llline.cpp b/indra/llmath/llline.cpp index b19857320..a503bfb4a 100644 --- a/indra/llmath/llline.cpp +++ b/indra/llmath/llline.cpp @@ -3,31 +3,25 @@ * @author Andrew Meadows * @brief Simple line class that can compute nearest approach between two lines * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&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$ */ diff --git a/indra/llmath/llline.h b/indra/llmath/llline.h index 9ab41b162..2d21d3b93 100644 --- a/indra/llmath/llline.h +++ b/indra/llmath/llline.h @@ -4,31 +4,25 @@ * @author Andrew Meadows * @brief Simple line for computing nearest approach between two infinite lines * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&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$ */ diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index 274663643..998b78750 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -30,6 +30,7 @@ #include #include #include +#include #include "lldefs.h" //#include "llstl.h" // *TODO: Remove when LLString is gone //#include "llstring.h" // *TODO: Remove when LLString is gone @@ -72,15 +73,21 @@ const F32 F_E = 2.71828182845904523536f; const F32 F_SQRT2 = 1.4142135623730950488016887242097f; const F32 F_SQRT3 = 1.73205080756888288657986402541f; const F32 OO_SQRT2 = 0.7071067811865475244008443621049f; +const F32 OO_SQRT3 = 0.577350269189625764509f; const F32 DEG_TO_RAD = 0.017453292519943295769236907684886f; const F32 RAD_TO_DEG = 57.295779513082320876798154814105f; const F32 F_APPROXIMATELY_ZERO = 0.00001f; +const F32 F_LN10 = 2.3025850929940456840179914546844f; +const F32 OO_LN10 = 0.43429448190325182765112891891661; const F32 F_LN2 = 0.69314718056f; const F32 OO_LN2 = 1.4426950408889634073599246810019f; const F32 F_ALMOST_ZERO = 0.0001f; const F32 F_ALMOST_ONE = 1.0f - F_ALMOST_ZERO; +const F32 GIMBAL_THRESHOLD = 0.000436f; // sets the gimballock threshold 0.025 away from +/-90 degrees +// formula: GIMBAL_THRESHOLD = sin(DEG_TO_RAD * gimbal_threshold_angle); + // BUG: Eliminate in favor of F_APPROXIMATELY_ZERO above? const F32 FP_MAG_THRESHOLD = 0.0000001f; @@ -111,6 +118,12 @@ inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < // WARNING: Infinity is comparable with F32_MAX and negative // infinity is comparable with F32_MIN +// handles negative and positive zeros +inline bool is_zero(F32 x) +{ + return (*(U32*)(&x) & 0x7fffffff) == 0; +} + inline bool is_approx_equal(F32 x, F32 y) { const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02; diff --git a/indra/llmath/llmatrix3a.cpp b/indra/llmath/llmatrix3a.cpp index ad008e9d3..ab077abcb 100644 --- a/indra/llmath/llmatrix3a.cpp +++ b/indra/llmath/llmatrix3a.cpp @@ -24,7 +24,6 @@ * $/LicenseInfo$ */ -#include "sys.h" #include "llmath.h" static LL_ALIGN_16(const F32 M_IDENT_3A[12]) = diff --git a/indra/llmath/llmatrix3a.h b/indra/llmath/llmatrix3a.h index 9916cfd2d..6d896613c 100644 --- a/indra/llmath/llmatrix3a.h +++ b/indra/llmath/llmatrix3a.h @@ -40,6 +40,7 @@ // LLMatrix3a is the base class for LLRotation, which should be used instead any time you're dealing with a // rotation matrix. +LL_ALIGN_PREFIX(16) class LLMatrix3a { public: @@ -113,8 +114,9 @@ protected: LL_ALIGN_16(LLVector4a mColumns[3]); -}; +} LL_ALIGN_POSTFIX(16); +LL_ALIGN_PREFIX(16) class LLRotation : public LLMatrix3a { public: @@ -123,6 +125,6 @@ public: // Returns true if this rotation is orthonormal with det ~= 1 inline bool isOkRotation() const; -}; +} LL_ALIGN_POSTFIX(16); #endif diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 94e5e54af..0af8105ec 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -31,10 +31,72 @@ #include "m4math.h" #include "m3math.h" +LL_ALIGN_PREFIX(16) class LLMatrix4a { -public: +private: LL_ALIGN_16(LLVector4a mMatrix[4]); +public: + enum + { + ROW_FWD = 0, + ROW_LEFT, + ROW_UP, + ROW_TRANS + }; + + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + + LLMatrix4a() + {} + LLMatrix4a(const LLQuad& q1,const LLQuad& q2,const LLQuad& q3,const LLQuad& q4) + { + mMatrix[0] = q1; + mMatrix[1] = q2; + mMatrix[2] = q3; + mMatrix[3] = q4; + } + LLMatrix4a(const LLQuaternion2& quat) + { + const LLVector4a& xyzw = quat.getVector4a(); + LLVector4a nyxwz = _mm_shuffle_ps(xyzw, xyzw, _MM_SHUFFLE(2,3,0,1)); + nyxwz.negate(); + + const LLVector4a xnyynx = _mm_unpacklo_ps(xyzw,nyxwz); + const LLVector4a znwwnz = _mm_unpackhi_ps(xyzw,nyxwz); + + LLMatrix4a mata; + mata.setRow<0>(_mm_shuffle_ps(xyzw, xnyynx, _MM_SHUFFLE(0,1,2,3))); + mata.setRow<1>(_mm_shuffle_ps(znwwnz, xyzw, _MM_SHUFFLE(1,0,2,3))); + mata.setRow<2>(_mm_shuffle_ps(xnyynx, xyzw, _MM_SHUFFLE(2,3,3,2))); + mata.setRow<3>(_mm_shuffle_ps(xnyynx, znwwnz, _MM_SHUFFLE(2,3,1,3))); + + LLMatrix4a matb; + matb.setRow<0>(_mm_shuffle_ps(xyzw, xnyynx, _MM_SHUFFLE(3,1,2,3))); + matb.setRow<1>(_mm_shuffle_ps(znwwnz, xnyynx, _MM_SHUFFLE(1,0,2,3))); + matb.setRow<2>(_mm_shuffle_ps(xnyynx, znwwnz, _MM_SHUFFLE(3,2,3,2))); + matb.setRow<3>(xyzw); + + setMul(matb,mata); + } + + inline F32* getF32ptr() + { + return mMatrix[0].getF32ptr(); + } + + inline const F32* getF32ptr() const + { + return mMatrix[0].getF32ptr(); + } inline void clear() { @@ -44,13 +106,21 @@ public: mMatrix[3].clear(); } + inline void setIdentity() + { + static __m128 ones = _mm_set_ps(1.f,0.f,0.f,1.f); + mMatrix[0] = _mm_movelh_ps(ones,_mm_setzero_ps()); + mMatrix[1] = _mm_movehl_ps(_mm_setzero_ps(),ones); + mMatrix[2] = _mm_movelh_ps(_mm_setzero_ps(),ones); + mMatrix[3] = _mm_movehl_ps(ones,_mm_setzero_ps()); + } + inline void loadu(const LLMatrix4& src) { - mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]); - mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]); - mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]); - mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]); - + mMatrix[0].loadua(src.mMatrix[0]); + mMatrix[1].loadua(src.mMatrix[1]); + mMatrix[2].loadua(src.mMatrix[2]); + mMatrix[3].loadua(src.mMatrix[3]); } inline void loadu(const LLMatrix3& src) @@ -61,6 +131,14 @@ public: mMatrix[3].set(0,0,0,1.f); } + inline void loadu(const F32* src) + { + mMatrix[0].loadua(src+0); + mMatrix[1].loadua(src+4); + mMatrix[2].loadua(src+8); + mMatrix[3].loadua(src+12); + } + inline void add(const LLMatrix4a& rhs) { mMatrix[0].add(rhs.mMatrix[0]); @@ -69,6 +147,75 @@ public: mMatrix[3].add(rhs.mMatrix[3]); } + inline void mul(const LLMatrix4a& rhs) + { + //Not using rotate4 to avoid extra copy of *this. + LLVector4a x0,y0,z0,w0; + LLVector4a x1,y1,z1,w1; + LLVector4a x2,y2,z2,w2; + LLVector4a x3,y3,z3,w3; + + //16 shuffles + x0.splat<0>(rhs.mMatrix[0]); + x1.splat<0>(rhs.mMatrix[1]); + x2.splat<0>(rhs.mMatrix[2]); + x3.splat<0>(rhs.mMatrix[3]); + + y0.splat<1>(rhs.mMatrix[0]); + y1.splat<1>(rhs.mMatrix[1]); + y2.splat<1>(rhs.mMatrix[2]); + y3.splat<1>(rhs.mMatrix[3]); + + z0.splat<2>(rhs.mMatrix[0]); + z1.splat<2>(rhs.mMatrix[1]); + z2.splat<2>(rhs.mMatrix[2]); + z3.splat<2>(rhs.mMatrix[3]); + + w0.splat<3>(rhs.mMatrix[0]); + w1.splat<3>(rhs.mMatrix[1]); + w2.splat<3>(rhs.mMatrix[2]); + w3.splat<3>(rhs.mMatrix[3]); + + //16 muls + x0.mul(mMatrix[0]); + x1.mul(mMatrix[0]); + x2.mul(mMatrix[0]); + x3.mul(mMatrix[0]); + + y0.mul(mMatrix[1]); + y1.mul(mMatrix[1]); + y2.mul(mMatrix[1]); + y3.mul(mMatrix[1]); + + z0.mul(mMatrix[2]); + z1.mul(mMatrix[2]); + z2.mul(mMatrix[2]); + z3.mul(mMatrix[2]); + + w0.mul(mMatrix[3]); + w1.mul(mMatrix[3]); + w2.mul(mMatrix[3]); + w3.mul(mMatrix[3]); + + //12 adds + x0.add(y0); + z0.add(w0); + + x1.add(y1); + z1.add(w1); + + x2.add(y2); + z2.add(w2); + + x3.add(y3); + z3.add(w3); + + mMatrix[0].setAdd(x0,z0); + mMatrix[1].setAdd(x1,z1); + mMatrix[2].setAdd(x2,z2); + mMatrix[3].setAdd(x3,z3); + } + inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2) { mMatrix[0] = r0; @@ -76,6 +223,44 @@ public: mMatrix[2] = r2; } + template + inline void setRow(const LLVector4a& row) + { + mMatrix[N] = row; + } + + template + inline const LLVector4a& getRow() const + { + return mMatrix[N]; + } + + template + inline LLVector4a& getRow() + { + return mMatrix[N]; + } + + template + inline void setColumn(const LLVector4a& col) + { + mMatrix[0].copyComponent(col.getScalarAt<0>()); + mMatrix[1].copyComponent(col.getScalarAt<1>()); + mMatrix[2].copyComponent(col.getScalarAt<2>()); + mMatrix[3].copyComponent(col.getScalarAt<3>()); + } + + template + inline LLVector4a getColumn() + { + LLVector4a v; + v.copyComponent<0>(mMatrix[0].getScalarAt()); + v.copyComponent<1>(mMatrix[1].getScalarAt()); + v.copyComponent<2>(mMatrix[2].getScalarAt()); + v.copyComponent<3>(mMatrix[3].getScalarAt()); + return v; + } + inline void setMul(const LLMatrix4a& m, const F32 s) { mMatrix[0].setMul(m.mMatrix[0], s); @@ -84,6 +269,14 @@ public: mMatrix[3].setMul(m.mMatrix[3], s); } + inline void setMul(const LLMatrix4a& m0, const LLMatrix4a& m1) + { + m0.rotate4(m1.mMatrix[0],mMatrix[0]); + m0.rotate4(m1.mMatrix[1],mMatrix[1]); + m0.rotate4(m1.mMatrix[2],mMatrix[2]); + m0.rotate4(m1.mMatrix[3],mMatrix[3]); + } + inline void setLerp(const LLMatrix4a& a, const LLMatrix4a& b, F32 w) { LLVector4a d0,d1,d2,d3; @@ -107,13 +300,14 @@ public: //Singu Note: Don't mess with this. It's intentionally different from LL's. // Note how res isn't manipulated until the very end. + //Fast(er). Treats v[VW] as 0.f inline void rotate(const LLVector4a& v, LLVector4a& res) const { LLVector4a x,y,z; - x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); - y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); - z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); + x.splat<0>(v); + y.splat<1>(v); + z.splat<2>(v); x.mul(mMatrix[0]); y.mul(mMatrix[1]); @@ -123,14 +317,15 @@ public: res.setAdd(x,z); } + //Proper. v[VW] as v[VW] inline void rotate4(const LLVector4a& v, LLVector4a& res) const { LLVector4a x,y,z,w; - x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); - y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); - z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); - w = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3)); + x.splat<0>(v); + y.splat<1>(v); + z.splat<2>(v); + w.splat<3>(v); x.mul(mMatrix[0]); y.mul(mMatrix[1]); @@ -142,14 +337,15 @@ public: res.setAdd(x,z); } + //Fast(er). Treats v[VW] as 1.f inline void affineTransform(const LLVector4a& v, LLVector4a& res) const { LLVector4a x,y,z; - x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); - y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); - z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); - + x.splat<0>(v); + y.splat<1>(v); + z.splat<2>(v); + x.mul(mMatrix[0]); y.mul(mMatrix[1]); z.mul(mMatrix[2]); @@ -158,6 +354,348 @@ public: z.add(mMatrix[3]); res.setAdd(x,z); } -}; + + inline void perspectiveTransform(const LLVector4a& v, LLVector4a& res) const + { + LLVector4a x,y,z,s,t,p,q; + + x.splat<0>(v); + y.splat<1>(v); + z.splat<2>(v); + + s.splat<3>(mMatrix[0]); + t.splat<3>(mMatrix[1]); + p.splat<3>(mMatrix[2]); + q.splat<3>(mMatrix[3]); + + s.mul(x); + t.mul(y); + p.mul(z); + q.add(s); + t.add(p); + q.add(t); + + x.mul(mMatrix[0]); + y.mul(mMatrix[1]); + z.mul(mMatrix[2]); + + x.add(y); + z.add(mMatrix[3]); + res.setAdd(x,z); + res.div(q); + } + + inline void transpose() + { + __m128 q1 = _mm_unpackhi_ps(mMatrix[0],mMatrix[1]); + __m128 q2 = _mm_unpacklo_ps(mMatrix[0],mMatrix[1]); + __m128 q3 = _mm_unpacklo_ps(mMatrix[2],mMatrix[3]); + __m128 q4 = _mm_unpackhi_ps(mMatrix[2],mMatrix[3]); + + mMatrix[0] = _mm_movelh_ps(q2,q3); + mMatrix[1] = _mm_movehl_ps(q3,q2); + mMatrix[2] = _mm_movelh_ps(q1,q4); + mMatrix[3] = _mm_movehl_ps(q4,q1); + } + +// Following procedure adapted from: +// http://software.intel.com/en-us/articles/optimized-matrix-library-for-use-with-the-intel-pentiumr-4-processors-sse2-instructions/ +// +// License/Copyright Statement: +// +// Copyright (c) 2001 Intel Corporation. +// +// Permition is granted to use, copy, distribute and prepare derivative works +// of this library for any purpose and without fee, provided, that the above +// copyright notice and this statement appear in all copies. +// Intel makes no representations about the suitability of this library for +// any purpose, and specifically disclaims all warranties. +// See LEGAL-intel_matrixlib.TXT for all the legal information. + inline float invert() + { + LL_ALIGN_16(const unsigned int Sign_PNNP[4]) = { 0x00000000, 0x80000000, 0x80000000, 0x00000000 }; + + // The inverse is calculated using "Divide and Conquer" technique. The + // original matrix is divide into four 2x2 sub-matrices. Since each + // register holds four matrix element, the smaller matrices are + // represented as a registers. Hence we get a better locality of the + // calculations. + + LLVector4a A = _mm_movelh_ps(mMatrix[0], mMatrix[1]), // the four sub-matrices + B = _mm_movehl_ps(mMatrix[1], mMatrix[0]), + C = _mm_movelh_ps(mMatrix[2], mMatrix[3]), + D = _mm_movehl_ps(mMatrix[3], mMatrix[2]); + LLVector4a iA, iB, iC, iD, // partial inverse of the sub-matrices + DC, AB; + LLSimdScalar dA, dB, dC, dD; // determinant of the sub-matrices + LLSimdScalar det, d, d1, d2; + LLVector4a rd; + + // AB = A# * B + AB.setMul(_mm_shuffle_ps(A,A,0x0F), B); + AB.sub(_mm_mul_ps(_mm_shuffle_ps(A,A,0xA5), _mm_shuffle_ps(B,B,0x4E))); + // DC = D# * C + DC.setMul(_mm_shuffle_ps(D,D,0x0F), C); + DC.sub(_mm_mul_ps(_mm_shuffle_ps(D,D,0xA5), _mm_shuffle_ps(C,C,0x4E))); + + // dA = |A| + dA = _mm_mul_ps(_mm_shuffle_ps(A, A, 0x5F),A); + dA -= _mm_movehl_ps(dA,dA); + // dB = |B| + dB = _mm_mul_ps(_mm_shuffle_ps(B, B, 0x5F),B); + dB -= _mm_movehl_ps(dB,dB); + + // dC = |C| + dC = _mm_mul_ps(_mm_shuffle_ps(C, C, 0x5F),C); + dC -= _mm_movehl_ps(dC,dC); + // dD = |D| + dD = _mm_mul_ps(_mm_shuffle_ps(D, D, 0x5F),D); + dD -= _mm_movehl_ps(dD,dD); + + // d = trace(AB*DC) = trace(A#*B*D#*C) + d = _mm_mul_ps(_mm_shuffle_ps(DC,DC,0xD8),AB); + + // iD = C*A#*B + iD.setMul(_mm_shuffle_ps(C,C,0xA0), _mm_movelh_ps(AB,AB)); + iD.add(_mm_mul_ps(_mm_shuffle_ps(C,C,0xF5), _mm_movehl_ps(AB,AB))); + // iA = B*D#*C + iA.setMul(_mm_shuffle_ps(B,B,0xA0), _mm_movelh_ps(DC,DC)); + iA.add(_mm_mul_ps(_mm_shuffle_ps(B,B,0xF5), _mm_movehl_ps(DC,DC))); + + // d = trace(AB*DC) = trace(A#*B*D#*C) [continue] + d = _mm_add_ps(d, _mm_movehl_ps(d, d)); + d += _mm_shuffle_ps(d, d, 1); + d1 = dA*dD; + d2 = dB*dC; + + // iD = D*|A| - C*A#*B + iD.setSub(_mm_mul_ps(D,_mm_shuffle_ps(dA,dA,0)), iD); + + // iA = A*|D| - B*D#*C; + iA.setSub(_mm_mul_ps(A,_mm_shuffle_ps(dD,dD,0)), iA); + + // det = |A|*|D| + |B|*|C| - trace(A#*B*D#*C) + det = d1+d2-d; + + __m128 is_zero_mask = _mm_cmpeq_ps(det,_mm_setzero_ps()); + rd = _mm_div_ss(_mm_set_ss(1.f),_mm_or_ps(_mm_andnot_ps(is_zero_mask, det), _mm_and_ps(is_zero_mask, _mm_set_ss(1.f)))); +#ifdef ZERO_SINGULAR + rd = _mm_and_ps(_mm_cmpneq_ss(det,_mm_setzero_ps()), rd); +#endif + + // iB = D * (A#B)# = D*B#*A + iB.setMul(D, _mm_shuffle_ps(AB,AB,0x33)); + iB.sub(_mm_mul_ps(_mm_shuffle_ps(D,D,0xB1), _mm_shuffle_ps(AB,AB,0x66))); + // iC = A * (D#C)# = A*C#*D + iC.setMul(A, _mm_shuffle_ps(DC,DC,0x33)); + iC.sub(_mm_mul_ps(_mm_shuffle_ps(A,A,0xB1), _mm_shuffle_ps(DC,DC,0x66))); + + rd = _mm_shuffle_ps(rd,rd,0); + rd = _mm_xor_ps(rd, _mm_load_ps((const float*)Sign_PNNP)); + + // iB = C*|B| - D*B#*A + iB.setSub(_mm_mul_ps(C,_mm_shuffle_ps(dB,dB,0)), iB); + + // iC = B*|C| - A*C#*D; + iC.setSub(_mm_mul_ps(B,_mm_shuffle_ps(dC,dC,0)), iC); + + + // iX = iX / det + iA.mul(rd); + iB.mul(rd); + iC.mul(rd); + iD.mul(rd); + + mMatrix[0] = _mm_shuffle_ps(iA,iB,0x77); + mMatrix[1] = _mm_shuffle_ps(iA,iB,0x22); + mMatrix[2] = _mm_shuffle_ps(iC,iD,0x77); + mMatrix[3] = _mm_shuffle_ps(iC,iD,0x22); + + F32 ret; + _mm_store_ss(&ret,det); + return ret; + } + + //=============Affine transformation matrix only========================= + + //Multiply matrix with a pure translation matrix. + inline void applyTranslation_affine(const F32& x, const F32& y, const F32& z) + { + const LLVector4a xyz0(x,y,z,0); //load + LLVector4a xxxx; + xxxx.splat<0>(xyz0); + LLVector4a yyyy; + yyyy.splat<1>(xyz0); + LLVector4a zzzz; + zzzz.splat<2>(xyz0); + + LLVector4a sum1; + LLVector4a sum2; + LLVector4a sum3; + + sum1.setMul(xxxx,mMatrix[0]); + sum2.setMul(yyyy,mMatrix[1]); + sum3.setMul(zzzz,mMatrix[2]); + + mMatrix[3].add(sum1); + mMatrix[3].add(sum2); + mMatrix[3].add(sum3); + } + + //Multiply matrix with a pure translation matrix. + inline void applyTranslation_affine(const LLVector3& trans) + { + applyTranslation_affine(trans.mV[VX],trans.mV[VY],trans.mV[VZ]); + } + + //Multiply matrix with a pure scale matrix. + inline void applyScale_affine(const F32& x, const F32& y, const F32& z) + { + const LLVector4a xyz0(x,y,z,0); //load + LLVector4a xxxx; + xxxx.splat<0>(xyz0); + LLVector4a yyyy; + yyyy.splat<1>(xyz0); + LLVector4a zzzz; + zzzz.splat<2>(xyz0); + + mMatrix[0].mul(xxxx); + mMatrix[1].mul(yyyy); + mMatrix[2].mul(zzzz); + } + + //Multiply matrix with a pure scale matrix. + inline void applyScale_affine(const LLVector3& scale) + { + applyScale_affine(scale.mV[VX],scale.mV[VY],scale.mV[VZ]); + } + + //Multiply matrix with a pure scale matrix. + inline void applyScale_affine(const F32& s) + { + const LLVector4a scale(s); //load + mMatrix[0].mul(scale); + mMatrix[1].mul(scale); + mMatrix[2].mul(scale); + } + + //Direct addition to row3. + inline void translate_affine(const LLVector3& trans) + { + LLVector4a translation; + translation.load3(trans.mV); + mMatrix[3].add(translation); + } + + //Direct assignment of row3. + inline void setTranslate_affine(const LLVector3& trans) + { + static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[3*4]); + + LLVector4a translation; + translation.load3(trans.mV); + + mMatrix[3].setSelectWithMask(mask,mMatrix[3],translation); + } + + inline void mul_affine(const LLMatrix4a& rhs) + { + LLVector4a x0,y0,z0; + LLVector4a x1,y1,z1; + LLVector4a x2,y2,z2; + LLVector4a x3,y3,z3; + + //12 shuffles + x0.splat<0>(rhs.mMatrix[0]); + x1.splat<0>(rhs.mMatrix[1]); + x2.splat<0>(rhs.mMatrix[2]); + x3.splat<0>(rhs.mMatrix[3]); + + y0.splat<1>(rhs.mMatrix[0]); + y1.splat<1>(rhs.mMatrix[1]); + y2.splat<1>(rhs.mMatrix[2]); + y3.splat<1>(rhs.mMatrix[3]); + + z0.splat<2>(rhs.mMatrix[0]); + z1.splat<2>(rhs.mMatrix[1]); + z2.splat<2>(rhs.mMatrix[2]); + z3.splat<2>(rhs.mMatrix[3]); + + //12 muls + x0.mul(mMatrix[0]); + x1.mul(mMatrix[0]); + x2.mul(mMatrix[0]); + x3.mul(mMatrix[0]); + + y0.mul(mMatrix[1]); + y1.mul(mMatrix[1]); + y2.mul(mMatrix[1]); + y3.mul(mMatrix[1]); + + z0.mul(mMatrix[2]); + z1.mul(mMatrix[2]); + z2.mul(mMatrix[2]); + z3.mul(mMatrix[2]); + + //9 adds + x0.add(y0); + + x1.add(y1); + + x2.add(y2); + + x3.add(y3); + z3.add(mMatrix[3]); + + mMatrix[0].setAdd(x0,z0); + mMatrix[1].setAdd(x1,z1); + mMatrix[2].setAdd(x2,z2); + mMatrix[3].setAdd(x3,z3); + } + + inline void extractRotation_affine() + { + static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[3*4]); + mMatrix[0].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[0]); + mMatrix[1].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[1]); + mMatrix[2].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[2]); + mMatrix[3].setSelectWithMask(mask,LLVector4a(1.f),_mm_setzero_ps()); + } + + //======================Logic==================== +private: + template inline void init_foos(LLMatrix4a& foos) const + { + static bool done(false); + if (done) return; + const LLVector4a delta(0.0001f); + foos.setIdentity(); + foos.getRow<0>().sub(delta); + foos.getRow<1>().sub(delta); + foos.getRow<2>().sub(delta); + foos.getRow<3>().sub(delta); + done = true; + } + +public: + inline bool isIdentity() const + { + static LLMatrix4a mins; + static LLMatrix4a maxs; + + init_foos(mins); + init_foos(maxs); + + LLVector4a mask1 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[0],mins.getRow<0>()), _mm_cmplt_ps(mMatrix[0],maxs.getRow<0>())); + LLVector4a mask2 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[1],mins.getRow<1>()), _mm_cmplt_ps(mMatrix[1],maxs.getRow<1>())); + LLVector4a mask3 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[2],mins.getRow<2>()), _mm_cmplt_ps(mMatrix[2],maxs.getRow<2>())); + LLVector4a mask4 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[3],mins.getRow<3>()), _mm_cmplt_ps(mMatrix[3],maxs.getRow<3>())); + + mask1 = _mm_and_ps(mask1,mask2); + mask2 = _mm_and_ps(mask3,mask4); + + return _mm_movemask_epi8(_mm_castps_si128(_mm_and_ps(mask1, mask2))) == 0xFFFF; + } +} LL_ALIGN_POSTFIX(16); #endif diff --git a/indra/llmath/llmodularmath.cpp b/indra/llmath/llmodularmath.cpp index e2d573fb0..96ead2176 100644 --- a/indra/llmath/llmodularmath.cpp +++ b/indra/llmath/llmodularmath.cpp @@ -2,36 +2,28 @@ * @file llmodularmath.cpp * @brief LLModularMath class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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$ - * */ - #include "linden_common.h" // implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes. diff --git a/indra/llmath/llmodularmath.h b/indra/llmath/llmodularmath.h index 60095293c..1caff880d 100644 --- a/indra/llmath/llmodularmath.h +++ b/indra/llmath/llmodularmath.h @@ -2,31 +2,25 @@ * @file llmodularmath.h * @brief Useful modular math functions. * - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&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$ */ diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 981e2176f..0be162f5c 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -932,10 +932,10 @@ protected: MIN = 3 } eDName; - LLVector4a mCenter; - LLVector4a mSize; - LLVector4a mMax; - LLVector4a mMin; + LL_ALIGN_16(LLVector4a mCenter); + LL_ALIGN_16(LLVector4a mSize); + LL_ALIGN_16(LLVector4a mMax); + LL_ALIGN_16(LLVector4a mMin); oct_node* mParent; U8 mOctant; @@ -964,6 +964,26 @@ public: : BaseType(center, size, parent) { } + +#ifdef LL_OCTREE_POOLS + void* operator new(size_t size) + { + return LLOctreeNode::getPool(size).malloc(); + } + void operator delete(void* ptr) + { + LLOctreeNode::getPool(sizeof(LLOctreeNode)).free(ptr); + } +#else + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } +#endif bool balance() { diff --git a/indra/llmath/llperlin.cpp b/indra/llmath/llperlin.cpp index 9293d972a..397547ff7 100644 --- a/indra/llmath/llperlin.cpp +++ b/indra/llmath/llperlin.cpp @@ -1,31 +1,25 @@ /** * @file llperlin.cpp * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ diff --git a/indra/llmath/llperlin.h b/indra/llmath/llperlin.h index e8815ece5..48b7d7b76 100644 --- a/indra/llmath/llperlin.h +++ b/indra/llmath/llperlin.h @@ -1,31 +1,25 @@ /** * @file llperlin.h * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h index 44c8327f5..0cbf02c83 100644 --- a/indra/llmath/llplane.h +++ b/indra/llmath/llplane.h @@ -1,31 +1,25 @@ /** * @file llplane.h * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ @@ -100,8 +94,14 @@ public: return mV.greaterEqual(LLVector4a::getZero()).getGatheredBits() & LLVector4Logical::MASK_XYZ; } + //check if two planes are nearly same + bool equal(const LLPlane& p) const + { + return mV.equals4(p.mV); + } + private: - LLVector4a mV; + LL_ALIGN_16(LLVector4a mV); } LL_ALIGN_POSTFIX(16); diff --git a/indra/llmath/llquantize.h b/indra/llmath/llquantize.h index c043f7f75..dd0cf2941 100644 --- a/indra/llmath/llquantize.h +++ b/indra/llmath/llquantize.h @@ -3,31 +3,25 @@ * @brief useful routines for quantizing floats to various length ints * and back out again * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp index 73c5f4505..699eaf2ab 100644 --- a/indra/llmath/llquaternion.cpp +++ b/indra/llmath/llquaternion.cpp @@ -2,31 +2,25 @@ * @file llquaternion.cpp * @brief LLQuaternion class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ @@ -64,34 +58,40 @@ LLQuaternion::LLQuaternion(const LLMatrix3 &mat) LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec) { - LLVector3 v(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); - v.normalize(); - - F32 c, s; - c = cosf(angle*0.5f); - s = sinf(angle*0.5f); - - mQ[VX] = v.mV[VX] * s; - mQ[VY] = v.mV[VY] * s; - mQ[VZ] = v.mV[VZ] * s; - mQ[VW] = c; - normalize(); + F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); + if (mag > FP_MAG_THRESHOLD) + { + angle *= 0.5; + F32 c = cosf(angle); + F32 s = sinf(angle) / mag; + mQ[VX] = vec.mV[VX] * s; + mQ[VY] = vec.mV[VY] * s; + mQ[VZ] = vec.mV[VZ] * s; + mQ[VW] = c; + } + else + { + loadIdentity(); + } } LLQuaternion::LLQuaternion(F32 angle, const LLVector3 &vec) { - LLVector3 v(vec); - v.normalize(); - - F32 c, s; - c = cosf(angle*0.5f); - s = sinf(angle*0.5f); - - mQ[VX] = v.mV[VX] * s; - mQ[VY] = v.mV[VY] * s; - mQ[VZ] = v.mV[VZ] * s; - mQ[VW] = c; - normalize(); + F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); + if (mag > FP_MAG_THRESHOLD) + { + angle *= 0.5; + F32 c = cosf(angle); + F32 s = sinf(angle) / mag; + mQ[VX] = vec.mV[VX] * s; + mQ[VY] = vec.mV[VY] * s; + mQ[VZ] = vec.mV[VZ] * s; + mQ[VW] = c; + } + else + { + loadIdentity(); + } } LLQuaternion::LLQuaternion(const LLVector3 &x_axis, @@ -142,57 +142,61 @@ void LLQuaternion::quantize8(F32 lower, F32 upper) const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, F32 x, F32 y, F32 z) { - LLVector3 vec(x, y, z); - vec.normalize(); - - angle *= 0.5f; - F32 c, s; - c = cosf(angle); - s = sinf(angle); - - mQ[VX] = vec.mV[VX]*s; - mQ[VY] = vec.mV[VY]*s; - mQ[VZ] = vec.mV[VZ]*s; - mQ[VW] = c; - - normalize(); + F32 mag = sqrtf(x * x + y * y + z * z); + if (mag > FP_MAG_THRESHOLD) + { + angle *= 0.5; + F32 c = cosf(angle); + F32 s = sinf(angle) / mag; + mQ[VX] = x * s; + mQ[VY] = y * s; + mQ[VZ] = z * s; + mQ[VW] = c; + } + else + { + loadIdentity(); + } return (*this); } const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector3 &vec) { - LLVector3 v(vec); - v.normalize(); - - angle *= 0.5f; - F32 c, s; - c = cosf(angle); - s = sinf(angle); - - mQ[VX] = v.mV[VX]*s; - mQ[VY] = v.mV[VY]*s; - mQ[VZ] = v.mV[VZ]*s; - mQ[VW] = c; - - normalize(); + F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); + if (mag > FP_MAG_THRESHOLD) + { + angle *= 0.5; + F32 c = cosf(angle); + F32 s = sinf(angle) / mag; + mQ[VX] = vec.mV[VX] * s; + mQ[VY] = vec.mV[VY] * s; + mQ[VZ] = vec.mV[VZ] * s; + mQ[VW] = c; + } + else + { + loadIdentity(); + } return (*this); } const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector4 &vec) { - LLVector3 v(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); - v.normalize(); - - F32 c, s; - c = cosf(angle*0.5f); - s = sinf(angle*0.5f); - - mQ[VX] = v.mV[VX]*s; - mQ[VY] = v.mV[VY]*s; - mQ[VZ] = v.mV[VZ]*s; - mQ[VW] = c; - - normalize(); + F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); + if (mag > FP_MAG_THRESHOLD) + { + angle *= 0.5; + F32 c = cosf(angle); + F32 s = sinf(angle) / mag; + mQ[VX] = vec.mV[VX] * s; + mQ[VY] = vec.mV[VY] * s; + mQ[VZ] = vec.mV[VZ] * s; + mQ[VW] = c; + } + else + { + loadIdentity(); + } return (*this); } @@ -225,68 +229,80 @@ const LLQuaternion& LLQuaternion::set(const LLMatrix4 &mat) // deprecated const LLQuaternion& LLQuaternion::setQuat(F32 angle, F32 x, F32 y, F32 z) { - LLVector3 vec(x, y, z); - vec.normalize(); - - angle *= 0.5f; - F32 c, s; - c = cosf(angle); - s = sinf(angle); - - mQ[VX] = vec.mV[VX]*s; - mQ[VY] = vec.mV[VY]*s; - mQ[VZ] = vec.mV[VZ]*s; - mQ[VW] = c; - - normalize(); + F32 mag = sqrtf(x * x + y * y + z * z); + if (mag > FP_MAG_THRESHOLD) + { + angle *= 0.5; + F32 c = cosf(angle); + F32 s = sinf(angle) / mag; + mQ[VX] = x * s; + mQ[VY] = y * s; + mQ[VZ] = z * s; + mQ[VW] = c; + } + else + { + loadIdentity(); + } return (*this); } // deprecated const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector3 &vec) { - LLVector3 v(vec); - v.normalize(); - - angle *= 0.5f; - F32 c, s; - c = cosf(angle); - s = sinf(angle); - - mQ[VX] = v.mV[VX]*s; - mQ[VY] = v.mV[VY]*s; - mQ[VZ] = v.mV[VZ]*s; - mQ[VW] = c; - - normalize(); + F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); + if (mag > FP_MAG_THRESHOLD) + { + angle *= 0.5; + F32 c = cosf(angle); + F32 s = sinf(angle) / mag; + mQ[VX] = vec.mV[VX] * s; + mQ[VY] = vec.mV[VY] * s; + mQ[VZ] = vec.mV[VZ] * s; + mQ[VW] = c; + } + else + { + loadIdentity(); + } return (*this); } const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector4 &vec) { - LLVector3 v(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); - v.normalize(); - - F32 c, s; - c = cosf(angle*0.5f); - s = sinf(angle*0.5f); - - mQ[VX] = v.mV[VX]*s; - mQ[VY] = v.mV[VY]*s; - mQ[VZ] = v.mV[VZ]*s; - mQ[VW] = c; - - normalize(); + F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); + if (mag > FP_MAG_THRESHOLD) + { + angle *= 0.5; + F32 c = cosf(angle); + F32 s = sinf(angle) / mag; + mQ[VX] = vec.mV[VX] * s; + mQ[VY] = vec.mV[VY] * s; + mQ[VZ] = vec.mV[VZ] * s; + mQ[VW] = c; + } + else + { + loadIdentity(); + } return (*this); } const LLQuaternion& LLQuaternion::setQuat(F32 roll, F32 pitch, F32 yaw) { - LLMatrix3 rot_mat(roll, pitch, yaw); - rot_mat.orthogonalize(); - *this = rot_mat.quaternion(); - - normalize(); + roll *= 0.5f; + pitch *= 0.5f; + yaw *= 0.5f; + F32 sinX = sinf(roll); + F32 cosX = cosf(roll); + F32 sinY = sinf(pitch); + F32 cosY = cosf(pitch); + F32 sinZ = sinf(yaw); + F32 cosZ = cosf(yaw); + mQ[VW] = cosX * cosY * cosZ - sinX * sinY * sinZ; + mQ[VX] = sinX * cosY * cosZ + cosX * sinY * sinZ; + mQ[VY] = cosX * sinY * cosZ - sinX * cosY * sinZ; + mQ[VZ] = cosX * cosY * sinZ + sinX * sinY * cosZ; return (*this); } @@ -431,68 +447,44 @@ LLMatrix4 LLQuaternion::getMatrix4(void) const // calculate the shortest rotation from a to b void LLQuaternion::shortestArc(const LLVector3 &a, const LLVector3 &b) { - // Make a local copy of both vectors. - LLVector3 vec_a = a; - LLVector3 vec_b = b; - - // Make sure neither vector is zero length. Also normalize - // the vectors while we are at it. - F32 vec_a_mag = vec_a.normalize(); - F32 vec_b_mag = vec_b.normalize(); - if (vec_a_mag < F_APPROXIMATELY_ZERO || - vec_b_mag < F_APPROXIMATELY_ZERO) + F32 ab = a * b; // dotproduct + LLVector3 c = a % b; // crossproduct + F32 cc = c * c; // squared length of the crossproduct + if (ab * ab + cc) // test if the arguments have sufficient magnitude { - // Can't calculate a rotation from this. - // Just return ZERO_ROTATION instead. - loadIdentity(); - return; - } - - // Create an axis to rotate around, and the cos of the angle to rotate. - LLVector3 axis = vec_a % vec_b; - F32 cos_theta = vec_a * vec_b; - - // Check the angle between the vectors to see if they are parallel or anti-parallel. - if (cos_theta > 1.0 - F_APPROXIMATELY_ZERO) - { - // a and b are parallel. No rotation is necessary. - loadIdentity(); - } - else if (cos_theta < -1.0 + F_APPROXIMATELY_ZERO) - { - // a and b are anti-parallel. - // Rotate 180 degrees around some orthogonal axis. - // Find the projection of the x-axis onto a, and try - // using the vector between the projection and the x-axis - // as the orthogonal axis. - LLVector3 proj = vec_a.mV[VX] / (vec_a * vec_a) * vec_a; - LLVector3 ortho_axis(1.f, 0.f, 0.f); - ortho_axis -= proj; - - // Turn this into an orthonormal axis. - F32 ortho_length = ortho_axis.normalize(); - // If the axis' length is 0, then our guess at an orthogonal axis - // was wrong (a is parallel to the x-axis). - if (ortho_length < F_APPROXIMATELY_ZERO) + if (cc > 0.0f) // test if the arguments are (anti)parallel { - // Use the z-axis instead. - ortho_axis.setVec(0.f, 0.f, 1.f); + F32 s = sqrtf(ab * ab + cc) + ab; // note: don't try to optimize this line + F32 m = 1.0f / sqrtf(cc + s * s); // the inverted magnitude of the quaternion + mQ[VX] = c.mV[VX] * m; + mQ[VY] = c.mV[VY] * m; + mQ[VZ] = c.mV[VZ] * m; + mQ[VW] = s * m; + return; + } + if (ab < 0.0f) // test if the angle is bigger than PI/2 (anti parallel) + { + c = a - b; // the arguments are anti-parallel, we have to choose an axis + F32 m = sqrtf(c.mV[VX] * c.mV[VX] + c.mV[VY] * c.mV[VY]); // the length projected on the XY-plane + if (m > FP_MAG_THRESHOLD) + { + mQ[VX] = -c.mV[VY] / m; // return the quaternion with the axis in the XY-plane + mQ[VY] = c.mV[VX] / m; + mQ[VZ] = 0.0f; + mQ[VW] = 0.0f; + return; + } + else // the vectors are parallel to the Z-axis + { + mQ[VX] = 1.0f; // rotate around the X-axis + mQ[VY] = 0.0f; + mQ[VZ] = 0.0f; + mQ[VW] = 0.0f; + return; + } } - - // Construct a quaternion from this orthonormal axis. - mQ[VX] = ortho_axis.mV[VX]; - mQ[VY] = ortho_axis.mV[VY]; - mQ[VZ] = ortho_axis.mV[VZ]; - mQ[VW] = 0.f; - } - else - { - // a and b are NOT parallel or anti-parallel. - // Return the rotation between these vectors. - F32 theta = (F32)acos(cos_theta); - - setAngleAxis(theta, axis); } + loadIdentity(); } // constrains rotation to a cone angle specified in radians @@ -844,79 +836,82 @@ LLQuaternion::Order StringToOrder( const char *str ) void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const { - F32 cos_a = mQ[VW]; - if (cos_a > 1.0f) cos_a = 1.0f; - if (cos_a < -1.0f) cos_a = -1.0f; - - F32 sin_a = (F32) sqrt( 1.0f - cos_a * cos_a ); - - if ( fabs( sin_a ) < 0.0005f ) - sin_a = 1.0f; - else - sin_a = 1.f/sin_a; - - F32 temp_angle = 2.0f * (F32) acos( cos_a ); - if (temp_angle > F_PI) + F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component + if (v > FP_MAG_THRESHOLD) { - // The (angle,axis) pair should never have angles outside [PI, -PI] - // since we want the _shortest_ (angle,axis) solution. - // Since acos is defined for [0, PI], and we multiply by 2.0, we - // can push the angle outside the acceptible range. - // When this happens we set the angle to the other portion of a - // full 2PI rotation, and negate the axis, which reverses the - // direction of the rotation (by the right-hand rule). - *angle = 2.f * F_PI - temp_angle; - vec.mV[VX] = - mQ[VX] * sin_a; - vec.mV[VY] = - mQ[VY] * sin_a; - vec.mV[VZ] = - mQ[VZ] * sin_a; + F32 oomag = 1.0f / v; + F32 w = mQ[VW]; + if (mQ[VW] < 0.0f) + { + w = -w; // make VW positive + oomag = -oomag; // invert the axis + } + vec.mV[VX] = mQ[VX] * oomag; // normalize the axis + vec.mV[VY] = mQ[VY] * oomag; + vec.mV[VZ] = mQ[VZ] * oomag; + *angle = 2.0f * atan2f(v, w); // get the angle } else { - *angle = temp_angle; - vec.mV[VX] = mQ[VX] * sin_a; - vec.mV[VY] = mQ[VY] * sin_a; - vec.mV[VZ] = mQ[VZ] * sin_a; + *angle = 0.0f; // no rotation + vec.mV[VX] = 0.0f; // around some dummy axis + vec.mV[VY] = 0.0f; + vec.mV[VZ] = 1.0f; } } - // quaternion does not need to be normalized void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const { - LLMatrix3 rot_mat(*this); - rot_mat.orthogonalize(); - rot_mat.getEulerAngles(roll, pitch, yaw); - -// // NOTE: LLQuaternion's are actually inverted with respect to -// // the matrices, so this code also assumes inverted quaternions -// // (-x, -y, -z, w). The result is that roll,pitch,yaw are applied -// // in reverse order (yaw,pitch,roll). -// F32 x = -mQ[VX], y = -mQ[VY], z = -mQ[VZ], w = mQ[VW]; -// F64 m20 = 2.0*(x*z-y*w); -// if (1.0f - fabsf(m20) < F_APPROXIMATELY_ZERO) -// { -// *roll = 0.0f; -// *pitch = (F32)asin(m20); -// *yaw = (F32)atan2(2.0*(x*y-z*w), 1.0 - 2.0*(x*x+z*z)); -// } -// else -// { -// *roll = (F32)atan2(-2.0*(y*z+x*w), 1.0-2.0*(x*x+y*y)); -// *pitch = (F32)asin(m20); -// *yaw = (F32)atan2(-2.0*(x*y+z*w), 1.0-2.0*(y*y+z*z)); -// } + F32 sx = 2 * (mQ[VX] * mQ[VW] - mQ[VY] * mQ[VZ]); // sine of the roll + F32 sy = 2 * (mQ[VY] * mQ[VW] + mQ[VX] * mQ[VZ]); // sine of the pitch + F32 ys = mQ[VW] * mQ[VW] - mQ[VY] * mQ[VY]; // intermediate cosine 1 + F32 xz = mQ[VX] * mQ[VX] - mQ[VZ] * mQ[VZ]; // intermediate cosine 2 + F32 cx = ys - xz; // cosine of the roll + F32 cy = sqrtf(sx * sx + cx * cx); // cosine of the pitch + if (cy > GIMBAL_THRESHOLD) // no gimbal lock + { + *roll = atan2f(sx, cx); + *pitch = atan2f(sy, cy); + *yaw = atan2f(2 * (mQ[VZ] * mQ[VW] - mQ[VX] * mQ[VY]), ys + xz); + } + else // gimbal lock + { + if (sy > 0) + { + *pitch = F_PI_BY_TWO; + *yaw = 2 * atan2f(mQ[VZ] + mQ[VX], mQ[VW] + mQ[VY]); + } + else + { + *pitch = -F_PI_BY_TWO; + *yaw = 2 * atan2f(mQ[VZ] - mQ[VX], mQ[VW] - mQ[VY]); + } + *roll = 0; + } } // Saves space by using the fact that our quaternions are normalized LLVector3 LLQuaternion::packToVector3() const { + F32 x = mQ[VX]; + F32 y = mQ[VY]; + F32 z = mQ[VZ]; + F32 w = mQ[VW]; + F32 mag = sqrtf(x * x + y * y + z * z + w * w); + if (mag > FP_MAG_THRESHOLD) + { + x /= mag; + y /= mag; + z /= mag; // no need to normalize w, it's not used + } if( mQ[VW] >= 0 ) { - return LLVector3( mQ[VX], mQ[VY], mQ[VZ] ); + return LLVector3( x, y , z ); } else { - return LLVector3( -mQ[VX], -mQ[VY], -mQ[VZ] ); + return LLVector3( -x, -y, -z ); } } diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h index a7bb09fae..349af0552 100644 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -2,31 +2,25 @@ * @file llquaternion.h * @brief LLQuaternion class header file. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ @@ -310,43 +304,29 @@ inline const LLQuaternion& LLQuaternion::setQuat(const F32 *q) return (*this); } -// There may be a cheaper way that avoids the sqrt. -// Does sin_a = VX*VX + VY*VY + VZ*VZ? -// Copied from Matrix and Quaternion FAQ 1.12 inline void LLQuaternion::getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const { - F32 cos_a = mQ[VW]; - if (cos_a > 1.0f) cos_a = 1.0f; - if (cos_a < -1.0f) cos_a = -1.0f; - - F32 sin_a = (F32) sqrt( 1.0f - cos_a * cos_a ); - - if ( fabs( sin_a ) < 0.0005f ) - sin_a = 1.0f; - else - sin_a = 1.f/sin_a; - - F32 temp_angle = 2.0f * (F32) acos( cos_a ); - if (temp_angle > F_PI) + F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component + if (v > FP_MAG_THRESHOLD) { - // The (angle,axis) pair should never have angles outside [PI, -PI] - // since we want the _shortest_ (angle,axis) solution. - // Since acos is defined for [0, PI], and we multiply by 2.0, we - // can push the angle outside the acceptible range. - // When this happens we set the angle to the other portion of a - // full 2PI rotation, and negate the axis, which reverses the - // direction of the rotation (by the right-hand rule). - *angle = 2.f * F_PI - temp_angle; - *x = - mQ[VX] * sin_a; - *y = - mQ[VY] * sin_a; - *z = - mQ[VZ] * sin_a; + F32 oomag = 1.0f / v; + F32 w = mQ[VW]; + if (w < 0.0f) + { + w = -w; // make VW positive + oomag = -oomag; // invert the axis + } + *x = mQ[VX] * oomag; // normalize the axis + *y = mQ[VY] * oomag; + *z = mQ[VZ] * oomag; + *angle = 2.0f * atan2f(v, w); // get the angle } else { - *angle = temp_angle; - *x = mQ[VX] * sin_a; - *y = mQ[VY] * sin_a; - *z = mQ[VZ] * sin_a; + *angle = 0.0f; // no rotation + *x = 0.0f; // around some dummy axis + *y = 0.0f; + *z = 1.0f; } } diff --git a/indra/llmath/llquaternion2.h b/indra/llmath/llquaternion2.h index fd9c0cf3a..6cfe91a02 100644 --- a/indra/llmath/llquaternion2.h +++ b/indra/llmath/llquaternion2.h @@ -40,6 +40,7 @@ ///////////////////////////// #include "llquaternion.h" +LL_ALIGN_PREFIX(16) class LLQuaternion2 { public: @@ -84,6 +85,8 @@ public: // Quantize this quaternion to 16 bit precision inline void quantize16(); + inline void mul(const LLQuaternion2& b); + ///////////////////////// // Quaternion inspection ///////////////////////// @@ -98,8 +101,8 @@ public: protected: - LLVector4a mQ; + LL_ALIGN_16(LLVector4a mQ); -}; +} LL_ALIGN_POSTFIX(16); #endif diff --git a/indra/llmath/llquaternion2.inl b/indra/llmath/llquaternion2.inl index 2a6987552..52d67620f 100644 --- a/indra/llmath/llquaternion2.inl +++ b/indra/llmath/llquaternion2.inl @@ -50,6 +50,39 @@ inline LLVector4a& LLQuaternion2::getVector4aRw() return mQ; } +inline void LLQuaternion2::mul(const LLQuaternion2& b) +{ + static LL_ALIGN_16(const unsigned int signMask[4]) = { 0x0, 0x0, 0x0, 0x80000000 }; + + LLVector4a sum1, sum2, prod1, prod2, prod3, prod4; + const LLVector4a& va = mQ; + const LLVector4a& vb = b.getVector4a(); + + // [VX] [VY] [VZ] [VW] + //prod1: +wx +wy +wz +ww Bwwww*Axyzw + //prod2: +xw +yw +zw -xx Bxyzx*Awwwx [VW] sign flip + //prod3: +yz +zx +xy -yy Byzxy*Azxyy [VW] sign flip + //prod4: -zy -xz -yx -zz Bzxyz*Ayzzz + + const LLVector4a Bwwww = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(3,3,3,3)); + const LLVector4a Bxyzx = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(0,2,1,0)); + const LLVector4a Awwwx = _mm_shuffle_ps(va,va,_MM_SHUFFLE(0,3,3,3)); + const LLVector4a Byzxy = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(1,0,2,1)); + const LLVector4a Azxyy = _mm_shuffle_ps(va,va,_MM_SHUFFLE(1,1,0,2)); + const LLVector4a Bzxyz = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(2,1,0,2)); + const LLVector4a Ayzxz = _mm_shuffle_ps(va,va,_MM_SHUFFLE(2,0,2,1)); + + prod1.setMul(Bwwww,va); + prod2.setMul(Bxyzx,Awwwx); + prod3.setMul(Byzxy,Azxyy); + prod4.setMul(Bzxyz,Ayzxz); + + sum1.setAdd(prod2,prod3); + sum1 = _mm_xor_ps(sum1, _mm_load_ps((const float*)signMask)); + sum2.setSub(prod1,prod4); + mQ.setAdd(sum1,sum2); +} + ///////////////////////// // Quaternion modification ///////////////////////// diff --git a/indra/llmath/llrect.cpp b/indra/llmath/llrect.cpp index 0db74f20f..a87a476aa 100644 --- a/indra/llmath/llrect.cpp +++ b/indra/llmath/llrect.cpp @@ -1,31 +1,26 @@ /** * @file llrect.cpp + * @brief LLRect class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ diff --git a/indra/llmath/llsdutil_math.cpp b/indra/llmath/llsdutil_math.cpp index 1bd12ae51..c35ee42f3 100644 --- a/indra/llmath/llsdutil_math.cpp +++ b/indra/llmath/llsdutil_math.cpp @@ -4,31 +4,25 @@ * @date 2006-05-24 * @brief Implementation of classes, functions, etc, for using structured data. * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&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$ */ diff --git a/indra/llmath/llsdutil_math.h b/indra/llmath/llsdutil_math.h index 3644cab35..7607abf0b 100644 --- a/indra/llmath/llsdutil_math.h +++ b/indra/llmath/llsdutil_math.h @@ -4,36 +4,28 @@ * @date 2009-05-19 * @brief Utility classes, functions, etc, for using structured data with math classes. * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2009&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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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$ - * */ - #ifndef LL_LLSDUTIL_MATH_H #define LL_LLSDUTIL_MATH_H diff --git a/indra/llmath/llsphere.cpp b/indra/llmath/llsphere.cpp index b260c134a..910b8772a 100644 --- a/indra/llmath/llsphere.cpp +++ b/indra/llmath/llsphere.cpp @@ -3,31 +3,25 @@ * @author Andrew Meadows * @brief Simple line class that can compute nearest approach between two lines * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&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$ */ diff --git a/indra/llmath/llsphere.h b/indra/llmath/llsphere.h index 58df07a56..c16f1115c 100644 --- a/indra/llmath/llsphere.h +++ b/indra/llmath/llsphere.h @@ -4,31 +4,25 @@ * @author Andrew Meadows * @brief Simple sphere implementation for basic geometric operations * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&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$ */ diff --git a/indra/llmath/lltreenode.h b/indra/llmath/lltreenode.h index ada1f0075..36e6f106a 100644 --- a/indra/llmath/lltreenode.h +++ b/indra/llmath/lltreenode.h @@ -1,31 +1,25 @@ /** * @file lltreenode.h * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&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,6 +30,7 @@ #include "xform.h" #include "llpointer.h" #include "llrefcount.h" + #include template class LLTreeNode; @@ -62,7 +57,14 @@ public: virtual bool remove(T* data); virtual void notifyRemoval(T* data); virtual U32 getListenerCount() { return mListeners.size(); } - virtual LLTreeListener* getListener(U32 index) const { return mListeners[index]; } + virtual LLTreeListener* getListener(U32 index) const + { + if(index < mListeners.size()) + { + return mListeners[index]; + } + return NULL; + } virtual void addListener(LLTreeListener* listener) { mListeners.push_back(listener); } protected: diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index ffd58114e..2e958b308 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -85,6 +85,7 @@ public: } // Copy words 16-byte blocks from src to dst. Source and destination must not overlap. + // Source and dest must be 16-byte aligned and size must be multiple of 16. static void memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes); //////////////////////////////////// @@ -127,7 +128,7 @@ public: inline void loadua(const F32* src); // Load only three floats beginning at address 'src'. Slowest method. - inline void load3(const F32* src); + inline void load3(const F32* src, const F32 w=0.f); // Store to a 16-byte aligned memory address inline void store4a(F32* dst) const; @@ -169,6 +170,9 @@ public: // Set all 4 elements to element i of v, with i NOT known at compile time inline void splat(const LLVector4a& v, U32 i); + + // Sets element N to that of src's element N. Much cleaner than.. {LLVector4Logical mask; mask.clear(); mask.setElement(); target.setSelectWithMask(mask,src,target);} + template inline void copyComponent(const LLVector4a& src); // Select bits from sourceIfTrue and sourceIfFalse according to bits in mask inline void setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse ); @@ -281,6 +285,8 @@ public: void quantize8( const LLVector4a& low, const LLVector4a& high ); void quantize16( const LLVector4a& low, const LLVector4a& high ); + void negate(); + //////////////////////////////////// // LOGICAL //////////////////////////////////// diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index 69d3d01ef..c3499d23d 100644 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -41,11 +41,11 @@ inline void LLVector4a::loadua(const F32* src) } // Load only three floats beginning at address 'src'. Slowest method. -inline void LLVector4a::load3(const F32* src) +inline void LLVector4a::load3(const F32* src, const F32 w) { // mQ = { 0.f, src[2], src[1], src[0] } = { W, Z, Y, X } // NB: This differs from the convention of { Z, Y, X, W } - mQ = _mm_set_ps(0.f, src[2], src[1], src[0]); + mQ = _mm_set_ps(w, src[2], src[1], src[0]); } // Store to a 16-byte aligned memory address @@ -154,6 +154,13 @@ inline void LLVector4a::splat(const LLVector4a& v, U32 i) } } +// Sets element N to that of src's element N +template inline void LLVector4a::copyComponent(const LLVector4a& src) +{ + static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[N*4]); + setSelectWithMask(mask,src,mQ); +} + // Select bits from sourceIfTrue and sourceIfFalse according to bits in mask inline void LLVector4a::setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse ) { @@ -529,6 +536,11 @@ inline void LLVector4a::clamp( const LLVector4a& low, const LLVector4a& high ) setSelectWithMask( lowMask, low, *this ); } +inline void LLVector4a::negate() +{ + static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 }; + mQ = _mm_xor_ps(*reinterpret_cast(signMask), mQ); +} //////////////////////////////////// // LOGICAL diff --git a/indra/llmath/llvector4logical.h b/indra/llmath/llvector4logical.h index c5698f7ce..5e2cc413b 100644 --- a/indra/llmath/llvector4logical.h +++ b/indra/llmath/llvector4logical.h @@ -79,7 +79,7 @@ public: { static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; ll_assert_aligned(allOnes,16); - mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) ); + mQ = _mm_andnot_ps( mQ, _mm_load_ps((F32*)(allOnes))); return *this; } @@ -115,7 +115,7 @@ public: template void setElement() { - mQ = _mm_or_ps( mQ, *reinterpret_cast(S_V4LOGICAL_MASK_TABLE + 4*N) ); + mQ = _mm_or_ps( mQ, _mm_load_ps( (F32*)&S_V4LOGICAL_MASK_TABLE[4*N] ) ); } private: diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 82fb7ce34..3b5b2f148 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -50,7 +50,6 @@ #include "llstl.h" #include "llsdserialize.h" #include "llvector4a.h" -#include "llmatrix4a.h" #include "lltimer.h" #define DEBUG_SILHOUETTE_BINORMALS 0 @@ -1094,8 +1093,6 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai } } - //genNormals(params); - return TRUE; } @@ -1651,7 +1648,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, F32 t = (F32)i * mStep; mPath[i].mPos.set(0, lerp(0, -sin(F_PI*params.getTwist()*t)*0.5f,t), - lerp(-0.5, cos(F_PI*params.getTwist()*t)*0.5f,t)); + lerp(-0.5f, cos(F_PI*params.getTwist()*t)*0.5f,t)); mPath[i].mScale.set(lerp(1,params.getScale().mV[0],t), lerp(1,params.getScale().mV[1],t), 0,1); mPath[i].mTexT = t; @@ -2186,7 +2183,7 @@ BOOL LLVolume::generate() 0, 0, scale[2], 0, 0, 0, 0, 1 }; - LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix); + LLMatrix4 rot(mPathp->mPath[s].mRot.getF32ptr()); LLMatrix4 scale_mat(sc); scale_mat *= rot; @@ -2374,7 +2371,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLSD mdl; if (!unzip_llsd(mdl, is, size)) { - LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD, will probably fetch from sim again." << llendl; + LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD, will probably fetch from sim again." << LL_ENDL; return false; } @@ -3672,16 +3669,14 @@ S32 LLVolume::getNumTriangles(S32* vcount) const void LLVolume::generateSilhouetteVertices(std::vector &vertices, std::vector &normals, const LLVector3& obj_cam_vec_in, - const LLMatrix4& mat_in, - const LLMatrix3& norm_mat_in, + const LLMatrix4a& mat_in, + const LLMatrix4a& norm_mat_in, S32 face_mask) { - LLMatrix4a mat; - mat.loadu(mat_in); + const LLMatrix4a& mat = mat_in; + + const LLMatrix4a& norm_mat = norm_mat_in; - LLMatrix4a norm_mat; - norm_mat.loadu(norm_mat_in); - LLVector4a obj_cam_vec; obj_cam_vec.load3(obj_cam_vec_in.mV); @@ -5617,7 +5612,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) else { resizeVertices(num_vertices); - if (!partial_build) { resizeIndices(num_indices); @@ -5722,6 +5716,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) cuv = (min_uv + max_uv)*0.5f; + VertexData vd; vd.setPosition(*mCenter); vd.mTexCoord = cuv; @@ -6770,7 +6765,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) return TRUE; } -//adapted from Lengyel, Eric. Computing Tangent Space Basis Vectors for an Arbitrary Mesh. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html +//adapted from Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary Mesh". Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 7a74d544c..2f52a5949 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -27,6 +27,9 @@ #ifndef LL_LLVOLUME_H #define LL_LLVOLUME_H +#ifdef IN_PCH +#error "llvolume.h should not be in pch include chain." +#endif #include class LLProfileParams; @@ -747,10 +750,10 @@ public: class PathPt { public: - LLMatrix4a mRot; - LLVector4a mPos; + LL_ALIGN_16(LLMatrix4a mRot); + LL_ALIGN_16(LLVector4a mPos); - LLVector4a mScale; + LL_ALIGN_16(LLVector4a mScale); F32 mTexT; F32 pad[3]; //for alignment PathPt() @@ -1017,8 +1020,8 @@ public: void generateSilhouetteVertices(std::vector &vertices, std::vector &normals, const LLVector3& view_vec, - const LLMatrix4& mat, - const LLMatrix3& norm_mat, + const LLMatrix4a& mat, + const LLMatrix4a& norm_mat, S32 face_index); //get the face index of the face that intersects with the given line segment at the point diff --git a/indra/llmath/llvolumemgr.h b/indra/llmath/llvolumemgr.h index f5dc4cd74..c242ca68c 100644 --- a/indra/llmath/llvolumemgr.h +++ b/indra/llmath/llvolumemgr.h @@ -2,31 +2,25 @@ * @file llvolumemgr.h * @brief LLVolumeMgr class. * - * $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$ */ diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index 40d2e890c..61b90f68a 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -127,13 +127,14 @@ public: LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; +LL_ALIGN_PREFIX(16) class LLOctreeTriangleRayIntersect : public LLOctreeTraveler { public: const LLVolumeFace* mFace; - LLVector4a mStart; - LLVector4a mDir; - LLVector4a mEnd; + LL_ALIGN_16(LLVector4a mStart); + LL_ALIGN_16(LLVector4a mDir); + LL_ALIGN_16(LLVector4a mEnd); LLVector4a* mIntersection; LLVector2* mTexCoord; LLVector4a* mNormal; @@ -148,7 +149,7 @@ public: void traverse(const LLOctreeNode* node); virtual void visit(const LLOctreeNode* node); -}; +} LL_ALIGN_POSTFIX(16); class LLVolumeOctreeValidate : public LLOctreeTraveler { diff --git a/indra/llmath/m3math.cpp b/indra/llmath/m3math.cpp index 1b878c8f4..fa5dfb62d 100644 --- a/indra/llmath/m3math.cpp +++ b/indra/llmath/m3math.cpp @@ -2,31 +2,25 @@ * @file m3math.cpp * @brief LLMatrix3 class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/m3math.h b/indra/llmath/m3math.h index 3ac963e5a..1bf42fefa 100644 --- a/indra/llmath/m3math.h +++ b/indra/llmath/m3math.h @@ -2,31 +2,25 @@ * @file m3math.h * @brief LLMatrix3 class header file. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 108aeb118..a1fd34047 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -2,31 +2,25 @@ * @file m4math.cpp * @brief LLMatrix4 class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ @@ -684,37 +678,6 @@ const LLMatrix4& LLMatrix4::initMatrix(const LLMatrix3 &mat, const LLVector4 & // LLMatrix4 Operators - -/* Not implemented to help enforce code consistency with the syntax of - row-major notation. This is a Good Thing. -LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b) -{ - // Operate "to the right" on column-vector b - LLVector4 vec; - vec.mV[VX] = a.mMatrix[VX][VX] * b.mV[VX] + - a.mMatrix[VY][VX] * b.mV[VY] + - a.mMatrix[VZ][VX] * b.mV[VZ] + - a.mMatrix[VW][VX] * b.mV[VW]; - - vec.mV[VY] = a.mMatrix[VX][VY] * b.mV[VX] + - a.mMatrix[VY][VY] * b.mV[VY] + - a.mMatrix[VZ][VY] * b.mV[VZ] + - a.mMatrix[VW][VY] * b.mV[VW]; - - vec.mV[VZ] = a.mMatrix[VX][VZ] * b.mV[VX] + - a.mMatrix[VY][VZ] * b.mV[VY] + - a.mMatrix[VZ][VZ] * b.mV[VZ] + - a.mMatrix[VW][VZ] * b.mV[VW]; - - vec.mV[VW] = a.mMatrix[VX][VW] * b.mV[VX] + - a.mMatrix[VY][VW] * b.mV[VY] + - a.mMatrix[VZ][VW] * b.mV[VZ] + - a.mMatrix[VW][VW] * b.mV[VW]; - return vec; -} -*/ - - LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b) { // Operate "to the left" on row-vector a diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index 27e4be4b4..9330ec332 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -2,31 +2,25 @@ * @file m4math.h * @brief LLMatrix4 class header file. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ @@ -229,9 +223,6 @@ public: // Operators // -// Not implemented to enforce code that agrees with symbolic syntax -// friend LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b); // Apply rotation a to vector b - // friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b); // Return a * b friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b); // Return transform of vector a by matrix b friend const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b); // Return full transform of a by matrix b diff --git a/indra/llmath/raytrace.cpp b/indra/llmath/raytrace.cpp index a5eb0d268..204d8f576 100644 --- a/indra/llmath/raytrace.cpp +++ b/indra/llmath/raytrace.cpp @@ -2,31 +2,25 @@ * @file raytrace.cpp * @brief Functions called by box object scripts. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ diff --git a/indra/llmath/raytrace.h b/indra/llmath/raytrace.h index b433e1769..eb721a5e0 100644 --- a/indra/llmath/raytrace.h +++ b/indra/llmath/raytrace.h @@ -2,31 +2,25 @@ * @file raytrace.h * @brief Ray intersection tests for primitives. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp index 2603127f7..bc1c2502d 100644 --- a/indra/llmath/v2math.cpp +++ b/indra/llmath/v2math.cpp @@ -2,31 +2,25 @@ * @file v2math.cpp * @brief LLVector2 class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h index 35fd1b604..194bcfcfb 100644 --- a/indra/llmath/v2math.h +++ b/indra/llmath/v2math.h @@ -2,31 +2,25 @@ * @file v2math.h * @brief LLVector2 class header file. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/v3color.cpp b/indra/llmath/v3color.cpp index b4cd41007..f4b4af34c 100644 --- a/indra/llmath/v3color.cpp +++ b/indra/llmath/v3color.cpp @@ -2,31 +2,25 @@ * @file v3color.cpp * @brief LLColor3 class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 95a3de8b6..6fe39e219 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -2,31 +2,25 @@ * @file v3color.h * @brief LLColor3 class header file. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ @@ -39,6 +33,7 @@ class LLVector4; #include "llerror.h" #include "llmath.h" #include "llsd.h" +#include // LLColor3 = |r g b| diff --git a/indra/llmath/v3dmath.cpp b/indra/llmath/v3dmath.cpp index 2bcbf632b..af5c8ef39 100644 --- a/indra/llmath/v3dmath.cpp +++ b/indra/llmath/v3dmath.cpp @@ -2,31 +2,25 @@ * @file v3dmath.cpp * @brief LLVector3d class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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. + * + * 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$ */ diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h index 5cd6e4dfe..f92c3984e 100644 --- a/indra/llmath/v3dmath.h +++ b/indra/llmath/v3dmath.h @@ -72,17 +72,22 @@ class LLVector3d BOOL clamp(const F64 min, const F64 max); // Clamps all values to (min,max), returns TRUE if data changed BOOL abs(); // sets all values to absolute value of original value (first octant), returns TRUE if changed - inline const LLVector3d& clearVec(); // Clears LLVector3d to (0, 0, 0, 1) + inline const LLVector3d& clear(); // Clears LLVector3d to (0, 0, 0, 1) + inline const LLVector3d& clearVec(); // deprecated inline const LLVector3d& setZero(); // Zero LLVector3d to (0, 0, 0, 0) inline const LLVector3d& zeroVec(); // deprecated - inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1) - inline const LLVector3d& setVec(const LLVector3d &vec); // Sets LLVector3d to vec - inline const LLVector3d& setVec(const F64 *vec); // Sets LLVector3d to vec - inline const LLVector3d& setVec(const LLVector3 &vec); + inline const LLVector3d& set(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1) + inline const LLVector3d& set(const LLVector3d &vec); // Sets LLVector3d to vec + inline const LLVector3d& set(const F64 *vec); // Sets LLVector3d to vec + inline const LLVector3d& set(const LLVector3 &vec); + inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // deprecated + inline const LLVector3d& setVec(const LLVector3d &vec); // deprecated + inline const LLVector3d& setVec(const F64 *vec); // deprecated + inline const LLVector3d& setVec(const LLVector3 &vec); // deprecated - F64 magVec() const; // Returns magnitude of LLVector3d - F64 magVecSquared() const; // Returns magnitude squared of LLVector3d - inline F64 normVec(); // Normalizes and returns the magnitude of LLVector3d + F64 magVec() const; // deprecated + F64 magVecSquared() const; // deprecated + inline F64 normVec(); // deprecated F64 length() const; // Returns magnitude of LLVector3d F64 lengthSquared() const; // Returns magnitude squared of LLVector3d @@ -127,7 +132,15 @@ class LLVector3d typedef LLVector3d LLGlobalVec; -const LLVector3d &LLVector3d::setVec(const LLVector3 &vec) +inline const LLVector3d &LLVector3d::set(const LLVector3 &vec) +{ + mdV[0] = vec.mV[0]; + mdV[1] = vec.mV[1]; + mdV[2] = vec.mV[2]; + return *this; +} + +inline const LLVector3d &LLVector3d::setVec(const LLVector3 &vec) { mdV[0] = vec.mV[0]; mdV[1] = vec.mV[1]; @@ -184,6 +197,14 @@ inline BOOL LLVector3d::isFinite() const // Clear and Assignment Functions +inline const LLVector3d& LLVector3d::clear(void) +{ + mdV[0] = 0.f; + mdV[1] = 0.f; + mdV[2]= 0.f; + return (*this); +} + inline const LLVector3d& LLVector3d::clearVec(void) { mdV[0] = 0.f; @@ -208,6 +229,30 @@ inline const LLVector3d& LLVector3d::zeroVec(void) return (*this); } +inline const LLVector3d& LLVector3d::set(const F64 x, const F64 y, const F64 z) +{ + mdV[VX] = x; + mdV[VY] = y; + mdV[VZ] = z; + return (*this); +} + +inline const LLVector3d& LLVector3d::set(const LLVector3d &vec) +{ + mdV[0] = vec.mdV[0]; + mdV[1] = vec.mdV[1]; + mdV[2] = vec.mdV[2]; + return (*this); +} + +inline const LLVector3d& LLVector3d::set(const F64 *vec) +{ + mdV[0] = vec[0]; + mdV[1] = vec[1]; + mdV[2] = vec[2]; + return (*this); +} + inline const LLVector3d& LLVector3d::setVec(const F64 x, const F64 y, const F64 z) { mdV[VX] = x; @@ -472,4 +517,15 @@ inline LLVector3d projected_vec(const LLVector3d &a, const LLVector3d &b) return project_axis * (a * project_axis); } +inline LLVector3d inverse_projected_vec(const LLVector3d& a, const LLVector3d& b) +{ + LLVector3d normalized_a = a; + normalized_a.normalize(); + LLVector3d normalized_b = b; + F64 b_length = normalized_b.normalize(); + + F64 dot_product = normalized_a * normalized_b; + return normalized_a * (b_length / dot_product); +} + #endif // LL_V3DMATH_H diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index daabbcc37..898296707 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -2,31 +2,25 @@ * @file v3math.cpp * @brief LLVector3 class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 0e5b196ee..193533678 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -159,6 +159,7 @@ F32 dist_vec(const LLVector3 &a, const LLVector3 &b); // Returns distance betwe F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b +LLVector3 inverse_projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a scaled such that projected_vec(inverse_projected_vec(a, b), b) == b; LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec) LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec) LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b @@ -490,9 +491,27 @@ inline F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b) inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b) { - LLVector3 project_axis = b; - project_axis.normalize(); - return project_axis * (a * project_axis); + F32 bb = b * b; + if (bb > FP_MAG_THRESHOLD * FP_MAG_THRESHOLD) + { + return ((a * b) / bb) * b; + } + else + { + return b.zero; + } +} + +inline LLVector3 inverse_projected_vec(const LLVector3& a, const LLVector3& b) +{ + LLVector3 normalized_a = a; + normalized_a.normalize(); + LLVector3 normalized_b = b; + F32 b_length = normalized_b.normalize(); + + F32 dot_product = normalized_a * normalized_b; + //NB: if a _|_ b, then returns an infinite vector + return normalized_a * (b_length / dot_product); } inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b) @@ -556,15 +575,13 @@ inline void update_min_max(LLVector3& min, LLVector3& max, const F32* pos) inline F32 angle_between(const LLVector3& a, const LLVector3& b) { - LLVector3 an = a; - LLVector3 bn = b; - an.normalize(); - bn.normalize(); - F32 cosine = an * bn; - F32 angle = (cosine >= 1.0f) ? 0.0f : - (cosine <= -1.0f) ? F_PI : - (F32)acos(cosine); - return angle; + F32 ab = a * b; // dotproduct + if (ab == -0.0f) + { + ab = 0.0f; // get rid of negative zero + } + LLVector3 c = a % b; // crossproduct + return atan2f(sqrtf(c * c), ab); // return the angle } inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon) diff --git a/indra/llmath/v4coloru.cpp b/indra/llmath/v4coloru.cpp index 061b4970f..23f53bb07 100644 --- a/indra/llmath/v4coloru.cpp +++ b/indra/llmath/v4coloru.cpp @@ -2,31 +2,25 @@ * @file v4coloru.cpp * @brief LLColor4U class implementation. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ diff --git a/indra/llmath/v4math.cpp b/indra/llmath/v4math.cpp index b938480dd..e9cc32632 100644 --- a/indra/llmath/v4math.cpp +++ b/indra/llmath/v4math.cpp @@ -2,31 +2,25 @@ * @file v4math.cpp * @brief LLVector4 class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h index 72a477ed2..4288916e4 100644 --- a/indra/llmath/v4math.h +++ b/indra/llmath/v4math.h @@ -2,31 +2,25 @@ * @file v4math.h * @brief LLVector4 class header file. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llmath/xform.cpp b/indra/llmath/xform.cpp index 7a8b0cf6a..62033eabd 100644 --- a/indra/llmath/xform.cpp +++ b/indra/llmath/xform.cpp @@ -1,31 +1,25 @@ /** * @file xform.cpp * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ @@ -42,7 +36,7 @@ LLXform::~LLXform() { } -// Link optimization - don't inline these llwarns +// Link optimization - don't inline these LL_WARNS() void LLXform::warn(const char* const msg) { llwarns << msg << llendl; @@ -96,30 +90,29 @@ void LLXformMatrix::updateMatrix(BOOL update_bounds) { update(); - mWorldMatrix.initAll(mScale, mWorldRotation, mWorldPosition); + LLMatrix4 world_matrix; + world_matrix.initAll(mScale, mWorldRotation, mWorldPosition); + mWorldMatrix.loadu(world_matrix); if (update_bounds && (mChanged & MOVED)) { - mMin.mV[0] = mMax.mV[0] = mWorldMatrix.mMatrix[3][0]; - mMin.mV[1] = mMax.mV[1] = mWorldMatrix.mMatrix[3][1]; - mMin.mV[2] = mMax.mV[2] = mWorldMatrix.mMatrix[3][2]; + mMax = mMin = mWorldMatrix.getRow<3>(); - F32 f0 = (fabs(mWorldMatrix.mMatrix[0][0])+fabs(mWorldMatrix.mMatrix[1][0])+fabs(mWorldMatrix.mMatrix[2][0])) * 0.5f; - F32 f1 = (fabs(mWorldMatrix.mMatrix[0][1])+fabs(mWorldMatrix.mMatrix[1][1])+fabs(mWorldMatrix.mMatrix[2][1])) * 0.5f; - F32 f2 = (fabs(mWorldMatrix.mMatrix[0][2])+fabs(mWorldMatrix.mMatrix[1][2])+fabs(mWorldMatrix.mMatrix[2][2])) * 0.5f; + LLVector4a total_sum,sum1,sum2; + total_sum.setAbs(mWorldMatrix.getRow<0>()); + sum1.setAbs(mWorldMatrix.getRow<1>()); + sum2.setAbs(mWorldMatrix.getRow<2>()); + sum1.add(sum2); + total_sum.add(sum1); + total_sum.mul(.5f); - mMin.mV[0] -= f0; - mMin.mV[1] -= f1; - mMin.mV[2] -= f2; - - mMax.mV[0] += f0; - mMax.mV[1] += f1; - mMax.mV[2] += f2; + mMax.add(total_sum); + mMin.sub(total_sum); } } void LLXformMatrix::getMinMax(LLVector3& min, LLVector3& max) const { - min = mMin; - max = mMax; + min.set(mMin.getF32ptr()); + max.set(mMax.getF32ptr()); } diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h index 299202d71..06c408fa5 100644 --- a/indra/llmath/xform.h +++ b/indra/llmath/xform.h @@ -28,6 +28,7 @@ #include "v3math.h" #include "m4math.h" +#include "llmatrix4a.h" #include "llquaternion.h" const F32 MAX_OBJECT_Z = 4096.f; // should match REGION_HEIGHT_METERS, Pre-havok4: 768.f @@ -103,9 +104,9 @@ public: inline void setRotation(const F32 x, const F32 y, const F32 z, const F32 s); // Above functions must be inline for speed, but also - // need to emit warnings. llwarns causes inline LLError::CallSite + // need to emit warnings. LL_WARNS() causes inline LLError::CallSite // static objects that make more work for the linker. - // Avoid inline llwarns by calling this function. + // Avoid inline LL_WARNS() by calling this function. void warn(const char* const msg); void setChanged(const U32 bits) { mChanged |= bits; } @@ -130,20 +131,21 @@ public: const LLVector3& getWorldPosition() const { return mWorldPosition; } }; +LL_ALIGN_PREFIX(16) class LLXformMatrix : public LLXform { public: LLXformMatrix() : LLXform() {}; virtual ~LLXformMatrix(); - const LLMatrix4& getWorldMatrix() const { return mWorldMatrix; } - void setWorldMatrix (const LLMatrix4& mat) { mWorldMatrix = mat; } + const LLMatrix4a& getWorldMatrix() const { return mWorldMatrix; } + void setWorldMatrix (const LLMatrix4a& mat) { mWorldMatrix = mat; } void init() { mWorldMatrix.setIdentity(); - mMin.clearVec(); - mMax.clearVec(); + mMin.clear(); + mMax.clear(); LLXform::init(); } @@ -153,11 +155,11 @@ public: void getMinMax(LLVector3& min,LLVector3& max) const; protected: - LLMatrix4 mWorldMatrix; - LLVector3 mMin; - LLVector3 mMax; + LL_ALIGN_16(LLMatrix4a mWorldMatrix); + LL_ALIGN_16(LLVector4a mMin); + LL_ALIGN_16(LLVector4a mMax); -}; +} LL_ALIGN_POSTFIX(16); BOOL LLXform::setParent(LLXform* parent) { diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index b9052f12f..a37a9f916 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -905,7 +905,7 @@ AIHTTPTimeoutPolicy const* AIHTTPTimeoutPolicy::getTimeoutPolicyByName(std::stri #define P2(n, b) AIHTTPTimeoutPolicy n##_timeout(#n, b) // Policy name Policy -P(accountingCostResponder); +//P(accountingCostResponder); P(agentStateResponder); P(appearanceChangeMetricsResponder); P(assetUploadResponder); @@ -934,7 +934,9 @@ P(fetchScriptLimitsRegionDetailsResponder); P(fetchScriptLimitsRegionInfoResponder); P(fetchScriptLimitsRegionSummaryResponder); P(fnPtrResponder); +P(floaterPermsResponder); P2(gamingDataReceived, transfer_22s_connect_10s); +P(groupBanDataResponder); P2(groupMemberDataResponder, transfer_300s); P2(groupProposalBallotResponder, transfer_300s); P(homeLocationResponder); @@ -991,4 +993,4 @@ P(webProfileResponders); P(wholeModelFeeResponder); P(wholeModelUploadResponder); P2(XMLRPCResponder, connect_40s); -P2(crashLoggerResponder, transfer_300s); \ No newline at end of file +P2(crashLoggerResponder, transfer_300s); diff --git a/indra/llmessage/aihttptimeoutpolicy.h b/indra/llmessage/aihttptimeoutpolicy.h index 6c8fa0683..ba5347482 100644 --- a/indra/llmessage/aihttptimeoutpolicy.h +++ b/indra/llmessage/aihttptimeoutpolicy.h @@ -95,7 +95,7 @@ class AIHTTPTimeoutPolicy { void sanity_checks(void) const; // Accessors. - char const* name(void) const { return mName; } + char const* name(void) const { return mName ? mName : "AIHTTPTimeoutPolicyBase"; } U16 getConnectTimeout(std::string const& hostname) const; U16 getDNSLookup(void) const { return mDNSLookupGrace; } U16 getConnect(void) const { return mMaximumConnectTime; } diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index b16b086a0..d6aca358e 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -192,13 +192,13 @@ public: : mAgentIDs(agent_ids) { } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { // Pull expiration out of headers if available F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(mReceivedHeaders); F64 now = LLFrameTimer::getTotalSeconds(); - LLSD agents = content["agents"]; + LLSD agents = mContent["agents"]; LLSD::array_const_iterator it = agents.beginArray(); for ( ; it != agents.endArray(); ++it) { @@ -228,7 +228,7 @@ public: } // Same logic as error response case - LLSD unresolved_agents = content["bad_ids"]; + LLSD unresolved_agents = mContent["bad_ids"]; S32 num_unresolved = unresolved_agents.size(); if (num_unresolved > 0) { @@ -252,13 +252,13 @@ public: << LL_ENDL; } - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { // If there's an error, it might be caused by PeopleApi, // or when loading textures on startup and using a very slow // network, this query may time out. // What we should do depends on whether or not we have a cached name - LL_WARNS("AvNameCache") << "LLAvatarNameResponder::error " << status << " " << reason + LL_WARNS("AvNameCache") << "LLAvatarNameResponder::httpFailure " << mStatus << " " << mReason << LL_ENDL; // Add dummy records for any agent IDs in this request that we do not have cached already @@ -794,6 +794,7 @@ void LLAvatarNameCache::setUseDisplayNames(bool use) if (use != sUseDisplayNames) { sUseDisplayNames = use; + LL_DEBUGS("AvNameCache") << "Display names are now: " << (use ? "on" : "off") << LL_ENDL; // flush our cache sCache.clear(); diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index bd40d8e69..bc208281d 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -243,7 +243,9 @@ bool LLHTTPClient::getByteRange(std::string const& url, AIHTTPHeaders& headers, { if (offset > 0 || bytes > 0) { - headers.addHeader("Range", llformat("bytes=%d-%d", offset, offset + bytes - 1)); + int const range_end = offset + bytes - 1; + char const* const range_format = (range_end >= HTTP_REQUESTS_RANGE_END_MAX) ? "bytes=%d-" : "bytes=%d-%d"; + headers.addHeader("Range", llformat(range_format, offset, range_end)); } request(url, HTTP_GET, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); } @@ -310,36 +312,36 @@ AIHTTPTimeoutPolicy const& LLHTTPClient::ResponderBase::getHTTPTimeoutPolicy(voi return AIHTTPTimeoutPolicy::getDebugSettingsCurlTimeout(); } -void LLHTTPClient::ResponderBase::decode_llsd_body(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer, LLSD& content) +void LLHTTPClient::ResponderBase::decode_llsd_body(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { AICurlInterface::Stats::llsd_body_count++; - if (is_internal_http_error(status)) + if (is_internal_http_error(mStatus)) { // In case of an internal error (ie, a curl error), a description of the (curl) error is the best we can do. // In any case, the body if anything was received at all, can not be relied upon. - content = reason; + mContent = mReason; return; } // If the status indicates success (and we get here) then we expect the body to be LLSD. - bool const should_be_llsd = (200 <= status && status < 300); + bool const should_be_llsd = isGoodStatus(mStatus); if (should_be_llsd) { LLBufferStream istr(channels, buffer.get()); - if (LLSDSerialize::fromXML(content, istr) == LLSDParser::PARSE_FAILURE) + if (LLSDSerialize::fromXML(mContent, istr) == LLSDParser::PARSE_FAILURE) { // Unfortunately we can't show the body of the message... I think this is a pretty serious error // though, so if this ever happens it has to be investigated by making a copy of the buffer // before serializing it, as is done below. - llwarns << "Failed to deserialize LLSD. " << mURL << " [" << status << "]: " << reason << llendl; + llwarns << "Failed to deserialize LLSD. " << mURL << " [" << mStatus << "]: " << mReason << llendl; AICurlInterface::Stats::llsd_body_parse_error++; } - // LLSDSerialize::fromXML destructed buffer, we can't initialize content now. + // LLSDSerialize::fromXML destructed buffer, we can't initialize mContent now. return; } - // Put the body in content as-is. + // Put the body in mContent as-is. std::stringstream ss; buffer->writeChannelTo(ss, channels.in()); - content = ss.str(); + mContent = ss.str(); #ifdef SHOW_ASSERT if (!should_be_llsd) { @@ -355,7 +357,7 @@ void LLHTTPClient::ResponderBase::decode_llsd_body(U32 status, std::string const LLSDSerialize::fromXML(dummy, ss) > 0; if (server_sent_llsd_with_http_error) { - llwarns << "The server sent us a response with http status " << status << " and LLSD(!) body: \"" << ss.str() << "\"!" << llendl; + llwarns << "The server sent us a response with http status " << mStatus << " and LLSD(!) body: \"" << ss.str() << "\"!" << llendl; } // This is not really an error, and it has been known to happen before. It just normally never happens (at the moment) // and therefore warrants an investigation. Linden Lab (or other grids) might start to send error messages @@ -368,14 +370,14 @@ void LLHTTPClient::ResponderBase::decode_llsd_body(U32 status, std::string const #endif } -void LLHTTPClient::ResponderBase::decode_raw_body(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer, std::string& content) +void LLHTTPClient::ResponderBase::decode_raw_body(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer, std::string& content) { AICurlInterface::Stats::raw_body_count++; - if (is_internal_http_error(status)) + if (is_internal_http_error(mStatus)) { // In case of an internal error (ie, a curl error), a description of the (curl) error is the best we can do. // In any case, the body if anything was received at all, can not be relied upon. - content = reason; + content = mReason; return; } LLMutexLock lock(buffer->getMutex()); @@ -407,19 +409,43 @@ std::string const& LLHTTPClient::ResponderBase::get_cookie(std::string const& ke return empty_dummy; } +std::string LLHTTPClient::ResponderBase::dumpResponse(void) const +{ + std::ostringstream s; + s << "[responder:" << getName() << "] " + << "[URL:" << mURL << "] " + << "[status:" << mStatus << "] " + << "[reason:" << mReason << "] "; + + AIHTTPReceivedHeaders::range_type content_type; + if (mReceivedHeaders.getValues("content-type", content_type)) + { + for (AIHTTPReceivedHeaders::iterator_type iter = content_type.first; iter != content_type.second; ++iter) + { + s << "[content-type:" << iter->second << "] "; + } + } + + if (mContent.isDefined()) + { + s << "[content:" << LLSDOStreamer(mContent, LLSDFormatter::OPTIONS_PRETTY) << "]"; + } + + return s.str(); +} + // Called with HTML body. // virtual -void LLHTTPClient::ResponderWithCompleted::completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) +void LLHTTPClient::ResponderWithCompleted::completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { - LLSD content; - decode_llsd_body(status, reason, channels, buffer, content); + decode_llsd_body(channels, buffer); // Allow derived class to override at this point. - completed(status, reason, content); + httpCompleted(); } // virtual -void LLHTTPClient::ResponderWithCompleted::completed(U32 status, std::string const& reason, LLSD const& content) +void LLHTTPClient::ResponderWithCompleted::httpCompleted(void) { // Either completedRaw() or this method must be overridden by the derived class. Hence, we should never get here. llassert_always(false); @@ -429,36 +455,31 @@ void LLHTTPClient::ResponderWithCompleted::completed(U32 status, std::string con void LLHTTPClient::ResponderWithResult::finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { mCode = code; + mStatus = http_status; + mReason = reason; - LLSD content; - decode_llsd_body(http_status, reason, channels, buffer, content); + // Fill mContent. + decode_llsd_body(channels, buffer); // HTTP status good? - if (200 <= http_status && http_status < 300) + if (isGoodStatus(http_status)) { // Allow derived class to override at this point. - result(content); + httpSuccess(); } else { // Allow derived class to override at this point. - errorWithContent(http_status, reason, content); + httpFailure(); } mFinished = true; } // virtual -void LLHTTPClient::ResponderWithResult::errorWithContent(U32 status, std::string const& reason, LLSD const&) +void LLHTTPClient::ResponderWithResult::httpFailure(void) { - // Allow derived class to override at this point. - error(status, reason); -} - -// virtual -void LLHTTPClient::ResponderWithResult::error(U32 status, std::string const& reason) -{ - llinfos << mURL << " [" << status << "]: " << reason << llendl; + llinfos << mURL << " [" << mStatus << "]: " << mReason << llendl; } // Friend functions. @@ -480,22 +501,20 @@ void intrusive_ptr_release(LLHTTPClient::ResponderBase* responder) // Blocking Responders. // -class BlockingResponder : public LLHTTPClient::LegacyPolledResponder { +class BlockingResponder : public LLHTTPClient::ResponderWithCompleted { private: LLCondition mSignal; // Wait condition to wait till mFinished is true. - static LLSD LLSD_dummy; static std::string Raw_dummy; public: void wait(void); // Blocks until mFinished is true. - virtual LLSD const& getLLSD(void) const { llassert(false); return LLSD_dummy; } virtual std::string const& getRaw(void) const { llassert(false); return Raw_dummy; } + /*virtual*/ LLSD const& getContent(void) const { llassert(false); return LLHTTPClient::ResponderWithCompleted::getContent(); } protected: void wakeup(void); // Call this at the end of completedRaw. }; -LLSD BlockingResponder::LLSD_dummy; std::string BlockingResponder::Raw_dummy; void BlockingResponder::wait(void) @@ -530,14 +549,11 @@ void BlockingResponder::wakeup(void) } class BlockingLLSDResponder : public BlockingResponder { -private: - LLSD mResponse; - protected: - /*virtual*/ LLSD const& getLLSD(void) const { llassert(mFinished && mCode == CURLE_OK); return mResponse; } - /*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) + /*virtual*/ LLSD const& getContent(void) const { llassert(mFinished && mCode == CURLE_OK); return LLHTTPClient::ResponderWithCompleted::getContent(); } + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { - decode_llsd_body(status, reason, channels, buffer, mResponse); // This puts the body asString() in mResponse in case of http error. + decode_llsd_body(channels, buffer); // This puts the body asString() in mContent in case of http error. wakeup(); } }; @@ -548,9 +564,9 @@ private: protected: /*virtual*/ std::string const& getRaw(void) const { llassert(mFinished && mCode == CURLE_OK); return mResponse; } - /*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { - decode_raw_body(mCode, reason, channels, buffer, mResponse); + decode_raw_body(channels, buffer, mResponse); wakeup(); } }; @@ -630,7 +646,7 @@ static LLSD blocking_request( LLSD response = LLSD::emptyMap(); CURLcode result = responder->result_code(); - S32 http_status = responder->http_status(); + S32 http_status = responder->getStatus(); bool http_success = http_status >= 200 && http_status < 300; if (result == CURLE_OK && http_success) @@ -641,7 +657,7 @@ static LLSD blocking_request( } else { - response["body"] = responder->getLLSD(); + response["body"] = responder->getContent(); } } else if (result == CURLE_OK && !is_internal_http_error(http_status)) @@ -663,7 +679,7 @@ static LLSD blocking_request( } else { - llwarns << "CURL ERROR BODY: " << responder->getLLSD().asString() << llendl; + llwarns << "CURL ERROR BODY: " << responder->getContent().asString() << llendl; } } if (method == HTTP_RAW_GET) @@ -672,12 +688,12 @@ static LLSD blocking_request( } else { - response["body"] = responder->getLLSD().asString(); + response["body"] = responder->getContent().asString(); } } else { - response["body"] = responder->reason(); + response["body"] = responder->getReason(); } response["status"] = http_status; diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index 3bb60b04f..b0fdd53f3 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -55,6 +55,17 @@ typedef struct _xmlrpc_request* XMLRPC_REQUEST; typedef struct _xmlrpc_value* XMLRPC_VALUE; extern AIEngine gMainThreadEngine; +// In Viewer 3 this definition is in indra/newview/lltexturefetch.cpp, +// but we need it in two .cpp files, so it's moved here. +// +// BUG-3323/SH-4375 +// *NOTE: This is a heuristic value. Texture fetches have a habit of using a +// value of 32MB to indicate 'get the rest of the image'. Certain ISPs and +// network equipment get confused when they see this in a Range: header. So, +// if the request end is beyond this value, we issue an open-ended Range: +// request (e.g. 'Range: -') which seems to fix the problem. +static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000; + // Output parameter of AICurlPrivate::CurlEasyRequest::getResult. // Used in XMLRPCResponder. struct AITransferInfo { @@ -136,7 +147,7 @@ public: /** * @brief return true if the status code indicates success. */ - static bool isGoodStatus(U32 status) + static bool isGoodStatus(S32 status) { return((200 <= status) && (status < 300)); } @@ -145,11 +156,11 @@ public: ResponderBase(void); virtual ~ResponderBase(); - // Read body from buffer and put it into content. If status indicates success, interpret it as LLSD, otherwise copy it as-is. - void decode_llsd_body(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer, LLSD& content); + // Read body from buffer and put it into mContent. If mStatus indicates success, interpret it as LLSD, otherwise copy it as-is. + void decode_llsd_body(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer); // Read body from buffer and put it into content. Always copy it as-is. - void decode_raw_body(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer, std::string& content); + void decode_raw_body(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer, std::string& content); protected: // Associated URL, used for debug output. @@ -161,6 +172,15 @@ public: // The curl result code. CURLcode mCode; + // HTTP status code, if any. + S32 mStatus; + + // Reason for error if mStatus is not good. + std::string mReason; + + // Content interpreted as LLSD. + LLSD mContent; + // Set when the transaction finished (with or without errors). bool mFinished; @@ -173,6 +193,29 @@ public: std::string const& getURL(void) const { return mURL; } CURLcode result_code(void) const { return mCode; } + protected: + // Short cut. + void setResult(S32 status, std::string const& reason, LLSD const& content) { mStatus = status; mReason = reason; mContent = content; mFinished = true; } + + // Call these only from the httpSuccess/httpFailure/httpComplete methods of derived classes. + + LLSD const& getContent(void) const { return mContent; } + // You can just access mReceivedHeaders directly from derived classes, but added this accessor + // for convenience because upstream introduced this method as part of a new API. + AIHTTPReceivedHeaders const& getResponseHeaders(void) const + { + // If this fails then you need to add '/*virtual*/ bool needsHeaders(void) const { return true; }' to the most derived class. + llassert(needsHeaders()); + return mReceivedHeaders; + } + // Another convenience method to match upstream. + std::string dumpResponse(void) const; + public: + // The next two are public because blocking_request() needs access too. + S32 getStatus(void) const { return mStatus; } + std::string const& getReason(void) const { return mReason; } + + public: // Called by BufferedCurlEasyRequest::timed_out or BufferedCurlEasyRequest::processOutput. virtual void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) = 0; @@ -215,7 +258,9 @@ public: // Called when the whole transaction is completed (also the body was received), but before the body is processed. /*virtual*/ void completed_headers(U32 status, std::string const& reason, AITransferInfo* info) { - completedHeaders(status, reason, mReceivedHeaders); + mStatus = status; + mReason = reason; + completedHeaders(); } // Extract cookie 'key' from mReceivedHeaders and return the string 'key=value', or an empty string if key does not exists. @@ -243,7 +288,7 @@ public: virtual AICapabilityType capability_type(void) const { return cap_other; } // Timeout policy to use. - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const = 0; + virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const; // The name of the derived responder object. For debugging purposes. virtual char const* getName(void) const = 0; @@ -251,7 +296,7 @@ public: protected: // Derived classes can override this to get the HTML headers that were received, when the message is completed. // Only actually called for classes that implement a needsHeaders() that returns true. - virtual void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + virtual void completedHeaders(void) { // The default does nothing. } @@ -278,8 +323,10 @@ public: /*virtual*/ void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { mCode = code; + mStatus = http_status; + mReason = reason; // Allow classes derived from ResponderHeadersOnly to override completedHeaders. - completedHeaders(http_status, reason, mReceivedHeaders); + completedHeaders(); mFinished = true; } @@ -291,10 +338,9 @@ public: // warning when a class accidently tries to override them. enum YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS { }; virtual void completedRaw(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } - virtual void completed(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } - virtual void result(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } - virtual void errorWithContent(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } - virtual void error(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } + virtual void httpCompleted(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } + virtual void httpSuccess(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } + virtual void httpFailure(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } #endif }; @@ -310,9 +356,11 @@ public: /*virtual*/ void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { mCode = code; + mStatus = http_status; + mReason = reason; // Allow classes derived from ResponderWithCompleted to override completedRaw // (if not they should override completed or be derived from ResponderWithResult instead). - completedRaw(http_status, reason, channels, buffer); + completedRaw(channels, buffer); mFinished = true; } @@ -320,13 +368,17 @@ public: // Events generated by this class. // Derived classes can override this to get the raw data of the body of the HTML message that was received. - // The default is to interpret the content as LLSD and call completed(). - virtual void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer); + // The default is to interpret the content as LLSD and call httpCompleted(). + virtual void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer); // ... or, derived classes can override this to get LLSD content when the message is completed. // The default aborts, as it should never be called (can't make it pure virtual though, so // classes that override completedRaw don't need to implement this function, too). - virtual void completed(U32 status, std::string const& reason, LLSD const& content); + virtual void httpCompleted(void); + + public: + // Ugly LL API... + void completeResult(S32 status, std::string const& reason, LLSD const& content) { mCode = CURLE_OK; setResult(status, reason, content); httpCompleted(); } #ifdef SHOW_ASSERT // Responders derived from this class must override either completedRaw or completed. @@ -334,9 +386,8 @@ public: // Define those functions here with different parameters in order to cause a compile // warning when a class accidently tries to override them. enum YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS { }; - virtual void result(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { } - virtual void errorWithContent(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { } - virtual void error(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { } + virtual void httpSuccess(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { } + virtual void httpFailure(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { } #endif }; @@ -355,22 +406,18 @@ public: // Events generated by this class. // Derived classes must override this to receive the content of a body upon success. - virtual void result(LLSD const& content) = 0; - - // Derived classes can override this to get informed when a bad HTML status code is received. - // The default calls error(). - virtual void errorWithContent(U32 status, std::string const& reason, LLSD const& content); + virtual void httpSuccess(void) = 0; // ... or, derived classes can override this to get informed when a bad HTML status code is received. // The default prints the error to llinfos. - virtual void error(U32 status, std::string const& reason); + virtual void httpFailure(void); public: // Called from LLSDMessage::ResponderAdapter::listener. // LLSDMessage::ResponderAdapter is a hack, showing among others by fact that it needs these functions. - void pubErrorWithContent(CURLcode code, U32 status, std::string const& reason, LLSD const& content) { mCode = code; errorWithContent(status, reason, content); mFinished = true; } - void pubResult(LLSD const& content) { mCode = CURLE_OK; result(content); mFinished = true; } + void failureResult(U32 status, std::string const& reason, LLSD const& content, CURLcode code = CURLE_OK) { mCode = code; setResult(status, reason, content); httpFailure(); } + void successResult(LLSD const& content) { mCode = CURLE_OK; setResult(HTTP_OK, "", content); httpSuccess(); } #ifdef SHOW_ASSERT // Responders derived from this class must override result, and either errorWithContent or error. @@ -379,48 +426,16 @@ public: // warning when a class accidently tries to override them. enum YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS { }; virtual void completedRaw(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { } - virtual void completed(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { } + virtual void httpCompleted(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { } #endif }; - /** - * @class LegacyPolledResponder - * @brief As ResponderWithCompleted but caches the result for polling. - * - * This class allows old polling code to poll if the transaction finished - * by calling is_finished() (from the main the thread) and then access the - * results-- as opposed to immediately digesting the results when any of - * the virtual functions are called. - */ - class LegacyPolledResponder : public ResponderWithCompleted { - protected: - U32 mStatus; - std::string mReason; - - protected: - // The responder finished. Do not override this function in derived classes. - /*virtual*/ void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) - { - mStatus = http_status; - mReason = reason; - // Call base class implementation. - ResponderWithCompleted::finished(code, http_status, reason, channels, buffer); - } - - public: - LegacyPolledResponder(void) : mStatus(HTTP_INTERNAL_ERROR_OTHER) { } - - // Accessors. - U32 http_status(void) const { return mStatus; } - std::string const& reason(void) const { return mReason; } - }; - /** * @class ResponderIgnoreBody * @brief Base class for responders that ignore the result body. */ class ResponderIgnoreBody : public ResponderWithResult { - void result(LLSD const&) { } + void httpSuccess(void) { } }; /** diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index 8d51207a9..c1cf26574 100644 --- a/indra/llmessage/llregionflags.h +++ b/indra/llmessage/llregionflags.h @@ -78,6 +78,8 @@ const U64 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23); const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26); +const U64 REGION_FLAGS_BLOCK_FLYOVER = (1 << 27); + const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28); const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29); diff --git a/indra/llmessage/llsdmessage.cpp b/indra/llmessage/llsdmessage.cpp index dc091a543..1841207ea 100644 --- a/indra/llmessage/llsdmessage.cpp +++ b/indra/llmessage/llsdmessage.cpp @@ -99,14 +99,14 @@ void LLSDMessage::EventResponder::setTimeoutPolicy(std::string const& name) mHTTPTimeoutPolicy = AIHTTPTimeoutPolicy::getTimeoutPolicyByName(name); } -void LLSDMessage::EventResponder::result(const LLSD& data) +void LLSDMessage::EventResponder::httpSuccess(void) { // If our caller passed an empty replyPump name, they're not // listening: this is a fire-and-forget message. Don't bother posting // to the pump whose name is "". if (! mReplyPump.empty()) { - LLSD response(data); + LLSD response(mContent); mReqID.stamp(response); mPumps.obtain(mReplyPump).post(response); } @@ -118,7 +118,7 @@ void LLSDMessage::EventResponder::result(const LLSD& data) } } -void LLSDMessage::EventResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content) +void LLSDMessage::EventResponder::httpFailure(void) { // If our caller passed an empty errorPump name, they're not // listening: "default error handling is acceptable." Only post to an @@ -129,9 +129,9 @@ void LLSDMessage::EventResponder::errorWithContent(U32 status, const std::string info["target"] = mTarget; info["message"] = mMessage; info["code"] = mCode; - info["status"] = LLSD::Integer(status); - info["reason"] = reason; - info["content"] = content; + info["status"] = LLSD::Integer(mStatus); + info["reason"] = mReason; + info["content"] = mContent; mPumps.obtain(mErrorPump).post(info); } else // default error handling @@ -139,8 +139,8 @@ void LLSDMessage::EventResponder::errorWithContent(U32 status, const std::string // convention seems to be to use llinfos, but that seems a bit casual? LL_WARNS("LLSDMessage::EventResponder") << "'" << mMessage << "' to '" << mTarget - << "' failed with code " << status << ": " << reason << '\n' - << ll_pretty_print_sd(content) + << "' failed with code " << mStatus << ": " << mReason << '\n' + << ll_pretty_print_sd(mContent) << LL_ENDL; } } @@ -165,15 +165,15 @@ bool LLSDMessage::ResponderAdapter::listener(const LLSD& payload, bool success) LLHTTPClient::ResponderWithResult* responder = dynamic_cast(mResponder.get()); // If this assertion fails then ResponderAdapter has been used for a ResponderWithCompleted derived class, // which is not allowed because ResponderAdapter can only work for classes derived from Responder that - // implement result() and errorWithContent (or just error). + // implement httpSuccess() and httpFailure(). llassert_always(responder); if (success) { - responder->pubResult(payload); + responder->successResult(payload); } else { - responder->pubErrorWithContent((CURLcode)payload["code"].asInteger(), payload["status"].asInteger(), payload["reason"], payload["content"]); + responder->failureResult(payload["status"].asInteger(), payload["reason"], payload["content"], (CURLcode)payload["code"].asInteger()); } /*---------------- MUST BE LAST STATEMENT BEFORE RETURN ----------------*/ diff --git a/indra/llmessage/llsdmessage.h b/indra/llmessage/llsdmessage.h index 6e7530ddb..bd99fdb9e 100644 --- a/indra/llmessage/llsdmessage.h +++ b/indra/llmessage/llsdmessage.h @@ -156,8 +156,8 @@ private: void setTimeoutPolicy(std::string const& name); - /*virtual*/ void result(const LLSD& data); - /*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return *mHTTPTimeoutPolicy; } /*virtual*/ char const* getName(void) const { return "EventResponder"; } diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index bfce2ea29..2813cbf7e 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -91,15 +91,17 @@ void LLTemplateMessageReader::getData(const char *blockname, const char *varname } LLMsgBlkData *msg_block_data = iter->second; - LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep]; + LLMsgBlkData::msg_var_data_map_t &var_data_map = msg_block_data->mMemberVarData; - if (!vardata.getName()) + if (var_data_map.find(vnamep) == var_data_map.end()) { llerrs << "Variable "<< vnamep << " not in message " << mCurrentRMessageData->mName<< " block " << bnamep << llendl; return; } + LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep]; + if (size && size != vardata.getSize()) { llerrs << "Msg " << mCurrentRMessageData->mName @@ -284,7 +286,7 @@ void LLTemplateMessageReader::getU8(const char *block, const char *var, void LLTemplateMessageReader::getBOOL(const char *block, const char *var, BOOL &b, S32 blocknum ) { - U8 value; + U8 value(0); getData(block, var, &value, sizeof(U8), blocknum); b = (BOOL) value; } diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 5b806161b..a112277ad 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -78,7 +78,7 @@ LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, std::string cons LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, AIPerService::Approvement* approved, bool keepalive, bool is_auth, bool compression) : mAction(action), mURL(url), mKeepAlive(keepalive), mIsAuth(is_auth), mNoCompression(!compression), - mBody(body), mResponder(responder), mHeaders(headers), mResponderNameCache(responder ? responder->getName() : "") + mBody(body), mResponder(responder), mHeaders(headers), mResponderNameCache(std::string("LLURLRequest:") + std::string(responder ? responder->getName() : "")) { if (approved) { @@ -276,32 +276,4 @@ bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w) return rv; } -// Called from AIStateMachine::mainloop, but put here because we don't want to include llurlrequest.h there of course. -void print_statemachine_diagnostics(U64 total_clocks, U64 max_delta, AIEngine::queued_type::const_reference slowest_element) -{ - AIStateMachine const& slowest_state_machine = slowest_element.statemachine(); - LLURLRequest const* request = dynamic_cast(&slowest_state_machine); - F64 const tfactor = 1000 / calc_clock_frequency(); - std::ostringstream msg; - if (total_clocks > max_delta) - { - msg << "AIStateMachine::mainloop did run for " << (total_clocks * tfactor) << " ms. The slowest "; - } - else - { - msg << "AIStateMachine::mainloop: A "; - } - msg << "state machine "; - if (request) - { - msg << "(" << request->getResponderName() << ") "; - } - msg << "ran for " << (max_delta * tfactor) << " ms"; - if (slowest_state_machine.getRuntime() > max_delta) - { - msg << " (" << (slowest_state_machine.getRuntime() * tfactor) << " ms in total now)"; - } - msg << "."; - llwarns << msg.str() << llendl; -} diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index c888b7db3..697b42b46 100644 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -72,7 +72,7 @@ class LLURLRequest : public AICurlEasyRequestStateMachine { /** * @brief Cached value of responder->getName() as passed to the constructor. */ - char const* getResponderName(void) const { return mResponderNameCache; } + /*virtual*/ const char* getName() const { return mResponderNameCache.c_str(); } protected: // Call abort(), not delete. @@ -113,7 +113,7 @@ class LLURLRequest : public AICurlEasyRequestStateMachine { U32 mBodySize; LLHTTPClient::ResponderPtr mResponder; AIHTTPHeaders mHeaders; - char const* mResponderNameCache; + std::string mResponderNameCache; protected: // Handle initializing the object. diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 814d407d0..b06751886 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -116,20 +116,20 @@ namespace { } - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { // don't spam when agent communication disconnected already - if (status != 410) + if (mStatus != 410) { - LL_WARNS("Messaging") << "error status " << status + LL_WARNS("Messaging") << "error status " << mStatus << " for message " << mMessageName - << " reason " << reason << llendl; + << " reason " << mReason << llendl; } - // TODO: Map status in to useful error code. + // TODO: Map mStatus in to useful error code. if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT); } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_NOERR); } diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 3e38db897..911d461f7 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -31,6 +31,7 @@ #include "llconvexdecomposition.h" #include "llsdserialize.h" #include "llvector4a.h" +#include "llmatrix4a.h" #if LL_MSVC #pragma warning (push) #pragma warning (disable : 4068) @@ -172,6 +173,11 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa return LLModel::BAD_ELEMENT; } + if (!pos_source) + { + llwarns << "Unable to process mesh without position data; invalid model; invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } domPRef p = tri->getP(); domListOfUInts& idx = p->getValue(); @@ -181,19 +187,22 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy ; domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy ; - if (pos_source) - { - face.mExtents[0].set(v[0], v[1], v[2]); - face.mExtents[1].set(v[0], v[1], v[2]); - } - LLVolumeFace::VertexMapData::PointMap point_map; - + U32 index_count = idx.getCount(); U32 vertex_count = pos_source ? v.getCount() : 0; U32 tc_count = tc_source ? tc.getCount() : 0; U32 norm_count = norm_source ? n.getCount() : 0; + if (vertex_count == 0) + { + llwarns << "Unable to process mesh with empty position array; invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } + + face.mExtents[0].set(v[0], v[1], v[2]); + face.mExtents[1].set(v[0], v[1], v[2]); + for (U32 i = 0; i < index_count; i += idx_stride) { LLVolumeFace::VertexData cv; diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 38adb7dd0..b03111f7e 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -74,6 +74,11 @@ set(llrender_HEADER_FILES set_source_files_properties(${llrender_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) +# Workaround hack for clang bugs +if (DARWIN) + set_property(SOURCE llgl.cpp PROPERTY COMPILE_FLAGS -O1) +endif (DARWIN) + list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES}) add_library (llrender ${llrender_SOURCE_FILES}) diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 45a3b1817..3fd4464fb 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -34,6 +34,7 @@ #include "v3dmath.h" #include "m3math.h" #include "m4math.h" +#include "llmatrix4a.h" #include "llrender.h" #include "llglslshader.h" @@ -265,18 +266,19 @@ void LLCubeMap::setMatrix(S32 stage) gGL.getTexUnit(stage)->activate(); } - LLVector3 x(gGLModelView+0); - LLVector3 y(gGLModelView+4); - LLVector3 z(gGLModelView+8); + LLVector3 x(gGLModelView.getRow<0>().getF32ptr()); + LLVector3 y(gGLModelView.getRow<1>().getF32ptr()); + LLVector3 z(gGLModelView.getRow<2>().getF32ptr()); LLMatrix3 mat3; mat3.setRows(x,y,z); - LLMatrix4 trans(mat3); + LLMatrix4a trans; + trans.loadu(mat3); trans.transpose(); gGL.matrixMode(LLRender::MM_TEXTURE); gGL.pushMatrix(); - gGL.loadMatrix((F32 *)trans.mMatrix); + gGL.loadMatrix(trans); gGL.matrixMode(LLRender::MM_MODELVIEW); /*if (stage > 0) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 11d8fa557..1471ccfb3 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -444,6 +444,7 @@ LLGLManager::LLGLManager() : mHasDebugOutput(FALSE), mHasAdaptiveVsync(FALSE), + mHasTextureSwizzle(FALSE), mIsATI(FALSE), mIsNVIDIA(FALSE), @@ -1382,6 +1383,35 @@ void flush_glerror() glGetError(); } +const std::string getGLErrorString(GLenum error) +{ + switch(error) + { + case GL_NO_ERROR: + return "No Error"; + case GL_INVALID_ENUM: + return "Invalid Enum"; + case GL_INVALID_VALUE: + return "Invalid Value"; + case GL_INVALID_OPERATION: + return "Invalid Operation"; + case GL_INVALID_FRAMEBUFFER_OPERATION: + return "Invalid Framebuffer Operation"; + case GL_OUT_OF_MEMORY: + return "Out of Memory"; + case GL_STACK_UNDERFLOW: + return "Stack Underflow"; + case GL_STACK_OVERFLOW: + return "Stack Overflow"; +#ifdef GL_TABLE_TOO_LARGE + case GL_TABLE_TOO_LARGE: + return "Table too large"; +#endif + default: + return "UNKNOWN ERROR"; + } +} + //this function outputs gl error to the log file, does not crash the code. void log_glerror() { @@ -1394,17 +1424,8 @@ void log_glerror() error = glGetError(); while (LL_UNLIKELY(error)) { - GLubyte const * gl_error_msg = gluErrorString(error); - if (NULL != gl_error_msg) - { - llwarns << "GL Error: " << error << " GL Error String: " << gl_error_msg << llendl ; - } - else - { - // gluErrorString returns NULL for some extensions' error codes. - // you'll probably have to grep for the number in glext.h. - llwarns << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << llendl; - } + std::string gl_error_msg = getGLErrorString(error); + llwarns << "GL Error: 0x" << std::hex << error << std::dec << " GL Error String: " << gl_error_msg << llendl; error = glGetError(); } } @@ -1418,27 +1439,13 @@ void do_assert_glerror() while (LL_UNLIKELY(error)) { quit = TRUE; - GLubyte const * gl_error_msg = gluErrorString(error); - if (NULL != gl_error_msg) + + std::string gl_error_msg = getGLErrorString(error); + LL_WARNS("RenderState") << "GL Error: 0x" << std::hex << error << std::dec << LL_ENDL; + LL_WARNS("RenderState") << "GL Error String: " << gl_error_msg << LL_ENDL; + if (gDebugSession) { - LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL; - LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL; - - if (gDebugSession) - { - gFailLog << "GL Error:" << gl_error_msg << std::endl; - } - } - else - { - // gluErrorString returns NULL for some extensions' error codes. - // you'll probably have to grep for the number in glext.h. - LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL; - - if (gDebugSession) - { - gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl; - } + gFailLog << "GL Error: 0x" << std::hex << error << std::dec << " GL Error String: " << gl_error_msg << std::endl; } error = glGetError(); } @@ -1662,10 +1669,6 @@ void LLGLState::checkTextureChannels(const std::string& msg) GLint stackDepth = 0; - glh::matrix4f mat; - glh::matrix4f identity; - identity.identity(); - for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++) { gGL.getTexUnit(i)->activate(); @@ -1685,10 +1688,11 @@ void LLGLState::checkTextureChannels(const std::string& msg) } } - glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m); + LLMatrix4a mat; + glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.mMatrix); stop_glerror(); - if (mat != identity) + if (!mat.isIdentity()) { error = TRUE; LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL; @@ -2179,7 +2183,7 @@ void parse_glsl_version(S32& major, S32& minor) LLStringUtil::convertToS32(minor_str, minor); } -LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply) +LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const LLMatrix4a& modelview, const LLMatrix4a& projection, bool apply) { mApply = apply; @@ -2194,27 +2198,42 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& mode void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d) { - glh::matrix4f& P = mProjection; - glh::matrix4f& M = mModelview; - - glh::matrix4f invtrans_MVP = (P * M).inverse().transpose(); - glh::vec4f oplane(a,b,c,d); - glh::vec4f cplane; - invtrans_MVP.mult_matrix_vec(oplane, cplane); + LLMatrix4a& P = mProjection; + LLMatrix4a& M = mModelview; - cplane /= fabs(cplane[2]); // normalize such that depth is not scaled - cplane[3] -= 1; + LLMatrix4a invtrans_MVP; + invtrans_MVP.setMul(P,M); + invtrans_MVP.invert(); + invtrans_MVP.transpose(); - if(cplane[2] < 0) - cplane *= -1; + LLVector4a oplane(a,b,c,d); + LLVector4a cplane; + LLVector4a cplane_splat; + LLVector4a cplane_neg; + + invtrans_MVP.rotate4(oplane,cplane); + + cplane_splat.splat<2>(cplane); + cplane_splat.setAbs(cplane_splat); + cplane.div(cplane_splat); + cplane.sub(LLVector4a(0.f,0.f,0.f,1.f)); + + cplane_splat.splat<2>(cplane); + cplane_neg = cplane; + cplane_neg.negate(); + + cplane.setSelectWithMask( cplane_splat.lessThan( _mm_setzero_ps() ), cplane_neg, cplane ); + + LLMatrix4a suffix; + suffix.setIdentity(); + suffix.setColumn<2>(cplane); + LLMatrix4a newP; + newP.setMul(suffix,P); - glh::matrix4f suffix; - suffix.set_row(2, cplane); - glh::matrix4f newP = suffix * P; gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); - gGL.loadMatrix(newP.m); - gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m); + gGL.loadMatrix(newP); + //gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m); gGL.matrixMode(LLRender::MM_MODELVIEW); } @@ -2403,19 +2422,18 @@ void LLGLDepthTest::checkState() } } -LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer) +LLGLSquashToFarClip::LLGLSquashToFarClip(const LLMatrix4a& P_in, U32 layer) { - + LLMatrix4a P = P_in; F32 depth = 0.99999f - 0.0001f * layer; - for (U32 i = 0; i < 4; i++) - { - P.element(2, i) = P.element(3, i) * depth; - } + LLVector4a col = P.getColumn<3>(); + col.mul(depth); + P.setColumn<2>(col); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); - gGL.loadMatrix(P.m); + gGL.loadMatrix(P); gGL.matrixMode(LLRender::MM_MODELVIEW); } diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 7b691e021..1cf65c8ca 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -38,12 +38,12 @@ #include "llstring.h" #include "stdtypes.h" #include "v4math.h" +#include "llmatrix4a.h" #include "llplane.h" #include "llgltypes.h" #include "llinstancetracker.h" #include "llglheaders.h" -#include "glh/glh_linear.h" extern BOOL gDebugGL; extern BOOL gDebugSession; @@ -321,21 +321,23 @@ public: Does not stack. Caches inverse of projection matrix used in gGLObliqueProjectionInverse */ +LL_ALIGN_PREFIX(16) class LLGLUserClipPlane { public: - LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply = true); + LLGLUserClipPlane(const LLPlane& plane, const LLMatrix4a& modelview, const LLMatrix4a& projection, bool apply = true); ~LLGLUserClipPlane(); void setPlane(F32 a, F32 b, F32 c, F32 d); private: - bool mApply; - glh::matrix4f mProjection; - glh::matrix4f mModelview; -}; + LL_ALIGN_16(LLMatrix4a mProjection); + LL_ALIGN_16(LLMatrix4a mModelview); + + bool mApply; +} LL_ALIGN_POSTFIX(16); /* Modify and load projection matrix to push depth values to far clip plane. @@ -348,7 +350,7 @@ private: class LLGLSquashToFarClip { public: - LLGLSquashToFarClip(glh::matrix4f projection, U32 layer = 0); + LLGLSquashToFarClip(const LLMatrix4a& projection, U32 layer = 0); ~LLGLSquashToFarClip(); }; @@ -455,8 +457,6 @@ public: void wait(); }; -extern LLMatrix4 gGLObliqueProjectionInverse; - #include "llglstates.h" void init_glstates(); diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 5aeed87ae..3a91c50ff 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -41,7 +41,6 @@ # include "GL/glx.h" # define GL_GLEXT_PROTOTYPES 1 # include "GL/glext.h" -# include "GL/glu.h" # include "GL/glx.h" # define GLX_GLXEXT_PROTOTYPES 1 # include "GL/glxext.h" @@ -266,7 +265,6 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; #define GL_GLEXT_PROTOTYPES 1 #include "GL/gl.h" #include "GL/glext.h" -#include "GL/glu.h" // The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly # define __APPLE__ @@ -282,7 +280,6 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; // quotes so we get libraries/.../GL/ version #include "GL/gl.h" #include "GL/glext.h" -#include "GL/glu.h" #if LL_LINUX && !LL_MESA_HEADLESS @@ -551,7 +548,6 @@ extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange; //---------------------------------------------------------------------------- #include -#include // quotes so we get libraries/.../GL/ version #include "GL/glext.h" @@ -789,7 +785,6 @@ extern PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB; // LL_DARWIN #include -#include #define GL_EXT_separate_specular_color 1 #include diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 2ad5d355e..a5fb16ee0 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -468,6 +468,8 @@ LLImageGL::~LLImageGL() sCount--; } +const S8 INVALID_OFFSET = -99 ; + void LLImageGL::init(BOOL usemipmaps) { // keep these members in the same order as declared in llimagehl.h @@ -484,14 +486,12 @@ void LLImageGL::init(BOOL usemipmaps) mHasExplicitFormat = FALSE; mAutoGenMips = FALSE; - mCanMask = TRUE; mIsMask = FALSE; mMaskRMSE = 1.f ; - - mNeedsAlphaAndPickMask = TRUE ; + mNeedsAlphaAndPickMask = FALSE ; mAlphaStride = 0 ; - mAlphaOffset = 0 ; + mAlphaOffset = INVALID_OFFSET ; mGLTextureCreated = FALSE ; mTexName = 0; @@ -1709,7 +1709,6 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b } //Used by media in V2 -const S8 INVALID_OFFSET = -99 ; void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask) { if(mNeedsAlphaAndPickMask != need_mask) @@ -1723,7 +1722,6 @@ void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask) else //do not need alpha mask { mAlphaOffset = INVALID_OFFSET ; - mCanMask = FALSE; } } } @@ -1746,8 +1744,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() mAlphaStride = 2; break; case GL_RGB: - mNeedsAlphaAndPickMask = FALSE ; - mCanMask = FALSE; + setNeedsAlphaAndPickMask(FALSE); return ; //no alpha channel. case GL_RGBA: mAlphaStride = 4; @@ -1793,15 +1790,14 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() { llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl; - mNeedsAlphaAndPickMask = FALSE ; - mCanMask = FALSE; + setNeedsAlphaAndPickMask(FALSE); } } //std::map > > sTextureMaskMap; void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) { - if(!mNeedsAlphaAndPickMask || !mCanMask) + if(!mNeedsAlphaAndPickMask) { return ; } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index d5632e553..ecb5222de 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -135,7 +135,7 @@ public: BOOL getHasGLTexture() const { return mTexName != 0; } LLGLuint getTexName() const { return mTexName; } - BOOL getIsAlphaMask(const F32 max_rmse) const { return mCanMask && (max_rmse < 0.f ? (bool)mIsMask : (mMaskRMSE <= max_rmse)); } + BOOL getIsAlphaMask(const F32 max_rmse) const { return mNeedsAlphaAndPickMask && (max_rmse < 0.f ? (bool)mIsMask : (mMaskRMSE <= max_rmse)); } BOOL getIsResident(BOOL test_now = FALSE); // not const @@ -185,7 +185,6 @@ private: S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents) S8 mAutoGenMips; - BOOL mCanMask; BOOL mIsMask; F32 mMaskRMSE; BOOL mNeedsAlphaAndPickMask; diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp index ebdbc17ef..18be01d24 100644 --- a/indra/llrender/llpostprocess.cpp +++ b/indra/llrender/llpostprocess.cpp @@ -43,6 +43,7 @@ #include "llsdutil_math.h" #include "llvertexbuffer.h" #include "llfasttimer.h" +#include "llmatrix4a.h" extern LLGLSLShader gPostColorFilterProgram; extern LLGLSLShader gPostNightVisionProgram; @@ -305,21 +306,21 @@ public: { addSetting(mStrength); } - /*virtual*/ bool isEnabled() const { return LLPostProcessShader::isEnabled() && llabs(gGLModelView[0] - gGLPreviousModelView[0]) > .0000001; } + /*virtual*/ bool isEnabled() const { return LLPostProcessShader::isEnabled() && llabs(gGLModelView.getF32ptr()[0] - gGLPreviousModelView.getF32ptr()[0]) > .0000001; } /*virtual*/ S32 getColorChannel() const { return 0; } /*virtual*/ S32 getDepthChannel() const { return 1; } /*virtual*/ QuadType preDraw() { - glh::matrix4f inv_proj(gGLModelView); - inv_proj.mult_left(gGLProjection); - inv_proj = inv_proj.inverse(); - glh::matrix4f prev_proj(gGLPreviousModelView); - prev_proj.mult_left(gGLProjection); + LLMatrix4a inv_proj; + inv_proj.setMul(gGLProjection,gGLModelView); + inv_proj.invert(); + LLMatrix4a prev_proj; + prev_proj.setMul(gGLProjection,gGLPreviousModelView); LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions(); - getShader().uniformMatrix4fv(sPrevProj, 1, GL_FALSE, prev_proj.m); - getShader().uniformMatrix4fv(sInvProj, 1, GL_FALSE, inv_proj.m); + getShader().uniformMatrix4fv(sPrevProj, 1, GL_FALSE, prev_proj.getF32ptr()); + getShader().uniformMatrix4fv(sInvProj, 1, GL_FALSE, inv_proj.getF32ptr()); getShader().uniform2fv(sScreenRes, 1, screen_rect.mV); getShader().uniform1i(sBlurStrength, mStrength); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 2439c75e6..ed8497536 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -35,17 +35,18 @@ #include "llrendertarget.h" #include "lltexture.h" #include "llshadermgr.h" +#include "llmatrix4a.h" LLRender gGL; // Handy copies of last good GL matrices //Would be best to migrate these to LLMatrix4a and LLVector4a, but that's too divergent right now. -LL_ALIGN_16(F32 gGLModelView[16]); -LL_ALIGN_16(F32 gGLLastModelView[16]); -LL_ALIGN_16(F32 gGLPreviousModelView[16]); -LL_ALIGN_16(F32 gGLLastProjection[16]); -LL_ALIGN_16(F32 gGLProjection[16]); -LL_ALIGN_16(S32 gGLViewport[4]); +LLMatrix4a gGLModelView; +LLMatrix4a gGLLastModelView; +LLMatrix4a gGLPreviousModelView; +LLMatrix4a gGLLastProjection; +LLMatrix4a gGLProjection; +S32 gGLViewport[4]; U32 LLRender::sUICalls = 0; U32 LLRender::sUIVerts = 0; @@ -928,12 +929,12 @@ void LLLightState::setPosition(const LLVector4& position) } else { //transform position by current modelview matrix - glh::vec4f pos(position.mV); + LLVector4a pos; + pos.loadua(position.mV); - const glh::matrix4f& mat = gGL.getModelviewMatrix(); - mat.mult_matrix_vec(pos); + gGL.getModelviewMatrix().rotate4(pos,pos); - mPosition.set(pos.v); + mPosition.set(pos.getF32ptr()); } } @@ -1014,12 +1015,12 @@ void LLLightState::setSpotDirection(const LLVector3& direction) } else { //transform direction by current modelview matrix - glh::vec3f dir(direction.mV); + LLVector4a dir; + dir.load3(direction.mV); - const glh::matrix4f& mat = gGL.getModelviewMatrix(); - mat.mult_matrix_dir(dir); + gGL.getModelviewMatrix().rotate(dir,dir); - mSpotDirection.set(dir.v); + mSpotDirection.set(dir.getF32ptr()); } } @@ -1066,6 +1067,18 @@ LLRender::LLRender() } mLightHash = 0; + + //Init base matrix for each mode + for(S32 i = 0; i < NUM_MATRIX_MODES; ++i) + { + mMatrix[i][0].setIdentity(); + } + + gGLModelView.setIdentity(); + gGLLastModelView.setIdentity(); + gGLPreviousModelView.setIdentity(); + gGLLastProjection.setIdentity(); + gGLProjection.setIdentity(); } LLRender::~LLRender() @@ -1188,12 +1201,11 @@ void LLRender::syncMatrices() }; LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - static glh::matrix4f cached_mvp; + static LLMatrix4a cached_mvp; static U32 cached_mvp_mdv_hash = 0xFFFFFFFF; static U32 cached_mvp_proj_hash = 0xFFFFFFFF; - static glh::matrix4f cached_normal; + static LLMatrix4a cached_normal; static U32 cached_normal_hash = 0xFFFFFFFF; if (shader) @@ -1205,9 +1217,9 @@ void LLRender::syncMatrices() U32 i = MM_MODELVIEW; if (mMatHash[i] != shader->mMatHash[i]) { //update modelview, normal, and MVP - glh::matrix4f& mat = mMatrix[i][mMatIdx[i]]; - - shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m); + const LLMatrix4a& mat = mMatrix[i][mMatIdx[i]]; + + shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.getF32ptr()); shader->mMatHash[i] = mMatHash[i]; //update normal matrix @@ -1216,20 +1228,20 @@ void LLRender::syncMatrices() { if (cached_normal_hash != mMatHash[i]) { - cached_normal = mat.inverse().transpose(); + cached_normal = mat; + cached_normal.invert(); + cached_normal.transpose(); cached_normal_hash = mMatHash[i]; } + + const LLMatrix4a& norm = cached_normal; - glh::matrix4f& norm = cached_normal; + LLVector3 norms[3]; + norms[0].set(norm.getRow<0>().getF32ptr()); + norms[1].set(norm.getRow<1>().getF32ptr()); + norms[2].set(norm.getRow<2>().getF32ptr()); - F32 norm_mat[] = - { - norm.m[0], norm.m[1], norm.m[2], - norm.m[4], norm.m[5], norm.m[6], - norm.m[8], norm.m[9], norm.m[10] - }; - - shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat); + shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norms[0].mV); } //update MVP matrix @@ -1241,13 +1253,12 @@ void LLRender::syncMatrices() if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) { - cached_mvp = mat; - cached_mvp.mult_left(mMatrix[proj][mMatIdx[proj]]); + cached_mvp.setMul(mMatrix[proj][mMatIdx[proj]], mat); cached_mvp_mdv_hash = mMatHash[i]; cached_mvp_proj_hash = mMatHash[MM_PROJECTION]; } - shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m); + shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.getF32ptr()); } } @@ -1255,9 +1266,9 @@ void LLRender::syncMatrices() i = MM_PROJECTION; if (mMatHash[i] != shader->mMatHash[i]) { //update projection matrix, normal, and MVP - glh::matrix4f& mat = mMatrix[i][mMatIdx[i]]; - - shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m); + const LLMatrix4a& mat = mMatrix[i][mMatIdx[i]]; + + shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.getF32ptr()); shader->mMatHash[i] = mMatHash[i]; if (!mvp_done) @@ -1269,13 +1280,12 @@ void LLRender::syncMatrices() if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) { U32 mdv = MM_MODELVIEW; - cached_mvp = mat; - cached_mvp.mult_right(mMatrix[mdv][mMatIdx[mdv]]); + cached_mvp.setMul(mat,mMatrix[mdv][mMatIdx[mdv]]); cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW]; cached_mvp_proj_hash = mMatHash[MM_PROJECTION]; } - - shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m); + + shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.getF32ptr()); } } } @@ -1284,7 +1294,7 @@ void LLRender::syncMatrices() { if (mMatHash[i] != shader->mMatHash[i]) { - shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m); + shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].getF32ptr()); shader->mMatHash[i] = mMatHash[i]; } } @@ -1312,7 +1322,7 @@ void LLRender::syncMatrices() if (mMatHash[i] != mCurMatHash[i]) { glMatrixMode(mode[i]); - glLoadMatrixf(mMatrix[i][mMatIdx[i]].m); + glLoadMatrixf(mMatrix[i][mMatIdx[i]].getF32ptr()); mCurMatHash[i] = mMatHash[i]; } } @@ -1323,7 +1333,7 @@ void LLRender::syncMatrices() { gGL.getTexUnit(i-2)->activate(); glMatrixMode(mode[i]); - glLoadMatrixf(mMatrix[i][mMatIdx[i]].m); + glLoadMatrixf(mMatrix[i][mMatIdx[i]].getF32ptr()); mCurMatHash[i] = mMatHash[i]; } } @@ -1332,32 +1342,143 @@ void LLRender::syncMatrices() stop_glerror(); } +LLMatrix4a LLRender::genRot(const GLfloat& a, const LLVector4a& axis) const +{ + F32 r = a * DEG_TO_RAD; + + F32 c = cosf(r); + F32 s = sinf(r); + + F32 ic = 1.f-c; + + const LLVector4a add1(c,axis[VZ]*s,-axis[VY]*s); //1,z,-y + const LLVector4a add2(-axis[VZ]*s,c,axis[VX]*s); //-z,1,x + const LLVector4a add3(axis[VY]*s,-axis[VX]*s,c); //y,-x,1 + + LLVector4a axis_x; + axis_x.splat<0>(axis); + LLVector4a axis_y; + axis_y.splat<1>(axis); + LLVector4a axis_z; + axis_z.splat<2>(axis); + + LLVector4a c_axis; + c_axis.setMul(axis,ic); + + LLMatrix4a rot_mat; + rot_mat.getRow<0>().setMul(c_axis,axis_x); + rot_mat.getRow<0>().add(add1); + rot_mat.getRow<1>().setMul(c_axis,axis_y); + rot_mat.getRow<1>().add(add2); + rot_mat.getRow<2>().setMul(c_axis,axis_z); + rot_mat.getRow<2>().add(add3); + rot_mat.setRow<3>(LLVector4a(0,0,0,1)); + + return rot_mat; +} +LLMatrix4a LLRender::genOrtho(const GLfloat& left, const GLfloat& right, const GLfloat& bottom, const GLfloat& top, const GLfloat& zNear, const GLfloat& zFar) const +{ + LLMatrix4a ortho_mat; + ortho_mat.setRow<0>(LLVector4a(2.f/(right-left),0,0)); + ortho_mat.setRow<1>(LLVector4a(0,2.f/(top-bottom),0)); + ortho_mat.setRow<2>(LLVector4a(0,0,-2.f/(zFar-zNear))); + ortho_mat.setRow<3>(LLVector4a(-(right+left)/(right-left),-(top+bottom)/(top-bottom),-(zFar+zNear)/(zFar-zNear),1)); + + return ortho_mat; +} + +LLMatrix4a LLRender::genPersp(const GLfloat& fovy, const GLfloat& aspect, const GLfloat& zNear, const GLfloat& zFar) const +{ + GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f); + + LLMatrix4a persp_mat; + persp_mat.setRow<0>(LLVector4a(f/aspect,0,0)); + persp_mat.setRow<1>(LLVector4a(0,f,0)); + persp_mat.setRow<2>(LLVector4a(0,0,(zFar+zNear)/(zNear-zFar),-1.f)); + persp_mat.setRow<3>(LLVector4a(0,0,(2.f*zFar*zNear)/(zNear-zFar),0)); + + return persp_mat; +} + +LLMatrix4a LLRender::genLook(const LLVector3& pos_in, const LLVector3& dir_in, const LLVector3& up_in) const +{ + const LLVector4a pos(pos_in.mV[VX],pos_in.mV[VY],pos_in.mV[VZ],1.f); + LLVector4a dir(dir_in.mV[VX],dir_in.mV[VY],dir_in.mV[VZ]); + const LLVector4a up(up_in.mV[VX],up_in.mV[VY],up_in.mV[VZ]); + + LLVector4a left_norm; + left_norm.setCross3(dir,up); + left_norm.normalize3fast(); + LLVector4a up_norm; + up_norm.setCross3(left_norm,dir); + up_norm.normalize3fast(); + LLVector4a& dir_norm = dir; + dir.normalize3fast(); + + LLVector4a left_dot; + left_dot.setAllDot3(left_norm,pos); + left_dot.negate(); + LLVector4a up_dot; + up_dot.setAllDot3(up_norm,pos); + up_dot.negate(); + LLVector4a dir_dot; + dir_dot.setAllDot3(dir_norm,pos); + + dir_norm.negate(); + + LLMatrix4a lookat_mat; + lookat_mat.setRow<0>(left_norm); + lookat_mat.setRow<1>(up_norm); + lookat_mat.setRow<2>(dir_norm); + lookat_mat.setRow<3>(LLVector4a(0,0,0,1)); + + lookat_mat.getRow<0>().copyComponent<3>(left_dot); + lookat_mat.getRow<1>().copyComponent<3>(up_dot); + lookat_mat.getRow<2>().copyComponent<3>(dir_dot); + + lookat_mat.transpose(); + + return lookat_mat; +} + +const LLMatrix4a& LLRender::genNDCtoWC() const +{ + static LLMatrix4a mat( + LLVector4a(.5f,0,0,0), + LLVector4a(0,.5f,0,0), + LLVector4a(0,0,.5f,0), + LLVector4a(.5f,.5f,.5f,1.f)); + return mat; +} + void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) { + if( llabs(x) < F_APPROXIMATELY_ZERO && + llabs(y) < F_APPROXIMATELY_ZERO && + llabs(z) < F_APPROXIMATELY_ZERO) + { + return; + } + flush(); - { - glh::matrix4f trans_mat(1,0,0,x, - 0,1,0,y, - 0,0,1,z, - 0,0,0,1); - - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat); - mMatHash[mMatrixMode]++; - } + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].applyTranslation_affine(x,y,z); + mMatHash[mMatrixMode]++; + } void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z) { + if( (llabs(x-1.f)) < F_APPROXIMATELY_ZERO && + (llabs(y-1.f)) < F_APPROXIMATELY_ZERO && + (llabs(z-1.f)) < F_APPROXIMATELY_ZERO) + { + return; + } flush(); { - glh::matrix4f scale_mat(x,0,0,0, - 0,y,0,0, - 0,0,z,0, - 0,0,0,1); - - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat); + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].applyScale_affine(x,y,z); mMatHash[mMatrixMode]++; } } @@ -1366,38 +1487,156 @@ void LLRender::ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zF { flush(); - { + LLMatrix4a ortho_mat; + ortho_mat.setRow<0>(LLVector4a(2.f/(right-left),0,0)); + ortho_mat.setRow<1>(LLVector4a(0,2.f/(top-bottom),0)); + ortho_mat.setRow<2>(LLVector4a(0,0,-2.f/(zFar-zNear))); + ortho_mat.setRow<3>(LLVector4a(-(right+left)/(right-left),-(top+bottom)/(top-bottom),-(zFar+zNear)/(zFar-zNear),1)); - glh::matrix4f ortho_mat(2.f/(right-left),0,0, -(right+left)/(right-left), - 0,2.f/(top-bottom),0, -(top+bottom)/(top-bottom), - 0,0,-2.f/(zFar-zNear), -(zFar+zNear)/(zFar-zNear), - 0,0,0,1); - - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat); - mMatHash[mMatrixMode]++; - } + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mul_affine(ortho_mat); + mMatHash[mMatrixMode]++; +} + +void LLRender::rotatef(const LLMatrix4a& rot) +{ + flush(); + + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mul_affine(rot); + mMatHash[mMatrixMode]++; } void LLRender::rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z) { + if( llabs(a) < F_APPROXIMATELY_ZERO || + llabs(a-360.f) < F_APPROXIMATELY_ZERO) + { + return; + } + flush(); - { - F32 r = a * DEG_TO_RAD; + rotatef(genRot(a,x,y,z)); +} - F32 c = cosf(r); - F32 s = sinf(r); +//LLRender::projectf & LLRender::unprojectf adapted from gluProject & gluUnproject in Mesa's GLU 9.0 library. +// License/Copyright Statement: +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ - F32 ic = 1.f-c; +bool LLRender::projectf(const LLVector3& object, const LLMatrix4a& modelview, const LLMatrix4a& projection, const LLRect& viewport, LLVector3& windowCoordinate) +{ + //Begin SSE intrinsics - glh::matrix4f rot_mat(x*x*ic+c, x*y*ic-z*s, x*z*ic+y*s, 0, - x*y*ic+z*s, y*y*ic+c, y*z*ic-x*s, 0, - x*z*ic-y*s, y*z*ic+x*s, z*z*ic+c, 0, - 0,0,0,1); + // Declare locals + const LLVector4a obj_vector(object.mV[VX],object.mV[VY],object.mV[VZ]); + const LLVector4a one(1.f); + LLVector4a temp_vec; //Scratch vector + LLVector4a w; //Splatted W-component. - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat); - mMatHash[mMatrixMode]++; - } + modelview.affineTransform(obj_vector, temp_vec); //temp_vec = modelview * obj_vector; + + //Passing temp_matrix as v and res is safe. res not altered until after all other calculations + projection.rotate4(temp_vec, temp_vec); //temp_vec = projection * temp_vec + + w.splat<3>(temp_vec); //w = temp_vec.wwww + + //If w == 0.f, use 1.f instead. + LLVector4a div; + div.setSelectWithMask( w.equal( _mm_setzero_ps() ), one, w ); //float div = (w[N] == 0.f ? 1.f : w[N]); + temp_vec.div(div); //temp_vec /= div; + + //Map x, y to range 0-1 + temp_vec.mul(.5f); + temp_vec.add(.5f); + + LLVector4Logical mask = temp_vec.equal(_mm_setzero_ps()); + if(mask.areAllSet(LLVector4Logical::MASK_W)) + return false; + + //End SSE intrinsics + + //Window coordinates + windowCoordinate[0]=temp_vec[VX]*viewport.getWidth()+viewport.mLeft; + windowCoordinate[1]=temp_vec[VY]*viewport.getHeight()+viewport.mBottom; + //This is only correct when glDepthRange(0.0, 1.0) + windowCoordinate[2]=temp_vec[VZ]; + + return true; +} + +bool LLRender::unprojectf(const LLVector3& windowCoordinate, const LLMatrix4a& modelview, const LLMatrix4a& projection, const LLRect& viewport, LLVector3& object) +{ + //Begin SSE intrinsics + + // Declare locals + static const LLVector4a one(1.f); + static const LLVector4a two(2.f); + LLVector4a norm_view( + ((windowCoordinate.mV[VX] - (F32)viewport.mLeft) / (F32)viewport.getWidth()), + ((windowCoordinate.mV[VY] - (F32)viewport.mBottom) / (F32)viewport.getHeight()), + windowCoordinate.mV[VZ], + 1.f); + + LLMatrix4a inv_mat; //Inverse transformation matrix + LLVector4a temp_vec; //Scratch vector + LLVector4a w; //Splatted W-component. + + inv_mat.setMul(projection,modelview); //inv_mat = projection*modelview + + float det = inv_mat.invert(); + + //Normalize. -1.0 : +1.0 + norm_view.mul(two); // norm_view *= vec4(.2f) + norm_view.sub(one); // norm_view -= vec4(1.f) + + inv_mat.rotate4(norm_view,temp_vec); //inv_mat * norm_view + + w.splat<3>(temp_vec); //w = temp_vec.wwww + + //If w == 0.f, use 1.f instead. Defer return if temp_vec.w == 0.f until after all SSE intrinsics. + LLVector4a div; + div.setSelectWithMask( w.equal( _mm_setzero_ps() ), one, w ); //float div = (w[N] == 0.f ? 1.f : w[N]); + temp_vec.div(div); //temp_vec /= div; + + LLVector4Logical mask = temp_vec.equal(_mm_setzero_ps()); + if(mask.areAllSet(LLVector4Logical::MASK_W)) + return false; + + //End SSE intrinsics + + if(det == 0.f) + return false; + + object.set(temp_vec.getF32ptr()); + + return true; } void LLRender::pushMatrix() @@ -1433,24 +1672,21 @@ void LLRender::popMatrix() } } -void LLRender::loadMatrix(const GLfloat* m) +void LLRender::loadMatrix(const LLMatrix4a& mat) { flush(); - { - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m); - mMatHash[mMatrixMode]++; - } + + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]] = mat; + mMatHash[mMatrixMode]++; } -void LLRender::multMatrix(const GLfloat* m) +void LLRender::multMatrix(const LLMatrix4a& mat) { flush(); - { - glh::matrix4f mat((GLfloat*) m); + + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mul_affine(mat); + mMatHash[mMatrixMode]++; - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat); - mMatHash[mMatrixMode]++; - } } void LLRender::matrixMode(U32 mode) @@ -1479,20 +1715,16 @@ void LLRender::loadIdentity() { flush(); - { - llassert_always(mMatrixMode < NUM_MATRIX_MODES) ; - - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity(); - mMatHash[mMatrixMode]++; - } + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].setIdentity(); + mMatHash[mMatrixMode]++; } -const glh::matrix4f& LLRender::getModelviewMatrix() +const LLMatrix4a& LLRender::getModelviewMatrix() { return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]]; } -const glh::matrix4f& LLRender::getProjectionMatrix() +const LLMatrix4a& LLRender::getProjectionMatrix() { return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]]; } diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 66786d6ee..82e212370 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -38,18 +38,19 @@ #include "v3math.h" #include "v4coloru.h" #include "v4math.h" +#include "llmatrix4a.h" #include "llalignedarray.h" #include "llstrider.h" #include "llpointer.h" #include "llglheaders.h" -#include "llmatrix4a.h" -#include "glh/glh_linear.h" +#include "llrect.h" class LLVertexBuffer; class LLCubeMap; class LLImageGL; class LLRenderTarget; class LLTexture ; +class LLMatrix4a; #define LL_MATRIX_STACK_DEPTH 32 @@ -257,6 +258,8 @@ protected: F32 mSpotExponent; F32 mSpotCutoff; }; + +LL_ALIGN_PREFIX(16) class LLRender { friend class LLTexUnit; @@ -343,21 +346,32 @@ public: // Needed when the render context has changed and invalidated the current state void refreshState(void); + LLMatrix4a genRot(const GLfloat& a, const LLVector4a& axis) const; + LLMatrix4a genRot(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z) const { return genRot(a,LLVector4a(x,y,z)); } + LLMatrix4a genOrtho(const GLfloat& left, const GLfloat& right, const GLfloat& bottom, const GLfloat& top, const GLfloat& znear, const GLfloat& zfar) const; + LLMatrix4a genPersp(const GLfloat& fovy, const GLfloat& aspect, const GLfloat& znear, const GLfloat& zfar) const; + LLMatrix4a genLook(const LLVector3& pos_in, const LLVector3& dir_in, const LLVector3& up_in) const; + const LLMatrix4a& genNDCtoWC() const; + void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z); void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z); + //rotatef requires generation of a transform matrix involving sine/cosine. If rotating by a constant value, use genRot, store the result in a static variable, and pass that var to rotatef. + void rotatef(const LLMatrix4a& rot); void rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z); void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar); + bool projectf(const LLVector3& object, const LLMatrix4a& modelview, const LLMatrix4a& projection, const LLRect& viewport, LLVector3& windowCoordinate); + bool unprojectf(const LLVector3& windowCoordinate, const LLMatrix4a& modelview, const LLMatrix4a& projection, const LLRect& viewport, LLVector3& object); void pushMatrix(); void popMatrix(); - void loadMatrix(const GLfloat* m); + void loadMatrix(const LLMatrix4a& mat); void loadIdentity(); - void multMatrix(const GLfloat* m); + void multMatrix(const LLMatrix4a& mat); void matrixMode(U32 mode); U32 getMatrixMode(); - const glh::matrix4f& getModelviewMatrix(); - const glh::matrix4f& getProjectionMatrix(); + const LLMatrix4a& getModelviewMatrix(); + const LLMatrix4a& getProjectionMatrix(); void syncMatrices(); void syncLightState(); @@ -447,7 +461,7 @@ private: U32 mMatrixMode; U32 mMatIdx[NUM_MATRIX_MODES]; U32 mMatHash[NUM_MATRIX_MODES]; - glh::matrix4f mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH]; + LL_ALIGN_16(LLMatrix4a mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH]); U32 mCurMatHash[NUM_MATRIX_MODES]; U32 mLightHash; LLColor4 mAmbientLightColor; @@ -478,13 +492,14 @@ private: LLAlignedArray mUIOffset; LLAlignedArray mUIScale; -}; +} LL_ALIGN_POSTFIX(16); -extern F32 gGLModelView[16]; -extern F32 gGLLastModelView[16]; -extern F32 gGLLastProjection[16]; -extern F32 gGLPreviousModelView[16]; -extern F32 gGLProjection[16]; + +extern LLMatrix4a gGLModelView; +extern LLMatrix4a gGLLastModelView; +extern LLMatrix4a gGLLastProjection; +extern LLMatrix4a gGLPreviousModelView; +extern LLMatrix4a gGLProjection; extern S32 gGLViewport[4]; extern LLRender gGL; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 5171dcf87..00f4e3dff 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -2044,6 +2044,10 @@ bool LLVertexBuffer::getNormalStrider(LLStrider& strider, S32 index, { return VertexBufferStrider::get(*this, strider, index, count, map_range); } +bool LLVertexBuffer::getNormalStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +{ + return VertexBufferStrider::get(*this, strider, index, count, map_range); +} bool LLVertexBuffer::getTangentStrider(LLStrider& strider, S32 index, S32 count, bool map_range) { return VertexBufferStrider::get(*this, strider, index, count, map_range); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 77c753fc9..28008b767 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -250,6 +250,7 @@ public: bool getTexCoord1Strider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTexCoord2Strider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getNormalStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getNormalStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTangentStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTangentStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getColorStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index daa7de213..1b9add0a4 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -272,7 +272,7 @@ void LLButton::onCommit() LLUICtrl::onCommit(); } -/*boost::signals2::connection LLButton::setClickedCallback(const CommitCallbackParam& cb) +boost::signals2::connection LLButton::setClickedCallback(const CommitCallbackParam& cb) { return setClickedCallback(initCommitCallback(cb)); } @@ -287,7 +287,7 @@ boost::signals2::connection LLButton::setMouseUpCallback(const CommitCallbackPar boost::signals2::connection LLButton::setHeldDownCallback(const CommitCallbackParam& cb) { return setHeldDownCallback(initCommitCallback(cb)); -}*/ +} boost::signals2::connection LLButton::setClickedCallback( const commit_signal_t::slot_type& cb ) diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 219b0dfec..1495740c6 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -116,10 +116,10 @@ public: void setSelectedLabelColor( const LLColor4& c ) { mSelectedLabelColor = c; } - /*boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb); + boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb); boost::signals2::connection setMouseDownCallback(const CommitCallbackParam& cb); boost::signals2::connection setMouseUpCallback(const CommitCallbackParam& cb); - boost::signals2::connection setHeldDownCallback(const CommitCallbackParam& cb);*/ + boost::signals2::connection setHeldDownCallback(const CommitCallbackParam& cb); boost::signals2::connection setClickedCallback( const commit_signal_t::slot_type& cb ); // mouse down and up within button boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb ); diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 7c8e1afeb..08ddc3c96 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -909,6 +909,19 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char) return result; } +BOOL LLComboBox::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + if (mList->getVisible()) return mList->handleScrollWheel(x, y, clicks); + if (mAllowTextEntry) // We might be editable + if (!mList->getFirstSelected()) // We aren't in the list, don't kill their text + return false; + + setCurrentByIndex(llclamp(getCurrentIndex() + clicks, 0, getItemCount() - 1)); + prearrangeList(); + onCommit(); + return true; +} + void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative) { mAllowTextEntry = allow; @@ -924,6 +937,7 @@ void LLComboBox::setTextEntry(const LLStringExplicit& text) if (mTextEntry) { mTextEntry->setText(text); + mTextEntry->setCursor(0); // Singu Note: Move the cursor over to the beginning mHasAutocompletedText = FALSE; updateSelection(); } diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 2131ba06c..4e180924e 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -76,6 +76,7 @@ public: virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleUnicodeCharHere(llwchar uni_char); + virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); // LLUICtrl interface virtual void clear(); // select nothing diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 16fb57c25..c8be07f43 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -571,6 +571,9 @@ void LLFloater::open() /* Flawfinder: ignore */ setVisibleAndFrontmost(mAutoFocus); } + if (!getControlName().empty()) + setControlValue(true); + onOpen(); } @@ -633,6 +636,9 @@ void LLFloater::close(bool app_quitting) } } + if (!app_quitting && !getControlName().empty()) + setControlValue(false); + // Let floater do cleanup. onClose(app_quitting); } diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 27df264af..039c7a789 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -221,7 +221,7 @@ BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) { if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) { - doIt(); + onCommit(); return TRUE; } return FALSE; @@ -342,7 +342,7 @@ void LLMenuItemGL::setJumpKey(KEY key) // virtual U32 LLMenuItemGL::getNominalHeight( void ) const { - return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING; + return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING; } //virtual @@ -400,7 +400,7 @@ void LLMenuItemGL::buildDrawLabel( void ) mDrawAccelLabel = st; } -void LLMenuItemGL::doIt( void ) +void LLMenuItemGL::onCommit( void ) { // Check torn-off status to allow left-arrow keyboard navigation back // to parent menu. @@ -411,6 +411,8 @@ void LLMenuItemGL::doIt( void ) { LLMenuGL::sMenuContainer->hideMenus(); } + + LLUICtrl::onCommit(); } // set the hover status (called by it's menu) @@ -456,7 +458,7 @@ BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask ) // switch to keyboard navigation mode LLMenuGL::setKeyboardMode(TRUE); - doIt(); + onCommit(); return TRUE; } } @@ -469,7 +471,7 @@ BOOL LLMenuItemGL::handleMouseUp( S32 x, S32 y, MASK mask) // switch to mouse navigation mode LLMenuGL::setKeyboardMode(FALSE); - doIt(); + onCommit(); make_ui_sound("UISndClickRelease"); return LLView::handleMouseUp(x, y, mask); } @@ -486,7 +488,7 @@ BOOL LLMenuItemGL::handleMouseDown( S32 x, S32 y, MASK mask) BOOL LLMenuItemGL::handleScrollWheel( S32 x, S32 y, S32 clicks ) { // If the menu is scrollable let it handle the wheel event. - return FALSE;//!getMenu()->isScrollable(); + return !getMenu()->isScrollable(); } void LLMenuItemGL::draw( void ) @@ -586,6 +588,7 @@ void LLMenuItemGL::handleVisibilityChange(BOOL new_visibility) } LLView::handleVisibilityChange(new_visibility); } + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuItemSeparatorGL // @@ -732,12 +735,15 @@ LLFloater* LLMenuItemTearOffGL::getParentFloater() return NULL; } -void LLMenuItemTearOffGL::doIt() +void LLMenuItemTearOffGL::onCommit() { if (getMenu()->getTornOff()) { - LLTearOffMenu* torn_off_menu = (LLTearOffMenu*)(getMenu()->getParent()); - torn_off_menu->close(); + LLTearOffMenu* torn_off_menu = dynamic_cast(getMenu()->getParent()); + if (torn_off_menu) + { + torn_off_menu->close(); + } } else { @@ -809,7 +815,7 @@ public: { setEnabled(FALSE); } - virtual void doIt( void ) {} + virtual void onCommit( void ) {} virtual void draw( void ) {} }; @@ -953,8 +959,7 @@ LLXMLNodePtr LLMenuItemCallGL::getXML(bool save_children) const return node; } -// doIt() - Call the callback provided -void LLMenuItemCallGL::doIt( void ) +void LLMenuItemCallGL::onCommit( void ) { // RN: menu item can be deleted in callback, so beware getMenu()->setItemLastSelected( this ); @@ -965,7 +970,7 @@ void LLMenuItemCallGL::doIt( void ) } LLPointer fired_event = new LLEvent(this); fireEvent(fired_event, "on_click"); - LLMenuItemGL::doIt(); + LLMenuItemGL::onCommit(); } void LLMenuItemCallGL::updateEnabled( void ) @@ -1150,14 +1155,14 @@ void LLMenuItemToggleGL::buildDrawLabel( void ) mDrawAccelLabel = st; } -// doIt() - do the primary funcationality of the menu item. -void LLMenuItemToggleGL::doIt( void ) +// onCommit() - do the primary funcationality of the menu item. +void LLMenuItemToggleGL::onCommit( void ) { getMenu()->setItemLastSelected( this ); - //llinfos << "LLMenuItemToggleGL::doIt " << mLabel.c_str() << llendl; + //llinfos << "LLMenuItemToggleGL::onCommit " << mLabel.c_str() << llendl; *mToggle = !(*mToggle); buildDrawLabel(); - LLMenuItemGL::doIt(); + LLMenuItemGL::onCommit(); } @@ -1187,6 +1192,8 @@ LLMenuItemBranchGL::~LLMenuItemBranchGL() } } + + // virtual LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const { @@ -1214,7 +1221,7 @@ BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask) // switch to mouse navigation mode LLMenuGL::setKeyboardMode(FALSE); - doIt(); + onCommit(); make_ui_sound("UISndClickRelease"); return TRUE; } @@ -1269,8 +1276,7 @@ void LLMenuItemBranchGL::buildDrawLabel( void ) mDrawBranchLabel = LLMenuGL::BRANCH_SUFFIX; } -// doIt() - do the primary functionality of the menu item. -void LLMenuItemBranchGL::doIt( void ) +void LLMenuItemBranchGL::onCommit( void ) { openMenu(); @@ -1280,6 +1286,8 @@ void LLMenuItemBranchGL::doIt( void ) { getBranch()->highlightNextItem(NULL); } + + LLUICtrl::onCommit(); } BOOL LLMenuItemBranchGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) @@ -1326,7 +1334,8 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight ) BOOL auto_open = getEnabled() && (!branch->getVisible() || branch->getTornOff()); // torn off menus don't open sub menus on hover unless they have focus - if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus()) + LLFloater * menu_parent = dynamic_cast(getMenu()->getParent()); + if (getMenu()->getTornOff() && menu_parent && !menu_parent->hasFocus()) { auto_open = FALSE; } @@ -1347,7 +1356,11 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight ) { if (branch->getTornOff()) { - ((LLFloater*)branch->getParent())->setFocus(FALSE); + LLFloater * branch_parent = dynamic_cast(branch->getParent()); + if (branch_parent) + { + branch_parent->setFocus(FALSE); + } branch->clearHoverItem(); } else @@ -1405,11 +1418,19 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask ) BOOL handled = branch->clearHoverItem(); if (branch->getTornOff()) { - ((LLFloater*)branch->getParent())->setFocus(FALSE); + LLFloater * branch_parent = dynamic_cast(branch->getParent()); + if (branch_parent) + { + branch_parent->setFocus(FALSE); + } } if (handled && getMenu()->getTornOff()) { - ((LLFloater*)getMenu()->getParent())->setFocus(TRUE); + LLFloater * menu_parent = dynamic_cast(getMenu()->getParent()); + if (menu_parent) + { + menu_parent->setFocus(TRUE); + } } return handled; } @@ -1449,9 +1470,13 @@ void LLMenuItemBranchGL::openMenu() if (branch->getTornOff()) { - gFloaterView->bringToFront((LLFloater*)branch->getParent()); - // this might not be necessary, as torn off branches don't get focus and hence no highligth - branch->highlightNextItem(NULL); + LLFloater * branch_parent = dynamic_cast(branch->getParent()); + if (branch_parent) + { + gFloaterView->bringToFront(branch_parent); + // this might not be necessary, as torn off branches don't get focus and hence no highligth + branch->highlightNextItem(NULL); + } } else if( !branch->getVisible() ) { @@ -1584,7 +1609,11 @@ void LLMenuItemBranchDownGL::openMenu( void ) { if (branch->getTornOff()) { - gFloaterView->bringToFront((LLFloater*)branch->getParent()); + LLFloater * branch_parent = dynamic_cast(branch->getParent()); + if (branch_parent) + { + gFloaterView->bringToFront(branch_parent); + } } else { @@ -1639,7 +1668,11 @@ void LLMenuItemBranchDownGL::setHighlight( BOOL highlight ) { if (branch->getTornOff()) { - ((LLFloater*)branch->getParent())->setFocus(FALSE); + LLFloater * branch_parent = dynamic_cast(branch->getParent()); + if (branch_parent) + { + branch_parent->setFocus(FALSE); + } branch->clearHoverItem(); } else @@ -1661,7 +1694,7 @@ BOOL LLMenuItemBranchDownGL::handleMouseDown( S32 x, S32 y, MASK mask ) { // switch to mouse control mode LLMenuGL::setKeyboardMode(FALSE); - doIt(); + onCommit(); make_ui_sound("UISndClick"); setVisible(TRUE); return TRUE; @@ -1701,7 +1734,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask) // open new menu only if previous menu was open if (itemp && itemp->getEnabled() && menu_open) { - itemp->doIt(); + itemp->onCommit(); } return TRUE; @@ -1715,7 +1748,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask) // open new menu only if previous menu was open if (itemp && itemp->getEnabled() && menu_open) { - itemp->doIt(); + itemp->onCommit(); } return TRUE; @@ -1727,7 +1760,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask) if (!isActive()) { - doIt(); + onCommit(); } getBranch()->highlightNextItem(NULL); return TRUE; @@ -1739,7 +1772,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask) if (!isActive()) { - doIt(); + onCommit(); } getBranch()->highlightPrevItem(NULL); return TRUE; @@ -1805,6 +1838,117 @@ void LLMenuItemBranchDownGL::draw( void ) setHover(FALSE); } + +class LLMenuScrollItem : public LLMenuItemCallGL +{ +public: + enum EArrowType + { + ARROW_DOWN, + ARROW_UP + }; + struct ArrowTypes : public LLInitParam::TypeValuesHelper + { + static void declareValues() + { + declare("up", ARROW_UP); + declare("down", ARROW_DOWN); + } + }; + + struct Params : public LLInitParam::Block + { + Optional arrow_type; + Optional scroll_callback; + }; + +protected: + LLMenuScrollItem(const Params&); + friend class LLUICtrlFactory; + +public: + /*virtual*/ void draw(); + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); + /*virtual*/ void setEnabled(BOOL enabled); + virtual void onCommit( void ); + +private: + LLButton* mArrowBtn; +}; + +LLMenuScrollItem::LLMenuScrollItem(const Params& p) +: LLMenuItemCallGL(p.name, NULL/*p*/) +{ + std::string icon; + if (p.arrow_type.isProvided() && p.arrow_type == ARROW_UP) + { + icon = "arrow_up.tga"; + } + else + { + icon = "arrow_down.tga"; + } + + /* Singu TODO: LLButton::Params + LLButton::Params bparams; + + // Disabled the Return key handling by LLMenuScrollItem instead of + // passing the key press to the currently selected menu item. See STORM-385. + bparams.commit_on_return(false); + bparams.mouse_opaque(true); + bparams.scale_image(false); + bparams.click_callback(p.scroll_callback); + bparams.mouse_held_callback(p.scroll_callback); + bparams.follows.flags(FOLLOWS_ALL); + std::string background = "transparent.j2c"; + bparams.image_unselected.name(background); + bparams.image_disabled.name(background); + bparams.image_selected.name(background); + bparams.image_hover_selected.name(background); + bparams.image_disabled_selected.name(background); + bparams.image_hover_unselected.name(background); + bparams.image_overlay.name(icon); + + mArrowBtn = LLUICtrlFactory::create(bparams); + */ + const LLRect rect = getRect(); + const std::string background = "transparent.j2c"; + mArrowBtn = new LLButton("", LLRect(0, 0, rect.getWidth(), rect.getHeight()), background, background, "", NULL); + mArrowBtn->setCommitOnReturn(false); + mArrowBtn->setMouseOpaque(true); + mArrowBtn->setScaleImage(false); + mArrowBtn->setClickedCallback(p.scroll_callback); + mArrowBtn->setHeldDownCallback(p.scroll_callback); + mArrowBtn->setFollows(FOLLOWS_ALL); + mArrowBtn->setImageOverlay(icon); + addChild(mArrowBtn); +} + +/*virtual*/ +void LLMenuScrollItem::draw() +{ + LLUICtrl::draw(); +} + +/*virtual*/ +void LLMenuScrollItem::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + mArrowBtn->reshape(width, height, called_from_parent); + LLView::reshape(width, height, called_from_parent); +} + +/*virtual*/ +void LLMenuScrollItem::setEnabled(BOOL enabled) +{ + mArrowBtn->setEnabled(enabled); + LLView::setEnabled(enabled); +} + +void LLMenuScrollItem::onCommit( void ) +{ + LLUICtrl::onCommit(); +} + ///============================================================================ /// Class LLMenuGL ///============================================================================ @@ -1816,10 +1960,12 @@ LLMenuGL::LLMenuGL( const std::string& name, const std::string& label ) : LLUICtrl( name, LLRect(), FALSE), mBackgroundColor( sDefaultBackgroundColor ), mBgVisible( TRUE ), - mHasSelection( FALSE ), + mHasSelection(false), + mHorizontalLayout(false), + mScrollable(mHorizontalLayout ? FALSE : /*p.scrollable*/false), // Scrolling is supported only for vertical layout + mMaxScrollableItems(/*p.max_scrollable_items*/ U32_MAX), mLabel( label ), mDropShadowed( TRUE ), - mHorizontalLayout( FALSE ), mKeepFixedSize( FALSE ), mLastMouseX(0), mLastMouseY(0), @@ -1829,9 +1975,13 @@ LLMenuGL::LLMenuGL( const std::string& name, const std::string& label ) mTearOffItem(NULL), mSpilloverBranch(NULL), mFirstVisibleItem(NULL), + mArrowUpItem(NULL), + mArrowDownItem(NULL), mSpilloverMenu(NULL), mJumpKey(KEY_NONE), + mCreateJumpKeys(true/*p.create_jump_keys*/), mNeedsArrange(FALSE), + mResetScrollPositionOnShow(true), mShortcutPad(ACCEL_PAD_PIXELS) { mFadeTimer.stop(); @@ -1842,10 +1992,12 @@ LLMenuGL::LLMenuGL( const std::string& label) : LLUICtrl( label, LLRect(), FALSE), mBackgroundColor( sDefaultBackgroundColor ), mBgVisible( TRUE ), - mHasSelection( FALSE ), + mHasSelection(false), + mHorizontalLayout(false), + mScrollable(mHorizontalLayout ? FALSE : /*p.scrollable*/false), // Scrolling is supported only for vertical layout + mMaxScrollableItems(/*p.max_scrollable_items*/ U32_MAX), mLabel( label ), mDropShadowed( TRUE ), - mHorizontalLayout( FALSE ), mKeepFixedSize( FALSE ), mLastMouseX(0), mLastMouseY(0), @@ -1856,8 +2008,12 @@ LLMenuGL::LLMenuGL( const std::string& label) mSpilloverBranch(NULL), mSpilloverMenu(NULL), mFirstVisibleItem(NULL), + mArrowUpItem(NULL), + mArrowDownItem(NULL), mJumpKey(KEY_NONE), + mCreateJumpKeys(true/*p.create_jump_keys*/), mNeedsArrange(FALSE), + mResetScrollPositionOnShow(true), mShortcutPad(ACCEL_PAD_PIXELS) { mFadeTimer.stop(); @@ -1933,7 +2089,7 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory { // SUBMENU LLMenuGL *submenu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory); - appendMenu(submenu, 0); + appendMenu(submenu); if (LLMenuGL::sMenuContainer != NULL) { submenu->updateParent(LLMenuGL::sMenuContainer); @@ -2204,27 +2360,18 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory } } -// This wrapper is needed because the virtual linkage causes errors if default parameters are used bool LLMenuGL::addChild(LLView* view, S32 tab_group) -{ - return addChild(view, 0, tab_group); -} - -bool LLMenuGL::addChild(LLView* view, LLView* insert_before, S32 tab_group) { if (LLMenuGL* menup = dynamic_cast(view)) { lldebugs << "Adding menu " << menup->getName() << " to " << getName() << llendl; - if (!insert_before) - appendMenu(menup); - else - appendMenu(menup, insert_before); + appendMenu(menup); return true; } else if (LLMenuItemGL* itemp = dynamic_cast(view)) { lldebugs << "Adding " << itemp->getName() << " to " << getName() << llendl; - append(itemp, insert_before); + append(itemp); return true; } lldebugs << "Error adding unknown child '"<<(view ? view->getName() : std::string("NULL")) << "' to " << getName() << llendl; @@ -2332,6 +2479,10 @@ LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa LLMenuGL *menu = new LLMenuGL(name, new_menu_label); + bool b(false); + node->getAttribute_bool("scrollable", b); + menu->setScrollable(b); + menu->setJumpKey(jump_key); BOOL tear_off = FALSE; @@ -2369,6 +2520,117 @@ LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa } + +bool LLMenuGL::scrollItems(EScrollingDirection direction) +{ + // Slowing down items scrolling when arrow button is held + if (mScrollItemsTimer.hasExpired() && NULL != mFirstVisibleItem) + { + mScrollItemsTimer.setTimerExpirySec(.033f); + } + else + { + return false; + } + + switch (direction) + { + case SD_UP: + { + item_list_t::iterator cur_item_iter; + item_list_t::iterator prev_item_iter; + for (cur_item_iter = mItems.begin(), prev_item_iter = mItems.begin(); cur_item_iter != mItems.end(); cur_item_iter++) + { + if( (*cur_item_iter) == mFirstVisibleItem) + { + break; + } + if ((*cur_item_iter)->getVisible()) + { + prev_item_iter = cur_item_iter; + } + } + + if ((*prev_item_iter)->getVisible()) + { + mFirstVisibleItem = *prev_item_iter; + } + break; + } + case SD_DOWN: + { + if (NULL == mFirstVisibleItem) + { + mFirstVisibleItem = *mItems.begin(); + } + + item_list_t::iterator cur_item_iter; + + for (cur_item_iter = mItems.begin(); cur_item_iter != mItems.end(); cur_item_iter++) + { + if( (*cur_item_iter) == mFirstVisibleItem) + { + break; + } + } + + item_list_t::iterator next_item_iter; + + if (cur_item_iter != mItems.end()) + { + for (next_item_iter = ++cur_item_iter; next_item_iter != mItems.end(); next_item_iter++) + { + if( (*next_item_iter)->getVisible()) + { + break; + } + } + + if (next_item_iter != mItems.end() && + (*next_item_iter)->getVisible()) + { + mFirstVisibleItem = *next_item_iter; + } + } + break; + } + case SD_BEGIN: + { + mFirstVisibleItem = *mItems.begin(); + break; + } + case SD_END: + { + item_list_t::reverse_iterator first_visible_item_iter = mItems.rend(); + + // Need to scroll through number of actual existing items in menu. + // Otherwise viewer will hang for a time needed to scroll U32_MAX + // times in std::advance(). STORM-659. + size_t nitems = mItems.size(); + U32 scrollable_items = nitems < mMaxScrollableItems ? nitems : mMaxScrollableItems; + + // Advance by mMaxScrollableItems back from the end of the list + // to make the last item visible. + std::advance(first_visible_item_iter, scrollable_items); + mFirstVisibleItem = *first_visible_item_iter; + break; + } + default: + //LL_WARNS() << "Unknown scrolling direction: " << direction << LL_ENDL; + llwarns << "Unknown scrolling direction: " << direction << llendl; + } + + mNeedsArrange = TRUE; + arrangeAndClear(); + + return true; +} + +void LLMenuGL::setScrollable(bool b) +{ + mScrollable = b; +} + // rearrange the child rects so they fit the shape of the menu. void LLMenuGL::arrange( void ) { @@ -2402,9 +2664,10 @@ void LLMenuGL::arrange( void ) // Scrolling support item_list_t::iterator first_visible_item_iter; - //S32 height_before_first_visible_item = -1; - //S32 visible_items_height = 0; - //U32 scrollable_items_cnt = 0; + item_list_t::iterator first_hidden_item_iter = mItems.end(); + S32 height_before_first_visible_item = -1; + S32 visible_items_height = 0; + U32 scrollable_items_cnt = 0; if (mHorizontalLayout) { @@ -2452,15 +2715,16 @@ void LLMenuGL::arrange( void ) else { item_list_t::iterator item_iter; + for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) { - llassert_always((*item_iter)!=NULL); // do first so LLMenuGLItemCall can call on_visible to determine if visible (*item_iter)->buildDrawLabel(); if ((*item_iter)->getVisible()) { if (!getTornOff() + && !mScrollable && *item_iter != mSpilloverBranch && height + (*item_iter)->getNominalHeight() > max_height - spillover_item_height) { @@ -2476,6 +2740,8 @@ void LLMenuGL::arrange( void ) removeChild(itemp); mSpilloverMenu->addChild(itemp); } + + addChild(mSpilloverBranch); height += mSpilloverBranch->getNominalHeight(); @@ -2489,20 +2755,170 @@ void LLMenuGL::arrange( void ) height += (*item_iter)->getNominalHeight(); width = llmax( width, (*item_iter)->getNominalWidth() ); } + + if (mScrollable) + { + // Determining visible items boundaries + if (NULL == mFirstVisibleItem) + { + mFirstVisibleItem = *item_iter; + } + + if (*item_iter == mFirstVisibleItem) + { + height_before_first_visible_item = height - (*item_iter)->getNominalHeight(); + first_visible_item_iter = item_iter; + scrollable_items_cnt = 0; + } + + if (-1 != height_before_first_visible_item && 0 == visible_items_height && + (++scrollable_items_cnt > mMaxScrollableItems || + height - height_before_first_visible_item > max_height - spillover_item_height * 2 )) + { + first_hidden_item_iter = item_iter; + visible_items_height = height - height_before_first_visible_item - (*item_iter)->getNominalHeight(); + scrollable_items_cnt--; + } + } + } + } + + if (mScrollable) + { + S32 max_items_height = max_height - spillover_item_height * 2; + + if (visible_items_height == 0) + visible_items_height = height - height_before_first_visible_item; + + // Fix mFirstVisibleItem value, if it doesn't allow to display all items, that can fit + if (visible_items_height < max_items_height && scrollable_items_cnt < mMaxScrollableItems) + { + item_list_t::iterator tmp_iter(first_visible_item_iter); + while (visible_items_height < max_items_height && + scrollable_items_cnt < mMaxScrollableItems && + first_visible_item_iter != mItems.begin()) + { + if ((*first_visible_item_iter)->getVisible()) + { + // It keeps visible item, after first_visible_item_iter + tmp_iter = first_visible_item_iter; + } + + first_visible_item_iter--; + + if ((*first_visible_item_iter)->getVisible()) + { + visible_items_height += (*first_visible_item_iter)->getNominalHeight(); + height_before_first_visible_item -= (*first_visible_item_iter)->getNominalHeight(); + scrollable_items_cnt++; + } + } + + // Roll back one item, that doesn't fit + if (visible_items_height > max_items_height) + { + visible_items_height -= (*first_visible_item_iter)->getNominalHeight(); + height_before_first_visible_item += (*first_visible_item_iter)->getNominalHeight(); + scrollable_items_cnt--; + first_visible_item_iter = tmp_iter; + } + if (!(*first_visible_item_iter)->getVisible()) + { + first_visible_item_iter = tmp_iter; + } + + mFirstVisibleItem = *first_visible_item_iter; } } } S32 cur_height = (S32)llmin(max_height, height); + + if (mScrollable && + (height_before_first_visible_item > MENU_ITEM_PADDING || + height_before_first_visible_item + visible_items_height < (S32)height)) + { + // Reserving 2 extra slots for arrow items + cur_height = visible_items_height + spillover_item_height * 2; + } + setRect(LLRect(getRect().mLeft, getRect().mTop, getRect().mLeft + width, getRect().mTop - cur_height)); S32 cur_width = 0; S32 offset = 0; + if (mScrollable) + { + // No space for all items, creating arrow items + if (height_before_first_visible_item > MENU_ITEM_PADDING || + height_before_first_visible_item + visible_items_height < (S32)height) + { + if (NULL == mArrowUpItem) + { + LLMenuScrollItem::Params item_params; + item_params.name(ARROW_UP); + item_params.arrow_type(LLMenuScrollItem::ARROW_UP); + item_params.scroll_callback.function(boost::bind(&LLMenuGL::scrollItems, this, SD_UP)); + + mArrowUpItem = LLUICtrlFactory::create(item_params); + LLUICtrl::addChild(mArrowUpItem); + + } + if (NULL == mArrowDownItem) + { + LLMenuScrollItem::Params item_params; + item_params.name(ARROW_DOWN); + item_params.arrow_type(LLMenuScrollItem::ARROW_DOWN); + item_params.scroll_callback.function(boost::bind(&LLMenuGL::scrollItems, this, SD_DOWN)); + + mArrowDownItem = LLUICtrlFactory::create(item_params); + LLUICtrl::addChild(mArrowDownItem); + } + + LLRect rect; + mArrowUpItem->setRect(rect.setLeftTopAndSize( 0, cur_height, width, mArrowUpItem->getNominalHeight())); + mArrowUpItem->setVisible(TRUE); + mArrowUpItem->setEnabled(height_before_first_visible_item > MENU_ITEM_PADDING); + mArrowUpItem->reshape(width, mArrowUpItem->getNominalHeight()); + mArrowDownItem->setRect(rect.setLeftTopAndSize( 0, mArrowDownItem->getNominalHeight(), width, mArrowDownItem->getNominalHeight())); + mArrowDownItem->setVisible(TRUE); + mArrowDownItem->setEnabled(height_before_first_visible_item + visible_items_height < (S32)height); + mArrowDownItem->reshape(width, mArrowDownItem->getNominalHeight()); + + cur_height -= mArrowUpItem->getNominalHeight(); + + offset = menu_region_rect.mRight; // This moves items behind visible area + } + else + { + if (NULL != mArrowUpItem) + { + mArrowUpItem->setVisible(FALSE); + } + if (NULL != mArrowDownItem) + { + mArrowDownItem->setVisible(FALSE); + } + } + + } + item_list_t::iterator item_iter; for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) { if ((*item_iter)->getVisible()) { + if (mScrollable) + { + if (item_iter == first_visible_item_iter) + { + offset = 0; + } + else if (item_iter == first_hidden_item_iter) + { + offset = menu_region_rect.mRight; // This moves items behind visible area + } + } + // setup item rect to hold label LLRect rect; if (mHorizontalLayout) @@ -2582,6 +2998,9 @@ void LLMenuGL::cleanupSpilloverBranch() void LLMenuGL::createJumpKeys() { + if (!mCreateJumpKeys) return; + mCreateJumpKeys = FALSE; + mJumpKeys.clear(); std::set unique_words; @@ -2683,9 +3102,64 @@ void LLMenuGL::empty( void ) mItems.clear(); mFirstVisibleItem = NULL; + mArrowUpItem = NULL; + mArrowDownItem = NULL; deleteAllChildren(); - +} + +// erase group of items from menu +void LLMenuGL::erase( S32 begin, S32 end, bool arrange/* = true*/) +{ + S32 items = mItems.size(); + + if ( items == 0 || begin >= end || begin < 0 || end > items ) + { + return; + } + + item_list_t::iterator start_position = mItems.begin(); + std::advance(start_position, begin); + + item_list_t::iterator end_position = mItems.begin(); + std::advance(end_position, end); + + for (item_list_t::iterator position_iter = start_position; position_iter != end_position; position_iter++) + { + LLUICtrl::removeChild(*position_iter); + } + + mItems.erase(start_position, end_position); + + if (arrange) + { + needsArrange(); + } +} + +// add new item at position +void LLMenuGL::insert(S32 position, LLView* ctrl, bool arrange /*= true*/) +{ + LLMenuItemGL* item = dynamic_cast(ctrl); + + if (NULL == item || position < 0 || (U32)position >= mItems.size()) + { + return; + } + + item_list_t::iterator position_iter = mItems.begin(); + std::advance(position_iter, position); + insert(position_iter, item, arrange); +} +void LLMenuGL::insert(item_list_t::iterator position_iter, LLMenuItemGL* item, bool arrange /*= true*/) +{ + mItems.insert(position_iter, item); + LLUICtrl::addChild(item); + + if (arrange) + { + needsArrange(); + } } // Adjust rectangle of the menu @@ -2707,7 +3181,7 @@ BOOL LLMenuGL::handleJumpKey(KEY key) // force highlight to close old menus and open and sub-menus found_it->second->setHighlight(TRUE); - found_it->second->doIt(); + found_it->second->onCommit(); } // if we are navigating the menus, we need to eat the keystroke @@ -2717,29 +3191,10 @@ BOOL LLMenuGL::handleJumpKey(KEY key) // Add the menu item to this menu. -// This wrapper is needed because the virtual linkage causes errors if default parameters are used BOOL LLMenuGL::append( LLMenuItemGL* item ) -{ - return append(item, 0); -} - -BOOL LLMenuGL::append(LLMenuItemGL* item, LLView* insert_before) { if (!item) return FALSE; - if (!insert_before) - { mItems.push_back( item ); - } - else - { - item_list_t::iterator i; - - for (i = mItems.begin(); i != mItems.end(); ++i) - if (*i == insert_before) - break; - mItems.insert(i, item); - } - LLUICtrl::addChild(item); needsArrange(); return TRUE; @@ -2753,13 +3208,7 @@ BOOL LLMenuGL::addSeparator() } // add a menu - this will create a cascading menu -// This wrapper is needed because the virtual linkage causes errors if default parameters are used BOOL LLMenuGL::appendMenu( LLMenuGL* menu ) -{ - return appendMenu(menu, 0); -} - -BOOL LLMenuGL::appendMenu(LLMenuGL* menu, LLView* insert_before) { if( menu == this ) { @@ -2771,7 +3220,7 @@ BOOL LLMenuGL::appendMenu(LLMenuGL* menu, LLView* insert_before) LLMenuItemBranchGL* branch = NULL; branch = new LLMenuItemBranchGL( menu->getName(), menu->getLabel(), menu->getHandle() ); branch->setJumpKey(menu->getJumpKey()); - success &= append( branch, insert_before ); + success &= append( branch ); // Inherit colors menu->setBackgroundColor( mBackgroundColor ); @@ -2826,7 +3275,7 @@ void LLMenuGL::setItemLastSelected(LLMenuItemGL* item) LLMenuHolderGL::setActivatedItem(item); } - // fix the checkmarks + // update enabled and checkmark status item->buildDrawLabel(); } @@ -2883,7 +3332,11 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa // same as giving focus to it if (!cur_item && getTornOff()) { - ((LLFloater*)getParent())->setFocus(TRUE); + LLFloater * parent = dynamic_cast(getParent()); + if (parent) + { + parent->setFocus(TRUE); + } } // Current item position in the items list @@ -2899,9 +3352,36 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa next_item_iter = cur_item_iter; next_item_iter++; + // First visible item position in the items list + item_list_t::iterator first_visible_item_iter = std::find(mItems.begin(), mItems.end(), mFirstVisibleItem); + if (next_item_iter == mItems.end()) { next_item_iter = mItems.begin(); + + // If current item is the last in the list, the menu is scrolled to the beginning + // and the first item is highlighted. + if (mScrollable && !scrollItems(SD_BEGIN)) + { + return NULL; + } + } + // If current item is the last visible, the menu is scrolled one item down + // and the next item is highlighted. + else if (mScrollable && + (U32)std::abs(std::distance(first_visible_item_iter, next_item_iter)) >= mMaxScrollableItems) + { + // Call highlightNextItem() recursively only if the menu was successfully scrolled down. + // If scroll timer hasn't expired yet the menu won't be scrolled and calling + // highlightNextItem() will result in an endless recursion. + if (scrollItems(SD_DOWN)) + { + return highlightNextItem(cur_item, skip_disabled); + } + else + { + return NULL; + } } } @@ -2958,7 +3438,11 @@ LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disa // same as giving focus to it if (!cur_item && getTornOff()) { - ((LLFloater*)getParent())->setFocus(TRUE); + LLFloater * parent = dynamic_cast(getParent()); + if (parent) + { + parent->setFocus(TRUE); + } } // Current item reverse position from the end of the list @@ -2974,9 +3458,36 @@ LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disa prev_item_iter = cur_item_iter; prev_item_iter++; + // First visible item reverse position in the items list + item_list_t::reverse_iterator first_visible_item_iter = std::find(mItems.rbegin(), mItems.rend(), mFirstVisibleItem); + if (prev_item_iter == mItems.rend()) { prev_item_iter = mItems.rbegin(); + + // If current item is the first in the list, the menu is scrolled to the end + // and the last item is highlighted. + if (mScrollable && !scrollItems(SD_END)) + { + return NULL; + } + } + // If current item is the first visible, the menu is scrolled one item up + // and the previous item is highlighted. + else if (mScrollable && + std::distance(first_visible_item_iter, cur_item_iter) <= 0) + { + // Call highlightNextItem() only if the menu was successfully scrolled up. + // If scroll timer hasn't expired yet the menu won't be scrolled and calling + // highlightNextItem() will result in an endless recursion. + if (scrollItems(SD_UP)) + { + return highlightPrevItem(cur_item, skip_disabled); + } + else + { + return NULL; + } } } @@ -3086,7 +3597,7 @@ BOOL LLMenuGL::handleHover( S32 x, S32 y, MASK mask ) if ((llabs(mMouseVelX) > 0 || llabs(mMouseVelY) > 0) /*&& (!mHasSelection || - (mouse_delta_x == 0 && mouse_delta_y == 0) || + // (mouse_delta_x == 0 && mouse_delta_y == 0) || (mMouseVelX < 0) || llabs((F32)mMouseVelY) / llabs((F32)mMouseVelX) > MAX_MOUSE_SLOPE_SUB_MENU)*/) { @@ -3141,9 +3652,24 @@ BOOL LLMenuGL::handleHover( S32 x, S32 y, MASK mask ) BOOL LLMenuGL::handleScrollWheel( S32 x, S32 y, S32 clicks ) { - return blockMouseEvent(x, y); + if (!mScrollable) + return blockMouseEvent(x, y); + + if( clicks > 0 ) + { + while( clicks-- ) + scrollItems(SD_DOWN); + } + else + { + while( clicks++ ) + scrollItems(SD_UP); + } + + return TRUE; } + void LLMenuGL::draw( void ) { if (mNeedsArrange) @@ -3153,9 +3679,8 @@ void LLMenuGL::draw( void ) } if (mDropShadowed && !mTornOff) { - static S32 drop_shadow_floater = LLUI::sConfigGroup->getS32("DropShadowFloater"); - static LLColor4 color_drop_shadow = LLUI::sColorsGroup->getColor("ColorDropShadow"); - + static LLUICachedControl drop_shadow_floater("DropShadowFloater", 0); + static const LLColor4 color_drop_shadow(LLUI::sColorsGroup->getColor4("ColorDropShadow")); gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, color_drop_shadow, drop_shadow_floater ); } @@ -3164,20 +3689,6 @@ void LLMenuGL::draw( void ) { gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0, mBackgroundColor ); } - - - /*LLRect rootRect = getRootView()->getRect(); - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLMenuItemGL* itemp = static_cast(*child_it); - if(itemp) - { - LLRect screenRect; - localRectToScreen(itemp->getRect(),&screenRect); - lldebugs << itemp->getName() << "Visible:" << itemp->getVisible() << " ValidRect: " << itemp->getRect().isValid() << " Overlaps: " << rootRect.overlaps(screenRect) << llendl; - } - }*/ - LLView::draw(); } @@ -3192,7 +3703,6 @@ void LLMenuGL::setVisible(BOOL visible) { if (visible != getVisible()) { - LLView::setVisible(visible); if (!visible) { lldebugs << "Hiding " << getName() << llendl; @@ -3209,6 +3719,8 @@ void LLMenuGL::setVisible(BOOL visible) mHasSelection = true; mFadeTimer.stop(); } + + LLView::setVisible(visible); } } @@ -3266,6 +3778,24 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) return; } + menu->setVisible( TRUE ); + + //Do not show menu if all menu items are disabled + BOOL item_enabled = false; + for (LLView::child_list_t::const_iterator itor = menu->getChildList()->begin(); + itor != menu->getChildList()->end(); + ++itor) + { + LLView *menu_item = (*itor); + item_enabled = item_enabled || menu_item->getEnabled(); + } + + if(!item_enabled) + { + menu->setVisible( FALSE ); + return; + } + // Save click point for detecting cursor moves before mouse-up. // Must be in local coords to compare with mouseUp events. // If the mouse doesn't move, the menu will stay open ala the Mac. @@ -3278,8 +3808,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) menu->mFirstVisibleItem = NULL; } - menu->setVisible( TRUE ); - // Fix menu rect if needed. menu->needsArrange(); menu->arrangeAndClear(); @@ -3310,6 +3838,765 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) menu->getParent()->sendChildToFront(menu); } +///============================================================================ +/// Class LLMenuBarGL +///============================================================================ + +static LLRegisterWidget r2("menu_bar"); + +// Default constructor +LLMenuBarGL::LLMenuBarGL( const std::string& name ) +: LLMenuGL ( name, name ) +{ + mHorizontalLayout = TRUE; + mKeepFixedSize = TRUE; + mAltKeyTrigger = FALSE; +} + +// Default destructor +LLMenuBarGL::~LLMenuBarGL() +{ + std::for_each(mAccelerators.begin(), mAccelerators.end(), DeletePointer()); + mAccelerators.clear(); +} + +// virtual +LLXMLNodePtr LLMenuBarGL::getXML(bool save_children) const +{ + // Sorty of hacky: reparent items to this and then back at the end of the export + LLView *orig_parent = NULL; + item_list_t::const_iterator item_iter; + for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) + { + LLMenuItemGL* child = *item_iter; + LLMenuItemBranchGL* branch = (LLMenuItemBranchGL*)child; + LLMenuGL *menu = branch->getBranch(); + orig_parent = menu->getParent(); + menu->updateParent((LLView *)this); + } + + LLXMLNodePtr node = LLMenuGL::getXML(); + + node->setName(LL_MENU_BAR_GL_TAG); + + for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) + { + LLMenuItemGL* child = *item_iter; + LLMenuItemBranchGL* branch = (LLMenuItemBranchGL*)child; + LLMenuGL *menu = branch->getBranch(); + menu->updateParent(orig_parent); + } + + return node; +} + +LLView* LLMenuBarGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +{ + BOOL opaque = FALSE; + node->getAttributeBOOL("opaque", opaque); + + LLMenuBarGL *menubar = new LLMenuBarGL("menu"); + + LLHandle parent_handle; + LLFloater* parent_floater = dynamic_cast(parent); + if (parent_floater) + { + parent_handle = parent_floater->getHandle(); + } + + // We need to have the rect early so that it's around when building + // the menu items + LLRect view_rect; + createRect(node, view_rect, parent, menubar->getRequiredRect()); + menubar->setRect(view_rect); + + if (node->hasAttribute("drop_shadow")) + { + BOOL drop_shadow = FALSE; + node->getAttributeBOOL("drop_shadow", drop_shadow); + menubar->setDropShadowed(drop_shadow); + } + + menubar->setBackgroundVisible(opaque); + LLColor4 color(0,0,0,0); + if (opaque && LLUICtrlFactory::getAttributeColor(node,"color", color)) + { + menubar->setBackgroundColor(color); + } + + LLXMLNodePtr child; + for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) + { + if (child->hasName("menu")) + { + LLMenuGL *menu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory); + menubar->appendMenu(menu); + if (LLMenuGL::sMenuContainer != NULL) + { + menu->updateParent(LLMenuGL::sMenuContainer); + } + else + { + menu->updateParent(parent); + } + } + } + + menubar->initFromXML(node, parent); + + BOOL create_jump_keys = FALSE; + node->getAttributeBOOL("create_jump_keys", create_jump_keys); + if (create_jump_keys) + { + menubar->createJumpKeys(); + } + + return menubar; +} + +BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask) +{ + if (getHighlightedItem() && mask == MASK_NONE) + { + // unmodified key accelerators are ignored when navigating menu + // (but are used as jump keys so will still work when appropriate menu is up) + return FALSE; + } + BOOL result = LLMenuGL::handleAcceleratorKey(key, mask); + if (result && mask & MASK_ALT) + { + // ALT key used to trigger hotkey, don't use as shortcut to open menu + mAltKeyTrigger = FALSE; + } + + if(!result + && (key == KEY_F10 && mask == MASK_CONTROL) + && !gKeyboard->getKeyRepeated(key) + && isInVisibleChain()) + { + if (getHighlightedItem()) + { + clearHoverItem(); + } + else + { + // close menus originating from other menu bars when first opening menu via keyboard + LLMenuGL::sMenuContainer->hideMenus(); + highlightNextItem(NULL); + LLMenuGL::setKeyboardMode(TRUE); + } + return TRUE; + } + + return result; +} + +BOOL LLMenuBarGL::handleKeyHere(KEY key, MASK mask) +{ + static LLUICachedControl use_altkey_for_menus ("UseAltKeyForMenus", 0); + if(key == KEY_ALT && !gKeyboard->getKeyRepeated(key) && use_altkey_for_menus) + { + mAltKeyTrigger = TRUE; + } + else // if any key other than ALT hit, clear out waiting for Alt key mode + { + mAltKeyTrigger = FALSE; + } + + if (key == KEY_ESCAPE && mask == MASK_NONE) + { + LLMenuGL::setKeyboardMode(FALSE); + // if any menus are visible, this will return TRUE, stopping further processing of ESCAPE key + return LLMenuGL::sMenuContainer->hideMenus(); + } + + // before processing any other key, check to see if ALT key has triggered menu access + checkMenuTrigger(); + + return LLMenuGL::handleKeyHere(key, mask); +} + +BOOL LLMenuBarGL::handleJumpKey(KEY key) +{ + // perform case-insensitive comparison + key = toupper(key); + navigation_key_map_t::iterator found_it = mJumpKeys.find(key); + if(found_it != mJumpKeys.end() && found_it->second->getEnabled()) + { + // switch to keyboard navigation mode + LLMenuGL::setKeyboardMode(TRUE); + + found_it->second->setHighlight(TRUE); + found_it->second->onCommit(); + } + return TRUE; +} + +BOOL LLMenuBarGL::handleMouseDown(S32 x, S32 y, MASK mask) +{ + // clicks on menu bar closes existing menus from other contexts but leave + // own menu open so that we get toggle behavior + if (!getHighlightedItem() || !getHighlightedItem()->isActive()) + { + LLMenuGL::sMenuContainer->hideMenus(); + } + + return LLMenuGL::handleMouseDown(x, y, mask); +} + +void LLMenuBarGL::setVisible(BOOL visible) +{ + if(visible != getVisible()) + { + if(!visible) + { + lldebugs << "Hiding " << getName() << llendl; + } + else + { + lldebugs << "Showing " << getName() << llendl; + } + } + LLUICtrl::setVisible(visible); +} + +void LLMenuBarGL::draw() +{ + LLMenuItemGL* itemp = getHighlightedItem(); + // If we are in mouse-control mode and the mouse cursor is not hovering over + // the current highlighted menu item and it isn't open, then remove the + // highlight. This is done via a polling mechanism here, as we don't receive + // notifications when the mouse cursor moves off of us + if (itemp && !itemp->isOpen() && !itemp->getHover() && !LLMenuGL::getKeyboardMode()) + { + clearHoverItem(); + } + + checkMenuTrigger(); + + LLMenuGL::draw(); +} + + +void LLMenuBarGL::checkMenuTrigger() +{ + // has the ALT key been pressed and subsequently released? + if (mAltKeyTrigger && !gKeyboard->getKeyDown(KEY_ALT)) + { + // if alt key was released quickly, treat it as a menu access key + // otherwise it was probably an Alt-zoom or similar action + static LLUICachedControl menu_access_key_time ("MenuAccessKeyTime", 0); + if (gKeyboard->getKeyElapsedTime(KEY_ALT) <= menu_access_key_time || + gKeyboard->getKeyElapsedFrameCount(KEY_ALT) < 2) + { + if (getHighlightedItem()) + { + clearHoverItem(); + } + else + { + // close menus originating from other menu bars + LLMenuGL::sMenuContainer->hideMenus(); + + highlightNextItem(NULL); + LLMenuGL::setKeyboardMode(TRUE); + } + } + mAltKeyTrigger = FALSE; + } +} + +BOOL LLMenuBarGL::jumpKeysActive() +{ + // require user to be in keyboard navigation mode to activate key triggers + // as menu bars are always visible and it is easy to leave the mouse cursor over them + return LLMenuGL::getKeyboardMode() && getHighlightedItem() && LLMenuGL::jumpKeysActive(); +} + +// rearrange the child rects so they fit the shape of the menu bar. +void LLMenuBarGL::arrange( void ) +{ + U32 pos = 0; + LLRect rect( 0, getRect().getHeight(), 0, 0 ); + item_list_t::const_iterator item_iter; + for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) + { + LLMenuItemGL* item = *item_iter; + if (item->getVisible()) + { + rect.mLeft = pos; + pos += item->getNominalWidth(); + rect.mRight = pos; + item->setRect( rect ); + item->buildDrawLabel(); + } + } + reshape(rect.mRight, rect.getHeight()); +} + + +S32 LLMenuBarGL::getRightmostMenuEdge() +{ + // Find the last visible menu + item_list_t::reverse_iterator item_iter; + for (item_iter = mItems.rbegin(); item_iter != mItems.rend(); ++item_iter) + { + if ((*item_iter)->getVisible()) + { + break; + } + } + + if (item_iter == mItems.rend()) + { + return 0; + } + return (*item_iter)->getRect().mRight; +} + +// add a vertical separator to this menu +BOOL LLMenuBarGL::addSeparator() +{ + LLMenuItemGL* separator = new LLMenuItemVerticalSeparatorGL(); + return append( separator ); +} + +// add a menu - this will create a drop down menu. +BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu ) +{ + if( menu == this ) + { + llerrs << "** Attempt to attach menu to itself. This is certainly " + << "a logic error." << llendl; + } + + BOOL success = TRUE; + + LLMenuItemBranchGL* branch = NULL; + branch = new LLMenuItemBranchDownGL( menu->getName(), menu->getLabel(), menu->getHandle()); + success &= branch->addToAcceleratorList(&mAccelerators); + success &= append( branch ); + branch->setJumpKey(branch->getJumpKey()); + menu->updateParent(LLMenuGL::sMenuContainer); + + return success; +} + +BOOL LLMenuBarGL::handleHover( S32 x, S32 y, MASK mask ) +{ + BOOL handled = FALSE; + LLView* active_menu = NULL; + + BOOL no_mouse_data = mLastMouseX == 0 && mLastMouseY == 0; + S32 mouse_delta_x = no_mouse_data ? 0 : x - mLastMouseX; + S32 mouse_delta_y = no_mouse_data ? 0 : y - mLastMouseY; + mMouseVelX = (mMouseVelX / 2) + (mouse_delta_x / 2); + mMouseVelY = (mMouseVelY / 2) + (mouse_delta_y / 2); + mLastMouseX = x; + mLastMouseY = y; + + // if nothing currently selected or mouse has moved since last call, pick menu item via mouse + // otherwise let keyboard control it + if (!getHighlightedItem() || !LLMenuGL::getKeyboardMode() || llabs(mMouseVelX) > 0 || llabs(mMouseVelY) > 0) + { + // find current active menu + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + if (((LLMenuItemGL*)viewp)->isOpen()) + { + active_menu = viewp; + } + } + + // check for new active menu + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; + if( viewp->getVisible() && + viewp->getEnabled() && + viewp->pointInView(local_x, local_y) && + viewp->handleHover(local_x, local_y, mask)) + { + ((LLMenuItemGL*)viewp)->setHighlight(TRUE); + handled = TRUE; + if (active_menu && active_menu != viewp) + { + ((LLMenuItemGL*)viewp)->onCommit(); + LLMenuGL::setKeyboardMode(FALSE); + } + LLMenuGL::setKeyboardMode(FALSE); + } + } + + if (handled) + { + // set hover false on inactive menus + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; + if (!viewp->pointInView(local_x, local_y) && ((LLMenuItemGL*)viewp)->getHighlight()) + { + ((LLMenuItemGL*)viewp)->setHighlight(FALSE); + } + } + } + } + + getWindow()->setCursor(UI_CURSOR_ARROW); + + return TRUE; +} + +///============================================================================ +/// Class LLMenuHolderGL +///============================================================================ +LLCoordGL LLMenuHolderGL::sContextMenuSpawnPos(S32_MAX, S32_MAX); +LLMenuHolderGL::LLMenuHolderGL() + : LLPanel(std::string("Menu Holder")) +{ + setMouseOpaque(FALSE); + sItemActivationTimer.stop(); + mCanHide = TRUE; +} + +LLMenuHolderGL::LLMenuHolderGL(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows) +: LLPanel(name, rect, FALSE) +{ + setMouseOpaque(mouse_opaque); + sItemActivationTimer.stop(); + mCanHide = TRUE; +} + +void LLMenuHolderGL::draw() +{ + LLView::draw(); + // now draw last selected item as overlay + LLMenuItemGL* selecteditem = (LLMenuItemGL*)sItemLastSelectedHandle.get(); + if (selecteditem && selecteditem->getVisible() && sItemActivationTimer.getStarted() && sItemActivationTimer.getElapsedTimeF32() < ACTIVATE_HIGHLIGHT_TIME) + { + // make sure toggle items, for example, show the proper state when fading out + selecteditem->buildDrawLabel(); + + LLRect item_rect; + selecteditem->localRectToOtherView(selecteditem->getLocalRect(), &item_rect, this); + + F32 interpolant = sItemActivationTimer.getElapsedTimeF32() / ACTIVATE_HIGHLIGHT_TIME; + + LLUI::pushMatrix(); + { + LLUI::translate((F32)item_rect.mLeft, (F32)item_rect.mBottom, 0.f); + LLColor4 bg_color(LLMenuItemGL::sHighlightBackground.mV[VRED], + LLMenuItemGL::sHighlightBackground.mV[VGREEN], + LLMenuItemGL::sHighlightBackground.mV[VBLUE], + lerp(LLMenuItemGL::sHighlightBackground.mV[VALPHA], 0.f, interpolant)); + selecteditem->getMenu()->drawBackground(selecteditem, bg_color); + selecteditem->draw(); + } + LLUI::popMatrix(); + } +} + +BOOL LLMenuHolderGL::handleMouseDown( S32 x, S32 y, MASK mask ) +{ + BOOL handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; + if (!handled) + { + // clicked off of menu, hide them all + hideMenus(); + } + return handled; +} + +BOOL LLMenuHolderGL::handleRightMouseDown( S32 x, S32 y, MASK mask ) +{ + BOOL handled = LLView::childrenHandleRightMouseDown(x, y, mask) != NULL; + if (!handled) + { + // clicked off of menu, hide them all + hideMenus(); + } + return handled; +} + +// This occurs when you mouse-down to spawn a context menu, hold the button +// down, move off the menu, then mouse-up. We want this to close the menu. +BOOL LLMenuHolderGL::handleRightMouseUp( S32 x, S32 y, MASK mask ) +{ + const S32 SLOP = 2; + S32 spawn_dx = (x - sContextMenuSpawnPos.mX); + S32 spawn_dy = (y - sContextMenuSpawnPos.mY); + if (-SLOP <= spawn_dx && spawn_dx <= SLOP + && -SLOP <= spawn_dy && spawn_dy <= SLOP) + { + // we're still inside the slop region from spawning this menu + // so interpret the mouse-up as a single-click to show and leave on + // screen + sContextMenuSpawnPos.set(S32_MAX, S32_MAX); + return TRUE; + } + + BOOL handled = LLView::childrenHandleRightMouseUp(x, y, mask) != NULL; + if (!handled) + { + // clicked off of menu, hide them all + hideMenus(); + } + return handled; +} + +BOOL LLMenuHolderGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) +{ + BOOL handled = false; + LLMenuGL* const pMenu = dynamic_cast(getVisibleMenu()); + + if (pMenu) + { + //eat TAB key - EXT-7000 + if (key == KEY_TAB && mask == MASK_NONE) + { + return TRUE; + } + + //handle ESCAPE and RETURN key + handled = LLPanel::handleKey(key, mask, called_from_parent); + if (!handled) + { + if (pMenu->getHighlightedItem()) + { + handled = pMenu->handleKey(key, mask, TRUE); + } + else + { + if (key == KEY_UP || key == KEY_DOWN) // Singu Note: Only highlight if the user actually meant to navigate through the menu + { + //highlight first enabled one + if (pMenu->highlightNextItem(NULL)) + { + handled = true; + } + } + } + } + } + + return handled; + +} + +void LLMenuHolderGL::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + if (width != getRect().getWidth() || height != getRect().getHeight()) + { + hideMenus(); + } + LLView::reshape(width, height, called_from_parent); +} + +LLView* const LLMenuHolderGL::getVisibleMenu() const +{ + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + if (viewp->getVisible() && dynamic_cast(viewp) != NULL && !dynamic_cast(viewp)) + { + return viewp; + } + } + return NULL; +} + + +BOOL LLMenuHolderGL::hideMenus() +{ + if (!mCanHide) + { + return FALSE; + } + + sItemActivationTimer.stop(); + + BOOL menu_visible = hasVisibleMenu(); + if (menu_visible) + { + LLMenuGL::setKeyboardMode(FALSE); + // clicked off of menu, hide them all + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + if (dynamic_cast(viewp) != NULL && viewp->getVisible() && !dynamic_cast(viewp)) + { + viewp->setVisible(FALSE); + } + } + } + //if (gFocusMgr.childHasKeyboardFocus(this)) + //{ + // gFocusMgr.setKeyboardFocus(NULL); + //} + + return menu_visible; +} + +void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) +{ + sItemLastSelectedHandle = item->getHandle(); + sItemActivationTimer.start(); +} + +///============================================================================ +/// Class LLTearOffMenu +///============================================================================ +LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : + LLFloater(menup->getName(), LLRect(0, 100, 100, 0), menup->getLabel(), FALSE, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, FALSE, FALSE) +{ + S32 floater_header_size = LLFLOATER_HEADER_SIZE; + + setName(menup->getName()); + setTitle(menup->getLabel()); + setCanMinimize(FALSE); + // flag menu as being torn off + menup->setTornOff(TRUE); + // update menu layout as torn off menu (no spillover menus) + menup->needsArrange(); + + LLRect rect; + menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView); + // make sure this floater is big enough for menu + mTargetHeight = (F32)(rect.getHeight() + floater_header_size); + reshape(rect.getWidth(), rect.getHeight()); + setRect(rect); + + // attach menu to floater + menup->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM); + mOldParent = menup->getParent(); + addChild(menup); + menup->setVisible(TRUE); + LLRect menu_rect = menup->getRect(); + menu_rect.setOriginAndSize( 1, 1, + menu_rect.getWidth(), menu_rect.getHeight()); + menup->setRect(menu_rect); + menup->setDropShadowed(FALSE); + + mMenu = menup; + + // highlight first item (tear off item will be disabled) + mMenu->highlightNextItem(NULL); +} + +LLTearOffMenu::~LLTearOffMenu() +{ +} + +void LLTearOffMenu::draw() +{ + mMenu->setBackgroundVisible(isBackgroundOpaque()); + mMenu->needsArrange(); + + if (getRect().getHeight() != mTargetHeight) + { + // animate towards target height + reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f)))); + } + LLFloater::draw(); +} + +void LLTearOffMenu::onFocusReceived() +{ + // if nothing is highlighted, just highlight first item + if (!mMenu->getHighlightedItem()) + { + mMenu->highlightNextItem(NULL); + } + + // parent menu items get highlights so navigation logic keeps working + LLMenuItemGL* parent_menu_item = mMenu->getParentMenuItem(); + while(parent_menu_item) + { + if (parent_menu_item->getMenu()->getVisible()) + { + parent_menu_item->setHighlight(TRUE); + parent_menu_item = parent_menu_item->getMenu()->getParentMenuItem(); + } + else + { + break; + } + } + LLFloater::onFocusReceived(); +} + +void LLTearOffMenu::onFocusLost() +{ + // remove highlight from parent item and our own menu + mMenu->clearHoverItem(); + LLFloater::onFocusLost(); +} + +BOOL LLTearOffMenu::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) +{ + // pass keystrokes down to menu + return mMenu->handleUnicodeChar(uni_char, TRUE); +} + +BOOL LLTearOffMenu::handleKeyHere(KEY key, MASK mask) +{ + if (!mMenu->getHighlightedItem()) + { + if (key == KEY_UP) + { + mMenu->highlightPrevItem(NULL); + return TRUE; + } + else if (key == KEY_DOWN) + { + mMenu->highlightNextItem(NULL); + return TRUE; + } + } + // pass keystrokes down to menu + return mMenu->handleKey(key, mask, TRUE); +} + +void LLTearOffMenu::translate(S32 x, S32 y) +{ + if (x != 0 && y != 0) + { + // hide open sub-menus by clearing current hover item + mMenu->clearHoverItem(); + } + LLFloater::translate(x, y); +} + +//static +LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup) +{ + LLTearOffMenu* tearoffp = new LLTearOffMenu(menup); + // keep onscreen + gFloaterView->adjustToFitScreen(tearoffp, FALSE); + tearoffp->open(); /* Flawfinder: ignore */ + + return tearoffp; +} + +void LLTearOffMenu::onClose(bool app_quitting) +{ + removeChild(mMenu); + mOldParent->addChild(mMenu); + mMenu->clearHoverItem(); + mMenu->setFollowsNone(); + mMenu->setBackgroundVisible(TRUE); + mMenu->setVisible(FALSE); + mMenu->setTornOff(FALSE); + mMenu->setDropShadowed(TRUE); + destroy(); +} + + LLContextMenuBranch::LLContextMenuBranch(const std::string& name, const std::string& label, LLContextMenu* branch) : LLMenuItemGL( name, label, KEY_NONE, MASK_NONE ), mBranch( branch ) @@ -3381,8 +4668,8 @@ void LLContextMenuBranch::showSubMenu() mBranch->show(center_x, center_y, context); } -// doIt() - do the primary funcationality of the menu item. -void LLContextMenuBranch::doIt( void ) +// onCommit() - do the primary funcationality of the menu item. +void LLContextMenuBranch::onCommit( void ) { showSubMenu(); } @@ -3406,7 +4693,8 @@ void LLContextMenuBranch::setHighlight( BOOL highlight ) } } -/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- // class LLContextMenu // A context menu @@ -3470,11 +4758,10 @@ void LLContextMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory void LLContextMenu::setVisible(BOOL visible) { if (!visible) - { hide(); - } } +// Takes cursor position in screen space? void LLContextMenu::show(S32 x, S32 y, bool context) { if (getChildList()->empty()) @@ -3501,7 +4788,7 @@ void LLContextMenu::show(S32 x, S32 y, bool context) // Open upwards if menu extends past bottom if (y - height < menu_region_rect.mBottom) { - if (getParentMenuItem()) + if (getParentMenuItem()) // Adjust if this is a submenu { y += height - getParentMenuItem()->getNominalHeight(); } @@ -3576,10 +4863,11 @@ void LLContextMenu::hide() if (mHoverItem) { mHoverItem->setHighlight( FALSE ); - mHoverItem = NULL; } + mHoverItem = NULL; } + BOOL LLContextMenu::handleHover( S32 x, S32 y, MASK mask ) { LLMenuGL::handleHover(x, y, mask); @@ -3596,7 +4884,7 @@ BOOL LLContextMenu::handleHoverOver(LLMenuItemGL* item, S32 x, S32 y) if (item && item->getEnabled()) { getWindow()->setCursor(UI_CURSOR_ARROW); - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; handled = TRUE; if (item != mHoverItem) @@ -3623,14 +4911,14 @@ BOOL LLContextMenu::handleHoverOver(LLMenuItemGL* item, S32 x, S32 y) if( !handled && pointInView( x, y ) ) { getWindow()->setCursor(UI_CURSOR_ARROW); - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; handled = TRUE; } return handled; } -// handleMouseUp and handleMouseDown are handled by LLMenuGL +// handleMouseDown and handleMouseUp are handled by LLMenuGL BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) @@ -3832,7 +5120,7 @@ BOOL LLPieMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) mUseInfiniteRadius = TRUE; handled = TRUE; } - + if (item) { // lie to the item about where the click happened @@ -3849,7 +5137,7 @@ BOOL LLPieMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL LLPieMenu::handleRightMouseUp( S32 x, S32 y, MASK mask ) { // release mouse capture when right mouse button released, and we're past the shrink time - if (mShrinkBorderTimer.getStarted() && + if (mShrinkBorderTimer.getStarted() && mShrinkBorderTimer.getElapsedTimeF32() > PIE_SHRINK_TIME) { mUseInfiniteRadius = FALSE; @@ -4031,8 +5319,7 @@ BOOL LLPieMenu::append(LLMenuItemGL *item) // virtual BOOL LLPieMenu::addSeparator() { - LLMenuItemGL* separator = new LLMenuItemBlankGL(); - return append( separator ); + return append( new LLMenuItemBlankGL() ); } // virtual @@ -4073,7 +5360,7 @@ void LLPieMenu::arrange() // Put in the right place around a circle centered at 0,0 rect.setCenterAndSize(ITEM_CENTER_X[i], - ITEM_CENTER_Y[i], + ITEM_CENTER_Y[i], item_width, font_height ); // Correct for the actual rectangle size @@ -4116,7 +5403,7 @@ S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y) } F32 angle = RAD_TO_DEG * (F32) atan2((F32)delta_y, (F32)delta_x); - + // rotate marks CCW so that east = [0, ARC_DEG) instead of // [-ARC_DEG/2, ARC_DEG/2) angle += ARC_DEG / 2.f; @@ -4136,12 +5423,9 @@ LLMenuItemGL* LLPieMenu::pieItemFromIndex(S32 which) { if (which == 0) { - if((*item_iter)->getVisible()) - return (*item_iter); - else - return NULL; + return (*item_iter)->getVisible() ? (*item_iter) : NULL; } - which--; + --which; } } @@ -4160,23 +5444,13 @@ void LLPieMenu::show(S32 x, S32 y, bool mouse_down) mUseInfiniteRadius = TRUE; mHoveredAnyItem = FALSE; - if (!mFirstMouseDown) - { - make_ui_sound("UISndPieMenuAppear"); - } + if (!mFirstMouseDown) make_ui_sound("UISndPieMenuAppear"); // we want all mouse events in case user does quick right click again off of pie menu // rectangle, to support gestural menu traversal gFocusMgr.setMouseCapture(this); - if (mouse_down) - { - mShrinkBorderTimer.stop(); - } - else - { - mShrinkBorderTimer.start(); - } + mouse_down ? mShrinkBorderTimer.stop() : mShrinkBorderTimer.start(); } // virtual @@ -4193,758 +5467,3 @@ void LLPieMenu::hide() gFocusMgr.setMouseCapture(NULL); } -///============================================================================ -/// Class LLMenuBarGL -///============================================================================ - -static LLRegisterWidget r2("menu_bar"); - -// Default constructor -LLMenuBarGL::LLMenuBarGL( const std::string& name ) -: LLMenuGL ( name, name ) -{ - mHorizontalLayout = TRUE; - mKeepFixedSize = TRUE; - mAltKeyTrigger = FALSE; -} - -// Default destructor -LLMenuBarGL::~LLMenuBarGL() -{ - std::for_each(mAccelerators.begin(), mAccelerators.end(), DeletePointer()); - mAccelerators.clear(); -} - -// virtual -LLXMLNodePtr LLMenuBarGL::getXML(bool save_children) const -{ - // Sorty of hacky: reparent items to this and then back at the end of the export - LLView *orig_parent = NULL; - item_list_t::const_iterator item_iter; - for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) - { - LLMenuItemGL* child = *item_iter; - LLMenuItemBranchGL* branch = (LLMenuItemBranchGL*)child; - LLMenuGL *menu = branch->getBranch(); - orig_parent = menu->getParent(); - menu->updateParent((LLView *)this); - } - - LLXMLNodePtr node = LLMenuGL::getXML(); - - node->setName(LL_MENU_BAR_GL_TAG); - - for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) - { - LLMenuItemGL* child = *item_iter; - LLMenuItemBranchGL* branch = (LLMenuItemBranchGL*)child; - LLMenuGL *menu = branch->getBranch(); - menu->updateParent(orig_parent); - } - - return node; -} - -LLView* LLMenuBarGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) -{ - BOOL opaque = FALSE; - node->getAttributeBOOL("opaque", opaque); - - LLMenuBarGL *menubar = new LLMenuBarGL("menu"); - - LLHandle parent_handle; - LLFloater* parent_floater = dynamic_cast(parent); - if (parent_floater) - { - parent_handle = parent_floater->getHandle(); - } - - // We need to have the rect early so that it's around when building - // the menu items - LLRect view_rect; - createRect(node, view_rect, parent, menubar->getRequiredRect()); - menubar->setRect(view_rect); - - if (node->hasAttribute("drop_shadow")) - { - BOOL drop_shadow = FALSE; - node->getAttributeBOOL("drop_shadow", drop_shadow); - menubar->setDropShadowed(drop_shadow); - } - - menubar->setBackgroundVisible(opaque); - LLColor4 color(0,0,0,0); - if (opaque && LLUICtrlFactory::getAttributeColor(node,"color", color)) - { - menubar->setBackgroundColor(color); - } - - LLXMLNodePtr child; - for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) - { - if (child->hasName("menu")) - { - LLMenuGL *menu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory); - menubar->appendMenu(menu); - if (LLMenuGL::sMenuContainer != NULL) - { - menu->updateParent(LLMenuGL::sMenuContainer); - } - else - { - menu->updateParent(parent); - } - } - } - - menubar->initFromXML(node, parent); - - BOOL create_jump_keys = FALSE; - node->getAttributeBOOL("create_jump_keys", create_jump_keys); - if (create_jump_keys) - { - menubar->createJumpKeys(); - } - - return menubar; -} - -BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask) -{ - if (getHighlightedItem() && mask == MASK_NONE) - { - // unmodified key accelerators are ignored when navigating menu - // (but are used as jump keys so will still work when appropriate menu is up) - return FALSE; - } - BOOL result = LLMenuGL::handleAcceleratorKey(key, mask); - if (result && mask & MASK_ALT) - { - // ALT key used to trigger hotkey, don't use as shortcut to open menu - mAltKeyTrigger = FALSE; - } - - if(!result - && (key == KEY_F10 && mask == MASK_CONTROL) - && !gKeyboard->getKeyRepeated(key) - && isInVisibleChain()) - { - if (getHighlightedItem()) - { - clearHoverItem(); - } - else - { - // close menus originating from other menu bars when first opening menu via keyboard - LLMenuGL::sMenuContainer->hideMenus(); - highlightNextItem(NULL); - LLMenuGL::setKeyboardMode(TRUE); - } - return TRUE; - } - - return result; -} - -BOOL LLMenuBarGL::handleKeyHere(KEY key, MASK mask) -{ - if(key == KEY_ALT && !gKeyboard->getKeyRepeated(key) && LLUI::sConfigGroup->getBOOL("UseAltKeyForMenus")) - { - mAltKeyTrigger = TRUE; - } - else // if any key other than ALT hit, clear out waiting for Alt key mode - { - mAltKeyTrigger = FALSE; - } - - if (key == KEY_ESCAPE && mask == MASK_NONE) - { - LLMenuGL::setKeyboardMode(FALSE); - // if any menus are visible, this will return TRUE, stopping further processing of ESCAPE key - return LLMenuGL::sMenuContainer->hideMenus(); - } - - // before processing any other key, check to see if ALT key has triggered menu access - checkMenuTrigger(); - - return LLMenuGL::handleKeyHere(key, mask); -} - -BOOL LLMenuBarGL::handleJumpKey(KEY key) -{ - // perform case-insensitive comparison - key = toupper(key); - navigation_key_map_t::iterator found_it = mJumpKeys.find(key); - if(found_it != mJumpKeys.end() && found_it->second->getEnabled()) - { - // switch to keyboard navigation mode - LLMenuGL::setKeyboardMode(TRUE); - - found_it->second->setHighlight(TRUE); - found_it->second->doIt(); - } - return TRUE; -} - -BOOL LLMenuBarGL::handleMouseDown(S32 x, S32 y, MASK mask) -{ - // clicks on menu bar closes existing menus from other contexts but leave - // own menu open so that we get toggle behavior - if (!getHighlightedItem() || !getHighlightedItem()->isActive()) - { - LLMenuGL::sMenuContainer->hideMenus(); - } - - return LLMenuGL::handleMouseDown(x, y, mask); -} - -void LLMenuBarGL::setVisible(BOOL visible) -{ - if(visible != getVisible()) - { - if(!visible) - { - lldebugs << "Hiding " << getName() << llendl; - } - else - { - lldebugs << "Showing " << getName() << llendl; - } - } - LLUICtrl::setVisible(visible); -} - -void LLMenuBarGL::draw() -{ - LLMenuItemGL* itemp = getHighlightedItem(); - // If we are in mouse-control mode and the mouse cursor is not hovering over - // the current highlighted menu item and it isn't open, then remove the - // highlight. This is done via a polling mechanism here, as we don't receive - // notifications when the mouse cursor moves off of us - if (itemp && !itemp->isOpen() && !itemp->getHover() && !LLMenuGL::getKeyboardMode()) - { - clearHoverItem(); - } - - checkMenuTrigger(); - - LLMenuGL::draw(); -} - -void LLMenuBarGL::checkMenuTrigger() -{ - // has the ALT key been pressed and subsequently released? - if (mAltKeyTrigger && !gKeyboard->getKeyDown(KEY_ALT)) - { - // if alt key was released quickly, treat it as a menu access key - // otherwise it was probably an Alt-zoom or similar action - if (gKeyboard->getKeyElapsedTime(KEY_ALT) <= LLUI::sConfigGroup->getF32("MenuAccessKeyTime") || - gKeyboard->getKeyElapsedFrameCount(KEY_ALT) < 2) - { - if (getHighlightedItem()) - { - clearHoverItem(); - } - else - { - // close menus originating from other menu bars - LLMenuGL::sMenuContainer->hideMenus(); - - highlightNextItem(NULL); - LLMenuGL::setKeyboardMode(TRUE); - } - } - mAltKeyTrigger = FALSE; - } -} - -BOOL LLMenuBarGL::jumpKeysActive() -{ - // require user to be in keyboard navigation mode to activate key triggers - // as menu bars are always visible and it is easy to leave the mouse cursor over them - return LLMenuGL::getKeyboardMode() && getHighlightedItem() && LLMenuGL::jumpKeysActive(); -} - -// rearrange the child rects so they fit the shape of the menu bar. -void LLMenuBarGL::arrange( void ) -{ - U32 pos = 0; - LLRect rect( 0, getRect().getHeight(), 0, 0 ); - item_list_t::const_iterator item_iter; - for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) - { - LLMenuItemGL* item = *item_iter; - if (item->getVisible()) - { - rect.mLeft = pos; - pos += item->getNominalWidth(); - rect.mRight = pos; - item->setRect( rect ); - item->buildDrawLabel(); - } - } - reshape(rect.mRight, rect.getHeight()); -} - - -S32 LLMenuBarGL::getRightmostMenuEdge() -{ - // Find the last visible menu - item_list_t::reverse_iterator item_iter; - for (item_iter = mItems.rbegin(); item_iter != mItems.rend(); ++item_iter) - { - if ((*item_iter)->getVisible()) - { - break; - } - } - - if (item_iter == mItems.rend()) - { - return 0; - } - return (*item_iter)->getRect().mRight; -} - -// add a vertical separator to this menu -BOOL LLMenuBarGL::addSeparator() -{ - LLMenuItemGL* separator = new LLMenuItemVerticalSeparatorGL(); - return append( separator ); -} - -// add a menu - this will create a drop down menu. -BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu ) -{ - if( menu == this ) - { - llerrs << "** Attempt to attach menu to itself. This is certainly " - << "a logic error." << llendl; - } - - BOOL success = TRUE; - - LLMenuItemBranchGL* branch = NULL; - branch = new LLMenuItemBranchDownGL( menu->getName(), menu->getLabel(), menu->getHandle()); - success &= branch->addToAcceleratorList(&mAccelerators); - success &= append( branch ); - branch->setJumpKey(branch->getJumpKey()); - menu->updateParent(LLMenuGL::sMenuContainer); - - return success; -} - -BOOL LLMenuBarGL::handleHover( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - LLView* active_menu = NULL; - - BOOL no_mouse_data = mLastMouseX == 0 && mLastMouseY == 0; - S32 mouse_delta_x = no_mouse_data ? 0 : x - mLastMouseX; - S32 mouse_delta_y = no_mouse_data ? 0 : y - mLastMouseY; - mMouseVelX = (mMouseVelX / 2) + (mouse_delta_x / 2); - mMouseVelY = (mMouseVelY / 2) + (mouse_delta_y / 2); - mLastMouseX = x; - mLastMouseY = y; - - // if nothing currently selected or mouse has moved since last call, pick menu item via mouse - // otherwise let keyboard control it - if (!getHighlightedItem() || !LLMenuGL::getKeyboardMode() || llabs(mMouseVelX) > 0 || llabs(mMouseVelY) > 0) - { - // find current active menu - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if (((LLMenuItemGL*)viewp)->isOpen()) - { - active_menu = viewp; - } - } - - // check for new active menu - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - S32 local_x = x - viewp->getRect().mLeft; - S32 local_y = y - viewp->getRect().mBottom; - if( viewp->getVisible() && - viewp->getEnabled() && - viewp->pointInView(local_x, local_y) && - viewp->handleHover(local_x, local_y, mask)) - { - ((LLMenuItemGL*)viewp)->setHighlight(TRUE); - handled = TRUE; - if (active_menu && active_menu != viewp) - { - ((LLMenuItemGL*)viewp)->doIt(); - LLMenuGL::setKeyboardMode(FALSE); - } - LLMenuGL::setKeyboardMode(FALSE); - } - } - - if (handled) - { - // set hover false on inactive menus - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - S32 local_x = x - viewp->getRect().mLeft; - S32 local_y = y - viewp->getRect().mBottom; - if (!viewp->pointInView(local_x, local_y) && ((LLMenuItemGL*)viewp)->getHighlight()) - { - ((LLMenuItemGL*)viewp)->setHighlight(FALSE); - } - } - } - } - - getWindow()->setCursor(UI_CURSOR_ARROW); - - return TRUE; -} - -///============================================================================ -/// Class LLMenuHolderGL -///============================================================================ -LLCoordGL LLMenuHolderGL::sContextMenuSpawnPos(S32_MAX, S32_MAX); -LLMenuHolderGL::LLMenuHolderGL() - : LLPanel(std::string("Menu Holder")) -{ - setMouseOpaque(FALSE); - sItemActivationTimer.stop(); - mCanHide = TRUE; -} - -LLMenuHolderGL::LLMenuHolderGL(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows) -: LLPanel(name, rect, FALSE) -{ - setMouseOpaque(mouse_opaque); - sItemActivationTimer.stop(); - mCanHide = TRUE; -} - - -void LLMenuHolderGL::draw() -{ - LLView::draw(); - // now draw last selected item as overlay - LLMenuItemGL* selecteditem = (LLMenuItemGL*)sItemLastSelectedHandle.get(); - if (selecteditem && selecteditem->getVisible() && sItemActivationTimer.getStarted() && sItemActivationTimer.getElapsedTimeF32() < ACTIVATE_HIGHLIGHT_TIME) - { - // make sure toggle items, for example, show the proper state when fading out - selecteditem->buildDrawLabel(); - - LLRect item_rect; - selecteditem->localRectToOtherView(selecteditem->getLocalRect(), &item_rect, this); - - F32 interpolant = sItemActivationTimer.getElapsedTimeF32() / ACTIVATE_HIGHLIGHT_TIME; - F32 alpha = lerp(LLMenuItemGL::sHighlightBackground.mV[VALPHA], 0.f, interpolant); - LLColor4 bg_color(LLMenuItemGL::sHighlightBackground.mV[VRED], - LLMenuItemGL::sHighlightBackground.mV[VGREEN], - LLMenuItemGL::sHighlightBackground.mV[VBLUE], - alpha); - - LLUI::pushMatrix(); - { - LLUI::translate((F32)item_rect.mLeft, (F32)item_rect.mBottom, 0.f); - selecteditem->getMenu()->drawBackground(selecteditem, bg_color); - selecteditem->draw(); - } - LLUI::popMatrix(); - } -} - -BOOL LLMenuHolderGL::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; - if (!handled) - { - // clicked off of menu, hide them all - hideMenus(); - } - return handled; -} - -BOOL LLMenuHolderGL::handleRightMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = LLView::childrenHandleRightMouseDown(x, y, mask) != NULL; - if (!handled) - { - // clicked off of menu, hide them all - hideMenus(); - } - return handled; -} - -// This occurs when you mouse-down to spawn a context menu, hold the button -// down, move off the menu, then mouse-up. We want this to close the menu. -BOOL LLMenuHolderGL::handleRightMouseUp( S32 x, S32 y, MASK mask ) -{ - const S32 SLOP = 2; - S32 spawn_dx = (x - sContextMenuSpawnPos.mX); - S32 spawn_dy = (y - sContextMenuSpawnPos.mY); - if (-SLOP <= spawn_dx && spawn_dx <= SLOP - && -SLOP <= spawn_dy && spawn_dy <= SLOP) - { - // we're still inside the slop region from spawning this menu - // so interpret the mouse-up as a single-click to show and leave on - // screen - sContextMenuSpawnPos.set(S32_MAX, S32_MAX); - return TRUE; - } - - BOOL handled = LLView::childrenHandleRightMouseUp(x, y, mask) != NULL; - if (!handled) - { - // clicked off of menu, hide them all - hideMenus(); - } - return handled; -} - -BOOL LLMenuHolderGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) -{ - BOOL handled = false; - LLMenuGL* const pMenu = dynamic_cast(getVisibleMenu()); - - if (pMenu) - { - //eat TAB key - EXT-7000 - if (key == KEY_TAB && mask == MASK_NONE) - { - return TRUE; - } - - //handle ESCAPE and RETURN key - handled = LLPanel::handleKey(key, mask, called_from_parent); - if (!handled) - { - if (pMenu->getHighlightedItem()) - { - handled = pMenu->handleKey(key, mask, TRUE); - } - else - { - if (key == KEY_UP || key == KEY_DOWN) // Singu Note: Only highlight if the user actually meant to navigate through the menu - { - //highlight first enabled one - if (pMenu->highlightNextItem(NULL)) - { - handled = true; - } - } - } - } - } - - return handled; - -} - -void LLMenuHolderGL::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - if (width != getRect().getWidth() || height != getRect().getHeight()) - { - hideMenus(); - } - LLView::reshape(width, height, called_from_parent); -} - -LLView* const LLMenuHolderGL::getVisibleMenu() const -{ - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if (viewp->getVisible() && dynamic_cast(viewp) != NULL && !dynamic_cast(viewp)) - { - return viewp; - } - } - return NULL; -} - - -BOOL LLMenuHolderGL::hideMenus() -{ - if (!mCanHide) - { - return FALSE; - } - - sItemActivationTimer.stop(); - - BOOL menu_visible = hasVisibleMenu(); - if (menu_visible) - { - LLMenuGL::setKeyboardMode(FALSE); - // clicked off of menu, hide them all - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if (dynamic_cast(viewp) != NULL && viewp->getVisible() && !dynamic_cast(viewp)) - { - viewp->setVisible(FALSE); - } - } - } - //if (gFocusMgr.childHasKeyboardFocus(this)) - //{ - // gFocusMgr.setKeyboardFocus(NULL); - //} - - return menu_visible; -} - -void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) -{ - sItemLastSelectedHandle = item->getHandle(); - sItemActivationTimer.start(); -} - -///============================================================================ -/// Class LLTearOffMenu -///============================================================================ -LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : - LLFloater(menup->getName(), LLRect(0, 100, 100, 0), menup->getLabel(), FALSE, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, FALSE, FALSE) -{ - S32 floater_header_size = LLFLOATER_HEADER_SIZE; - - setName(menup->getName()); - setTitle(menup->getLabel()); - setCanMinimize(FALSE); - // flag menu as being torn off - menup->setTornOff(TRUE); - // update menu layout as torn off menu (no spillover menus) - menup->needsArrange(); - - LLRect rect; - menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView); - // make sure this floater is big enough for menu - mTargetHeight = (F32)(rect.getHeight() + floater_header_size); - reshape(rect.getWidth(), rect.getHeight()); - setRect(rect); - - // attach menu to floater - menup->setFollows(FOLLOWS_BOTTOM|FOLLOWS_LEFT); - mOldParent = menup->getParent(); - addChild(menup); - menup->setVisible(TRUE); - - LLRect menu_rect = menup->getRect(); - menu_rect.setOriginAndSize( 1, 1, - menu_rect.getWidth(), menu_rect.getHeight()); - menup->setRect(menu_rect); - menup->setDropShadowed(FALSE); - - mMenu = menup; - - // highlight first item (tear off item will be disabled) - mMenu->highlightNextItem(NULL); -} - - -void LLTearOffMenu::draw() -{ - mMenu->setBackgroundVisible(isBackgroundOpaque()); - mMenu->needsArrange(); - - if (getRect().getHeight() != mTargetHeight) - { - // animate towards target height - reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f)))); - } - LLFloater::draw(); -} - -void LLTearOffMenu::onFocusReceived() -{ - // if nothing is highlighted, just highlight first item - if (!mMenu->getHighlightedItem()) - { - mMenu->highlightNextItem(NULL); - } - - // parent menu items get highlights so navigation logic keeps working - LLMenuItemGL* parent_menu_item = mMenu->getParentMenuItem(); - while(parent_menu_item) - { - if (parent_menu_item->getMenu()->getVisible()) - { - parent_menu_item->setHighlight(TRUE); - parent_menu_item = parent_menu_item->getMenu()->getParentMenuItem(); - } - else - { - break; - } - } - LLFloater::onFocusReceived(); -} - -void LLTearOffMenu::onFocusLost() -{ - // remove highlight from parent item and our own menu - mMenu->clearHoverItem(); - LLFloater::onFocusLost(); -} - -BOOL LLTearOffMenu::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) -{ - // pass keystrokes down to menu - return mMenu->handleUnicodeChar(uni_char, TRUE); -} - -BOOL LLTearOffMenu::handleKeyHere(KEY key, MASK mask) -{ - if (!mMenu->getHighlightedItem()) - { - if (key == KEY_UP) - { - mMenu->highlightPrevItem(NULL); - return TRUE; - } - else if (key == KEY_DOWN) - { - mMenu->highlightNextItem(NULL); - return TRUE; - } - } - // pass keystrokes down to menu - return mMenu->handleKey(key, mask, TRUE); -} - -void LLTearOffMenu::translate(S32 x, S32 y) -{ - if (x != 0 && y != 0) - { - // hide open sub-menus by clearing current hover item - mMenu->clearHoverItem(); - } - LLFloater::translate(x, y); -} - -//static -LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup) -{ - LLTearOffMenu* tearoffp = new LLTearOffMenu(menup); - // keep onscreen - gFloaterView->adjustToFitScreen(tearoffp, FALSE); - tearoffp->open(); /* Flawfinder: ignore */ - - return tearoffp; -} - -void LLTearOffMenu::onClose(bool app_quitting) -{ - removeChild(mMenu); - mOldParent->addChild(mMenu); - mMenu->clearHoverItem(); - mMenu->setFollowsNone(); - mMenu->setBackgroundVisible(TRUE); - mMenu->setVisible(FALSE); - mMenu->setTornOff(FALSE); - mMenu->setDropShadowed(TRUE); - destroy(); -} - diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 9fd6868b7..4c5811321 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -79,16 +79,6 @@ typedef void (*label_callback)(std::string&,void*); class LLMenuItemGL : public LLUICtrl { public: - // static functions to control the global color scheme. - /*static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; } - static const LLColor4& getEnabledColor() { return sEnabledColor; } - static void setDisabledColor( const LLColor4& color ) { sDisabledColor = color; } - static const LLColor4& getDisabledColor() { return sDisabledColor; } - static void setHighlightBGColor( const LLColor4& color ) { sHighlightBackground = color; } - static const LLColor4& getHighlightBGColor() { return sHighlightBackground; } - static void setHighlightFGColor( const LLColor4& color ) { sHighlightForeground = color; } - static const LLColor4& getHighlightFGColor() { return sHighlightForeground; }*/ - LLMenuItemGL( const std::string& name, const std::string& label, KEY key = KEY_NONE, MASK = MASK_NONE ); virtual ~LLMenuItemGL(); @@ -148,7 +138,7 @@ public: // lead to visual errors if the state of the object changes // without the knowledge of the menu item. For example, if a // boolean being watched is changed outside of the menu item's - // doIt() function, the draw buffer will not be updated and will + // onCommit() function, the draw buffer will not be updated and will // reflect the wrong value. If this ever becomes an issue, there // are ways to fix this. // Returns the enabled state of the item. @@ -157,8 +147,7 @@ public: // for branching menu items, bring sub menus up to root level of menu hierarchy virtual void updateBranchParent( LLView* parentp ){}; - // doIt() - do the primary funcationality of the menu item. - virtual void doIt( void ); + virtual void onCommit( void ); virtual void setHighlight( BOOL highlight ); virtual BOOL getHighlight() const { return mHighlight; } @@ -190,6 +179,7 @@ protected: // the current accelerator key and mask to the provided string. void appendAcceleratorString( std::string& st ) const; +protected: KEY mAcceleratorKey; MASK mAcceleratorMask; // mLabel contains the actual label specified by the user. @@ -245,15 +235,14 @@ public: virtual std::string getType() const { return "separator"; } - // doIt() - do the primary funcationality of the menu item. - virtual void doIt( void ) {} + virtual void onCommit( void ) {} - virtual void draw( void ); - 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*/ void draw( void ); + /*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 U32 getNominalHeight( void ) const; + /*virtual*/ U32 getNominalHeight( void ) const; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -323,8 +312,7 @@ public: // called to rebuild the draw label virtual void buildDrawLabel( void ); - // doIt() - do the primary funcationality of the menu item. - virtual void doIt( void ); + virtual void onCommit( void ); virtual BOOL handleAcceleratorKey(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask); @@ -419,8 +407,8 @@ public: // called to rebuild the draw label virtual void buildDrawLabel( void ); - // doIt() - do the primary funcationality of the menu item. - virtual void doIt( void ); + // onCommit() - do the primary funcationality of the menu item. + virtual void onCommit( void ); // LLView Functionality //virtual void draw( void ); @@ -429,7 +417,6 @@ private: BOOL* mToggle; }; - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuGL // @@ -453,6 +440,15 @@ public: static const std::string ARROW_UP; static const std::string ARROW_DOWN; + // for scrollable menus + typedef enum e_scrolling_direction + { + SD_UP = 0, + SD_DOWN = 1, + SD_BEGIN = 2, + SD_END = 3 + } EScrollingDirection; + protected: // let branching menu items use my protected traversal methods friend class LLMenuItemBranchGL; @@ -470,14 +466,12 @@ public: /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); /*virtual*/ BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); /*virtual*/ void draw( void ); - virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color); + /*virtual*/ void drawBackground(LLMenuItemGL* itemp, LLColor4& color); /*virtual*/ void setVisible(BOOL visible); /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); /*virtual*/ void removeChild( LLView* ctrl); /*virtual*/ BOOL postBuild(); - bool addChild(LLView* view, LLView* insert_before, S32 tab_group = 0); - virtual BOOL handleAcceleratorKey(KEY key, MASK mask); LLMenuGL* getChildMenuByName(const std::string& name, BOOL recurse) const; @@ -531,6 +525,16 @@ public: // remove all items on the menu void empty( void ); + // erase group of items from menu + void erase(S32 begin, S32 end, bool arrange = true); + + // add new item at position + void insert(S32 begin, LLView* ctrl, bool arrange = true); + void insert(std::list::iterator position_iter, LLMenuItemGL* item, bool arrange = true); + + // find an item's position + std::list::iterator find(LLMenuItemGL* item) { return std::find(mItems.begin(), mItems.end(), item); } + void setItemLastSelected(LLMenuItemGL* item); // must be in menu U32 getItemCount(); // number of menu items LLMenuItemGL* getItem(S32 number); // 0 = first item @@ -545,7 +549,7 @@ public: // Show popup in global screen space based on last mouse location. static void showPopup(LLMenuGL* menu); - // Show popup at a specific location. + // Show popup at a specific location, in the spawn_view's coordinate frame static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y); // Whether to drop shadow menu bar @@ -566,27 +570,29 @@ public: static BOOL getKeyboardMode() { return sKeyboardMode; } S32 getShortcutPad() { return mShortcutPad; } - BOOL isScrollable() const { return FALSE; } + + bool scrollItems(EScrollingDirection direction); + BOOL isScrollable() const { return mScrollable; } + void setScrollable(bool b); static class LLMenuHolderGL* sMenuContainer; - bool isScrollPositionOnShowReset() { return false; } + void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; } + bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; } protected: void createSpilloverBranch(); void cleanupSpilloverBranch(); - // Add the menu item to this menu. virtual BOOL append( LLMenuItemGL* item ); - BOOL append(LLMenuItemGL* item, LLView* insert_before); // add a menu - this will create a cascading menu virtual BOOL appendMenu( LLMenuGL* menu ); - BOOL appendMenu(LLMenuGL* menu, LLView* insert_before); // TODO: create accessor methods for these? typedef std::list< LLMenuItemGL* > item_list_t; item_list_t mItems; LLMenuItemGL*mFirstVisibleItem; + LLMenuItemGL *mArrowUpItem, *mArrowDownItem; typedef std::map navigation_key_map_t; navigation_key_map_t mJumpKeys; @@ -594,11 +600,15 @@ protected: S32 mLastMouseY; S32 mMouseVelX; S32 mMouseVelY; + U32 mMaxScrollableItems; BOOL mHorizontalLayout; + BOOL mScrollable; BOOL mKeepFixedSize; BOOL mNeedsArrange; private: + + static LLColor4 sDefaultBackgroundColor; static BOOL sKeyboardMode; @@ -609,12 +619,15 @@ private: BOOL mDropShadowed; // Whether to drop shadow bool mHasSelection; LLFrameTimer mFadeTimer; + LLTimer mScrollItemsTimer; BOOL mTornOff; class LLMenuItemTearOffGL* mTearOffItem; class LLMenuItemBranchGL* mSpilloverBranch; LLMenuGL* mSpilloverMenu; KEY mJumpKey; + BOOL mCreateJumpKeys; S32 mShortcutPad; + bool mResetScrollPositionOnShow; }; // end class LLMenuGL @@ -648,8 +661,7 @@ public: // called to rebuild the draw label virtual void buildDrawLabel( void ); - // doIt() - do the primary funcationality of the menu item. - virtual void doIt( void ); + virtual void onCommit( void ); virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); @@ -684,11 +696,11 @@ private: }; // end class LLMenuItemBranchGL - //----------------------------------------------------------------------------- // class LLContextMenu // A context menu //----------------------------------------------------------------------------- + class LLContextMenu : public LLMenuGL { @@ -792,8 +804,8 @@ public: return TRUE; } - // doIt() - do the primary funcationality of the menu item. - virtual void doIt( void ); + // onCommit() - do the primary funcationality of the menu item. + virtual void onCommit( void ); LLContextMenu* getBranch() { return mBranch; } void setHighlight( BOOL highlight ); @@ -904,7 +916,8 @@ class LLTearOffMenu : public LLFloater { public: static LLTearOffMenu* create(LLMenuGL* menup); - virtual ~LLTearOffMenu() {} + virtual ~LLTearOffMenu(); + virtual void onClose(bool app_quitting); virtual void draw(void); virtual void onFocusReceived(); @@ -935,7 +948,7 @@ public: virtual LLXMLNodePtr getXML(bool save_children = true) const; virtual std::string getType() const { return "tearoff_menu"; } - virtual void doIt(void); + virtual void onCommit(void); virtual void draw(void); virtual U32 getNominalHeight() const; diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index e0ec85523..29b146f59 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1543,6 +1543,8 @@ class UpdateItemSM : public AIStateMachine static void add(UpdateItem const& ui); + /*virtual*/ const char* getName() const { return "UpdateItemSM"; } + private: static UpdateItemSM* sSelf; typedef std::deque updateQueue_type; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index fb9383ecb..3e6e70703 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -3214,6 +3214,11 @@ void LLScrollListCtrl::setFocus(BOOL b) selectFirstItem(); //onCommit(); // SJB: selectFirstItem() will call onCommit() if appropriate } + + // Singu Note: Edit menu handler, y'know for Ctrl-A and such! + if (b) gEditMenuHandler = this; + else if (gEditMenuHandler == this) gEditMenuHandler = NULL; + LLUICtrl::setFocus(b); } diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 239ac5b74..4a64b0044 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -395,8 +395,14 @@ void LLTextBox::initFromXML(LLXMLNodePtr node, LLView* parent) LLFontGL* font = LLView::selectFont(node); if(font) mFontGL = font; - - setText(node->getTextContents()); + + if (node->hasAttribute("value")) + { + std::string text; + node->getAttributeString("value", text); + setText(text); + } + else setText(node->getTextContents()); LLFontGL::HAlign halign = LLView::selectFontHAlign(node); setHAlign(halign); diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index c3a042247..26c5c11b7 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -301,19 +301,19 @@ void LLDir::setDumpDir( const std::string& path ) const std::string &LLDir::getDumpDir() const { - if (sDumpDir.empty() ) - { + if (sDumpDir.empty() ) + { /* Singu Note: don't generate a different dump dir each time - LLUUID uid; - uid.generate(); - - sDumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") - + "dump-" + uid.asString(); + LLUUID uid; + uid.generate(); + + sDumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + + "dump-" + uid.asString(); */ - sDumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug"; - dir_exists_or_crash(sDumpDir); - } + sDumpDir = getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug"; + dir_exists_or_crash(sDumpDir); + } return LLDir::sDumpDir; } @@ -710,6 +710,33 @@ void LLDir::setLindenUserDir(const std::string &grid, const std::string &first, dumpCurrentDirectories(); } +void LLDir::makePortable() +{ + std::string dir = mExecutableDir; + dir.erase(dir.rfind(mDirDelimiter)); // Go one level up + dir += mDirDelimiter + "portable_viewer"; + if (LLFile::mkdir(dir) == -1) + { + if (errno != EEXIST) + { + llwarns << "Couldn't create portable_viewer directory." << llendl; + return; // Failed, don't mess anything up. + } + } + mOSUserDir = dir + mDirDelimiter + "settings"; + mOSCacheDir = dir + mDirDelimiter + "cache"; + if (LLFile::mkdir(mOSUserDir) == -1 || LLFile::mkdir(mOSCacheDir) == -1) + { + if (errno != EEXIST) + { + llwarns << "Couldn't create portable_viewer cache and settings directories." << llendl; + return; // Failed, don't mess up the existing initialization. + } + } + mDefaultCacheDir = buildSLOSCacheDir(); + initAppDirs(mAppName); // This is kinda lazy, but it's probably the quickest, most uniform way. +} + void LLDir::setChatLogsDir(const std::string &path) { if (!path.empty() ) diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index 5058b5479..2be6dd3ec 100644 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -133,6 +133,7 @@ class LLDir static std::string getForbiddenFileChars(); void setDumpDir( const std::string& path ); + void makePortable(); virtual void setChatLogsDir(const std::string &path); // Set the chat logs dir to this user's dir virtual void setPerAccountChatLogsDir(const std::string &grid, const std::string &first, const std::string &last); // Set the per user chat log directory. virtual void setLindenUserDir(const std::string& grid, const std::string& first, const std::string& last); // Set the linden user dir to this user's dir diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index f611c6594..9a580d50f 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -62,13 +62,13 @@ LLDir_Win32::LLDir_Win32() if((*pSHGetKnownFolderPath)(FOLDERID_RoamingAppData, 0, NULL, &pPath) == S_OK) wcscpy_s(w_str,pPath); else - SHGetSpecialFolderPath(NULL, w_str, CSIDL_APPDATA, TRUE); + SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str ); if(pPath) CoTaskMemFree(pPath); } else //XP doesn't support SHGetKnownFolderPath { - SHGetSpecialFolderPath(NULL, w_str, CSIDL_APPDATA, TRUE); + SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str ); } mOSUserDir = utf16str_to_utf8str(llutf16string(w_str)); @@ -91,13 +91,13 @@ LLDir_Win32::LLDir_Win32() if((*pSHGetKnownFolderPath)(FOLDERID_LocalAppData, 0, NULL, &pPath) == S_OK) wcscpy_s(w_str,pPath); else - SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE); + SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str ); if(pPath) CoTaskMemFree(pPath); } else //XP doesn't support SHGetKnownFolderPath { - SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE); + SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str ); } if(shell) diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index c7d9509e1..34c4a8d53 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -68,7 +68,6 @@ if (LINUX) ${LLMATH_LIBRARIES} ${LLRENDER_LIBRARIES} ${LLVFS_LIBRARIES} - ${LLWINDOW_LIBRARIES} ${LLXML_LIBRARIES} ${UI_LIBRARIES} # for GTK ${SDL_LIBRARY} diff --git a/indra/llwindow/glh/glh_linear.h b/indra/llwindow/glh/glh_linear.h deleted file mode 100644 index c46b81531..000000000 --- a/indra/llwindow/glh/glh_linear.h +++ /dev/null @@ -1,1621 +0,0 @@ -/* - glh - is a platform-indepenedent C++ OpenGL helper library - - - Copyright (c) 2000 Cass Everitt - Copyright (c) 2000 NVIDIA Corporation - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - * Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - * The names of contributors to this software may not be used - to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - - Cass Everitt - cass@r3.nu -*/ - -/* -glh_linear.h -*/ - -// Author: Cass W. Everitt - -#ifndef GLH_LINEAR_H -#define GLH_LINEAR_H - -#include -#include -#include - -// only supports float for now... -#define GLH_REAL_IS_FLOAT - -#ifdef GLH_REAL_IS_FLOAT -# define GLH_REAL float -# define GLH_REAL_NAMESPACE ns_float -#endif - -#define GLH_QUATERNION_NORMALIZATION_THRESHOLD 64 - -#define GLH_RAD_TO_DEG GLH_REAL(57.2957795130823208767981548141052) -#define GLH_DEG_TO_RAD GLH_REAL(0.0174532925199432957692369076848861) -#define GLH_ZERO GLH_REAL(0.0) -#define GLH_ONE GLH_REAL(1.0) -#define GLH_TWO GLH_REAL(2.0) -#define GLH_EPSILON GLH_REAL(10e-6) -#define GLH_PI GLH_REAL(3.1415926535897932384626433832795) - - -namespace glh -{ - inline bool equivalent(GLH_REAL a, GLH_REAL b) { return b - GLH_EPSILON < a && a < b + GLH_EPSILON; } - - inline GLH_REAL to_degrees(GLH_REAL radians) { return radians*GLH_RAD_TO_DEG; } - inline GLH_REAL to_radians(GLH_REAL degrees) { return degrees*GLH_DEG_TO_RAD; } - - // forward declarations for friend template functions. - template class vec; - - // forward declarations for friend template functions. - template - bool operator == ( const vec & v1, const vec & v2 ); - - // forward declarations for friend template functions. - template - bool operator != ( const vec & v1, const vec & v2 ); - - template - class vec - { - public: - int size() const { return N; } - - vec(const T & t = T()) - { for(int i = 0; i < N; i++) v[i] = t; } - vec(const T * tp) - { for(int i = 0; i < N; i++) v[i] = tp[i]; } - - const T * get_value() const - { return v; } - - - T dot( const vec & rhs ) const - { - T r = 0; - for(int i = 0; i < N; i++) r += v[i]*rhs.v[i]; - return r; - } - - T length() const - { - T r = 0; - for(int i = 0; i < N; i++) r += v[i]*v[i]; - return T(sqrt(r)); - } - - T square_norm() const - { - T r = 0; - for(int i = 0; i < N; i++) r += v[i]*v[i]; - return r; - } - - void negate() - { for(int i = 0; i < N; i++) v[i] = -v[i]; } - - - T normalize() - { - T sum(0); - for(int i = 0; i < N; i++) - sum += v[i]*v[i]; - sum = T(sqrt(sum)); - if (sum > GLH_EPSILON) - for(int i = 0; i < N; i++) - v[i] /= sum; - return sum; - } - - - vec & set_value( const T * rhs ) - { for(int i = 0; i < N; i++) v[i] = rhs[i]; return *this; } - - T & operator [] ( int i ) - { return v[i]; } - - const T & operator [] ( int i ) const - { return v[i]; } - - vec & operator *= ( T d ) - { for(int i = 0; i < N; i++) v[i] *= d; return *this;} - - vec & operator *= ( const vec & u ) - { for(int i = 0; i < N; i++) v[i] *= u[i]; return *this;} - - vec & operator /= ( T d ) - { if(d == 0) return *this; for(int i = 0; i < N; i++) v[i] /= d; return *this;} - - vec & operator += ( const vec & u ) - { for(int i = 0; i < N; i++) v[i] += u.v[i]; return *this;} - - vec & operator -= ( const vec & u ) - { for(int i = 0; i < N; i++) v[i] -= u.v[i]; return *this;} - - - vec operator - () const - { vec rv = v; rv.negate(); return rv; } - - vec operator + ( const vec &v) const - { vec rt(*this); return rt += v; } - - vec operator - ( const vec &v) const - { vec rt(*this); return rt -= v; } - - vec operator * ( T d) const - { vec rt(*this); return rt *= d; } - - friend bool operator == <> ( const vec &v1, const vec &v2 ); - friend bool operator != <> ( const vec &v1, const vec &v2 ); - - - //protected: - T v[N]; - }; - - - - // vector friend operators - - template inline - vec operator * ( const vec & b, T d ) - { - vec rt(b); - return rt *= d; - } - - template inline - vec operator * ( T d, const vec & b ) - { return b*d; } - - template inline - vec operator * ( const vec & b, const vec & d ) - { - vec rt(b); - return rt *= d; - } - - template inline - vec operator / ( const vec & b, T d ) - { vec rt(b); return rt /= d; } - - template inline - vec operator + ( const vec & v1, const vec & v2 ) - { vec rt(v1); return rt += v2; } - - template inline - vec operator - ( const vec & v1, const vec & v2 ) - { vec rt(v1); return rt -= v2; } - - - template inline - bool operator == ( const vec & v1, const vec & v2 ) - { - for(int i = 0; i < N; i++) - if(v1.v[i] != v2.v[i]) - return false; - return true; - } - - template inline - bool operator != ( const vec & v1, const vec & v2 ) - { return !(v1 == v2); } - - - typedef vec<3,unsigned char> vec3ub; - typedef vec<4,unsigned char> vec4ub; - - - - - - namespace GLH_REAL_NAMESPACE - { - typedef GLH_REAL real; - - class line; - class plane; - class matrix4; - class quaternion; - typedef quaternion rotation; - - class vec2 : public vec<2,real> - { - public: - vec2(const real & t = real()) : vec<2,real>(t) - {} - vec2(const vec<2,real> & t) : vec<2,real>(t) - {} - vec2(const real * tp) : vec<2,real>(tp) - {} - - vec2(real x, real y ) - { v[0] = x; v[1] = y; } - - void get_value(real & x, real & y) const - { x = v[0]; y = v[1]; } - - vec2 & set_value( const real & x, const real & y) - { v[0] = x; v[1] = y; return *this; } - - }; - - - class vec3 : public vec<3,real> - { - public: - vec3(const real & t = real()) : vec<3,real>(t) - {} - vec3(const vec<3,real> & t) : vec<3,real>(t) - {} - vec3(const real * tp) : vec<3,real>(tp) - {} - - vec3(real x, real y, real z) - { v[0] = x; v[1] = y; v[2] = z; } - - void get_value(real & x, real & y, real & z) const - { x = v[0]; y = v[1]; z = v[2]; } - - vec3 cross( const vec3 &rhs ) const - { - vec3 rt; - rt.v[0] = v[1]*rhs.v[2]-v[2]*rhs.v[1]; - rt.v[1] = v[2]*rhs.v[0]-v[0]*rhs.v[2]; - rt.v[2] = v[0]*rhs.v[1]-v[1]*rhs.v[0]; - return rt; - } - - vec3 & set_value( const real & x, const real & y, const real & z) - { v[0] = x; v[1] = y; v[2] = z; return *this; } - - }; - - - class vec4 : public vec<4,real> - { - public: - vec4(const real & t = real()) : vec<4,real>(t) - {} - vec4(const vec<4,real> & t) : vec<4,real>(t) - {} - - vec4(const vec<3,real> & t, real fourth) - - { v[0] = t.v[0]; v[1] = t.v[1]; v[2] = t.v[2]; v[3] = fourth; } - vec4(const real * tp) : vec<4,real>(tp) - {} - vec4(real x, real y, real z, real w) - { v[0] = x; v[1] = y; v[2] = z; v[3] = w; } - - void get_value(real & x, real & y, real & z, real & w) const - { x = v[0]; y = v[1]; z = v[2]; w = v[3]; } - - vec4 & set_value( const real & x, const real & y, const real & z, const real & w) - { v[0] = x; v[1] = y; v[2] = z; v[3] = w; return *this; } - }; - - inline - vec3 homogenize(const vec4 & v) - { - vec3 rt; - assert(v.v[3] != GLH_ZERO); - rt.v[0] = v.v[0]/v.v[3]; - rt.v[1] = v.v[1]/v.v[3]; - rt.v[2] = v.v[2]/v.v[3]; - return rt; - } - - - - class line - { - public: - - line() - { set_value(vec3(0,0,0),vec3(0,0,1)); } - - line( const vec3 & p0, const vec3 &p1) - { set_value(p0,p1); } - - void set_value( const vec3 &p0, const vec3 &p1) - { - position = p0; - direction = p1-p0; - direction.normalize(); - } - - bool get_closest_points(const line &line2, - vec3 &pointOnThis, - vec3 &pointOnThat) - { - - // quick check to see if parallel -- if so, quit. - if(fabs(direction.dot(line2.direction)) == 1.0) - return 0; - line l2 = line2; - - // Algorithm: Brian Jean - // - register real u; - register real v; - vec3 Vr = direction; - vec3 Vs = l2.direction; - register real Vr_Dot_Vs = Vr.dot(Vs); - register real detA = real(1.0 - (Vr_Dot_Vs * Vr_Dot_Vs)); - vec3 C = l2.position - position; - register real C_Dot_Vr = C.dot(Vr); - register real C_Dot_Vs = C.dot(Vs); - - u = (C_Dot_Vr - Vr_Dot_Vs * C_Dot_Vs)/detA; - v = (C_Dot_Vr * Vr_Dot_Vs - C_Dot_Vs)/detA; - - pointOnThis = position; - pointOnThis += direction * u; - pointOnThat = l2.position; - pointOnThat += l2.direction * v; - - return 1; - } - - vec3 get_closest_point(const vec3 &point) - { - vec3 np = point - position; - vec3 rp = direction*direction.dot(np)+position; - return rp; - } - - const vec3 & get_position() const {return position;} - - const vec3 & get_direction() const {return direction;} - - //protected: - vec3 position; - vec3 direction; - }; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // matrix - - - class matrix4 - { - - public: - - matrix4() { make_identity(); } - - matrix4( real r ) - { set_value(r); } - - matrix4( real * m ) - { set_value(m); } - - matrix4( real a00, real a01, real a02, real a03, - real a10, real a11, real a12, real a13, - real a20, real a21, real a22, real a23, - real a30, real a31, real a32, real a33 ) - { - element(0,0) = a00; - element(0,1) = a01; - element(0,2) = a02; - element(0,3) = a03; - - element(1,0) = a10; - element(1,1) = a11; - element(1,2) = a12; - element(1,3) = a13; - - element(2,0) = a20; - element(2,1) = a21; - element(2,2) = a22; - element(2,3) = a23; - - element(3,0) = a30; - element(3,1) = a31; - element(3,2) = a32; - element(3,3) = a33; - } - - - void get_value( real * mp ) const - { - int c = 0; - for(int j=0; j < 4; j++) - for(int i=0; i < 4; i++) - mp[c++] = element(i,j); - } - - - const real * get_value() const - { return m; } - - void set_value( real * mp) - { - int c = 0; - for(int j=0; j < 4; j++) - for(int i=0; i < 4; i++) - element(i,j) = mp[c++]; - } - - void set_value( real r ) - { - for(int i=0; i < 4; i++) - for(int j=0; j < 4; j++) - element(i,j) = r; - } - - void make_identity() - { - element(0,0) = 1.0; - element(0,1) = 0.0; - element(0,2) = 0.0; - element(0,3) = 0.0; - - element(1,0) = 0.0; - element(1,1) = 1.0; - element(1,2) = 0.0; - element(1,3) = 0.0; - - element(2,0) = 0.0; - element(2,1) = 0.0; - element(2,2) = 1.0; - element(2,3) = 0.0; - - element(3,0) = 0.0; - element(3,1) = 0.0; - element(3,2) = 0.0; - element(3,3) = 1.0; - } - - - static matrix4 identity() - { - static matrix4 mident ( - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 ); - return mident; - } - - - void set_scale( real s ) - { - element(0,0) = s; - element(1,1) = s; - element(2,2) = s; - } - - void set_scale( const vec3 & s ) - { - element(0,0) = s.v[0]; - element(1,1) = s.v[1]; - element(2,2) = s.v[2]; - } - - - void set_translate( const vec3 & t ) - { - element(0,3) = t.v[0]; - element(1,3) = t.v[1]; - element(2,3) = t.v[2]; - } - - void set_row(int r, const vec4 & t) - { - element(r,0) = t.v[0]; - element(r,1) = t.v[1]; - element(r,2) = t.v[2]; - element(r,3) = t.v[3]; - } - - void set_column(int c, const vec4 & t) - { - element(0,c) = t.v[0]; - element(1,c) = t.v[1]; - element(2,c) = t.v[2]; - element(3,c) = t.v[3]; - } - - - void get_row(int r, vec4 & t) const - { - t.v[0] = element(r,0); - t.v[1] = element(r,1); - t.v[2] = element(r,2); - t.v[3] = element(r,3); - } - - vec4 get_row(int r) const - { - vec4 v; get_row(r, v); - return v; - } - - void get_column(int c, vec4 & t) const - { - t.v[0] = element(0,c); - t.v[1] = element(1,c); - t.v[2] = element(2,c); - t.v[3] = element(3,c); - } - - vec4 get_column(int c) const - { - vec4 v; get_column(c, v); - return v; - } - - matrix4 inverse() const - { - matrix4 minv; - - real r1[8], r2[8], r3[8], r4[8]; - real *s[4], *tmprow; - - s[0] = &r1[0]; - s[1] = &r2[0]; - s[2] = &r3[0]; - s[3] = &r4[0]; - - register int i,j,p,jj; - for(i=0;i<4;i++) - { - for(j=0;j<4;j++) - { - s[i][j] = element(i,j); - if(i==j) s[i][j+4] = 1.0; - else s[i][j+4] = 0.0; - } - } - real scp[4]; - for(i=0;i<4;i++) - { - scp[i] = real(fabs(s[i][0])); - for(j=1;j<4;j++) - if(real(fabs(s[i][j])) > scp[i]) scp[i] = real(fabs(s[i][j])); - if(scp[i] == 0.0) return minv; // singular matrix! - } - - int pivot_to; - real scp_max; - for(i=0;i<4;i++) - { - // select pivot row - pivot_to = i; - scp_max = real(fabs(s[i][i]/scp[i])); - // find out which row should be on top - for(p=i+1;p<4;p++) - if(real(fabs(s[p][i]/scp[p])) > scp_max) - { scp_max = real(fabs(s[p][i]/scp[p])); pivot_to = p; } - // Pivot if necessary - if(pivot_to != i) - { - tmprow = s[i]; - s[i] = s[pivot_to]; - s[pivot_to] = tmprow; - real tmpscp; - tmpscp = scp[i]; - scp[i] = scp[pivot_to]; - scp[pivot_to] = tmpscp; - } - - real mji; - // perform gaussian elimination - for(j=i+1;j<4;j++) - { - mji = s[j][i]/s[i][i]; - s[j][i] = 0.0; - for(jj=i+1;jj<8;jj++) - s[j][jj] -= mji*s[i][jj]; - } - } - if(s[3][3] == 0.0) return minv; // singular matrix! - - // - // Now we have an upper triangular matrix. - // - // x x x x | y y y y - // 0 x x x | y y y y - // 0 0 x x | y y y y - // 0 0 0 x | y y y y - // - // we'll back substitute to get the inverse - // - // 1 0 0 0 | z z z z - // 0 1 0 0 | z z z z - // 0 0 1 0 | z z z z - // 0 0 0 1 | z z z z - // - - real mij; - for(i=3;i>0;i--) - { - for(j=i-1;j > -1; j--) - { - mij = s[j][i]/s[i][i]; - for(jj=j+1;jj<8;jj++) - s[j][jj] -= mij*s[i][jj]; - } - } - - for(i=0;i<4;i++) - for(j=0;j<4;j++) - minv(i,j) = s[i][j+4] / s[i][i]; - - return minv; - } - - - matrix4 transpose() const - { - matrix4 mtrans; - - for(int i=0;i<4;i++) - for(int j=0;j<4;j++) - mtrans(i,j) = element(j,i); - return mtrans; - } - - matrix4 & mult_right( const matrix4 & b ) - { - matrix4 mt(*this); - set_value(real(0)); - - for(int i=0; i < 4; i++) - for(int j=0; j < 4; j++) - for(int c=0; c < 4; c++) - element(i,j) += mt(i,c) * b(c,j); - return *this; - } - - matrix4 & mult_left( const matrix4 & b ) - { - matrix4 mt(*this); - set_value(real(0)); - - for(int i=0; i < 4; i++) - for(int j=0; j < 4; j++) - for(int c=0; c < 4; c++) - element(i,j) += b(i,c) * mt(c,j); - return *this; - } - - // dst = M * src - void mult_matrix_vec( const vec3 &src, vec3 &dst ) const - { - real w = ( - src.v[0] * element(3,0) + - src.v[1] * element(3,1) + - src.v[2] * element(3,2) + - element(3,3) ); - - assert(w != GLH_ZERO); - - dst.v[0] = ( - src.v[0] * element(0,0) + - src.v[1] * element(0,1) + - src.v[2] * element(0,2) + - element(0,3) ) / w; - dst.v[1] = ( - src.v[0] * element(1,0) + - src.v[1] * element(1,1) + - src.v[2] * element(1,2) + - element(1,3) ) / w; - dst.v[2] = ( - src.v[0] * element(2,0) + - src.v[1] * element(2,1) + - src.v[2] * element(2,2) + - element(2,3) ) / w; - } - - void mult_matrix_vec( vec3 & src_and_dst) const - { mult_matrix_vec(vec3(src_and_dst), src_and_dst); } - - - // dst = src * M - void mult_vec_matrix( const vec3 &src, vec3 &dst ) const - { - real w = ( - src.v[0] * element(0,3) + - src.v[1] * element(1,3) + - src.v[2] * element(2,3) + - element(3,3) ); - - assert(w != GLH_ZERO); - - dst.v[0] = ( - src.v[0] * element(0,0) + - src.v[1] * element(1,0) + - src.v[2] * element(2,0) + - element(3,0) ) / w; - dst.v[1] = ( - src.v[0] * element(0,1) + - src.v[1] * element(1,1) + - src.v[2] * element(2,1) + - element(3,1) ) / w; - dst.v[2] = ( - src.v[0] * element(0,2) + - src.v[1] * element(1,2) + - src.v[2] * element(2,2) + - element(3,2) ) / w; - } - - - void mult_vec_matrix( vec3 & src_and_dst) const - { mult_vec_matrix(vec3(src_and_dst), src_and_dst); } - - // dst = M * src - void mult_matrix_vec( const vec4 &src, vec4 &dst ) const - { - dst.v[0] = ( - src.v[0] * element(0,0) + - src.v[1] * element(0,1) + - src.v[2] * element(0,2) + - src.v[3] * element(0,3)); - dst.v[1] = ( - src.v[0] * element(1,0) + - src.v[1] * element(1,1) + - src.v[2] * element(1,2) + - src.v[3] * element(1,3)); - dst.v[2] = ( - src.v[0] * element(2,0) + - src.v[1] * element(2,1) + - src.v[2] * element(2,2) + - src.v[3] * element(2,3)); - dst.v[3] = ( - src.v[0] * element(3,0) + - src.v[1] * element(3,1) + - src.v[2] * element(3,2) + - src.v[3] * element(3,3)); - } - - void mult_matrix_vec( vec4 & src_and_dst) const - { mult_matrix_vec(vec4(src_and_dst), src_and_dst); } - - - // dst = src * M - void mult_vec_matrix( const vec4 &src, vec4 &dst ) const - { - dst.v[0] = ( - src.v[0] * element(0,0) + - src.v[1] * element(1,0) + - src.v[2] * element(2,0) + - src.v[3] * element(3,0)); - dst.v[1] = ( - src.v[0] * element(0,1) + - src.v[1] * element(1,1) + - src.v[2] * element(2,1) + - src.v[3] * element(3,1)); - dst.v[2] = ( - src.v[0] * element(0,2) + - src.v[1] * element(1,2) + - src.v[2] * element(2,2) + - src.v[3] * element(3,2)); - dst.v[3] = ( - src.v[0] * element(0,3) + - src.v[1] * element(1,3) + - src.v[2] * element(2,3) + - src.v[3] * element(3,3)); - } - - - void mult_vec_matrix( vec4 & src_and_dst) const - { mult_vec_matrix(vec4(src_and_dst), src_and_dst); } - - - // dst = M * src - void mult_matrix_dir( const vec3 &src, vec3 &dst ) const - { - dst.v[0] = ( - src.v[0] * element(0,0) + - src.v[1] * element(0,1) + - src.v[2] * element(0,2) ) ; - dst.v[1] = ( - src.v[0] * element(1,0) + - src.v[1] * element(1,1) + - src.v[2] * element(1,2) ) ; - dst.v[2] = ( - src.v[0] * element(2,0) + - src.v[1] * element(2,1) + - src.v[2] * element(2,2) ) ; - } - - - void mult_matrix_dir( vec3 & src_and_dst) const - { mult_matrix_dir(vec3(src_and_dst), src_and_dst); } - - - // dst = src * M - void mult_dir_matrix( const vec3 &src, vec3 &dst ) const - { - dst.v[0] = ( - src.v[0] * element(0,0) + - src.v[1] * element(1,0) + - src.v[2] * element(2,0) ) ; - dst.v[1] = ( - src.v[0] * element(0,1) + - src.v[1] * element(1,1) + - src.v[2] * element(2,1) ) ; - dst.v[2] = ( - src.v[0] * element(0,2) + - src.v[1] * element(1,2) + - src.v[2] * element(2,2) ) ; - } - - - void mult_dir_matrix( vec3 & src_and_dst) const - { mult_dir_matrix(vec3(src_and_dst), src_and_dst); } - - - real & operator () (int row, int col) - { return element(row,col); } - - const real & operator () (int row, int col) const - { return element(row,col); } - - real & element (int row, int col) - { return m[row | (col<<2)]; } - - const real & element (int row, int col) const - { return m[row | (col<<2)]; } - - matrix4 & operator *= ( const matrix4 & mat ) - { - mult_right( mat ); - return *this; - } - - matrix4 & operator *= ( const real & r ) - { - for (int i = 0; i < 4; ++i) - { - element(0,i) *= r; - element(1,i) *= r; - element(2,i) *= r; - element(3,i) *= r; - } - return *this; - } - - matrix4 & operator += ( const matrix4 & mat ) - { - for (int i = 0; i < 4; ++i) - { - element(0,i) += mat.element(0,i); - element(1,i) += mat.element(1,i); - element(2,i) += mat.element(2,i); - element(3,i) += mat.element(3,i); - } - return *this; - } - - friend matrix4 operator * ( const matrix4 & m1, const matrix4 & m2 ); - friend bool operator == ( const matrix4 & m1, const matrix4 & m2 ); - friend bool operator != ( const matrix4 & m1, const matrix4 & m2 ); - - //protected: - real m[16]; - }; - - inline - matrix4 operator * ( const matrix4 & m1, const matrix4 & m2 ) - { - matrix4 product; - - product = m1; - product.mult_right(m2); - - return product; - } - - inline - bool operator ==( const matrix4 &m1, const matrix4 &m2 ) - { - return ( - m1(0,0) == m2(0,0) && - m1(0,1) == m2(0,1) && - m1(0,2) == m2(0,2) && - m1(0,3) == m2(0,3) && - m1(1,0) == m2(1,0) && - m1(1,1) == m2(1,1) && - m1(1,2) == m2(1,2) && - m1(1,3) == m2(1,3) && - m1(2,0) == m2(2,0) && - m1(2,1) == m2(2,1) && - m1(2,2) == m2(2,2) && - m1(2,3) == m2(2,3) && - m1(3,0) == m2(3,0) && - m1(3,1) == m2(3,1) && - m1(3,2) == m2(3,2) && - m1(3,3) == m2(3,3) ); - } - - inline - bool operator != ( const matrix4 & m1, const matrix4 & m2 ) - { return !( m1 == m2 ); } - - - - - - - - - - - - - - class quaternion - { - public: - - quaternion() - { - *this = identity(); - } - - quaternion( const real v[4] ) - { - set_value( v ); - } - - - quaternion( real q0, real q1, real q2, real q3 ) - { - set_value( q0, q1, q2, q3 ); - } - - - quaternion( const matrix4 & m ) - { - set_value( m ); - } - - - quaternion( const vec3 &axis, real radians ) - { - set_value( axis, radians ); - } - - - quaternion( const vec3 &rotateFrom, const vec3 &rotateTo ) - { - set_value( rotateFrom, rotateTo ); - } - - quaternion( const vec3 & from_look, const vec3 & from_up, - const vec3 & to_look, const vec3& to_up) - { - set_value(from_look, from_up, to_look, to_up); - } - - const real * get_value() const - { - return &q[0]; - } - - void get_value( real &q0, real &q1, real &q2, real &q3 ) const - { - q0 = q[0]; - q1 = q[1]; - q2 = q[2]; - q3 = q[3]; - } - - quaternion & set_value( real q0, real q1, real q2, real q3 ) - { - q[0] = q0; - q[1] = q1; - q[2] = q2; - q[3] = q3; - counter = 0; - return *this; - } - - void get_value( vec3 &axis, real &radians ) const - { - radians = real(acos( q[3] ) * GLH_TWO); - if ( radians == GLH_ZERO ) - axis = vec3( 0.0, 0.0, 1.0 ); - else - { - axis.v[0] = q[0]; - axis.v[1] = q[1]; - axis.v[2] = q[2]; - axis.normalize(); - } - } - - void get_value( matrix4 & m ) const - { - real s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz; - - real norm = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; - - s = (equivalent(norm,GLH_ZERO)) ? GLH_ZERO : ( GLH_TWO / norm ); - - xs = q[0] * s; - ys = q[1] * s; - zs = q[2] * s; - - wx = q[3] * xs; - wy = q[3] * ys; - wz = q[3] * zs; - - xx = q[0] * xs; - xy = q[0] * ys; - xz = q[0] * zs; - - yy = q[1] * ys; - yz = q[1] * zs; - zz = q[2] * zs; - - m(0,0) = real( GLH_ONE - ( yy + zz )); - m(1,0) = real ( xy + wz ); - m(2,0) = real ( xz - wy ); - - m(0,1) = real ( xy - wz ); - m(1,1) = real ( GLH_ONE - ( xx + zz )); - m(2,1) = real ( yz + wx ); - - m(0,2) = real ( xz + wy ); - m(1,2) = real ( yz - wx ); - m(2,2) = real ( GLH_ONE - ( xx + yy )); - - m(3,0) = m(3,1) = m(3,2) = m(0,3) = m(1,3) = m(2,3) = GLH_ZERO; - m(3,3) = GLH_ONE; - } - - quaternion & set_value( const real * qp ) - { - memcpy(q,qp,sizeof(real) * 4); - - counter = 0; - return *this; - } - - quaternion & set_value( const matrix4 & m ) - { - real tr, s; - int i, j, k; - const int nxt[3] = { 1, 2, 0 }; - - tr = m(0,0) + m(1,1) + m(2,2); - - if ( tr > GLH_ZERO ) - { - s = real(sqrt( tr + m(3,3) )); - q[3] = real ( s * 0.5 ); - s = real(0.5) / s; - - q[0] = real ( ( m(1,2) - m(2,1) ) * s ); - q[1] = real ( ( m(2,0) - m(0,2) ) * s ); - q[2] = real ( ( m(0,1) - m(1,0) ) * s ); - } - else - { - i = 0; - if ( m(1,1) > m(0,0) ) - i = 1; - - if ( m(2,2) > m(i,i) ) - i = 2; - - j = nxt[i]; - k = nxt[j]; - - s = real(sqrt( ( m(i,j) - ( m(j,j) + m(k,k) )) + GLH_ONE )); - - q[i] = real ( s * 0.5 ); - s = real(0.5 / s); - - q[3] = real ( ( m(j,k) - m(k,j) ) * s ); - q[j] = real ( ( m(i,j) + m(j,i) ) * s ); - q[k] = real ( ( m(i,k) + m(k,i) ) * s ); - } - - counter = 0; - return *this; - } - - quaternion & set_value( const vec3 &axis, real theta ) - { - real sqnorm = axis.square_norm(); - - if (sqnorm <= GLH_EPSILON) - { - // axis too small. - x = y = z = 0.0; - w = 1.0; - } - else - { - theta *= real(0.5); - real sin_theta = real(sin(theta)); - - if (!equivalent(sqnorm,GLH_ONE)) - sin_theta /= real(sqrt(sqnorm)); - x = sin_theta * axis.v[0]; - y = sin_theta * axis.v[1]; - z = sin_theta * axis.v[2]; - w = real(cos(theta)); - } - return *this; - } - - quaternion & set_value( const vec3 & rotateFrom, const vec3 & rotateTo ) - { - vec3 p1, p2; - real alpha; - - p1 = rotateFrom; - p1.normalize(); - p2 = rotateTo; - p2.normalize(); - - alpha = p1.dot(p2); - - if(equivalent(alpha,GLH_ONE)) - { - *this = identity(); - return *this; - } - - // ensures that the anti-parallel case leads to a positive dot - if(equivalent(alpha,-GLH_ONE)) - { - vec3 v; - - if(p1.v[0] != p1.v[1] || p1.v[0] != p1.v[2]) - v = vec3(p1.v[1], p1.v[2], p1.v[0]); - else - v = vec3(-p1.v[0], p1.v[1], p1.v[2]); - - v -= p1 * p1.dot(v); - v.normalize(); - - set_value(v, GLH_PI); - return *this; - } - - p1 = p1.cross(p2); - p1.normalize(); - set_value(p1,real(acos(alpha))); - - counter = 0; - return *this; - } - - quaternion & set_value( const vec3 & from_look, const vec3 & from_up, - const vec3 & to_look, const vec3 & to_up) - { - quaternion r_look = quaternion(from_look, to_look); - - vec3 rotated_from_up(from_up); - r_look.mult_vec(rotated_from_up); - - quaternion r_twist = quaternion(rotated_from_up, to_up); - - *this = r_twist; - *this *= r_look; - return *this; - } - - quaternion & operator *= ( const quaternion & qr ) - { - quaternion ql(*this); - - w = ql.w * qr.w - ql.x * qr.x - ql.y * qr.y - ql.z * qr.z; - x = ql.w * qr.x + ql.x * qr.w + ql.y * qr.z - ql.z * qr.y; - y = ql.w * qr.y + ql.y * qr.w + ql.z * qr.x - ql.x * qr.z; - z = ql.w * qr.z + ql.z * qr.w + ql.x * qr.y - ql.y * qr.x; - - counter += qr.counter; - counter++; - counter_normalize(); - return *this; - } - - void normalize() - { - real rnorm = GLH_ONE / real(sqrt(w * w + x * x + y * y + z * z)); - if (equivalent(rnorm, GLH_ZERO)) - return; - x *= rnorm; - y *= rnorm; - z *= rnorm; - w *= rnorm; - counter = 0; - } - - friend bool operator == ( const quaternion & q1, const quaternion & q2 ); - - friend bool operator != ( const quaternion & q1, const quaternion & q2 ); - - friend quaternion operator * ( const quaternion & q1, const quaternion & q2 ); - - bool equals( const quaternion & r, real tolerance ) const - { - real t; - - t = ( - (q[0]-r.q[0])*(q[0]-r.q[0]) + - (q[1]-r.q[1])*(q[1]-r.q[1]) + - (q[2]-r.q[2])*(q[2]-r.q[2]) + - (q[3]-r.q[3])*(q[3]-r.q[3]) ); - if(t > GLH_EPSILON) - return false; - return 1; - } - - quaternion & conjugate() - { - q[0] *= -GLH_ONE; - q[1] *= -GLH_ONE; - q[2] *= -GLH_ONE; - return *this; - } - - quaternion & invert() - { - return conjugate(); - } - - quaternion inverse() const - { - quaternion r = *this; - return r.invert(); - } - - // - // Quaternion multiplication with cartesian vector - // v' = q*v*q(star) - // - void mult_vec( const vec3 &src, vec3 &dst ) const - { - real v_coef = w * w - x * x - y * y - z * z; - real u_coef = GLH_TWO * (src.v[0] * x + src.v[1] * y + src.v[2] * z); - real c_coef = GLH_TWO * w; - - dst.v[0] = v_coef * src.v[0] + u_coef * x + c_coef * (y * src.v[2] - z * src.v[1]); - dst.v[1] = v_coef * src.v[1] + u_coef * y + c_coef * (z * src.v[0] - x * src.v[2]); - dst.v[2] = v_coef * src.v[2] + u_coef * z + c_coef * (x * src.v[1] - y * src.v[0]); - } - - void mult_vec( vec3 & src_and_dst) const - { - mult_vec(vec3(src_and_dst), src_and_dst); - } - - void scale_angle( real scaleFactor ) - { - vec3 axis; - real radians; - - get_value(axis, radians); - radians *= scaleFactor; - set_value(axis, radians); - } - - static quaternion slerp( const quaternion & p, const quaternion & q, real alpha ) - { - quaternion r; - - real cos_omega = p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w; - // if B is on opposite hemisphere from A, use -B instead - - int bflip; - if ( ( bflip = (cos_omega < GLH_ZERO)) ) - cos_omega = -cos_omega; - - // complementary interpolation parameter - real beta = GLH_ONE - alpha; - - if(cos_omega <= GLH_ONE - GLH_EPSILON) - return p; - - real omega = real(acos(cos_omega)); - real one_over_sin_omega = GLH_ONE / real(sin(omega)); - - beta = real(sin(omega*beta) * one_over_sin_omega); - alpha = real(sin(omega*alpha) * one_over_sin_omega); - - if (bflip) - alpha = -alpha; - - r.x = beta * p.q[0]+ alpha * q.q[0]; - r.y = beta * p.q[1]+ alpha * q.q[1]; - r.z = beta * p.q[2]+ alpha * q.q[2]; - r.w = beta * p.q[3]+ alpha * q.q[3]; - return r; - } - - static quaternion identity() - { - static quaternion ident( vec3( 0.0, 0.0, 0.0 ), GLH_ONE ); - return ident; - } - - real & operator []( int i ) - { - assert(i < 4); - return q[i]; - } - - const real & operator []( int i ) const - { - assert(i < 4); - return q[i]; - } - - protected: - - void counter_normalize() - { - if (counter > GLH_QUATERNION_NORMALIZATION_THRESHOLD) - normalize(); - } - - union - { - struct - { - real q[4]; - }; - struct - { - real x; - real y; - real z; - real w; - }; - }; - - // renormalization counter - unsigned char counter; - }; - - inline - bool operator == ( const quaternion & q1, const quaternion & q2 ) - { - return (equivalent(q1.x, q2.x) && - equivalent(q1.y, q2.y) && - equivalent(q1.z, q2.z) && - equivalent(q1.w, q2.w) ); - } - - inline - bool operator != ( const quaternion & q1, const quaternion & q2 ) - { - return ! ( q1 == q2 ); - } - - inline - quaternion operator * ( const quaternion & q1, const quaternion & q2 ) - { - quaternion r(q1); - r *= q2; - return r; - } - - - - - - - - - - - class plane - { - public: - - plane() - { - planedistance = 0.0; - planenormal.set_value( 0.0, 0.0, 1.0 ); - } - - - plane( const vec3 &p0, const vec3 &p1, const vec3 &p2 ) - { - vec3 v0 = p1 - p0; - vec3 v1 = p2 - p0; - planenormal = v0.cross(v1); - planenormal.normalize(); - planedistance = p0.dot(planenormal); - } - - plane( const vec3 &normal, real distance ) - { - planedistance = distance; - planenormal = normal; - planenormal.normalize(); - } - - plane( const vec3 &normal, const vec3 &point ) - { - planenormal = normal; - planenormal.normalize(); - planedistance = point.dot(planenormal); - } - - void offset( real d ) - { - planedistance += d; - } - - bool intersect( const line &l, vec3 &intersection ) const - { - vec3 pos, dir; - vec3 pn = planenormal; - real pd = planedistance; - - pos = l.get_position(); - dir = l.get_direction(); - - if(dir.dot(pn) == 0.0) return 0; - pos -= pn*pd; - // now we're talking about a plane passing through the origin - if(pos.dot(pn) < 0.0) pn.negate(); - if(dir.dot(pn) > 0.0) dir.negate(); - vec3 ppos = pn * pos.dot(pn); - pos = (ppos.length()/dir.dot(-pn))*dir; - intersection = l.get_position(); - intersection += pos; - return 1; - } - void transform( const matrix4 &matrix ) - { - matrix4 invtr = matrix.inverse(); - invtr = invtr.transpose(); - - vec3 pntOnplane = planenormal * planedistance; - vec3 newPntOnplane; - vec3 newnormal; - - invtr.mult_dir_matrix(planenormal, newnormal); - matrix.mult_vec_matrix(pntOnplane, newPntOnplane); - - newnormal.normalize(); - planenormal = newnormal; - planedistance = newPntOnplane.dot(planenormal); - } - - bool is_in_half_space( const vec3 &point ) const - { - - if(( point.dot(planenormal) - planedistance) < 0.0) - return 0; - return 1; - } - - - real distance( const vec3 & point ) const - { - return planenormal.dot(point - planenormal*planedistance); - } - - const vec3 &get_normal() const - { - return planenormal; - } - - - real get_distance_from_origin() const - { - return planedistance; - } - - - friend bool operator == ( const plane & p1, const plane & p2 ); - - - friend bool operator != ( const plane & p1, const plane & p2 ); - - //protected: - vec3 planenormal; - real planedistance; - }; - - inline - bool operator == (const plane & p1, const plane & p2 ) - { - return ( p1.planedistance == p2.planedistance && p1.planenormal == p2.planenormal); - } - - inline - bool operator != ( const plane & p1, const plane & p2 ) - { return ! (p1 == p2); } - - - - } // "ns_##GLH_REAL" - - // make common typedefs... -#ifdef GLH_REAL_IS_FLOAT - typedef GLH_REAL_NAMESPACE::vec2 vec2f; - typedef GLH_REAL_NAMESPACE::vec3 vec3f; - typedef GLH_REAL_NAMESPACE::vec4 vec4f; - typedef GLH_REAL_NAMESPACE::quaternion quaternionf; - typedef GLH_REAL_NAMESPACE::quaternion rotationf; - typedef GLH_REAL_NAMESPACE::line linef; - typedef GLH_REAL_NAMESPACE::plane planef; - typedef GLH_REAL_NAMESPACE::matrix4 matrix4f; -#endif - - - - -} // namespace glh - - - -#endif - diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index d8058baf5..d90e21e5d 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -2,31 +2,25 @@ * @file lldxhardware.cpp * @brief LLDXHardware implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ @@ -40,9 +34,12 @@ #include #undef INITGUID +#include + #include #include "lldxhardware.h" + #include "llerror.h" #include "llstring.h" @@ -59,11 +56,160 @@ LLDXHardware gDXHardware; #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } -std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName) +typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc, + OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel, + RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities ); + +HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam ) { - HRESULT hr; + HRESULT hr; + bool bGotMemory = false; + HRESULT hrCoInitialize = S_OK; + IWbemLocator* pIWbemLocator = nullptr; + IWbemServices* pIWbemServices = nullptr; + BSTR pNamespace = nullptr; + + *pdwAdapterRam = 0; + hrCoInitialize = CoInitialize( 0 ); + + hr = CoCreateInstance( CLSID_WbemLocator, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IWbemLocator, + ( LPVOID* )&pIWbemLocator ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) wprintf( L"WMI: CoCreateInstance failed: 0x%0.8x\n", hr ); +#endif + + if( SUCCEEDED( hr ) && pIWbemLocator ) + { + // Using the locator, connect to WMI in the given namespace. + pNamespace = SysAllocString( L"\\\\.\\root\\cimv2" ); + + hr = pIWbemLocator->ConnectServer( pNamespace, nullptr, nullptr, 0L, + 0L, nullptr, nullptr, &pIWbemServices ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) wprintf( L"WMI: pIWbemLocator->ConnectServer failed: 0x%0.8x\n", hr ); +#endif + if( SUCCEEDED( hr ) && pIWbemServices != 0 ) + { + HINSTANCE hinstOle32 = nullptr; + + hinstOle32 = LoadLibraryW( L"ole32.dll" ); + if( hinstOle32 ) + { + PfnCoSetProxyBlanket pfnCoSetProxyBlanket = nullptr; + + pfnCoSetProxyBlanket = ( PfnCoSetProxyBlanket )GetProcAddress( hinstOle32, "CoSetProxyBlanket" ); + if( pfnCoSetProxyBlanket != 0 ) + { + // Switch security level to IMPERSONATE. + pfnCoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0 ); + } + + FreeLibrary( hinstOle32 ); + } + + IEnumWbemClassObject* pEnumVideoControllers = nullptr; + BSTR pClassName = nullptr; + + pClassName = SysAllocString( L"Win32_VideoController" ); + + hr = pIWbemServices->CreateInstanceEnum( pClassName, 0, + nullptr, &pEnumVideoControllers ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) wprintf( L"WMI: pIWbemServices->CreateInstanceEnum failed: 0x%0.8x\n", hr ); +#endif + + if( SUCCEEDED( hr ) && pEnumVideoControllers ) + { + IWbemClassObject* pVideoControllers[10] = {0}; + DWORD uReturned = 0; + BSTR pPropName = nullptr; + + // Get the first one in the list + pEnumVideoControllers->Reset(); + hr = pEnumVideoControllers->Next( 5000, // timeout in 5 seconds + 10, // return the first 10 + pVideoControllers, + &uReturned ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) wprintf( L"WMI: pEnumVideoControllers->Next failed: 0x%0.8x\n", hr ); + if( uReturned == 0 ) wprintf( L"WMI: pEnumVideoControllers uReturned == 0\n" ); +#endif + + VARIANT var; + if( SUCCEEDED( hr ) ) + { + bool bFound = false; + for( UINT iController = 0; iController < uReturned; iController++ ) + { + if ( !pVideoControllers[iController] ) + continue; + + pPropName = SysAllocString( L"PNPDeviceID" ); + hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) + wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr ); +#endif + if( SUCCEEDED( hr ) ) + { + if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 ) + bFound = true; + } + VariantClear( &var ); + if( pPropName ) SysFreeString( pPropName ); + + if( bFound ) + { + pPropName = SysAllocString( L"AdapterRAM" ); + hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) + wprintf( L"WMI: pVideoControllers[iController]->Get AdapterRAM failed: 0x%0.8x\n", + hr ); +#endif + if( SUCCEEDED( hr ) ) + { + bGotMemory = true; + *pdwAdapterRam = var.ulVal; + } + VariantClear( &var ); + if( pPropName ) SysFreeString( pPropName ); + break; + } + SAFE_RELEASE( pVideoControllers[iController] ); + } + } + } + + if( pClassName ) + SysFreeString( pClassName ); + SAFE_RELEASE( pEnumVideoControllers ); + } + + if( pNamespace ) + SysFreeString( pNamespace ); + SAFE_RELEASE( pIWbemServices ); + } + + SAFE_RELEASE( pIWbemLocator ); + + if( SUCCEEDED( hrCoInitialize ) ) + CoUninitialize(); + + if( bGotMemory ) + return S_OK; + else + return E_FAIL; +} + +void get_wstring(IDxDiagContainer* containerp, WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize) +{ + HRESULT hr; VARIANT var; - WCHAR wszPropValue[256]; VariantInit( &var ); hr = containerp->GetProp(wszPropName, &var ); @@ -82,13 +228,19 @@ std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName) wcscpy( wszPropValue, (var.boolVal) ? L"true" : L"false" ); /* Flawfinder: ignore */ break; case VT_BSTR: - wcsncpy( wszPropValue, var.bstrVal, 255 ); /* Flawfinder: ignore */ - wszPropValue[255] = 0; + wcsncpy( wszPropValue, var.bstrVal, outputSize-1 ); /* Flawfinder: ignore */ + wszPropValue[outputSize-1] = 0; break; } } // Clear the variant (this is needed to free BSTR memory) VariantClear( &var ); +} + +std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName) +{ + WCHAR wszPropValue[256]; + get_wstring(containerp, wszPropName, wszPropValue, 256); return utf16str_to_utf8str(wszPropValue); } @@ -126,7 +278,7 @@ BOOL LLVersion::set(const std::string &version_string) } if (count < 4) { - //llwarns << "Potentially bogus version string!" << version_string << llendl; + //LL_WARNS() << "Potentially bogus version string!" << version_string << LL_ENDL; for (i = 0; i < 4; i++) { mFields[i] = 0; @@ -177,6 +329,7 @@ std::string LLDXDriverFile::dump() LLDXDevice::~LLDXDevice() { for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer()); + mDriverFiles.clear(); } std::string LLDXDevice::dump() @@ -236,6 +389,7 @@ LLDXHardware::LLDXHardware() void LLDXHardware::cleanup() { // for_each(mDevices.begin(), mDevices.end(), DeletePairedPointer()); + // mDevices.clear(); } /* @@ -365,8 +519,18 @@ BOOL LLDXHardware::getInfo(BOOL vram_only) goto LCleanup; } - // Get the English VRAM string + DWORD vram = 0; + + WCHAR deviceID[512]; + + get_wstring(device_containerp, L"szDeviceID", deviceID, 512); + + if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram))) { + mVRAM = vram/(1024*1024); + } + else + { // Get the English VRAM string std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish"); // We don't need the device any more diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 09502ebac..e706e328f 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -57,6 +57,7 @@ LLKeyboard::LLKeyboard() : mCallbacks(NULL), mNumpadDistinct(ND_NUMLOCK_OFF) mKeyUp[i] = FALSE; mKeyDown[i] = FALSE; mKeyRepeated[i] = FALSE; + mControllerKeys[i] = FALSE; } mInsertMode = LL_KIM_INSERT; diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index f8b155bf1..80ac3acfc 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -113,6 +113,12 @@ public: F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed. S32 getKeyElapsedFrameCount( KEY key ); // Returns time in frames since key was pressed. + void setControllerKey(KEY key, bool level) + { + mControllerKeys[key] = mKeyLevel[key] = level; + (level ? mKeyDown[key] : mKeyUp[key]) = true; + } + protected: void addKeyName(KEY key, const std::string& name); @@ -127,6 +133,7 @@ protected: BOOL mKeyRepeated[KEY_COUNT]; // Key was repeated BOOL mKeyUp[KEY_COUNT]; // Up edge BOOL mKeyDown[KEY_COUNT]; // Down edge + BOOL mControllerKeys[KEY_COUNT]; // Keys held in controller KEY mCurTranslatedKey; KEY mCurScanKey; // Used during the scanKeyboard() diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index df78816bd..f86222e15 100644 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -267,7 +267,7 @@ void LLKeyboardWin32::scanKeyboard() // ...translate back to windows key U16 virtual_key = inverseTranslateExtendedKey(key); // keydown in highest bit - if (!pending_key_events && !(GetAsyncKeyState(virtual_key) & 0x8000)) + if (!mControllerKeys[key] && !pending_key_events && !(GetAsyncKeyState(virtual_key) & 0x8000)) { //llinfos << "Key up event missed, resetting" << llendl; mKeyLevel[key] = FALSE; diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index 438964dae..6c0e872e2 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -30,7 +30,6 @@ #if LL_MESA_HEADLESS #include "llwindow.h" -#include "GL/glu.h" #include "GL/osmesa.h" class LLWindowMesaHeadless : public LLWindow diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 341739d1d..e7832731e 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -125,7 +125,9 @@ bool LLWindowSDL::ll_try_gtk_init(void) if (!tried_gtk_init) { tried_gtk_init = TRUE; +#if !GLIB_CHECK_VERSION(2, 32, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif maybe_lock_display(); gtk_is_good = gtk_init_check(NULL, NULL); maybe_unlock_display(); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index a29c5378e..c1151f8e1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -38,6 +38,7 @@ // Linden library includes #include "llerror.h" +#include "llfasttimer.h" #include "llgl.h" #include "llstring.h" #include "lldir.h" @@ -58,8 +59,6 @@ #include #include -#include "llfasttimer.h" - // culled from winuser.h #ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */ const S32 WM_MOUSEWHEEL = 0x020A; @@ -87,6 +86,18 @@ void show_window_creation_error(const std::string& title) LL_WARNS("Window") << title << LL_ENDL; } +HGLRC SafeCreateContext(HDC hdc) +{ + __try + { + return wglCreateContext(hdc); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + return NULL; + } +} + //static BOOL LLWindowWin32::sIsClassRegistered = FALSE; @@ -163,7 +174,6 @@ LLWinImm::LLWinImm() : mHImmDll(NULL) // Check system metrics if ( !GetSystemMetrics( SM_DBCSENABLED ) ) return; - mHImmDll = LoadLibraryA("Imm32"); if (mHImmDll != NULL) @@ -205,7 +215,7 @@ LLWinImm::LLWinImm() : mHImmDll(NULL) // the case, since it is very unusual; these APIs are available from // the beginning, and all versions of IMM32.DLL should have them all. // Unfortunately, this code may be executed before initialization of - // the logging channel (llwarns), and we can't do it here... Yes, this + // the logging channel (LL_WARNS()), and we can't do it here... Yes, this // is one of disadvantages to use static constraction to DLL loading. FreeLibrary(mHImmDll); mHImmDll = NULL; @@ -554,6 +564,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, if (closest_refresh == 0) { LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL; + //success = FALSE; if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) { @@ -1012,7 +1023,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co dw_ex_style = WS_EX_APPWINDOW; dw_style = WS_POPUP; - // Move window borders out not to cover window contents + // Move window borders out not to cover window contents. + // This converts client rect to window rect, i.e. expands it by the window border size. AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style); } // If it failed, we don't want to run fullscreen @@ -1059,7 +1071,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co mhInstance, NULL); - LL_INFOS("Window") << "window is created." << llendl ; + LL_INFOS("Window") << "window is created." << LL_ENDL ; //----------------------------------------------------------------------- // Create GL drawing context @@ -1092,7 +1104,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co return FALSE; } - LL_INFOS("Window") << "Device context retrieved." << llendl ; + LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ; if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) { @@ -1102,7 +1114,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co return FALSE; } - LL_INFOS("Window") << "Pixel format chosen." << llendl ; + LL_INFOS("Window") << "Pixel format chosen." << LL_ENDL ; // Verify what pixel format we actually received. if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), @@ -1115,35 +1127,35 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co } // (EXP-1765) dump pixel data to see if there is a pattern that leads to unreproducible crash - LL_INFOS("Window") << "--- begin pixel format dump ---" << llendl ; - LL_INFOS("Window") << "pixel_format is " << pixel_format << llendl ; - LL_INFOS("Window") << "pfd.nSize: " << pfd.nSize << llendl ; - LL_INFOS("Window") << "pfd.nVersion: " << pfd.nVersion << llendl ; - LL_INFOS("Window") << "pfd.dwFlags: 0x" << std::hex << pfd.dwFlags << std::dec << llendl ; - LL_INFOS("Window") << "pfd.iPixelType: " << (int)pfd.iPixelType << llendl ; - LL_INFOS("Window") << "pfd.cColorBits: " << (int)pfd.cColorBits << llendl ; - LL_INFOS("Window") << "pfd.cRedBits: " << (int)pfd.cRedBits << llendl ; - LL_INFOS("Window") << "pfd.cRedShift: " << (int)pfd.cRedShift << llendl ; - LL_INFOS("Window") << "pfd.cGreenBits: " << (int)pfd.cGreenBits << llendl ; - LL_INFOS("Window") << "pfd.cGreenShift: " << (int)pfd.cGreenShift << llendl ; - LL_INFOS("Window") << "pfd.cBlueBits: " << (int)pfd.cBlueBits << llendl ; - LL_INFOS("Window") << "pfd.cBlueShift: " << (int)pfd.cBlueShift << llendl ; - LL_INFOS("Window") << "pfd.cAlphaBits: " << (int)pfd.cAlphaBits << llendl ; - LL_INFOS("Window") << "pfd.cAlphaShift: " << (int)pfd.cAlphaShift << llendl ; - LL_INFOS("Window") << "pfd.cAccumBits: " << (int)pfd.cAccumBits << llendl ; - LL_INFOS("Window") << "pfd.cAccumRedBits: " << (int)pfd.cAccumRedBits << llendl ; - LL_INFOS("Window") << "pfd.cAccumGreenBits: " << (int)pfd.cAccumGreenBits << llendl ; - LL_INFOS("Window") << "pfd.cAccumBlueBits: " << (int)pfd.cAccumBlueBits << llendl ; - LL_INFOS("Window") << "pfd.cAccumAlphaBits: " << (int)pfd.cAccumAlphaBits << llendl ; - LL_INFOS("Window") << "pfd.cDepthBits: " << (int)pfd.cDepthBits << llendl ; - LL_INFOS("Window") << "pfd.cStencilBits: " << (int)pfd.cStencilBits << llendl ; - LL_INFOS("Window") << "pfd.cAuxBuffers: " << (int)pfd.cAuxBuffers << llendl ; - LL_INFOS("Window") << "pfd.iLayerType: " << (int)pfd.iLayerType << llendl ; - LL_INFOS("Window") << "pfd.bReserved: " << (int)pfd.bReserved << llendl ; - LL_INFOS("Window") << "pfd.dwLayerMask: " << pfd.dwLayerMask << llendl ; - LL_INFOS("Window") << "pfd.dwVisibleMask: " << pfd.dwVisibleMask << llendl ; - LL_INFOS("Window") << "pfd.dwDamageMask: " << pfd.dwDamageMask << llendl ; - LL_INFOS("Window") << "--- end pixel format dump ---" << llendl ; + LL_INFOS("Window") << "--- begin pixel format dump ---" << LL_ENDL ; + LL_INFOS("Window") << "pixel_format is " << pixel_format << LL_ENDL ; + LL_INFOS("Window") << "pfd.nSize: " << pfd.nSize << LL_ENDL ; + LL_INFOS("Window") << "pfd.nVersion: " << pfd.nVersion << LL_ENDL ; + LL_INFOS("Window") << "pfd.dwFlags: 0x" << std::hex << pfd.dwFlags << std::dec << LL_ENDL ; + LL_INFOS("Window") << "pfd.iPixelType: " << (int)pfd.iPixelType << LL_ENDL ; + LL_INFOS("Window") << "pfd.cColorBits: " << (int)pfd.cColorBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cRedBits: " << (int)pfd.cRedBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cRedShift: " << (int)pfd.cRedShift << LL_ENDL ; + LL_INFOS("Window") << "pfd.cGreenBits: " << (int)pfd.cGreenBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cGreenShift: " << (int)pfd.cGreenShift << LL_ENDL ; + LL_INFOS("Window") << "pfd.cBlueBits: " << (int)pfd.cBlueBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cBlueShift: " << (int)pfd.cBlueShift << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAlphaBits: " << (int)pfd.cAlphaBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAlphaShift: " << (int)pfd.cAlphaShift << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumBits: " << (int)pfd.cAccumBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumRedBits: " << (int)pfd.cAccumRedBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumGreenBits: " << (int)pfd.cAccumGreenBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumBlueBits: " << (int)pfd.cAccumBlueBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumAlphaBits: " << (int)pfd.cAccumAlphaBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cDepthBits: " << (int)pfd.cDepthBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cStencilBits: " << (int)pfd.cStencilBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAuxBuffers: " << (int)pfd.cAuxBuffers << LL_ENDL ; + LL_INFOS("Window") << "pfd.iLayerType: " << (int)pfd.iLayerType << LL_ENDL ; + LL_INFOS("Window") << "pfd.bReserved: " << (int)pfd.bReserved << LL_ENDL ; + LL_INFOS("Window") << "pfd.dwLayerMask: " << pfd.dwLayerMask << LL_ENDL ; + LL_INFOS("Window") << "pfd.dwVisibleMask: " << pfd.dwVisibleMask << LL_ENDL ; + LL_INFOS("Window") << "pfd.dwDamageMask: " << pfd.dwDamageMask << LL_ENDL ; + LL_INFOS("Window") << "--- end pixel format dump ---" << LL_ENDL ; if (pfd.cColorBits < 32) { @@ -1169,7 +1181,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co return FALSE; } - if (!(mhRC = wglCreateContext(mhDC))) + if (!(mhRC = SafeCreateContext(mhDC))) { close(); OSMessageBox(mCallbacks->translateString("MBGLContextErr"), @@ -1185,7 +1197,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co return FALSE; } - LL_INFOS("Window") << "Drawing context is created." << llendl ; + LL_INFOS("Window") << "Drawing context is created." << LL_ENDL ; gGLManager.initWGL(); @@ -1323,142 +1335,15 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co LL_INFOS("Window") << "Choosing pixel formats: " << num_formats << " pixel formats returned" << LL_ENDL; } - LL_INFOS("Window") << "pixel formats done." << llendl ; - - /*for(int i = 0; i <= num_formats-1; ++i) - { - GLint query[] = { WGL_SAMPLE_BUFFERS_ARB, - WGL_SAMPLES_ARB, - WGL_NUMBER_PIXEL_FORMATS_ARB, - WGL_DRAW_TO_WINDOW_ARB, - WGL_DRAW_TO_BITMAP_ARB, - WGL_ACCELERATION_ARB, - WGL_NEED_PALETTE_ARB, - WGL_NEED_SYSTEM_PALETTE_ARB, - WGL_SWAP_LAYER_BUFFERS_ARB, - WGL_SWAP_METHOD_ARB, - WGL_NUMBER_OVERLAYS_ARB, - WGL_NUMBER_UNDERLAYS_ARB, - WGL_TRANSPARENT_ARB, - WGL_TRANSPARENT_RED_VALUE_ARB, - WGL_TRANSPARENT_GREEN_VALUE_ARB, - WGL_TRANSPARENT_BLUE_VALUE_ARB, - WGL_TRANSPARENT_ALPHA_VALUE_ARB, - WGL_TRANSPARENT_INDEX_VALUE_ARB, - WGL_SHARE_DEPTH_ARB, - WGL_SHARE_STENCIL_ARB, - WGL_SHARE_ACCUM_ARB, - WGL_SUPPORT_GDI_ARB, - WGL_SUPPORT_OPENGL_ARB, - WGL_DOUBLE_BUFFER_ARB, - WGL_STEREO_ARB, - WGL_PIXEL_TYPE_ARB, - WGL_COLOR_BITS_ARB, - WGL_RED_BITS_ARB, - WGL_RED_SHIFT_ARB, - WGL_GREEN_BITS_ARB, - WGL_GREEN_SHIFT_ARB, - WGL_BLUE_BITS_ARB, - WGL_BLUE_SHIFT_ARB, - WGL_ALPHA_BITS_ARB, - WGL_ALPHA_SHIFT_ARB, - WGL_ACCUM_BITS_ARB, - WGL_ACCUM_RED_BITS_ARB, - WGL_ACCUM_GREEN_BITS_ARB, - WGL_ACCUM_BLUE_BITS_ARB, - WGL_ACCUM_ALPHA_BITS_ARB, - WGL_DEPTH_BITS_ARB, - WGL_STENCIL_BITS_ARB, - WGL_AUX_BUFFERS_ARB}; - std::string names[] = { "WGL_SAMPLE_BUFFERS_ARB", - "WGL_SAMPLES_ARB", - "WGL_NUMBER_PIXEL_FORMATS_ARB", - "WGL_DRAW_TO_WINDOW_ARB", - "WGL_DRAW_TO_BITMAP_ARB", - "WGL_ACCELERATION_ARB", - "WGL_NEED_PALETTE_ARB", - "WGL_NEED_SYSTEM_PALETTE_ARB", - "WGL_SWAP_LAYER_BUFFERS_ARB", - "WGL_SWAP_METHOD_ARB", - "WGL_NUMBER_OVERLAYS_ARB", - "WGL_NUMBER_UNDERLAYS_ARB", - "WGL_TRANSPARENT_ARB", - "WGL_TRANSPARENT_RED_VALUE_ARB", - "WGL_TRANSPARENT_GREEN_VALUE_ARB", - "WGL_TRANSPARENT_BLUE_VALUE_ARB", - "WGL_TRANSPARENT_ALPHA_VALUE_ARB", - "WGL_TRANSPARENT_INDEX_VALUE_ARB", - "WGL_SHARE_DEPTH_ARB", - "WGL_SHARE_STENCIL_ARB", - "WGL_SHARE_ACCUM_ARB", - "WGL_SUPPORT_GDI_ARB", - "WGL_SUPPORT_OPENGL_ARB", - "WGL_DOUBLE_BUFFER_ARB", - "WGL_STEREO_ARB", - "WGL_PIXEL_TYPE_ARB", - "WGL_COLOR_BITS_ARB", - "WGL_RED_BITS_ARB", - "WGL_RED_SHIFT_ARB", - "WGL_GREEN_BITS_ARB", - "WGL_GREEN_SHIFT_ARB", - "WGL_BLUE_BITS_ARB", - "WGL_BLUE_SHIFT_ARB", - "WGL_ALPHA_BITS_ARB", - "WGL_ALPHA_SHIFT_ARB", - "WGL_ACCUM_BITS_ARB", - "WGL_ACCUM_RED_BITS_ARB", - "WGL_ACCUM_GREEN_BITS_ARB", - "WGL_ACCUM_BLUE_BITS_ARB", - "WGL_ACCUM_ALPHA_BITS_ARB", - "WGL_DEPTH_BITS_ARB", - "WGL_STENCIL_BITS_ARB", - "WGL_AUX_BUFFERS_ARB"}; - S32 results[sizeof(query)/sizeof(query[0])]={0}; - - if(wglGetPixelFormatAttribivARB(mhDC, pixel_formats[i], 0, sizeof(query)/sizeof(query[0]), query, results)) - { - llinfos << i << ":" << llendl; - for(int j = 0; j < sizeof(query)/sizeof(query[0]); ++j) - { - switch(results[j]) - { - case WGL_NO_ACCELERATION_ARB: - llinfos << " " << names[j] << " = " << "WGL_NO_ACCELERATION_ARB" << llendl; - break; - case WGL_GENERIC_ACCELERATION_ARB: - llinfos << " " << names[j] << " = " << "WGL_GENERIC_ACCELERATION_ARB" << llendl; - break; - case WGL_FULL_ACCELERATION_ARB: - llinfos << " " << names[j] << " = " << "WGL_FULL_ACCELERATION_ARB" << llendl; - break; - case WGL_SWAP_EXCHANGE_ARB: - llinfos << " " << names[j] << " = " << "WGL_SWAP_EXCHANGE_ARB" << llendl; - break; - case WGL_SWAP_COPY_ARB: - llinfos << " " << names[j] << " = " << "WGL_SWAP_COPY_ARB" << llendl; - break; - case WGL_SWAP_UNDEFINED_ARB: - llinfos << " " << names[j] << " = " << "WGL_SWAP_UNDEFINED_ARB" << llendl; - break; - case WGL_TYPE_RGBA_ARB: - llinfos << " " << names[j] << " = " << "WGL_TYPE_RGBA_ARB" << llendl; - break; - case WGL_TYPE_COLORINDEX_ARB: - llinfos << " " << names[j] << " = " << "WGL_TYPE_COLORINDEX_ARB" << llendl; - break; - default: - llinfos << " " << names[j] << " = " << results[j] << llendl; - } - - } - } - }*/ + LL_INFOS("Window") << "pixel formats done." << LL_ENDL ; //Singu note: Reversed order of this loop. Generally, choosepixelformat returns an array with the closer matches towards the start. S32 swap_method = 0; S32 cur_format = 0;//num_formats-1; GLint swap_query = WGL_SWAP_METHOD_ARB; + BOOL found_format = FALSE; + while (!found_format && wglGetPixelFormatAttribivARB(mhDC, pixel_formats[cur_format], 0, 1, &swap_query, &swap_method)) { if (swap_method == WGL_SWAP_UNDEFINED_ARB /*|| cur_format <= 0*/) @@ -1507,7 +1392,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co mhInstance, NULL); - LL_INFOS("Window") << "recreate window done." << llendl ; + LL_INFOS("Window") << "recreate window done." << LL_ENDL ; if (!(mhDC = GetDC(mWindowHandle))) { @@ -1747,6 +1632,7 @@ BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position) return FALSE; } + // Inform the application of the new mouse position (needed for per-frame // hover/picking to function). mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); @@ -1996,6 +1882,10 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // This helps prevent avatar walking after maximizing the window by double-clicking the title bar. static bool sHandleLeftMouseUp = true; + // Ignore the double click received right after activating app. + // This is to avoid triggering double click teleport after returning focus (see MAINT-3786). + static bool sHandleDoubleClick = true; + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr(h_wnd, GWLP_USERDATA); @@ -2123,6 +2013,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ } } + if (!activating) + { + sHandleDoubleClick = false; + } + window_imp->mCallbacks->handleActivateApp(window_imp, activating); break; @@ -2347,6 +2242,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_NCLBUTTONDOWN"); // A click in a non-client area, e.g. title bar or window border. sHandleLeftMouseUp = false; + sHandleDoubleClick = true; } break; @@ -2391,6 +2287,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ //case WM_RBUTTONDBLCLK: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDBLCLK"); + + if (!sHandleDoubleClick) + { + sHandleDoubleClick = true; + break; + } + // Because we move the cursor position in the app, we need to query // to find out where the cursor at the time the event is handled. // If we don't do this, many clicks could get buffered up, and if the diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l index d7d591cc5..f7e592afb 100644 --- a/indra/lscript/lscript_compile/indra.l +++ b/indra/lscript/lscript_compile/indra.l @@ -594,7 +594,8 @@ void parse_string(); "REGION_FLAG_SANDBOX" { count(); yylval.ival = REGION_FLAGS_SANDBOX; return(INTEGER_CONSTANT); } "REGION_FLAG_DISABLE_COLLISIONS" { count(); yylval.ival = REGION_FLAGS_SKIP_COLLISIONS; return(INTEGER_CONSTANT); } "REGION_FLAG_DISABLE_PHYSICS" { count(); yylval.ival = REGION_FLAGS_SKIP_PHYSICS; return(INTEGER_CONSTANT); } -"REGION_FLAG_BLOCK_FLY" { count(); yylval.ival = REGION_FLAGS_BLOCK_FLY; return(INTEGER_CONSTANT); } +"REGION_FLAG_BLOCK_FLY" { count(); yylval.ival = REGION_FLAGS_BLOCK_FLY; return(INTEGER_CONSTANT); } +"REGION_FLAG_BLOCK_FLYOVER" { count(); yylval.ival = REGION_FLAGS_BLOCK_FLYOVER; return(INTEGER_CONSTANT); } "REGION_FLAG_ALLOW_DIRECT_TELEPORT" { count(); yylval.ival = REGION_FLAGS_ALLOW_DIRECT_TELEPORT; return(INTEGER_CONSTANT); } "REGION_FLAG_RESTRICT_PUSHOBJECT" { count(); yylval.ival = REGION_FLAGS_RESTRICT_PUSHOBJECT; return(INTEGER_CONSTANT); } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 008e1d420..4668e2c97 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -183,6 +183,7 @@ set(viewer_SOURCE_FILES llfloateractivespeakers.cpp llfloaterauction.cpp llfloaterautoreplacesettings.cpp + llfloateravatar.cpp llfloateravatarinfo.cpp llfloateravatarlist.cpp llfloateravatarpicker.cpp @@ -204,6 +205,7 @@ set(viewer_SOURCE_FILES llfloatercolorpicker.cpp llfloatercustomize.cpp llfloaterdaycycle.cpp + llfloaterdestinations.cpp llfloaterdirectory.cpp llfloaterdisplayname.cpp llfloatereditui.cpp @@ -216,6 +218,7 @@ set(viewer_SOURCE_FILES llfloaterfriends.cpp llfloatergesture.cpp llfloatergodtools.cpp + llfloatergroupbulkban.cpp llfloatergroupinfo.cpp llfloatergroupinvite.cpp llfloatergroups.cpp @@ -231,6 +234,7 @@ set(viewer_SOURCE_FILES llfloaterlandholdings.cpp llfloaterlandmark.cpp llfloatermap.cpp + llfloatermediafilter.cpp llfloatermediasettings.cpp llfloatermemleak.cpp llfloatermessagelog.cpp @@ -240,6 +244,7 @@ set(viewer_SOURCE_FILES llfloaternamedesc.cpp llfloaternotificationsconsole.cpp llfloaterobjectiminfo.cpp + llfloaterobjectweights.cpp llfloateropenobject.cpp llfloateroutbox.cpp llfloaterparcel.cpp @@ -332,6 +337,7 @@ set(viewer_SOURCE_FILES llmaterialmgr.cpp llmediactrl.cpp llmediadataclient.cpp + llmediafilter.cpp llmediaremotectrl.cpp llmenucommands.cpp llmenuoptionpathfindingrebakenavmesh.cpp @@ -367,6 +373,8 @@ set(viewer_SOURCE_FILES llpanelface.cpp llpanelgeneral.cpp llpanelgroup.cpp + llpanelgroupbulk.cpp + llpanelgroupbulkban.cpp llpanelgroupgeneral.cpp llpanelgroupinvite.cpp llpanelgrouplandmoney.cpp @@ -590,7 +598,6 @@ set(viewer_SOURCE_FILES sgversion.cpp shcommandhandler.cpp shfloatermediaticker.cpp - slfloatermediafilter.cpp wlfPanel_AdvSettings.cpp ) @@ -705,6 +712,7 @@ set(viewer_HEADER_FILES llfloateractivespeakers.h llfloaterauction.h llfloaterautoreplacesettings.h + llfloateravatar.h llfloateravatarinfo.h llfloateravatarlist.h llfloateravatarpicker.h @@ -726,6 +734,7 @@ set(viewer_HEADER_FILES llfloatercolorpicker.h llfloatercustomize.h llfloaterdaycycle.h + llfloaterdestinations.h llfloaterdirectory.h llfloaterdisplayname.h llfloatereditui.h @@ -738,6 +747,7 @@ set(viewer_HEADER_FILES llfloaterfriends.h llfloatergesture.h llfloatergodtools.h + llfloatergroupbulkban.h llfloatergroupinfo.h llfloatergroupinvite.h llfloatergroups.h @@ -753,6 +763,7 @@ set(viewer_HEADER_FILES llfloaterlandholdings.h llfloaterlandmark.h llfloatermap.h + llfloatermediafilter.h llfloatermediasettings.h llfloatermemleak.h llfloatermessagelog.h @@ -762,6 +773,7 @@ set(viewer_HEADER_FILES llfloaternamedesc.h llfloaternotificationsconsole.h llfloaterobjectiminfo.h + llfloaterobjectweights.h llfloateropenobject.h llfloateroutbox.h llfloaterparcel.h @@ -854,6 +866,7 @@ set(viewer_HEADER_FILES llmaterialmgr.h llmediactrl.h llmediadataclient.h + llmediafilter.h llmediaremotectrl.h llmenucommands.h llmenuoptionpathfindingrebakenavmesh.h @@ -889,6 +902,9 @@ set(viewer_HEADER_FILES llpanelface.h llpanelgeneral.h llpanelgroup.h + llpanelgroupbulk.h + llpanelgroupbulkban.h + llpanelgroupbulkimpl.h llpanelgroupgeneral.h llpanelgroupinvite.h llpanelgrouplandmoney.h @@ -1115,12 +1131,12 @@ set(viewer_HEADER_FILES rlvinventory.h rlvlocks.h rlvui.h + roles_constants.h scriptcounter.h sgmemstat.h sgversion.h shcommandhandler.h shfloatermediaticker.h - slfloatermediafilter.h wlfPanel_AdvSettings.h VertexCache.h VorbisFramework.h @@ -1282,6 +1298,7 @@ if (WINDOWS) shell32 user32 Vfw32 + Wbemuuid winspool ) @@ -1798,7 +1815,7 @@ if (PACKAGE) if (LINUX) list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged") set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux.tar.bz2") - set(VIEWER_EXE_GLOBS "singularity-do-not-run-directly SLPlugin") + set(VIEWER_EXE_GLOBS "${VIEWER_BRANDING_ID}-do-not-run-directly SLPlugin") set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*") set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest) endif (LINUX) diff --git a/indra/newview/app_settings/autoreplace.xml b/indra/newview/app_settings/autoreplace.xml index 09d19f7b0..f4075a16e 100644 --- a/indra/newview/app_settings/autoreplace.xml +++ b/indra/newview/app_settings/autoreplace.xml @@ -8142,8 +8142,6 @@ very waht what - wanna - want to warantee warranty wardobe diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 7e35949ed..253b0ad6e 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -253,6 +253,12 @@ UserConnectionPort + portable + + count + 0 + + purge desc diff --git a/indra/newview/app_settings/keysZQSD.ini b/indra/newview/app_settings/keysZQSD.ini new file mode 100644 index 000000000..3510587c3 --- /dev/null +++ b/indra/newview/app_settings/keysZQSD.ini @@ -0,0 +1,362 @@ +# keys.ini +# +# keyboard binding initialization +# +# comments must have # in the first column +# blank lines OK +# +# Format: +# mode key mask function +# +# mode must be one of FIRST_PERSON, THIRD_PERSON, EDIT, EDIT_AVATAR, or CONVERSATION +# key must be upper case, or SPACE, HOME, END, PGUP, PGDN, LEFT, RIGHT, UP, DOWN, +# or one of ,.;'[] +# mask must be NONE, SHIFT, ALT, ALT_SHIFT. +# Control is reserved for user commands. +# function must be a function named in llkeyboard.cpp + +FIRST_PERSON Q NONE slide_left +FIRST_PERSON D NONE slide_right +FIRST_PERSON Z NONE push_forward +FIRST_PERSON S NONE push_backward +FIRST_PERSON E NONE jump +FIRST_PERSON C NONE push_down +FIRST_PERSON F NONE toggle_fly + +FIRST_PERSON LEFT NONE slide_left +FIRST_PERSON RIGHT NONE slide_right +FIRST_PERSON UP NONE push_forward +FIRST_PERSON DOWN NONE push_backward +FIRST_PERSON PGUP NONE jump +FIRST_PERSON PGDN NONE push_down +FIRST_PERSON HOME NONE toggle_fly + +FIRST_PERSON PAD_LEFT NONE slide_left +FIRST_PERSON PAD_RIGHT NONE slide_right +FIRST_PERSON PAD_UP NONE push_forward +FIRST_PERSON PAD_DOWN NONE push_backward +FIRST_PERSON PAD_PGUP NONE jump +FIRST_PERSON PAD_PGDN NONE push_down +FIRST_PERSON PAD_HOME NONE toggle_fly +FIRST_PERSON PAD_CENTER NONE stop_moving +FIRST_PERSON PAD_ENTER NONE start_chat +FIRST_PERSON PAD_DIVIDE NONE start_gesture + +FIRST_PERSON Q SHIFT slide_left +FIRST_PERSON D SHIFT slide_right +FIRST_PERSON Z SHIFT push_forward +FIRST_PERSON S SHIFT push_backward +FIRST_PERSON E SHIFT jump +FIRST_PERSON C SHIFT toggle_down +FIRST_PERSON F SHIFT toggle_fly + +FIRST_PERSON SPACE NONE stop_moving +FIRST_PERSON ENTER NONE start_chat +FIRST_PERSON DIVIDE NONE start_gesture +FIRST_PERSON / NONE start_gesture + +FIRST_PERSON LEFT SHIFT slide_left +FIRST_PERSON RIGHT SHIFT slide_right +FIRST_PERSON UP SHIFT push_forward +FIRST_PERSON DOWN SHIFT push_backward +FIRST_PERSON PGUP SHIFT jump +FIRST_PERSON PGDN SHIFT toggle_down + +FIRST_PERSON PAD_LEFT SHIFT slide_left +FIRST_PERSON PAD_RIGHT SHIFT slide_right +FIRST_PERSON PAD_UP SHIFT push_forward +FIRST_PERSON PAD_DOWN SHIFT push_backward +FIRST_PERSON PAD_PGUP SHIFT jump +FIRST_PERSON PAD_PGDN SHIFT toggle_down +FIRST_PERSON PAD_HOME SHIFT toggle_fly +FIRST_PERSON PAD_ENTER SHIFT start_chat +FIRST_PERSON PAD_DIVIDE SHIFT start_gesture + +THIRD_PERSON Q NONE turn_left +THIRD_PERSON D NONE turn_right +THIRD_PERSON Q SHIFT slide_left +THIRD_PERSON D SHIFT slide_right +THIRD_PERSON Z NONE push_forward +THIRD_PERSON S NONE push_backward +THIRD_PERSON Z SHIFT push_forward +THIRD_PERSON S SHIFT push_backward +THIRD_PERSON E NONE jump +THIRD_PERSON C NONE push_down +THIRD_PERSON E SHIFT jump +THIRD_PERSON C SHIFT toggle_down + +THIRD_PERSON F NONE toggle_fly +THIRD_PERSON F SHIFT toggle_fly + +THIRD_PERSON SPACE NONE stop_moving +THIRD_PERSON ENTER NONE start_chat +THIRD_PERSON DIVIDE NONE start_gesture +THIRD_PERSON / NONE start_gesture + +THIRD_PERSON LEFT NONE turn_left +THIRD_PERSON LEFT SHIFT slide_left +THIRD_PERSON RIGHT NONE turn_right +THIRD_PERSON RIGHT SHIFT slide_right +THIRD_PERSON UP NONE push_forward +THIRD_PERSON DOWN NONE push_backward +THIRD_PERSON UP SHIFT push_forward +THIRD_PERSON DOWN SHIFT push_backward +THIRD_PERSON PGUP NONE jump +THIRD_PERSON PGDN NONE push_down +THIRD_PERSON PGUP SHIFT jump +THIRD_PERSON PGDN SHIFT toggle_down +THIRD_PERSON HOME SHIFT toggle_fly +THIRD_PERSON HOME NONE toggle_fly + +THIRD_PERSON PAD_LEFT NONE turn_left +THIRD_PERSON PAD_LEFT SHIFT slide_left +THIRD_PERSON PAD_RIGHT NONE turn_right +THIRD_PERSON PAD_RIGHT SHIFT slide_right +THIRD_PERSON PAD_UP NONE push_forward +THIRD_PERSON PAD_DOWN NONE push_backward +THIRD_PERSON PAD_UP SHIFT push_forward +THIRD_PERSON PAD_DOWN SHIFT push_backward +THIRD_PERSON PAD_PGUP NONE jump +THIRD_PERSON PAD_PGDN NONE push_down +THIRD_PERSON PAD_PGUP SHIFT jump +THIRD_PERSON PAD_PGDN SHIFT toggle_down +THIRD_PERSON PAD_HOME NONE toggle_fly +THIRD_PERSON PAD_HOME SHIFT toggle_fly +THIRD_PERSON PAD_CENTER NONE stop_moving +THIRD_PERSON PAD_CENTER SHIFT stop_moving +THIRD_PERSON PAD_ENTER NONE start_chat +THIRD_PERSON PAD_ENTER SHIFT start_chat +THIRD_PERSON PAD_DIVIDE NONE start_gesture +THIRD_PERSON PAD_DIVIDE SHIFT start_gesture + +# Camera controls in third person on Alt +THIRD_PERSON LEFT ALT spin_around_cw +THIRD_PERSON RIGHT ALT spin_around_ccw +THIRD_PERSON UP ALT move_forward +THIRD_PERSON DOWN ALT move_backward +THIRD_PERSON PGUP ALT spin_over +THIRD_PERSON PGDN ALT spin_under + +THIRD_PERSON Q ALT spin_around_cw +THIRD_PERSON D ALT spin_around_ccw +THIRD_PERSON Z ALT move_forward +THIRD_PERSON S ALT move_backward +THIRD_PERSON E ALT spin_over +THIRD_PERSON C ALT spin_under + +THIRD_PERSON PAD_LEFT ALT spin_around_cw +THIRD_PERSON PAD_RIGHT ALT spin_around_ccw +THIRD_PERSON PAD_UP ALT move_forward +THIRD_PERSON PAD_DOWN ALT move_backward +THIRD_PERSON PAD_PGUP ALT spin_over +THIRD_PERSON PAD_PGDN ALT spin_under +THIRD_PERSON PAD_ENTER ALT start_chat +THIRD_PERSON PAD_DIVIDE ALT start_gesture + +# mimic alt zoom behavior with keyboard only +THIRD_PERSON Q CTL_ALT spin_around_cw +THIRD_PERSON D CTL_ALT spin_around_ccw +THIRD_PERSON Z CTL_ALT spin_over +THIRD_PERSON S CTL_ALT spin_under +THIRD_PERSON E CTL_ALT spin_over +THIRD_PERSON C CTL_ALT spin_under + +THIRD_PERSON LEFT CTL_ALT spin_around_cw +THIRD_PERSON RIGHT CTL_ALT spin_around_ccw +THIRD_PERSON UP CTL_ALT spin_over +THIRD_PERSON DOWN CTL_ALT spin_under +THIRD_PERSON PGUP CTL_ALT spin_over +THIRD_PERSON PGDN CTL_ALT spin_under + +THIRD_PERSON PAD_LEFT CTL_ALT spin_around_cw +THIRD_PERSON PAD_RIGHT CTL_ALT spin_around_ccw +THIRD_PERSON PAD_UP CTL_ALT spin_over +THIRD_PERSON PAD_DOWN CTL_ALT spin_under +THIRD_PERSON PAD_PGUP CTL_ALT spin_over +THIRD_PERSON PAD_PGDN CTL_ALT spin_under +THIRD_PERSON PAD_ENTER CTL_ALT start_chat +THIRD_PERSON PAD_DIVIDE CTL_ALT start_gesture + +# Therefore pan on Alt-Shift +THIRD_PERSON Q CTL_ALT_SHIFT pan_left +THIRD_PERSON D CTL_ALT_SHIFT pan_right +THIRD_PERSON Z CTL_ALT_SHIFT pan_up +THIRD_PERSON S CTL_ALT_SHIFT pan_down + +THIRD_PERSON LEFT CTL_ALT_SHIFT pan_left +THIRD_PERSON RIGHT CTL_ALT_SHIFT pan_right +THIRD_PERSON UP CTL_ALT_SHIFT pan_up +THIRD_PERSON DOWN CTL_ALT_SHIFT pan_down + +THIRD_PERSON PAD_LEFT CTL_ALT_SHIFT pan_left +THIRD_PERSON PAD_RIGHT CTL_ALT_SHIFT pan_right +THIRD_PERSON PAD_UP CTL_ALT_SHIFT pan_up +THIRD_PERSON PAD_DOWN CTL_ALT_SHIFT pan_down +THIRD_PERSON PAD_ENTER CTL_ALT_SHIFT start_chat +THIRD_PERSON PAD_DIVIDE CTL_ALT_SHIFT start_gesture + +# Basic editing camera control +EDIT Q NONE spin_around_cw +EDIT D NONE spin_around_ccw +EDIT Z NONE move_forward +EDIT S NONE move_backward +EDIT E NONE spin_over +EDIT C NONE spin_under +EDIT ENTER NONE start_chat +EDIT DIVIDE NONE start_gesture +EDIT / NONE start_gesture +EDIT PAD_ENTER NONE start_chat +EDIT PAD_DIVIDE NONE start_gesture + +EDIT LEFT NONE spin_around_cw +EDIT RIGHT NONE spin_around_ccw +EDIT UP NONE move_forward +EDIT DOWN NONE move_backward +EDIT PGUP NONE spin_over +EDIT PGDN NONE spin_under + +EDIT Q SHIFT pan_left +EDIT D SHIFT pan_right +EDIT Z SHIFT pan_up +EDIT S SHIFT pan_down + +EDIT LEFT SHIFT pan_left +EDIT RIGHT SHIFT pan_right +EDIT UP SHIFT pan_up +EDIT DOWN SHIFT pan_down + +# Walking works with ALT held down. +EDIT Q ALT slide_left +EDIT D ALT slide_right +EDIT Z ALT push_forward +EDIT S ALT push_backward +EDIT E ALT jump +EDIT C ALT push_down + +EDIT LEFT ALT slide_left +EDIT RIGHT ALT slide_right +EDIT UP ALT push_forward +EDIT DOWN ALT push_backward +EDIT PGUP ALT jump +EDIT PGDN ALT push_down +EDIT HOME ALT toggle_fly + +EDIT PAD_LEFT ALT slide_left +EDIT PAD_RIGHT ALT slide_right +EDIT PAD_UP ALT push_forward +EDIT PAD_DOWN ALT push_backward +EDIT PAD_PGUP ALT jump +EDIT PAD_PGDN ALT push_down +EDIT PAD_ENTER ALT start_chat +EDIT PAD_DIVIDE ALT start_gesture + +SITTING Q ALT spin_around_cw +SITTING D ALT spin_around_ccw +SITTING Z ALT move_forward +SITTING S ALT move_backward +SITTING E ALT spin_over_sitting +SITTING C ALT spin_under_sitting + +SITTING LEFT ALT spin_around_cw +SITTING RIGHT ALT spin_around_ccw +SITTING UP ALT move_forward +SITTING DOWN ALT move_backward +SITTING PGUP ALT spin_over +SITTING PGDN ALT spin_under + +SITTING Q CTL_ALT spin_around_cw +SITTING D CTL_ALT spin_around_ccw +SITTING Z CTL_ALT spin_over +SITTING S CTL_ALT spin_under +SITTING E CTL_ALT spin_over +SITTING C CTL_ALT spin_under + +SITTING LEFT CTL_ALT spin_around_cw +SITTING RIGHT CTL_ALT spin_around_ccw +SITTING UP CTL_ALT spin_over +SITTING DOWN CTL_ALT spin_under +SITTING PGUP CTL_ALT spin_over +SITTING PGDN CTL_ALT spin_under + + +SITTING Q NONE spin_around_cw_sitting +SITTING D NONE spin_around_ccw_sitting +SITTING Z NONE move_forward_sitting +SITTING S NONE move_backward_sitting +SITTING E NONE spin_over_sitting +SITTING C NONE spin_under_sitting + +SITTING LEFT NONE spin_around_cw_sitting +SITTING RIGHT NONE spin_around_ccw_sitting +SITTING UP NONE move_forward_sitting +SITTING DOWN NONE move_backward_sitting +SITTING PGUP NONE spin_over_sitting +SITTING PGDN NONE spin_under_sitting + +SITTING PAD_LEFT NONE spin_around_cw_sitting +SITTING PAD_RIGHT NONE spin_around_ccw_sitting +SITTING PAD_UP NONE move_forward_sitting +SITTING PAD_DOWN NONE move_backward_sitting +SITTING PAD_PGUP NONE spin_over_sitting +SITTING PAD_PGDN NONE spin_under_sitting +SITTING PAD_CENTER NONE stop_moving +SITTING PAD_ENTER NONE start_chat +SITTING PAD_DIVIDE NONE start_gesture + +# these are for passing controls when sitting on vehicles +SITTING Q SHIFT slide_left +SITTING D SHIFT slide_right +SITTING LEFT SHIFT slide_left +SITTING RIGHT SHIFT slide_right + +SITTING PAD_LEFT SHIFT slide_left +SITTING PAD_RIGHT SHIFT slide_right +SITTING PAD_ENTER SHIFT start_chat +SITTING PAD_DIVIDE SHIFT start_gesture + +# pan on Alt-Shift +SITTING Q CTL_ALT_SHIFT pan_left +SITTING D CTL_ALT_SHIFT pan_right +SITTING Z CTL_ALT_SHIFT pan_up +SITTING S CTL_ALT_SHIFT pan_down + +SITTING LEFT CTL_ALT_SHIFT pan_left +SITTING RIGHT CTL_ALT_SHIFT pan_right +SITTING UP CTL_ALT_SHIFT pan_up +SITTING DOWN CTL_ALT_SHIFT pan_down + +SITTING PAD_LEFT CTL_ALT_SHIFT pan_left +SITTING PAD_RIGHT CTL_ALT_SHIFT pan_right +SITTING PAD_UP CTL_ALT_SHIFT pan_up +SITTING PAD_DOWN CTL_ALT_SHIFT pan_down +SITTING PAD_ENTER CTL_ALT_SHIFT start_chat +SITTING PAD_DIVIDE CTL_ALT_SHIFT start_gesture + +SITTING ENTER NONE start_chat +SITTING DIVIDE NONE start_gesture +SITTING / NONE start_gesture + +# Avatar editing camera controls +EDIT_AVATAR Q NONE edit_avatar_spin_cw +EDIT_AVATAR D NONE edit_avatar_spin_ccw +EDIT_AVATAR Z NONE edit_avatar_move_forward +EDIT_AVATAR S NONE edit_avatar_move_backward +EDIT_AVATAR E NONE edit_avatar_spin_over +EDIT_AVATAR C NONE edit_avatar_spin_under +EDIT_AVATAR LEFT NONE edit_avatar_spin_cw +EDIT_AVATAR RIGHT NONE edit_avatar_spin_ccw +EDIT_AVATAR UP NONE edit_avatar_move_forward +EDIT_AVATAR DOWN NONE edit_avatar_move_backward +EDIT_AVATAR PGUP NONE edit_avatar_spin_over +EDIT_AVATAR PGDN NONE edit_avatar_spin_under +EDIT_AVATAR ENTER NONE start_chat +EDIT_AVATAR DIVIDE NONE start_gesture +EDIT_AVATAR / NONE start_gesture +EDIT_AVATAR PAD_LEFT NONE edit_avatar_spin_cw +EDIT_AVATAR PAD_RIGHT NONE edit_avatar_spin_ccw +EDIT_AVATAR PAD_UP NONE edit_avatar_move_forward +EDIT_AVATAR PAD_DOWN NONE edit_avatar_move_backward +EDIT_AVATAR PAD_PGUP NONE edit_avatar_spin_over +EDIT_AVATAR PAD_PGDN NONE edit_avatar_spin_under +EDIT_AVATAR PAD_ENTER NONE start_chat +EDIT_AVATAR PAD_DIVIDE NONE start_gesture diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index f6033d87d..d880d48f3 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -489,6 +489,15 @@ PRIM_PHYSICS_SHAPE_PRIM Use the normal prim shape for physics (th PRIM_PHYSICS_SHAPE_NONE Use the convex hull of the prim shape for physics (this is the default for mesh objects) PRIM_PHYSICS_SHAPE_CONVEX Ignore this prim in the physics shape. This cannot be applied to the root prim. +PRIM_SPECULAR Used to get or set the specular map texture settings of a prim's face. +PRIM_NORMAL Used to get or set the normal map texture settings of a prim's face. + +PRIM_ALPHA_MODE Used to specify how the alpha channel of the diffuse texture should affect rendering of a prims face. +PRIM_ALPHA_MODE_NONE Render the diffuse texture as though the alpha channel were nonexistent. +PRIM_ALPHA_MODE_BLEND Render the diffuse texture with alpha-blending. +PRIM_ALPHA_MODE_MASK Render the prim face in alpha-masked mode. +PRIM_ALPHA_MODE_EMISSIVE Render the prim face in emissivity mode. + MASK_BASE Base permissions MASK_OWNER Owner permissions MASK_GROUP Group permissions @@ -554,6 +563,7 @@ REGION_FLAG_SANDBOX Used with llGetRegionFlags to find if a r REGION_FLAG_DISABLE_COLLISIONS Used with llGetRegionFlags to find if a region has disabled collisions REGION_FLAG_DISABLE_PHYSICS Used with llGetRegionFlags to find if a region has disabled physics REGION_FLAG_BLOCK_FLY Used with llGetRegionFlags to find if a region blocks flying +REGION_FLAG_BLOCK_FLYOVER Used with llGetRegionFlags to find if a region enforces higher altitude parcel access rules REGION_FLAG_ALLOW_DIRECT_TELEPORT Used with llGetRegionFlags to find if a region allows direct teleports REGION_FLAG_RESTRICT_PUSHOBJECT Used with llGetRegionFlags to find if a region restricts llPushObject() calls diff --git a/indra/newview/app_settings/lsl_functions_os.xml b/indra/newview/app_settings/lsl_functions_os.xml index f7f0ab1e8..bfda9ca09 100644 --- a/indra/newview/app_settings/lsl_functions_os.xml +++ b/indra/newview/app_settings/lsl_functions_os.xml @@ -287,6 +287,16 @@ osRegexIsMatch + osForceCreateLink + + osForceBreakLink + + osForceBreakAllLinks + + osGetRegionSize + + osGetPhysicsEngineType + osReturnObject diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 52b98e92d..64861526c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -243,6 +243,22 @@ Value 0 + FloaterAvatarRect + + Comment + Avatar picker floater position + Persist + 1 + Type + Rect + Value + + 30 + 505 + 580 + 275 + + FloaterAvatarTextRect Comment @@ -345,17 +361,6 @@ - MediaEnableFilter - - Comment - Enable media domain filtering - Persist - 1 - Type - Boolean - Value - 1 - MediaFilterRect Comment @@ -558,17 +563,6 @@ Value - ShowcaseURLDefault - - Comment - URL to load for the Showcase tab in Second Life - Persist - 1 - Type - String - Value - http://secondlife.com/app/showcase/index.php? - CheckForGridUpdates @@ -651,6 +645,17 @@ Value 0 + LiruBlockConferences + + Comment + When true, new incoming conference chats will not be opened. + Persist + 1 + Type + Boolean + Value + 0 + LiruContinueFlyingOnUnsit Comment @@ -678,6 +683,19 @@ 1.0 + LiruCustomizeAnim + + Comment + Whether or not to animate when going into appearance mode. + Persist + 1 + Type + Boolean + Value + 1 + IsCOA + 1 + LiruGridInTitle Comment @@ -724,6 +742,17 @@ Value 0 + LiruLegacyDisplayMuteds + + Comment + When off, muted people will go unrendered... + Persist + 1 + Type + Boolean + Value + 1 + LiruLegacyLandmarks Comment @@ -768,6 +797,17 @@ Value 1 + LiruLegacyScrollToEnd + + Comment + Automatically scroll to the end of a chat's history when the chat regains focus. + Persist + 1 + Type + Boolean + Value + 0 + LiruLocalTime Comment @@ -845,6 +885,17 @@ Value 1 + LiruMouselookInstantZoom + + Comment + Whether or not the right click zoom in mouselook will be instant or smoothly transition between zooms + Persist + 1 + Type + Boolean + Value + 0 + LiruMouselookMenu Comment @@ -893,6 +944,19 @@ IsCOA 1 + LiruNewMessageSoundIMsOn + + Comment + Whether or not ding defaults to being on for new IMs. + Persist + 1 + Type + Boolean + Value + 0 + IsCOA + 1 + LiruNoTransactionClutter Comment @@ -951,6 +1015,28 @@ Found in Advanced->Rendering->Info Displays Value 0 + LiruShowTransactionThreshold + + Comment + Threshold of money changes before which transaction notifications will not be shown. + Persist + 1 + Type + U32 + Value + 0 + + LiruUseAdvancedMenuShortcut + + Comment + Use ctrl-alt(-shift)-d to toggle the advanced menu. + Persist + 1 + Type + Boolean + Value + 1 + LiruUseContextMenus Comment @@ -962,6 +1048,28 @@ Found in Advanced->Rendering->Info Displays Value 0 + LiruUseZQSDKeys + + Comment + Use ZQSD layout instead of WASD. + Persist + 1 + Type + Boolean + Value + 0 + + SFMapShowRegionPositions + + Comment + Shows the X and Y coordinates above the sim name in the world map. + Persist + 1 + Type + Boolean + Value + 0 + SLBShowFPS Comment @@ -984,6 +1092,17 @@ Found in Advanced->Rendering->Info Displays Value 1 + UseRealisticMouselook + + Comment + Use a realistic first person view, this prevents your camera from being the center of everything and your avatar always beeing locked below you, it allows your Avatar to move around freely in mouselook while your camera will follow it around. Prepare your seatbelts for an awesome shaky View! May break with certain super unrealistic animations. + Persist + 1 + Type + Boolean + Value + 0 + LogShowHistoryLines Comment @@ -1222,6 +1341,17 @@ This should be as low as possible, but too low may break functionality Value 0 + RightClickTurnsAvatar + + Comment + When false, right clicking on objects that are certain angles from the direction your avatar is facing will not turn your avatar to face them. + Persist + 1 + Type + Boolean + Value + 1 + ShowDisplayNameChanges Comment @@ -3025,6 +3155,17 @@ This should be as low as possible, but too low may break functionality Value 2 + AvatarPickerURL + + Comment + Avatar picker contents + Persist + 0 + Type + String + Value + http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/avatars.html + AvatarRotateThresholdSlow Comment @@ -4100,6 +4241,28 @@ This should be as low as possible, but too low may break functionality Value 0 + ChatLoadGroupMaxMembers + + Comment + Max number of active members we'll show up for an unresponsive group + Persist + 1 + Type + S32 + Value + 100 + + ChatLoadGroupTimeout + + Comment + Time we give the server to send group participants before we hit the server for group info (seconds) + Persist + 1 + Type + F32 + Value + 10.0 + ChatOnlineNotification Comment @@ -5933,6 +6096,44 @@ This should be as low as possible, but too low may break functionality Value 89556747-24cb-43ed-920b-47caed15465f + DestinationGuideRect + + Comment + Rectangle for destination guide + Persist + 1 + Type + Rect + Value + + 30 + 505 + 580 + 275 + + + DestinationGuideShown + + Comment + Show destination guide + Persist + 1 + Type + Boolean + Value + 0 + + DestinationGuideURL + + Comment + Destination guide contents + Persist + 0 + Type + String + Value + http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/guide.html + DisableCameraConstraints Comment @@ -6417,17 +6618,6 @@ This should be as low as possible, but too low may break functionality Value 175 - EveryoneCopy - - Comment - Everyone can copy the newly created objects - Persist - 1 - Type - Boolean - Value - 0 - FPSLogFrequency Comment @@ -8410,6 +8600,17 @@ This should be as low as possible, but too low may break functionality Value 1.0 + FlycamBuildModeScale + + Comment + Scale factor to apply to flycam movements when in build mode. + Persist + 1 + Type + F32 + Value + 0.3333333 + FlycamFeathering Comment @@ -10714,39 +10915,6 @@ This should be as low as possible, but too low may break functionality Value 20 - NextOwnerCopy - - Comment - Newly created objects can be copied by next owner - Persist - 1 - Type - Boolean - Value - 0 - - NextOwnerModify - - Comment - Newly created objects can be modified by next owner - Persist - 1 - Type - Boolean - Value - 0 - - NextOwnerTransfer - - Comment - Newly created objects can be resold or given away by next owner - Persist - 1 - Type - Boolean - Value - 1 - NewCacheLocation Comment @@ -14564,17 +14732,6 @@ This should be as low as possible, but too low may break functionality Value 0 - ShareWithGroup - - Comment - Newly created objects are shared with the currently active group - Persist - 1 - Type - Boolean - Value - 0 - ShowActiveSpeakers Comment @@ -14597,6 +14754,17 @@ This should be as low as possible, but too low may break functionality Value 0 + ShowAvatarFloater + + Comment + Display avatar picker floater on login + Persist + 1 + Type + Boolean + Value + 0 + ShowAxes Comment @@ -17795,6 +17963,17 @@ This should be as low as possible, but too low may break functionality Value 0 + GenericErrorPageURL + + Comment + URL to set as a property on LLMediaControl to navigate to if the a page completes with a 400-499 HTTP status code + Persist + 1 + Type + String + Value + http://common-flash-secondlife-com.s3.amazonaws.com/viewer/v2.6/agni/404.html + WebProfileFloaterRect Comment @@ -17811,6 +17990,336 @@ This should be as low as possible, but too low may break functionality 0 + ObjectsNextOwnerCopy + + Comment + Newly created objects can be copied by next owner + Persist + 1 + Type + Boolean + Value + 0 + + ObjectsNextOwnerModify + + Comment + Newly created objects can be modified by next owner + Persist + 1 + Type + Boolean + Value + 0 + + ObjectsNextOwnerTransfer + + Comment + Newly created objects can be resold or given away by next owner + Persist + 1 + Type + Boolean + Value + 1 + + ObjectsEveryoneCopy + + Comment + Everyone can copy the newly created object + Persist + 1 + Type + Boolean + Value + 0 + + ObjectsShareWithGroup + + Comment + Newly created objects are shared with the currently active group + Persist + 1 + Type + Boolean + Value + 0 + + UploadsNextOwnerCopy + + Comment + Newly uploaded items can be copied by next owner + Persist + 1 + Type + Boolean + Value + 0 + + UploadsNextOwnerModify + + Comment + Newly uploaded items can be modified by next owner + Persist + 1 + Type + Boolean + Value + 0 + + UploadsNextOwnerTransfer + + Comment + Newly uploaded items can be resold or given away by next owner + Persist + 1 + Type + Boolean + Value + 1 + + UploadsEveryoneCopy + + Comment + Everyone can copy the newly uploaded item + Persist + 1 + Type + Boolean + Value + 0 + + UploadsShareWithGroup + + Comment + Newly uploaded items are shared with the currently active group + Persist + 1 + Type + Boolean + Value + 0 + + ScriptsNextOwnerCopy + + Comment + Newly created scripts can be copied by next owner + Persist + 1 + Type + Boolean + Value + 0 + + ScriptsNextOwnerModify + + Comment + Newly created scripts can be modified by next owner + Persist + 1 + Type + Boolean + Value + 0 + + ScriptsNextOwnerTransfer + + Comment + Newly created scripts can be resold or given away by next owner + Persist + 1 + Type + Boolean + Value + 1 + + ScriptsEveryoneCopy + + Comment + Everyone can copy the newly created script + Persist + 1 + Type + Boolean + Value + 0 + + ScriptsShareWithGroup + + Comment + Newly created scripts are shared with the currently active group + Persist + 1 + Type + Boolean + Value + 0 + + NotecardsNextOwnerCopy + + Comment + Newly created notecards can be copied by next owner + Persist + 1 + Type + Boolean + Value + 1 + + NotecardsNextOwnerModify + + Comment + Newly created notecards can be modified by next owner + Persist + 1 + Type + Boolean + Value + 1 + + NotecardsNextOwnerTransfer + + Comment + Newly created notecards can be resold or given away by next owner + Persist + 1 + Type + Boolean + Value + 1 + + NotecardsEveryoneCopy + + Comment + Everyone can copy the newly created notecard + Persist + 1 + Type + Boolean + Value + 0 + + NotecardsShareWithGroup + + Comment + Newly created scripts are shared with the currently active group + Persist + 1 + Type + Boolean + Value + 0 + + GesturesNextOwnerCopy + + Comment + Newly created gestures can be copied by next owner + Persist + 1 + Type + Boolean + Value + 1 + + GesturesNextOwnerModify + + Comment + Newly created gestures can be modified by next owner + Persist + 1 + Type + Boolean + Value + 1 + + GesturesNextOwnerTransfer + + Comment + Newly created gestures can be resold or given away by next owner + Persist + 1 + Type + Boolean + Value + 1 + + GesturesEveryoneCopy + + Comment + Everyone can copy the newly created gesture + Persist + 1 + Type + Boolean + Value + 0 + + GesturesShareWithGroup + + Comment + Newly created gestures are shared with the currently active group + Persist + 1 + Type + Boolean + Value + 0 + + WearablesNextOwnerCopy + + Comment + Newly created clothing or body part can be copied by next owner + Persist + 1 + Type + Boolean + Value + 0 + + WearablesNextOwnerModify + + Comment + Newly created clothing or body part can be modified by next owner + Persist + 1 + Type + Boolean + Value + 0 + + WearablesNextOwnerTransfer + + Comment + Newly created clothing or body part can be resold or given away by next owner + Persist + 1 + Type + Boolean + Value + 1 + + WearablesEveryoneCopy + + Comment + Everyone can copy the newly created clothing or body part + Persist + 1 + Type + Boolean + Value + 0 + + WearablesShareWithGroup + + Comment + Newly created clothing or body part is shared with the currently active group + Persist + 1 + Type + Boolean + Value + 0 + SimulateFBOFailure Comment @@ -18083,6 +18592,73 @@ This should be as low as possible, but too low may break functionality Value 0 + + EveryoneCopy + + Comment + (obsolete) Everyone can copy the newly created objects + Persist + 1 + Type + Boolean + Value + 0 + + NextOwnerCopy + + Comment + (obsolete) Newly created objects can be copied by next owner + Persist + 1 + Type + Boolean + Value + 0 + + NextOwnerModify + + Comment + (obsolete) Newly created objects can be modified by next owner + Persist + 1 + Type + Boolean + Value + 0 + + NextOwnerTransfer + + Comment + (obsolete) Newly created objects can be resold or given away by next owner + Persist + 1 + Type + Boolean + Value + 1 + + ShareWithGroup + + Comment + (obsolete) Newly created objects are shared with the currently active group + Persist + 1 + Type + Boolean + Value + 0 + + MediaFilterEnable + + Comment + Enable media domain filtering (0 = Off, 1 = Blacklist only, 2 = Prompt) + Persist + 1 + Type + U32 + Value + 2 + diff --git a/indra/newview/app_settings/settings_ascent.xml b/indra/newview/app_settings/settings_ascent.xml index 8288edc6b..8be48da2d 100644 --- a/indra/newview/app_settings/settings_ascent.xml +++ b/indra/newview/app_settings/settings_ascent.xml @@ -58,6 +58,17 @@ Value 1 + LookAtNameSystem + + Comment + For name on lookat crosshairs. 0 = Old Style, 1 = Display Names and Username, 2 = Displayname only, 3 = Old Style (Display Name), less than 0 for off + Persist + 1 + Type + S32 + Value + 0 + PhoenixNameSystem Comment @@ -91,6 +102,28 @@ Value 1 + AlchemyConnectToNeighbors + + Comment + If false, disconnect from neighboring regions and all further neighbors on teleport + Persist + 1 + Type + Boolean + Value + 1 + + AlchemyLookAtLines + + Comment + Render a line from Look At beacon to the originating avatar + Persist + 1 + Type + Boolean + Value + 0 + AlchemyRegionRestartShake Comment @@ -664,6 +697,17 @@ Value /away + SinguCmdLineRegionSay + + Comment + Command prefix for chat to say to entire region, if allowed(EM). + Persist + 1 + Type + String + Value + /regionsay + SinguCmdLineURL Comment @@ -975,6 +1019,17 @@ Value 0 + ToolbarVisibleAvatar + + Comment + Whether or not the button for default avatars is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + ToolbarVisibleBeacons Comment @@ -1129,6 +1184,17 @@ Value 0 + ToolbarVisibleDestinations + + Comment + Whether or not the button for destinations is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + ToolbarVisibleDisplayName Comment @@ -1351,6 +1417,17 @@ Value 0 + ToolbarVisibleJoystick + + Comment + Whether or not the button for joystick configuration is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + ToolbarVisibleLagMeter Comment diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 295b4180d..d5c721237 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -463,7 +463,40 @@ + DefaultUploadPermissionsConverted + + Comment + Default upload permissions have been converted to default creation permissions + Persist + 1 + Type + Boolean + Value + 0 + EveryoneExport + + Comment + (obsolete) Whether content you upload has exportability permission by default + Persist + 1 + Type + Boolean + Value + 0 + + ObjectsEveryoneExport + + Comment + Whether objects you create have exportability permission by default + Persist + 1 + Type + Boolean + Value + 0 + + UploadsEveryoneExport Comment Whether content you upload has exportability permission by default @@ -474,6 +507,50 @@ Value 0 + ScriptsEveryoneExport + + Comment + Whether scripts you make have exportability permission by default + Persist + 1 + Type + Boolean + Value + 0 + + NotecardsEveryoneExport + + Comment + Whether notecards you make have exportability permission by default + Persist + 1 + Type + Boolean + Value + 0 + + GesturesEveryoneExport + + Comment + Whether gestures you make have exportability permission by default + Persist + 1 + Type + Boolean + Value + 0 + + WearablesEveryoneExport + + Comment + Whether wearables you make have exportability permission by default + Persist + 1 + Type + Boolean + Value + 0 + RLVaLoginLastLocation Comment @@ -745,5 +822,16 @@ Value + EmergencyTeleportLandmarkBackup + + Comment + UUID of the landmark to teleport to in the last twenty seconds before a region will restart if you're already in the region of EmergencyTeleportLandmark or if EmergencyTeleportLandmark is set but canot be found, empty is none. + Persist + 1 + Type + String + Value + + diff --git a/indra/newview/app_settings/settings_rlv.xml b/indra/newview/app_settings/settings_rlv.xml index c0bd30a1a..5e645f404 100644 --- a/indra/newview/app_settings/settings_rlv.xml +++ b/indra/newview/app_settings/settings_rlv.xml @@ -90,6 +90,17 @@ Value + + RLVaDebugDeprecateExplicitPoint + + Comment + Ignore attachment point names on inventory items and categories (incomplete) + Persist + 1 + Type + Boolean + Value + 0 + RLVaDebugHideUnsetDuplicate Comment diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 6acbf0aaf..2bd85f88b 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -22,6 +22,8 @@ * $/LicenseInfo$ */ +#define FLT_MAX 3.402823466e+38 + ATTRIBUTE vec4 weight4; uniform mat3x4 matrixPalette[52]; @@ -29,6 +31,9 @@ uniform float maxWeight; mat4 getObjectSkinnedTransform() { + + + int i; vec4 w = fract(weight4); @@ -38,6 +43,10 @@ mat4 getObjectSkinnedTransform() index = max(index, vec4( 0.0)); float sum = (w.x+w.y+w.z+w.w); + if(sum > 0.0) + w*=1.0/sum; + else + w=vec4(FLT_MAX); int i1 = int(index.x); int i2 = int(index.y); @@ -59,7 +68,7 @@ mat4 getObjectSkinnedTransform() ret[0] = vec4(mat[0], 0); ret[1] = vec4(mat[1], 0); ret[2] = vec4(mat[2], 0); - ret[3] = vec4(trans, sum); + ret[3] = vec4(trans, 1.0); return ret; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 4f4d2cd6b..b0be02f0d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -198,5 +198,5 @@ void main() frag_data[0] = vec4(color.rgb, color.a); // diffuse frag_data[1] = vec4(0); // speccolor, spec - frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0 + frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.05, 0);// normalxy, 0, 0 } diff --git a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl index cdb228157..bde9a4537 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl @@ -26,7 +26,7 @@ uniform mat4 modelview_projection_matrix; ATTRIBUTE vec3 position; -ATTRIBUTE vec2 texcoord0; +ATTRIBUTE vec2 texcoord1; uniform vec2 glowDelta; @@ -39,12 +39,12 @@ void main() { gl_Position = modelview_projection_matrix * vec4(position, 1.0); - vary_texcoord0.xy = texcoord0 + glowDelta*(-3.5); - vary_texcoord1.xy = texcoord0 + glowDelta*(-2.5); - vary_texcoord2.xy = texcoord0 + glowDelta*(-1.5); - vary_texcoord3.xy = texcoord0 + glowDelta*(-0.5); - vary_texcoord0.zw = texcoord0 + glowDelta*(0.5); - vary_texcoord1.zw = texcoord0 + glowDelta*(1.5); - vary_texcoord2.zw = texcoord0 + glowDelta*(2.5); - vary_texcoord3.zw = texcoord0 + glowDelta*(3.5); + vary_texcoord0.xy = texcoord1 + glowDelta*(-3.5); + vary_texcoord1.xy = texcoord1 + glowDelta*(-2.5); + vary_texcoord2.xy = texcoord1 + glowDelta*(-1.5); + vary_texcoord3.xy = texcoord1 + glowDelta*(-0.5); + vary_texcoord0.zw = texcoord1 + glowDelta*(0.5); + vary_texcoord1.zw = texcoord1 + glowDelta*(1.5); + vary_texcoord2.zw = texcoord1 + glowDelta*(2.5); + vary_texcoord3.zw = texcoord1 + glowDelta*(3.5); } diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl index 891b971f1..f76a90158 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl @@ -39,6 +39,6 @@ VARYING vec2 vary_texcoord1; void main() { - frag_color = texture2D(glowMap, vary_texcoord0.xy) + - texture2DRect(screenMap, vary_texcoord1.xy); + frag_color = texture2D(glowMap, vary_texcoord1.xy) + + texture2DRect(screenMap, vary_texcoord0.xy); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl index 3586652cb..248bff55f 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl @@ -39,10 +39,10 @@ void default_lighting_water() { vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; - if(color.a < .004) + /*if(color.a < .004) { discard; - } + }*/ color.rgb = atmosLighting(color.rgb); diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index dc8f0bc9b..3f50e53b6 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -262,6 +262,7 @@ void LLPrefsAscentChat::refreshValues() mOneLineGroupButt = gSavedSettings.getBOOL("UseConciseGroupChatButtons"); mOneLineConfButt = gSavedSettings.getBOOL("UseConciseConferenceButtons"); mOnlyComm = gSavedSettings.getBOOL("CommunicateSpecificShortcut"); + mLegacyEndScroll = gSavedSettings.getBOOL("LiruLegacyScrollToEnd"); mItalicizeActions = gSavedSettings.getBOOL("LiruItalicizeActions"); mLegacyLogLaunch = gSavedSettings.getBOOL("LiruLegacyLogLaunch"); mFriendNames = gSavedSettings.getS32("FriendNameSystem"); @@ -497,6 +498,7 @@ void LLPrefsAscentChat::cancel() gSavedSettings.setBOOL("UseConciseGroupChatButtons", mOneLineGroupButt); gSavedSettings.setBOOL("UseConciseConferenceButtons", mOneLineConfButt); gSavedSettings.setBOOL("CommunicateSpecificShortcut", mOnlyComm); + gSavedSettings.setBOOL("LiruLegacyScrollToEnd", mLegacyEndScroll); gSavedSettings.setBOOL("LiruItalicizeActions", mItalicizeActions); gSavedSettings.setBOOL("LiruLegacyLogLaunch", mLegacyLogLaunch); gSavedSettings.setS32("FriendNameSystem", mFriendNames); diff --git a/indra/newview/ascentprefschat.h b/indra/newview/ascentprefschat.h index bc45d71d7..c04a2d297 100644 --- a/indra/newview/ascentprefschat.h +++ b/indra/newview/ascentprefschat.h @@ -84,6 +84,7 @@ private: bool mOneLineGroupButt; bool mOneLineConfButt; bool mOnlyComm; + bool mLegacyEndScroll; bool mItalicizeActions; bool mLegacyLogLaunch; S32 mFriendNames; diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index 6ae4a634a..2170d0824 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -71,6 +71,7 @@ LLPrefsAscentSys::LLPrefsAscentSys() getChild("AscentCmdLineMapTo")->setCommitCallback(lineEditorControl); getChild("AscentCmdLineTP2")->setCommitCallback(lineEditorControl); getChild("SinguCmdLineAway")->setCommitCallback(lineEditorControl); + getChild("SinguCmdLineRegionSay")->setCommitCallback(lineEditorControl); getChild("SinguCmdLineURL")->setCommitCallback(lineEditorControl); //Security ---------------------------------------------------------------------------- @@ -78,7 +79,7 @@ LLPrefsAscentSys::LLPrefsAscentSys() //Build ------------------------------------------------------------------------------- getChild("next_owner_copy")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); - childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("NextOwnerCopy")); + getChild("script_next_owner_copy")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); getChild("material")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitComboBox, this, _1, _2)); getChild("combobox shininess")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitComboBox, this, _1, _2)); getChild("texture control")->setDefaultImageAssetID(LLUUID(gSavedSettings.getString("EmeraldBuildPrefs_Texture"))); @@ -120,8 +121,11 @@ void LLPrefsAscentSys::onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value) } else if (name == "next_owner_copy") { - if (!enabled) gSavedSettings.setBOOL("NextOwnerTransfer", true); - childSetEnabled("next_owner_transfer", enabled); + if (!enabled) gSavedSettings.setBOOL("ObjectsNextOwnerTransfer", true); + } + else if (name == "script_next_owner_copy") + { + if (!enabled) gSavedSettings.setBOOL("ScriptsNextOwnerTransfer", true); } } @@ -180,6 +184,7 @@ void LLPrefsAscentSys::refreshValues() mCmdMapToKeepPos = gSavedSettings.getBOOL("AscentMapToKeepPos"); mCmdLineTP2 = gSavedSettings.getString("AscentCmdLineTP2"); mCmdLineAway = gSavedSettings.getString("SinguCmdLineAway"); + mCmdLineRegionSay = gSavedSettings.getString("SinguCmdLineRegionSay"); mCmdLineURL = gSavedSettings.getString("SinguCmdLineURL"); //Security ---------------------------------------------------------------------------- @@ -187,6 +192,8 @@ void LLPrefsAscentSys::refreshValues() mDisablePointAtAndBeam = gSavedSettings.getBOOL("DisablePointAtAndBeam"); mPrivateLookAt = gSavedSettings.getBOOL("PrivateLookAt"); mShowLookAt = gSavedSettings.getBOOL("AscentShowLookAt"); + mLookAtNames = gSavedSettings.getS32("LookAtNameSystem"); + mLookAtLines = gSavedSettings.getBOOL("AlchemyLookAtLines"); mQuietSnapshotsToDisk = gSavedSettings.getBOOL("QuietSnapshotsToDisk"); mAnnounceBumps = gSavedSettings.getBOOL("AnnounceBumps"); mDetachBridge = gSavedSettings.getBOOL("SGDetachBridge"); @@ -198,6 +205,7 @@ void LLPrefsAscentSys::refreshValues() mRestartMinimized = gSavedSettings.getBOOL("LiruRegionRestartMinimized"); mRestartSound = gSavedSettings.getString("UISndRestart"); mLandmark = gSavedPerAccountSettings.getString("EmergencyTeleportLandmark"); + mLandmarkBackup = gSavedPerAccountSettings.getString("EmergencyTeleportLandmarkBackup"); //Build ------------------------------------------------------------------------------- mAlpha = gSavedSettings.getF32("EmeraldBuildPrefs_Alpha"); @@ -206,9 +214,12 @@ void LLPrefsAscentSys::refreshValues() mGlow = gSavedSettings.getF32("EmeraldBuildPrefs_Glow"); mItem = gSavedPerAccountSettings.getString("EmeraldBuildPrefs_Item"); mMaterial = gSavedSettings.getString("BuildPrefs_Material"); - mNextCopy = gSavedSettings.getBOOL("NextOwnerCopy"); - mNextMod = gSavedSettings.getBOOL("NextOwnerModify"); - mNextTrans = gSavedSettings.getBOOL("NextOwnerTransfer"); + mNextCopy = gSavedSettings.getBOOL("ObjectsNextOwnerCopy"); + mNextMod = gSavedSettings.getBOOL("ObjectsNextOwnerModify"); + mNextTrans = gSavedSettings.getBOOL("ObjectsNextOwnerTransfer"); + mScriptNextCopy = gSavedSettings.getBOOL("ScriptsNextOwnerCopy"); + mScriptNextMod = gSavedSettings.getBOOL("ScriptsNextOwnerModify"); + mScriptNextTrans = gSavedSettings.getBOOL("ScriptsNextOwnerTransfer"); mShiny = gSavedSettings.getString("EmeraldBuildPrefs_Shiny"); mTemporary = gSavedSettings.getBOOL("EmeraldBuildPrefs_Temporary"); mTexture = gSavedSettings.getString("EmeraldBuildPrefs_Texture"); @@ -229,7 +240,7 @@ void LLPrefsAscentSys::refresh() ctrl->setValue(mPowerUser); } - //Security ---------------------------------------------------------------------------- + //Command Line ---------------------------------------------------------------------------- childSetValue("AscentCmdLinePos", mCmdLinePos); childSetValue("AscentCmdLineGround", mCmdLineGround); childSetValue("AscentCmdLineHeight", mCmdLineHeight); @@ -244,11 +255,15 @@ void LLPrefsAscentSys::refresh() childSetValue("AscentCmdLineMapTo", mCmdLineMapTo); childSetValue("AscentCmdLineTP2", mCmdLineTP2); childSetValue("SinguCmdLineAway", mCmdLineAway); + childSetValue("SinguCmdLineRegionSay", mCmdLineRegionSay); childSetValue("SinguCmdLineURL", mCmdLineURL); //Security ---------------------------------------------------------------------------- getChildView("UISndRestart")->setValue(mRestartSound); + if (LLComboBox* combo = getChild("lookat_namesystem_combobox")) + combo->setValue(mLookAtNames); + //Build ------------------------------------------------------------------------------- childSetValue("alpha", mAlpha); getChild("colorswatch")->setOriginal(mColor); @@ -311,6 +326,7 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("AscentMapToKeepPos", mCmdMapToKeepPos); gSavedSettings.setString("AscentCmdLineTP2", mCmdLineTP2); gSavedSettings.setString("SinguCmdLineAway", mCmdLineAway); + gSavedSettings.setString("SinguCmdLineRegionSay", mCmdLineRegionSay); gSavedSettings.setString("SinguCmdLineURL", mCmdLineURL); //Security ---------------------------------------------------------------------------- @@ -318,6 +334,8 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("DisablePointAtAndBeam", mDisablePointAtAndBeam); gSavedSettings.setBOOL("PrivateLookAt", mPrivateLookAt); gSavedSettings.setBOOL("AscentShowLookAt", mShowLookAt); + gSavedSettings.setS32("LookAtNameSystem", mLookAtNames); + gSavedSettings.setBOOL("AlchemyLookAtLines", mLookAtLines); gSavedSettings.setBOOL("QuietSnapshotsToDisk", mQuietSnapshotsToDisk); gSavedSettings.setBOOL("AnnounceBumps", mAnnounceBumps); gSavedSettings.setBOOL("SGDetachBridge", mDetachBridge); @@ -329,6 +347,7 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("LiruRegionRestartMinimized", mRestartMinimized); gSavedSettings.setString("UISndRestart", mRestartSound); gSavedPerAccountSettings.setString("EmergencyTeleportLandmark", mLandmark); + gSavedPerAccountSettings.setString("EmergencyTeleportLandmarkBackup", mLandmarkBackup); //Build ------------------------------------------------------------------------------- gSavedSettings.setF32("EmeraldBuildPrefs_Alpha", mAlpha); @@ -337,9 +356,12 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setF32("EmeraldBuildPrefs_Glow", mGlow); gSavedPerAccountSettings.setString("EmeraldBuildPrefs_Item", mItem); gSavedSettings.setString("BuildPrefs_Material", mMaterial); - gSavedSettings.setBOOL("NextOwnerCopy", mNextCopy); - gSavedSettings.setBOOL("NextOwnerModify", mNextMod); - gSavedSettings.setBOOL("NextOwnerTransfer", mNextTrans); + gSavedSettings.setBOOL("ObjectsNextOwnerCopy", mNextCopy); + gSavedSettings.setBOOL("ObjectsNextOwnerModify", mNextMod); + gSavedSettings.setBOOL("ObjectsNextOwnerTransfer", mNextTrans); + gSavedSettings.setBOOL("ScriptsNextOwnerCopy", mScriptNextCopy); + gSavedSettings.setBOOL("ScriptsNextOwnerModify", mScriptNextMod); + gSavedSettings.setBOOL("ScriptsNextOwnerTransfer", mScriptNextTrans); gSavedSettings.setBOOL("EmeraldBuildPrefs_Phantom", mPhantom); gSavedSettings.setBOOL("EmeraldBuildPrefs_Physical", mPhysical); gSavedSettings.setString("EmeraldBuildPrefs_Shiny", mShiny); diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h index 8a8bed9e3..50fbdae30 100644 --- a/indra/newview/ascentprefssys.h +++ b/indra/newview/ascentprefssys.h @@ -94,6 +94,7 @@ private: bool mCmdMapToKeepPos; std::string mCmdLineTP2; std::string mCmdLineAway; + std::string mCmdLineRegionSay; std::string mCmdLineURL; //Security ---------------------------------------------------------------------------- @@ -101,6 +102,8 @@ private: bool mDisablePointAtAndBeam; bool mPrivateLookAt; bool mShowLookAt; + S32 mLookAtNames; + bool mLookAtLines; bool mQuietSnapshotsToDisk; bool mAnnounceBumps; bool mDetachBridge; @@ -112,6 +115,7 @@ private: F32 mNumScriptDiff; std::string mRestartSound; std::string mLandmark; + std::string mLandmarkBackup; //Build ------------------------------------------------------------------------------- F32 mAlpha; @@ -123,6 +127,9 @@ private: bool mNextCopy; bool mNextMod; bool mNextTrans; + bool mScriptNextCopy; + bool mScriptNextMod; + bool mScriptNextTrans; std::string mShiny; bool mTemporary; std::string mTexture; diff --git a/indra/newview/ascentprefsvan.cpp b/indra/newview/ascentprefsvan.cpp index b746c0747..6a51b580f 100644 --- a/indra/newview/ascentprefsvan.cpp +++ b/indra/newview/ascentprefsvan.cpp @@ -123,11 +123,13 @@ void LLPrefsAscentVan::refreshValues() mDisableChatAnimation = gSavedSettings.getBOOL("SGDisableChatAnimation"); mAddNotReplace = gSavedSettings.getBOOL("LiruAddNotReplace"); mTurnAround = gSavedSettings.getBOOL("TurnAroundWhenWalkingBackwards"); + mCustomizeAnim = gSavedSettings.getBOOL("LiruCustomizeAnim"); mAnnounceSnapshots = gSavedSettings.getBOOL("AnnounceSnapshots"); mAnnounceStreamMetadata = gSavedSettings.getBOOL("AnnounceStreamMetadata"); mUnfocusedFloatersOpaque = gSavedSettings.getBOOL("FloaterUnfocusedBackgroundOpaque"); mCompleteNameProfiles = gSavedSettings.getBOOL("SinguCompleteNameProfiles"); mScriptErrorsStealFocus = gSavedSettings.getBOOL("LiruScriptErrorsStealFocus"); + mConnectToNeighbors = gSavedSettings.getBOOL("AlchemyConnectToNeighbors"); //Tags\Colors ---------------------------------------------------------------------------- mAscentBroadcastTag = gSavedSettings.getBOOL("AscentBroadcastTag"); @@ -173,10 +175,6 @@ void LLPrefsAscentVan::refresh() combo->setCurrentByIndex(mSelectedClient); childSetEnabled("friends_color_textbox", mUseStatusColors); - childSetEnabled("friend_color_swatch", mUseStatusColors || mColorFriendChat); - childSetEnabled("estate_owner_color_swatch", mUseStatusColors || mColorEOChat); - childSetEnabled("linden_color_swatch", mUseStatusColors || mColorLindenChat); - childSetEnabled("muted_color_swatch", mUseStatusColors || mColorMutedChat); childSetEnabled("custom_tag_label_text", mCustomTagOn); childSetEnabled("custom_tag_label_box", mCustomTagOn); @@ -196,11 +194,13 @@ void LLPrefsAscentVan::cancel() gSavedSettings.setBOOL("SGDisableChatAnimation", mDisableChatAnimation); gSavedSettings.setBOOL("LiruAddNotReplace", mAddNotReplace); gSavedSettings.setBOOL("TurnAroundWhenWalkingBackwards", mTurnAround); + gSavedSettings.setBOOL("LiruCustomizeAnim", mCustomizeAnim); gSavedSettings.setBOOL("AnnounceSnapshots", mAnnounceSnapshots); gSavedSettings.setBOOL("AnnounceStreamMetadata", mAnnounceStreamMetadata); gSavedSettings.setBOOL("FloaterUnfocusedBackgroundOpaque", mUnfocusedFloatersOpaque); gSavedSettings.setBOOL("SinguCompleteNameProfiles", mCompleteNameProfiles); gSavedSettings.setBOOL("LiruScriptErrorsStealFocus", mScriptErrorsStealFocus); + gSavedSettings.setBOOL("AlchemyConnectToNeighbors", mConnectToNeighbors); //Tags\Colors ---------------------------------------------------------------------------- gSavedSettings.setBOOL("AscentBroadcastTag", mAscentBroadcastTag); diff --git a/indra/newview/ascentprefsvan.h b/indra/newview/ascentprefsvan.h index 9d5100559..b45adf652 100644 --- a/indra/newview/ascentprefsvan.h +++ b/indra/newview/ascentprefsvan.h @@ -59,11 +59,13 @@ private: bool mDisableChatAnimation; bool mAddNotReplace; bool mTurnAround; + bool mCustomizeAnim; bool mAnnounceSnapshots; bool mAnnounceStreamMetadata; bool mUnfocusedFloatersOpaque; bool mCompleteNameProfiles; bool mScriptErrorsStealFocus; + bool mConnectToNeighbors; //Tags\Colors bool mAscentBroadcastTag; std::string mReportClientUUID; diff --git a/indra/newview/awavefront.h b/indra/newview/awavefront.h index 3f58ee4a0..09f0dc3b9 100644 --- a/indra/newview/awavefront.h +++ b/indra/newview/awavefront.h @@ -28,6 +28,9 @@ class LLFace; class LLPolyMesh; class LLViewerObject; class LLVOAvatar; +class LLVolume; +class LLVolumeFace; +class LLXform; typedef std::vector > vert_t; typedef std::vector vec3_t; diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index f33d06be1..d0bbd1830 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -3563,7 +3563,7 @@ + pos="0.07 0 -0.07"/> diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index 4b8bd598b..ddbfca284 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -33,40 +33,36 @@ #include "chatbar_as_cmdline.h" +#include "llavatarnamecache.h" #include "llcalc.h" #include "llchatbar.h" #include "llagent.h" #include "llagentcamera.h" -#include "stdtypes.h" +#include "llagentui.h" +#include "llavataractions.h" #include "llviewerregion.h" #include "llworld.h" -#include "lluuid.h" #include "lleventtimer.h" -#include "llviewercontrol.h" -#include "material_codes.h" #include "llvolume.h" -#include "object_flags.h" #include "llvolumemessage.h" #include "llurldispatcher.h" #include "llworld.h" #include "llworldmap.h" #include "llfloateravatarlist.h" +#include "llfloaterregioninfo.h" #include "llviewerobjectlist.h" #include "llviewertexteditor.h" #include "llviewermenu.h" #include "llvoavatar.h" #include "lltooldraganddrop.h" #include "llinventorymodel.h" +#include "llregioninfomodel.h" #include "llselectmgr.h" #include "llslurl.h" #include "llurlaction.h" -#include - -#include - #include "llchat.h" #include "llfloaterchat.h" @@ -221,6 +217,12 @@ struct ProfCtrlListAccum : public LLControlGroup::ApplyFunctor std::vector > mVariableList; }; #endif //PROF_CTRL_CALLS +void spew_key_to_name(const LLUUID& targetKey, const LLAvatarName& av_name) +{ + std::string object_name; + LLAvatarNameCache::getPNSName(av_name, object_name); + cmdline_printchat(llformat("%s: %s", targetKey.asString().c_str(), object_name.c_str())); +} bool cmd_line_chat(std::string revised_text, EChatType type) { static LLCachedControl sAscentCmdLine(gSavedSettings, "AscentCmdLine"); @@ -239,6 +241,7 @@ bool cmd_line_chat(std::string revised_text, EChatType type) static LLCachedControl sAscentCmdLineTP2(gSavedSettings, "AscentCmdLineTP2"); static LLCachedControl sAscentCmdLineClearChat(gSavedSettings, "AscentCmdLineClearChat"); static LLCachedControl sSinguCmdLineAway(gSavedSettings, "SinguCmdLineAway"); + static LLCachedControl sSinguCmdLineRegionSay(gSavedSettings, "SinguCmdLineRegionSay"); static LLCachedControl sSinguCmdLineURL(gSavedSettings, "SinguCmdLineURL"); if(sAscentCmdLine) @@ -256,17 +259,16 @@ bool cmd_line_chat(std::string revised_text, EChatType type) { if (i >> y) { - if (i >> z) + if (!(i >> z)) + z = gAgent.getPositionAgent().mV[VZ]; + + if (LLViewerRegion* agentRegionp = gAgent.getRegion()) { - LLViewerRegion* agentRegionp = gAgent.getRegion(); - if(agentRegionp) - { - LLVector3 targetPos(x,y,z); - LLVector3d pos_global = from_region_handle(agentRegionp->getHandle()); - pos_global += LLVector3d((F64)targetPos.mV[0],(F64)targetPos.mV[1],(F64)targetPos.mV[2]); - gAgent.teleportViaLocation(pos_global); - return false; - } + LLVector3 targetPos(x,y,z); + LLVector3d pos_global = from_region_handle(agentRegionp->getHandle()); + pos_global += LLVector3d((F64)targetPos.mV[0],(F64)targetPos.mV[1],(F64)targetPos.mV[2]); + gAgent.teleportViaLocation(pos_global); + return false; } } } @@ -294,11 +296,13 @@ bool cmd_line_chat(std::string revised_text, EChatType type) LLUUID targetKey; if(i >> targetKey) { - std::string object_name; - gCacheName->getFullName(targetKey, object_name); - char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ - snprintf(buffer,sizeof(buffer),"%s: (%s)",targetKey.asString().c_str(), object_name.c_str()); - cmdline_printchat(std::string(buffer)); + LLAvatarName av_name; + if (!LLAvatarNameCache::get(targetKey, &av_name)) + { + LLAvatarNameCache::get(targetKey, boost::bind(spew_key_to_name, _1, _2)); + return false; + } + spew_key_to_name(targetKey, av_name); } return false; } @@ -433,7 +437,31 @@ bool cmd_line_chat(std::string revised_text, EChatType type) { if (revised_text.length() > command.length() + 1) { - LLUrlAction::clickAction(revised_text.substr(command.length()+1)); + const std::string sub(revised_text.substr(command.length()+1)); + LLUUID id; + if (id.parseUUID(sub, &id)) + { + LLAvatarActions::showProfile(id); + return false; + } + LLUrlAction::clickAction(sub); + } + return false; + } + else if(command == utf8str_tolower(sSinguCmdLineRegionSay)) + { + if (revised_text.length() > command.length() + 1) + { + std::vector strings(5, "-1"); + // [0] grid_x, unused here + // [1] grid_y, unused here + strings[2] = gAgentID.asString(); // [2] agent_id of sender + // [3] sender name + std::string name; + LLAgentUI::buildFullname(name); + strings[3] = name; + strings[4] = revised_text.substr(command.length()+1); // [4] message + LLRegionInfoModel::sendEstateOwnerMessage(gMessageSystem, "simulatormessage", LLFloaterRegionInfo::getLastInvoice(), strings); } return false; } diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 96384d700..c097b42fd 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -57,7 +57,7 @@ WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 -RenderTextureMemoryMultiple 1 0.5 +RenderTextureMemoryMultiple 1 1.0 RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 @@ -395,7 +395,7 @@ list ATI_Mobility_Radeon_9600 Disregard96DefaultDrawDistance 1 0 list NVIDIA_GeForce_8600 -RenderTextureMemoryMultiple 1 0.375 +RenderTextureMemoryMultiple 1 1 RenderUseImpostors 0 0 UseOcclusion 0 0 diff --git a/indra/newview/floatervoicelicense.cpp b/indra/newview/floatervoicelicense.cpp index 288704d83..cfb66a569 100644 --- a/indra/newview/floatervoicelicense.cpp +++ b/indra/newview/floatervoicelicense.cpp @@ -84,20 +84,20 @@ class LLIamHereVoice : public LLHTTPClient::ResponderWithResult mParent = parentIn; }; - /*virtual*/ void result( const LLSD& content ) + /*virtual*/ void httpSuccess(void) { if ( mParent ) mParent->setSiteIsAlive( true ); }; - /*virtual*/ void error( U32 status, const std::string& reason ) + /*virtual*/ void httpFailure(void) { if ( mParent ) { // *HACK: For purposes of this alive check, 302 Found // (aka Moved Temporarily) is considered alive. The web site // redirects this link to a "cache busting" temporary URL. JC - bool alive = (status == HTTP_FOUND); + bool alive = (mStatus == HTTP_FOUND); mParent->setSiteIsAlive( alive ); } }; diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index af1a861ca..27082628b 100644 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -304,6 +304,10 @@ Intel HD Graphics 3000 .*Intel.*HD Graphics 3000.* 2 1 Intel HD Graphics 3000 .*Intel.*Sandybridge.* 2 1 Intel HD Graphics 4000 .*Intel.*HD Graphics 4000.* 2 1 Intel HD Graphics 4000 .*Intel.*Ivybridge.* 2 1 +Intel Intel Iris Pro Graphics 5200 .*Intel.*Iris Pro Graphics 52.* 2 1 +Intel Intel Iris Graphics 5100 .*Intel.*Iris Graphics 51.* 2 1 +Intel Intel Iris OpenGL Engine .*Intel.*Iris OpenGL.* 2 1 +Intel Intel Iris Pro OpenGL Engine .*Intel.*Iris Pro OpenGL.* 3 1 Intel HD Graphics 5000 .*Intel.*HD Graphics 5.* 2 1 Intel HD Graphics 5000 .*Intel.*Haswell.* 2 1 Intel HD Graphics .*Intel.*HD Graphics.* 2 1 diff --git a/indra/newview/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp index b0fd2b254..ddadd6742 100644 --- a/indra/newview/hippogridmanager.cpp +++ b/indra/newview/hippogridmanager.cpp @@ -153,7 +153,7 @@ void HippoGridInfo::setGridNick(std::string gridNick) { mIsInProductionGrid = true; } - if(gridNick == "avination") + else if(gridNick == "avination") { mIsInAvination = true; } @@ -177,12 +177,12 @@ void HippoGridInfo::setLoginUri(const std::string& loginUri) useHttps(); setPlatform(PLATFORM_SECONDLIFE); } - if (utf8str_tolower(LLURI(mLoginUri).hostName()) == "login.aditi.lindenlab.com") + else if (utf8str_tolower(LLURI(mLoginUri).hostName()) == "login.aditi.lindenlab.com") { useHttps(); setPlatform(PLATFORM_SECONDLIFE); } - if (utf8str_tolower(LLURI(mLoginUri).hostName()) == "login.avination.com" || + else if (utf8str_tolower(LLURI(mLoginUri).hostName()) == "login.avination.com" || utf8str_tolower(LLURI(mLoginUri).hostName()) == "login.avination.net") { mIsInAvination = true; @@ -260,99 +260,6 @@ void HippoGridInfo::setDirectoryFee(int fee) // ******************************************************************** // Grid Info -std::string HippoGridInfo::getSearchUrl(SearchType ty, bool is_web) const -{ - // Don't worry about whether or not mSearchUrl is empty here anymore -- MC - if (is_web) - { - if (mPlatform == PLATFORM_SECONDLIFE) - { - // Second Life defaults - if (ty == SEARCH_ALL_EMPTY) - { - return gSavedSettings.getString("SearchURLDefault"); - } - else if (ty == SEARCH_ALL_QUERY) - { - return gSavedSettings.getString("SearchURLQuery"); - } - else if (ty == SEARCH_ALL_TEMPLATE) - { - return gSavedSettings.getString("SearchURLSuffix2"); - } - else - { - llinfos << "Illegal search URL type " << ty << llendl; - return ""; - } - } - else if (!mSearchUrl.empty()) - { - // Search url sent to us in the login response - if (ty == SEARCH_ALL_EMPTY) - { - return (mSearchUrl); - } - else if (ty == SEARCH_ALL_QUERY) - { - return (mSearchUrl + "q=[QUERY]&s=[COLLECTION]&"); - } - else if (ty == SEARCH_ALL_TEMPLATE) - { - return "lang=[LANG]&mat=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]&dice=[DICE]"; - } - else - { - llinfos << "Illegal search URL type " << ty << llendl; - return ""; - } - } - else - { - // OpenSim and other web search defaults - if (ty == SEARCH_ALL_EMPTY) - { - return gSavedSettings.getString("SearchURLDefaultOpenSim"); - } - else if (ty == SEARCH_ALL_QUERY) - { - return gSavedSettings.getString("SearchURLQueryOpenSim"); - } - else if (ty == SEARCH_ALL_TEMPLATE) - { - return gSavedSettings.getString("SearchURLSuffixOpenSim"); - } - else - { - llinfos << "Illegal search URL type " << ty << llendl; - return ""; - } - } - } - else - { - // Use the old search all - if (ty == SEARCH_ALL_EMPTY) - { - return (mSearchUrl + "panel=All&"); - } - else if (ty == SEARCH_ALL_QUERY) - { - return (mSearchUrl + "q=[QUERY]&s=[COLLECTION]&"); - } - else if (ty == SEARCH_ALL_TEMPLATE) - { - return "lang=[LANG]&m=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]&dice=[DICE]"; - } - else - { - llinfos << "Illegal search URL type " << ty << llendl; - return ""; - } - } -} - - //static void HippoGridInfo::onXmlElementStart(void* userData, const XML_Char* name, const XML_Char** atts) { diff --git a/indra/newview/hippogridmanager.h b/indra/newview/hippogridmanager.h index 4416e8598..a33970e28 100644 --- a/indra/newview/hippogridmanager.h +++ b/indra/newview/hippogridmanager.h @@ -31,11 +31,6 @@ public: PLATFORM_SECONDLIFE, PLATFORM_LAST }; - enum SearchType { - SEARCH_ALL_EMPTY, - SEARCH_ALL_QUERY, - SEARCH_ALL_TEMPLATE - }; explicit HippoGridInfo(const std::string& gridName); @@ -58,7 +53,6 @@ public: const std::string& getSearchUrl() const { return mSearchUrl; } const std::string& getGridMessage() const { return mGridMessage; } const std::string& getVoiceConnector() const { return mVoiceConnector; } - std::string getSearchUrl(SearchType ty, bool is_web) const; bool isRenderCompat() const { return mRenderCompat; } std::string getGridNick() const; int getMaxAgentGroups() const { return mMaxAgentGroups; } diff --git a/indra/newview/importtracker.cpp b/indra/newview/importtracker.cpp index e88081969..4b8a7e843 100644 --- a/indra/newview/importtracker.cpp +++ b/indra/newview/importtracker.cpp @@ -226,7 +226,9 @@ void ImportTracker::get_update(S32 newid, BOOL justCreated, BOOL createSelected) } } } - + + // Anything below here must be permissions!!! + if (gAgent.getRegion()->getCapability("AgentPreferences").empty()) break; // This cap automates perm setting on the server msg->newMessageFast(_PREHASH_ObjectPermissions); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); @@ -238,20 +240,36 @@ void ImportTracker::get_update(S32 newid, BOOL justCreated, BOOL createSelected) msg->addU8Fast(_PREHASH_Field, PERM_NEXT_OWNER); msg->addU8Fast(_PREHASH_Set, PERM_SET_TRUE); U32 flags = 0; - if ( gSavedSettings.getBOOL("NextOwnerCopy") ) + if ( gSavedSettings.getBOOL("ObjectsNextOwnerCopy") ) { flags |= PERM_COPY; } - if ( gSavedSettings.getBOOL("NextOwnerModify") ) + if ( gSavedSettings.getBOOL("ObjectsNextOwnerModify") ) { flags |= PERM_MODIFY; } - if ( gSavedSettings.getBOOL("NextOwnerTransfer") ) + bool next_owner_trans; + if ( next_owner_trans = gSavedSettings.getBOOL("ObjectsNextOwnerTransfer") ) { flags |= PERM_TRANSFER; } msg->addU32Fast(_PREHASH_Mask, flags); msg->sendReliable(gAgent.getRegion()->getHost()); + if (!next_owner_trans) // Workaround transfer being true by default. + { + msg->newMessageFast(_PREHASH_ObjectPermissions); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgentID); + msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); + msg->nextBlockFast(_PREHASH_HeaderData); + msg->addBOOLFast(_PREHASH_Override, false); + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_ObjectLocalID, (U32)newid); + msg->addU8Fast(_PREHASH_Field, PERM_NEXT_OWNER); + msg->addU8Fast(_PREHASH_Set, PERM_SET_FALSE); + msg->addU32Fast(_PREHASH_Mask, PERM_TRANSFER); + msg->sendReliable(gAgent.getRegion()->getHost()); + } //llinfos << "LGG SENDING CUBE TEXTURE.." << llendl; } break; @@ -383,7 +401,7 @@ public: create_inventory_item(gAgent.getID(), gAgent.getSessionID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH), data->tid, data->name, data->description, data->type, LLInventoryType::defaultForAssetType(data->type), data->wear_type, - LLFloaterPerms::getNextOwnerPerms(), + LLFloaterPerms::getNextOwnerPerms("Uploads"), cb); } @@ -526,7 +544,7 @@ void JCImportInventorycallback(const LLUUID& uuid, void* user_data, S32 result, create_inventory_item(gAgent.getID(), gAgent.getSessionID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH), data->tid, data->name, data->description, data->type, LLInventoryType::defaultForAssetType(data->type), data->wear_type, - LLFloaterPerms::getNextOwnerPerms(), + LLFloaterPerms::getNextOwnerPerms("Uploads"), cb); }else cmdline_printchat("err: "+std::string(LLAssetStorage::getErrorString(result))); } @@ -674,7 +692,7 @@ void ImportTracker::send_inventory(LLSD& prim) create_inventory_item(gAgent.getID(), gAgent.getSessionID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH), data->tid, data->name, data->description, data->type, LLInventoryType::defaultForAssetType(data->type), data->wear_type, - LLFloaterPerms::getNextOwnerPerms(), + LLFloaterPerms::getNextOwnerPerms("Notecards"), cb); } break; @@ -686,7 +704,7 @@ void ImportTracker::send_inventory(LLSD& prim) create_inventory_item(gAgent.getID(), gAgent.getSessionID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH), data->tid, data->name, data->description, data->type, LLInventoryType::defaultForAssetType(data->type), data->wear_type, - LLFloaterPerms::getNextOwnerPerms(), + LLFloaterPerms::getNextOwnerPerms("Scripts"), cb); } break; diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 3f2cfbd0f..8399d9f56 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -210,7 +210,8 @@ Function CloseSecondLife Push $0 FindWindow $0 "Second Life" "" IntCmp $0 0 DONE - MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL + MessageBox MB_YESNOCANCEL $(CloseSecondLifeInstMB) IDYES CLOSE IDNO DONE + Goto CANCEL_INSTALL ; IDCANCEL CANCEL_INSTALL: Quit @@ -436,7 +437,8 @@ Function un.CloseSecondLife Push $0 FindWindow $0 "Second Life" "" IntCmp $0 0 DONE - MessageBox MB_OKCANCEL $(CloseSecondLifeUnInstMB) IDOK CLOSE IDCANCEL CANCEL_UNINSTALL + MessageBox MB_YESNOCANCEL $(CloseSecondLifeUnInstMB) IDYES CLOSE IDNO DONE + Goto CANCEL_UNINSTALL ; IDCANCEL CANCEL_UNINSTALL: Quit @@ -805,6 +807,8 @@ CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \ "$INSTDIR\$INSTEXE" "$INSTFLAGS $SHORTCUT_LANG_PARAM" CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \ "$INSTDIR\$INSTEXE" "$INSTFLAGS $SHORTCUT_LANG_PARAM" +CreateShortCut "$INSTDIR\$INSTSHORTCUT Portable.lnk" \ + "$INSTDIR\$INSTEXE" "$INSTFLAGS $SHORTCUT_LANG_PARAM --portable" CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \ '"$INSTDIR\uninst.exe"' '' diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi index 331c4a3a3..9ff482075 100644 Binary files a/indra/newview/installers/windows/lang_en-us.nsi and b/indra/newview/installers/windows/lang_en-us.nsi differ diff --git a/indra/newview/lffloaterinvpanel.cpp b/indra/newview/lffloaterinvpanel.cpp index 522762080..31d144673 100644 --- a/indra/newview/lffloaterinvpanel.cpp +++ b/indra/newview/lffloaterinvpanel.cpp @@ -29,7 +29,7 @@ LFFloaterInvPanel::LFFloaterInvPanel(const LLUUID& cat_id, LLInventoryModel* model, const std::string& name) : LLInstanceTracker(cat_id) { - mCommitCallbackRegistrar.add("InvPanel.Search", boost::bind(&LFFloaterInvPanel::onSearch, this, _2)); + mCommitCallbackRegistrar.add("InvPanel.Search", boost::bind(&LLInventoryPanel::setFilterSubString, boost::ref(mPanel), _2)); LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inv_panel.xml"); LLPanel* panel = getChild("placeholder_panel"); mPanel = new LLInventoryPanel("inv_panel", LLInventoryPanel::DEFAULT_SORT_ORDER, cat_id.asString(), panel->getRect(), model, true); @@ -83,8 +83,3 @@ BOOL LFFloaterInvPanel::handleKeyHere(KEY key, MASK mask) return LLFloater::handleKeyHere(key, mask); } - -void LFFloaterInvPanel::onSearch(const LLSD& val) -{ - mPanel->setFilterSubString(val.asString()); -} diff --git a/indra/newview/lffloaterinvpanel.h b/indra/newview/lffloaterinvpanel.h index 24ae089fd..3c9104db1 100644 --- a/indra/newview/lffloaterinvpanel.h +++ b/indra/newview/lffloaterinvpanel.h @@ -35,7 +35,6 @@ public: static void closeAll(); // Called when not allowed to have inventory open /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); - void onSearch(const LLSD& val); private: class LLInventoryPanel* mPanel; diff --git a/indra/newview/lfsimfeaturehandler.cpp b/indra/newview/lfsimfeaturehandler.cpp index e4b6408e2..2e6b55b37 100644 --- a/indra/newview/lfsimfeaturehandler.cpp +++ b/indra/newview/lfsimfeaturehandler.cpp @@ -26,6 +26,8 @@ LFSimFeatureHandler::LFSimFeatureHandler() : mSupportsExport(false) +, mDestinationGuideURL(gSavedSettings.getString("DestinationGuideURL")) +, mSearchURL(gSavedSettings.getString("SearchURL")) , mSayRange(20) , mShoutRange(100) , mWhisperRange(10) @@ -54,57 +56,82 @@ void LFSimFeatureHandler::handleRegionChange() } } +template +void has_feature_or_default(SignaledType& type, const LLSD& features, const std::string& feature) +{ + type = (features.has(feature)) ? static_cast(features[feature]) : type.getDefault(); +} +template<> +void has_feature_or_default(SignaledType& type, const LLSD& features, const std::string& feature) +{ + type = (features.has(feature)) ? features[feature].asInteger() : type.getDefault(); +} + void LFSimFeatureHandler::setSupportedFeatures() { if (LLViewerRegion* region = gAgent.getRegion()) { LLSD info; region->getSimulatorFeatures(info); + //bool hg(); // Singu Note: There should probably be a flag for this some day. if (info.has("OpenSimExtras")) // OpenSim specific sim features { // For definition of OpenSimExtras please see // http://opensimulator.org/wiki/SimulatorFeatures_Extras const LLSD& extras(info["OpenSimExtras"]); - mSupportsExport = extras.has("ExportSupported") ? extras["ExportSupported"].asBoolean() : false; - mMapServerURL = extras.has("map-server-url") ? extras["map-server-url"].asString() : ""; - mSearchURL = extras.has("search-server-url") ? extras["search-server-url"].asString() : ""; - mSayRange = extras.has("say-range") ? extras["say-range"].asInteger() : 20; - mShoutRange = extras.has("shout-range") ? extras["shout-range"].asInteger() : 100; - mWhisperRange = extras.has("whisper-range") ? extras["whisper-range"].asInteger() : 10; + has_feature_or_default(mSupportsExport, extras, "ExportSupported"); + //if (hg) + { + has_feature_or_default(mDestinationGuideURL, extras, "destination-guide-url"); + mMapServerURL = extras.has("map-server-url") ? extras["map-server-url"].asString() : ""; + has_feature_or_default(mSearchURL, extras, "search-server-url"); + } + has_feature_or_default(mSayRange, extras, "say-range"); + has_feature_or_default(mShoutRange, extras, "shout-range"); + has_feature_or_default(mWhisperRange, extras, "whisper-range"); } else // OpenSim specifics are unsupported reset all to default { - mSupportsExport = false; - mMapServerURL = ""; - mSearchURL = ""; - mSayRange = 20; - mShoutRange = 100; - mWhisperRange = 10; + mSupportsExport.reset(); + //if (hg) + { + mDestinationGuideURL.reset(); + mMapServerURL = ""; + mSearchURL.reset(); + } + mSayRange.reset(); + mShoutRange.reset(); + mWhisperRange.reset(); } } } -boost::signals2::connection LFSimFeatureHandler::setSupportsExportCallback(const boost::signals2::signal::slot_type& slot) +boost::signals2::connection LFSimFeatureHandler::setSupportsExportCallback(const SignaledType::slot_t& slot) { return mSupportsExport.connect(slot); } -boost::signals2::connection LFSimFeatureHandler::setSearchURLCallback(const boost::signals2::signal::slot_type& slot) +boost::signals2::connection LFSimFeatureHandler::setDestinationGuideURLCallback(const SignaledType::slot_t& slot) +{ + return mDestinationGuideURL.connect(slot); +} + +boost::signals2::connection LFSimFeatureHandler::setSearchURLCallback(const SignaledType::slot_t& slot) { return mSearchURL.connect(slot); } -boost::signals2::connection LFSimFeatureHandler::setSayRangeCallback(const boost::signals2::signal::slot_type& slot) +boost::signals2::connection LFSimFeatureHandler::setSayRangeCallback(const SignaledType::slot_t& slot) { return mSayRange.connect(slot); } -boost::signals2::connection LFSimFeatureHandler::setShoutRangeCallback(const boost::signals2::signal::slot_type& slot) +boost::signals2::connection LFSimFeatureHandler::setShoutRangeCallback(const SignaledType::slot_t& slot) { return mShoutRange.connect(slot); } -boost::signals2::connection LFSimFeatureHandler::setWhisperRangeCallback(const boost::signals2::signal::slot_type& slot) +boost::signals2::connection LFSimFeatureHandler::setWhisperRangeCallback(const SignaledType::slot_t& slot) { return mWhisperRange.connect(slot); } diff --git a/indra/newview/lfsimfeaturehandler.h b/indra/newview/lfsimfeaturehandler.h index d26983fcd..c1260d4cc 100644 --- a/indra/newview/lfsimfeaturehandler.h +++ b/indra/newview/lfsimfeaturehandler.h @@ -21,29 +21,33 @@ #include "llsingleton.h" #include "llpermissions.h" // ExportPolicy -template > +template > class SignaledType { public: - SignaledType() : mValue() {} - SignaledType(Type b) : mValue(b) {} + SignaledType() : mValue(), mDefaultValue() {} + SignaledType(Type b) : mValue(b), mDefaultValue(b) {} - boost::signals2::connection connect(const typename Signal::slot_type& slot) { return mSignal.connect(slot); } + typedef typename Signal::slot_type slot_t; + boost::signals2::connection connect(const slot_t& slot) { return mSignal.connect(slot); } SignaledType& operator =(Type val) { if (val != mValue) { mValue = val; - mSignal(); + mSignal(val); } return *this; } operator Type() const { return mValue; } + void reset() { *this = mDefaultValue; } + const Type& getDefault() const { return mDefaultValue; } private: Signal mSignal; Type mValue; + const Type mDefaultValue; }; class LFSimFeatureHandler : public LLSingleton @@ -57,14 +61,16 @@ public: void setSupportedFeatures(); // Connection setters - boost::signals2::connection setSupportsExportCallback(const boost::signals2::signal::slot_type& slot); - boost::signals2::connection setSearchURLCallback(const boost::signals2::signal::slot_type& slot); - boost::signals2::connection setSayRangeCallback(const boost::signals2::signal::slot_type& slot); - boost::signals2::connection setShoutRangeCallback(const boost::signals2::signal::slot_type& slot); - boost::signals2::connection setWhisperRangeCallback(const boost::signals2::signal::slot_type& slot); + boost::signals2::connection setSupportsExportCallback(const SignaledType::slot_t& slot); + boost::signals2::connection setDestinationGuideURLCallback(const SignaledType::slot_t& slot); + boost::signals2::connection setSearchURLCallback(const SignaledType::slot_t& slot); + boost::signals2::connection setSayRangeCallback(const SignaledType::slot_t& slot); + boost::signals2::connection setShoutRangeCallback(const SignaledType::slot_t& slot); + boost::signals2::connection setWhisperRangeCallback(const SignaledType::slot_t& slot); // Accessors bool simSupportsExport() const { return mSupportsExport; } + std::string destinationGuideURL() const { return mDestinationGuideURL; } std::string mapServerURL() const { return mMapServerURL; } std::string searchURL() const { return mSearchURL; } U32 sayRange() const { return mSayRange; } @@ -75,6 +81,7 @@ public: private: // SignaledTypes SignaledType mSupportsExport; + SignaledType mDestinationGuideURL; std::string mMapServerURL; SignaledType mSearchURL; SignaledType mSayRange; diff --git a/indra/newview/lggdicdownload.cpp b/indra/newview/lggdicdownload.cpp index 8207ed0bc..eff00f87f 100644 --- a/indra/newview/lggdicdownload.cpp +++ b/indra/newview/lggdicdownload.cpp @@ -58,8 +58,6 @@ public: EmeraldDicDownloader(lggDicDownloadFloater* spanel, std::string sname); ~EmeraldDicDownloader() { } /*virtual*/ void completedRaw( - U32 status, - const std::string& reason, const LLChannelDescriptors& channels, const buffer_ptr_t& buffer); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return emeraldDicDownloader_timeout; } @@ -167,9 +165,9 @@ EmeraldDicDownloader::EmeraldDicDownloader(lggDicDownloadFloater* spanel, std::s } -void EmeraldDicDownloader::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const buffer_ptr_t& buffer) +void EmeraldDicDownloader::completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { - if (status < 200 || status >= 300) + if (!isGoodStatus(mStatus)) { return; } diff --git a/indra/newview/linux_tools/client-readme-voice.txt b/indra/newview/linux_tools/client-readme-voice.txt index aa04a5704..0637e9d17 100644 --- a/indra/newview/linux_tools/client-readme-voice.txt +++ b/indra/newview/linux_tools/client-readme-voice.txt @@ -11,9 +11,9 @@ groups inside Second Life, with an appropriate headset/microphone. Linux Voice Support is currently EXPERIMENTAL and is known to still have some compatibility issues. -SINGULARITY MULTI-VOICE +MULTI-VOICE -=-=-=-=-=-=-=-=-=-=-=- -Singularity multi-voice is an experimental feature that allows you to run multiple +Multi-voice is an experimental feature that allows you to run multiple SLVoice daemons at the same time, in order to do this, the debug setting VoiceMultiInstance must be TRUE, this allows multiple instances of the viewer to run concurrently and each connect to voice. diff --git a/indra/newview/linux_tools/handle_secondlifeprotocol.sh b/indra/newview/linux_tools/handle_secondlifeprotocol.sh.in similarity index 81% rename from indra/newview/linux_tools/handle_secondlifeprotocol.sh rename to indra/newview/linux_tools/handle_secondlifeprotocol.sh.in index 4ff3e2637..54d20279e 100755 --- a/indra/newview/linux_tools/handle_secondlifeprotocol.sh +++ b/indra/newview/linux_tools/handle_secondlifeprotocol.sh.in @@ -13,5 +13,5 @@ fi RUN_PATH=`dirname "$0" || echo .` cd "${RUN_PATH}" -exec ./singularity -url \'"${URL}"\' +exec ./@VIEWER_BRANDING_ID@ -url \'"${URL}"\' diff --git a/indra/newview/linux_tools/install.sh b/indra/newview/linux_tools/install.sh.in old mode 100644 new mode 100755 similarity index 83% rename from indra/newview/linux_tools/install.sh rename to indra/newview/linux_tools/install.sh.in index 86d020671..17a837fbb --- a/indra/newview/linux_tools/install.sh +++ b/indra/newview/linux_tools/install.sh.in @@ -1,6 +1,6 @@ #!/bin/bash -# Install Singularity Viewer. This script can install the viewer both +# Install @VIEWER_CHANNEL@. This script can install the viewer both # system-wide and for an individual user. VT102_STYLE_NORMAL='\E[0m' @@ -48,8 +48,8 @@ function warn() function homedir_install() { warn "You are not running as a privileged user, so you will only be able" - warn "to install Singularity Viewer in your home directory. If you" - warn "would like to install Singularity Viewer system-wide, please run" + warn "to install @VIEWER_CHANNEL@ in your home directory. If you" + warn "would like to install @VIEWER_CHANNEL@ system-wide, please run" warn "this script as the root user, or with the 'sudo' command." echo @@ -58,13 +58,13 @@ function homedir_install() exit 0 fi - install_to_prefix "$HOME/.singularity-install" - $HOME/.singularity-install/refresh_desktop_app_entry.sh + install_to_prefix "$HOME/.@VIEWER_BRANDING_ID@-install" + $HOME/.@VIEWER_BRANDING_ID@-install/refresh_desktop_app_entry.sh } function root_install() { - local default_prefix="/opt/singularity-install" + local default_prefix="/opt/@VIEWER_BRANDING_ID@-install" echo -n "Enter the desired installation directory [${default_prefix}]: "; read diff --git a/indra/newview/linux_tools/refresh_desktop_app_entry.sh b/indra/newview/linux_tools/refresh_desktop_app_entry.sh.in similarity index 74% rename from indra/newview/linux_tools/refresh_desktop_app_entry.sh rename to indra/newview/linux_tools/refresh_desktop_app_entry.sh.in index 9412c840c..b865b4df0 100755 --- a/indra/newview/linux_tools/refresh_desktop_app_entry.sh +++ b/indra/newview/linux_tools/refresh_desktop_app_entry.sh.in @@ -12,10 +12,10 @@ function install_desktop_entry() local desktop_entry="\ [Desktop Entry]\n\ -Name=Singularity\n\ +Name=@VIEWER_BRANDING_ID@\n\ Comment=Client for Online Virtual Worlds, such as Second Life\n\ -Exec=${installation_prefix}/singularity\n\ -Icon=${installation_prefix}/singularity_icon.png\n\ +Exec=${installation_prefix}/@VIEWER_BRANDING_ID@\n\ +Icon=${installation_prefix}/@VIEWER_BRANDING_ID@_icon.png\n\ Terminal=false\n\ Type=Application\n\ Categories=Application;Network;\n\ @@ -24,7 +24,7 @@ X-Desktop-File-Install-Version=3.0" echo " - Installing menu entries in ${desktop_entries_dir}" mkdir -vp "${desktop_entries_dir}" - echo -e $desktop_entry > "${desktop_entries_dir}/singularity-viewer.desktop" || "Failed to install application menu!" + echo -e $desktop_entry > "${desktop_entries_dir}/@VIEWER_BRANDING_ID@-viewer.desktop" || "Failed to install application menu!" } if [ "$UID" == "0" ]; then diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh.in similarity index 97% rename from indra/newview/linux_tools/wrapper.sh rename to indra/newview/linux_tools/wrapper.sh.in index 9dd8caf36..40719f8d1 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh.in @@ -64,7 +64,7 @@ if [ -n "$ASCENDED_DEVELOPER" ]; then elif [ "$ASCENDED_DEVELOPER" = "2" ]; then export LL_WRAPPER='valgrind --smc-check=all --error-limit=no --log-file=secondlife.vg --leak-check=full --suppressions=/usr/lib/valgrind/glibc-2.5.supp --suppressions=secondlife-i686.supp' elif [ "$ASCENDED_DEVELOPER" = "3" ]; then - export LL_WRAPPER='strace -f -ff -o singularity.strace' + export LL_WRAPPER='strace -f -ff -o @VIEWER_BRANDING_ID@.strace' fi fi @@ -142,7 +142,7 @@ if [ -n "$LL_TCMALLOC" ]; then fi fi -export VIEWER_BINARY='singularity-do-not-run-directly' +export VIEWER_BINARY='@VIEWER_BRANDING_ID@-do-not-run-directly' BINARY_TYPE=$(expr match "$(file -b bin/$VIEWER_BINARY)" '\(.*executable\)' | sed -e 's/ / /g') if [ "${BINARY_TYPE}" == "ELF 64-bit LSB executable" ]; then SL_ENV+='LD_LIBRARY_PATH="`pwd`/lib64:`pwd`/lib32:$LD_LIBRARY_PATH"' diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index d4a5108c5..815054c33 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -30,9 +30,6 @@ #include "llcurl.h" #include "llhttpclient.h" -class AIHTTPTimeoutPolicy; -extern AIHTTPTimeoutPolicy accountingCostResponder_timeout; - //=============================================================================== LLAccountingCostManager::LLAccountingCostManager() { @@ -41,9 +38,15 @@ LLAccountingCostManager::LLAccountingCostManager() class LLAccountingCostResponder : public LLHTTPClient::ResponderWithResult { public: - LLAccountingCostResponder( const LLSD& objectIDs ) - : mObjectIDs( objectIDs ) + LLAccountingCostResponder( const LLSD& objectIDs, const LLHandle& observer_handle ) + : mObjectIDs( objectIDs ), + mObserverHandle( observer_handle ) { + LLAccountingCostObserver* observer = mObserverHandle.get(); + if (observer) + { + mTransactionID = observer->getTransactionID(); + } } void clearPendingRequests ( void ) @@ -54,50 +57,63 @@ public: } } - /*virtual*/ void error( U32 statusNum, const std::string& reason ) + void httpFailure(void) { - llwarns << "Transport error "<getTransactionID() == mTransactionID) + { + observer->setErrorStatus(mStatus, mReason); + } } - /*virtual*/ void result( const LLSD& content ) + void httpSuccess(void) { //Check for error - if ( !content.isMap() || content.has("error") ) + if ( !mContent.isMap() || mContent.has("error") ) { llwarns << "Error on fetched data"<< llendl; - clearPendingRequests(); } - else if (content.has("selected")) + else if (mContent.has("selected")) { F32 physicsCost = 0.0f; F32 networkCost = 0.0f; F32 simulationCost = 0.0f; - //LLTransactionID transactionID; - - //transactionID = content["selected"][i]["local_id"].asUUID(); - physicsCost = content["selected"]["physics"].asReal(); - networkCost = content["selected"]["streaming"].asReal(); - simulationCost = content["selected"]["simulation"].asReal(); + physicsCost = mContent["selected"]["physics"].asReal(); + networkCost = mContent["selected"]["streaming"].asReal(); + simulationCost = mContent["selected"]["simulation"].asReal(); SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost ); - + + LLAccountingCostObserver* observer = mObserverHandle.get(); + if (observer && observer->getTransactionID() == mTransactionID) + { + observer->onWeightsUpdate(selectionCost); + } } clearPendingRequests(); } - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return accountingCostResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLAccountingCostResponder"; } private: //List of posted objects LLSD mObjectIDs; -}; + // Current request ID + LLUUID mTransactionID; + + // Cost update observer handle + LLHandle mObserverHandle; +}; //=============================================================================== -void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const std::string& url ) +void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, + const std::string& url, + const LLHandle& observer_handle ) { // Invoking system must have already determined capability availability if ( !url.empty() ) @@ -144,7 +160,7 @@ void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const st LLSD dataToPost = LLSD::emptyMap(); dataToPost[keystr.c_str()] = objectList; - LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList )); + LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList, observer_handle )); } } else diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h index 8ae696a98..731705288 100644 --- a/indra/newview/llaccountingcostmanager.h +++ b/indra/newview/llaccountingcostmanager.h @@ -27,8 +27,28 @@ #ifndef LL_ACCOUNTINGQUOTAMANAGER_H #define LL_ACCOUNTINGQUOTAMANAGER_H //=============================================================================== +#include "llhandle.h" + #include "llaccountingcost.h" //=============================================================================== +// An interface class for panels which display the parcel accounting information. +class LLAccountingCostObserver +{ +public: + LLAccountingCostObserver() { mObserverHandle.bind(this); } + virtual ~LLAccountingCostObserver() {} + virtual void onWeightsUpdate(const SelectionCost& selection_cost) = 0; + virtual void setErrorStatus(U32 status, const std::string& reason) = 0; + const LLHandle& getObserverHandle() const { return mObserverHandle; } + const LLUUID& getTransactionID() { return mTransactionID; } + +protected: + virtual void generateTransactionID() = 0; + + LLRootHandle mObserverHandle; + LLUUID mTransactionID; +}; +//=============================================================================== class LLAccountingCostManager : public LLSingleton { public: @@ -37,7 +57,8 @@ public: //Store an object that will be eventually fetched void addObject( const LLUUID& objectID ); //Request quotas for object list - void fetchCosts( eSelectionType selectionType, const std::string& url ); + void fetchCosts( eSelectionType selectionType, const std::string& url, + const LLHandle& observer_handle ); //Delete a specific object from the pending list void removePendingObject( const LLUUID& objectID ); diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 973466967..7fb21ab0d 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1293,20 +1293,12 @@ F32 LLAgent::clampPitchToLimits(F32 angle) LLVector3 skyward = getReferenceUpVector(); - F32 look_down_limit; - F32 look_up_limit = 10.f * DEG_TO_RAD; + static const LLCachedControl useRealisticMouselook(gSavedSettings, "UseRealisticMouselook", false); + const F32 look_down_limit = (useRealisticMouselook ? 160.f : (isAgentAvatarValid() && gAgentAvatarp->isSitting() ? 130.f : 179.f)) * DEG_TO_RAD; + const F32 look_up_limit = (useRealisticMouselook ? 20.f : 1.f) * DEG_TO_RAD;; F32 angle_from_skyward = acos( mFrameAgent.getAtAxis() * skyward ); - if (isAgentAvatarValid() && gAgentAvatarp->isSitting()) - { - look_down_limit = 130.f * DEG_TO_RAD; - } - else - { - look_down_limit = 170.f * DEG_TO_RAD; - } - // clamp pitch to limits if ((angle >= 0.f) && (angle_from_skyward + angle > look_down_limit)) { @@ -2582,8 +2574,8 @@ public: LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity); virtual ~LLMaturityPreferencesResponder(); - /*virtual*/ void result(const LLSD &pContent); - /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return maturityPreferences_timeout; } /*virtual*/ char const* getName(void) const { return "LLMaturityPreferencesResponder"; } @@ -2607,25 +2599,25 @@ LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder() { } -void LLMaturityPreferencesResponder::result(const LLSD &pContent) +void LLMaturityPreferencesResponder::httpSuccess(void) { - U8 actualMaturity = parseMaturityFromServerResponse(pContent); + U8 actualMaturity = parseMaturityFromServerResponse(mContent); if (actualMaturity != mPreferredMaturity) { llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', the server responded with '" << LLViewerRegion::accessToString(actualMaturity) << "' [value:" << static_cast(actualMaturity) << ", llsd:" - << pContent << "]" << llendl; + << mContent << "]" << llendl; } mAgent->handlePreferredMaturityResult(actualMaturity); } -void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason) +void LLMaturityPreferencesResponder::httpFailure(void) { llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '" - << pReason << "' [status:" << pStatus << "]" << llendl; + << mReason << "' [status:" << mStatus << "]" << llendl; mAgent->handlePreferredMaturityError(); } @@ -2815,7 +2807,7 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity) // If we don't have a region, report it as an error if (getRegion() == NULL) { - responderPtr->error(0U, "region is not defined"); + responderPtr->failureResult(0U, "region is not defined", LLSD()); } else { @@ -2825,7 +2817,7 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity) // If the capability is not defined, report it as an error if (url.empty()) { - responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region"); + responderPtr->failureResult(0U, "capability 'UpdateAgentInformation' is not defined for region", LLSD()); } else { diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 5c21a75a3..a8e0a5c2a 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -395,7 +395,7 @@ void LLAgentCamera::slamLookAt(const LLVector3 &look_at) //----------------------------------------------------------------------------- LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 original_focus_point, S32 x, S32 y) { - LLMatrix4 obj_matrix = object->getRenderMatrix(); + const LLMatrix4a& obj_matrix = object->getRenderMatrix(); LLQuaternion obj_rot = object->getRenderRotation(); LLVector3 obj_pos = object->getRenderPosition(); @@ -427,24 +427,24 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi // find the largest ratio stored in obj_to_cam_ray_proportions // this corresponds to the object's local axial plane (XY, YZ, XZ) that is *most* facing the camera - LLVector3 longest_object_axis; + LLVector4a focus_plane_normal; // is x-axis longest? if (obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VY] && obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VZ]) { // then grab it - longest_object_axis.setVec(obj_matrix.getFwdRow4()); + focus_plane_normal = obj_matrix.getRow(); } // is y-axis longest? else if (obj_to_cam_ray_proportions.mV[VY] > obj_to_cam_ray_proportions.mV[VZ]) { // then grab it - longest_object_axis.setVec(obj_matrix.getLeftRow4()); + focus_plane_normal = obj_matrix.getRow(); } // otherwise, use z axis else { - longest_object_axis.setVec(obj_matrix.getUpRow4()); + focus_plane_normal = obj_matrix.getRow(); } // Use this axis as the normal to project mouse click on to plane with that normal, at the object center. @@ -453,11 +453,10 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi // We do this to allow the camera rotation tool to "tumble" the object by rotating the camera. // If the focus point were the object surface under the mouse, camera rotation would introduce an undesirable // eccentricity to the object orientation - LLVector3 focus_plane_normal(longest_object_axis); - focus_plane_normal.normalize(); + focus_plane_normal.normalize3fast(); LLVector3d focus_pt_global; - gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), focus_plane_normal); + gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), LLVector3(focus_plane_normal.getF32ptr())); LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global); // find vector from camera to focus point in object space @@ -941,6 +940,8 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction) F32 max_distance = /*llmin(mDrawDistance*/ INT_MAX - DIST_FUDGE//, /*LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE )*/; + max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154 + if (new_distance > max_distance) { // screw cam constraints @@ -1178,7 +1179,9 @@ void LLAgentCamera::updateCamera() validateFocusObject(); - if (isAgentAvatarValid() && + static const LLCachedControl realistic_ml("UseRealisticMouselook"); + if (isAgentAvatarValid() && + !realistic_ml && gAgentAvatarp->isSitting() && camera_mode == CAMERA_MODE_MOUSELOOK) { @@ -1461,13 +1464,11 @@ void LLAgentCamera::updateCamera() } gAgent.setLastPositionGlobal(global_pos); - if (LLVOAvatar::sVisibleInFirstPerson && isAgentAvatarValid() && !gAgentAvatarp->isSitting() && cameraMouselook()) + if (LLVOAvatar::sVisibleInFirstPerson && isAgentAvatarValid() && (realistic_ml || !gAgentAvatarp->isSitting()) && cameraMouselook()) { LLVector3 head_pos = gAgentAvatarp->mHeadp->getWorldPosition() + LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() + LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation(); - LLVector3 diff = mCameraPositionAgent - head_pos; - diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation(); LLJoint* torso_joint = gAgentAvatarp->mTorsop; LLJoint* chest_joint = gAgentAvatarp->mChestp; @@ -1489,7 +1490,19 @@ void LLAgentCamera::updateCamera() diff.mV[VZ] = 0.f; }*/ - gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff); + if (realistic_ml) + { + LLQuaternion agent_rot(gAgent.getFrameAgent().getQuaternion()); + if (LLViewerObject* parent = static_cast(gAgentAvatarp->getParent())) + if (static_cast(gAgentAvatarp->getRoot())->flagCameraDecoupled()) + agent_rot *= parent->getRenderRotation(); + LLViewerCamera::getInstance()->updateCameraLocation(head_pos, mCameraUpVector, gAgentAvatarp->mHeadp->getWorldPosition() + LLVector3(1.0, 0.0, 0.0) * agent_rot); + } + else + { + const LLVector3 diff((mCameraPositionAgent - head_pos) * ~gAgentAvatarp->mRoot->getWorldRotation()); + gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff); + } gAgentAvatarp->mRoot->updateWorldMatrixChildren(); @@ -1781,7 +1794,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) head_offset.mdV[VX] = gAgentAvatarp->mHeadOffset.mV[VX]; head_offset.mdV[VY] = gAgentAvatarp->mHeadOffset.mV[VY]; head_offset.mdV[VZ] = gAgentAvatarp->mHeadOffset.mV[VZ] + 0.1f; - const LLMatrix4& mat = ((LLViewerObject*) gAgentAvatarp->getParent())->getRenderMatrix(); + const LLMatrix4 mat(((LLViewerObject*) gAgentAvatarp->getParent())->getRenderMatrix().getF32ptr()); camera_position_global = gAgent.getPosGlobalFromAgent ((gAgentAvatarp->getPosition()+ LLVector3(head_offset)*gAgentAvatarp->getRotation()) * mat); @@ -2433,9 +2446,12 @@ void LLAgentCamera::changeCameraToCustomizeAvatar() at.normalize(); gAgent.resetAxes(at); - gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); - gAgent.setCustomAnim(TRUE); - gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); + if (gSavedSettings.getBOOL("LiruCustomizeAnim")) + { + gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); + gAgent.setCustomAnim(TRUE); + gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); + } LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); if (turn_motion) diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 9b0132be7..c91147d8f 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -50,6 +50,7 @@ #include "llwearablelist.h" #include "llfloatercustomize.h" +#include "llfloaterperms.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) @@ -77,7 +78,20 @@ using namespace LLAvatarAppearanceDefines; void wear_and_edit_cb(const LLUUID& inv_item) { if (inv_item.isNull()) return; - + + LLViewerInventoryItem* item = gInventory.getItem(inv_item); + if (!item) return; + + LLPermissions perm = item->getPermissions(); + perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables")); + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables")); + item->setPermissions(perm); + + item->updateServer(FALSE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + // Request editing the item after it gets worn. gAgentWearables.requestEditingWearable(inv_item); @@ -85,6 +99,26 @@ void wear_and_edit_cb(const LLUUID& inv_item) LLAppearanceMgr::instance().wearItemOnAvatar(inv_item); } +void wear_cb(const LLUUID& inv_item) +{ + if (!inv_item.isNull()) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item); + if (item) + { + LLPermissions perm = item->getPermissions(); + perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables")); + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables")); + item->setPermissions(perm); + + item->updateServer(FALSE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + } + } +} + /////////////////////////////////////////////////////////////////////////////// // HACK: For EXT-3923: Pants item shows in inventory with skin icon and messes with "current look" @@ -502,6 +536,7 @@ LLViewerWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType t old_wearable, trunc_name, trunc_description); + LLPointer cb = new addWearableToAgentInventoryCallback( LLPointer(NULL), @@ -1976,7 +2011,7 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp); LLAssetType::EType asset_type = wearable->getAssetType(); LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; - LLPointer cb = wear ? new LLBoostFuncInventoryCallback(wear_and_edit_cb) : NULL; + LLPointer cb = new LLBoostFuncInventoryCallback(wear ? wear_and_edit_cb : wear_cb); LLUUID folder_id; if (parent_id.notNull()) @@ -1989,10 +2024,16 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con folder_id = gInventory.findCategoryUUIDForType(folder_type); } - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - folder_id, wearable->getTransactionID(), wearable->getName(), - wearable->getDescription(), asset_type, inv_type, wearable->getType(), - wearable->getPermissions().getMaskNextOwner(), + create_inventory_item(gAgent.getID(), + gAgent.getSessionID(), + folder_id, + wearable->getTransactionID(), + wearable->getName(), + wearable->getDescription(), + asset_type, + inv_type, + wearable->getType(), + LLFloaterPerms::getNextOwnerPerms("Wearables"), cb); } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index c76abdf64..6294e62af 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3506,10 +3506,10 @@ public: } // Successful completion. - /* virtual */ void result(const LLSD& content) + /* virtual */ void httpSuccess(void) { - LL_DEBUGS("Avatar") << "content: " << ll_pretty_print_sd(content) << LL_ENDL; - if (content["success"].asBoolean()) + LL_DEBUGS("Avatar") << "content: " << ll_pretty_print_sd(mContent) << LL_ENDL; + if (mContent["success"].asBoolean()) { LL_DEBUGS("Avatar") << "OK" << LL_ENDL; } @@ -3520,11 +3520,10 @@ public: } // Error - /*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content) + /*virtual*/ void httpFailure(void) { - 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); + llwarns << "appearance update request failed, " << dumpResponse() << llendl; + onFailure(mStatus); } void onFailure(U32 status) @@ -4465,7 +4464,9 @@ public: LLFolderType::FT_CLOTHING, "Quick Appearance"); LLSD::UUID folder_uuid = query_map["folder_id"].asUUID(); - if ( gInventory.getCategory( folder_uuid ) != NULL ) + if ( gInventory.getCategory( folder_uuid ) != NULL && + folder_uuid != gInventory.getRootFolderID() && + folder_uuid != gInventory.getLibraryRootFolderID() ) { LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 67c44f5ab..caf66d6bc 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -98,6 +98,7 @@ #include "llprimitive.h" #include "llurlaction.h" #include "llurlentry.h" +#include "llvolumemgr.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include @@ -357,6 +358,7 @@ void init_default_trans_args() default_trans_args.insert("APP_NAME"); default_trans_args.insert("SHORT_APP_NAME"); default_trans_args.insert("CAPITALIZED_APP_NAME"); + default_trans_args.insert("APP_SITE"); default_trans_args.insert("SECOND_LIFE_GRID"); default_trans_args.insert("SUPPORT_SITE"); default_trans_args.insert("CURRENCY"); @@ -587,6 +589,18 @@ public: } }; +void load_default_bindings(bool zqsd) +{ + gViewerKeyboard.unloadBindings(); + const std::string keys(zqsd ? "keysZQSD.ini" : "keys.ini"); + if (!gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, keys))) + { + LL_ERRS("InitInfo") << "Unable to open " << keys << LL_ENDL; + } + // Load Custom bindings (override defaults) + gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"custom_keys.ini")); +} + bool LLAppViewer::init() { setupErrorHandling(); @@ -871,12 +885,7 @@ bool LLAppViewer::init() bind_keyboard_functions(); // Load Default bindings - if (!gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"keys.ini"))) - { - LL_ERRS("InitInfo") << "Unable to open keys.ini" << LL_ENDL; - } - // Load Custom bindings (override defaults) - gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"custom_keys.ini")); + load_default_bindings(gSavedSettings.getBOOL("LiruUseZQSDKeys")); // If we don't have the right GL requirements, exit. if (!gGLManager.mHasRequirements && !gNoRender) @@ -1937,6 +1946,7 @@ void errorCallback(const std::string &error_string) } } +bool init_logging(); bool LLAppViewer::initLogging() { // @@ -1946,6 +1956,10 @@ bool LLAppViewer::initLogging() gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); LLError::setFatalFunction(errorCallback); + return init_logging(); +} +bool init_logging() +{ // Remove the last ".old" log file. std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, OLD_LOG_FILE); LLFile::remove(old_log_file); @@ -2206,6 +2220,19 @@ bool LLAppViewer::initConfiguration() // - selectively apply settings + // Portability Mode! + if (clp.hasOption("portable")) + { + const std::string log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOG_FILE); + llinfos << "Attempting to use portable settings and cache!" << llendl; + gDirUtilp->makePortable(); + init_logging(); // Switch to portable log file + llinfos << "Portable viewer configuration initialized!" << llendl; + LLFile::remove(log); + llinfos << "Cleaned up local log file to keep this computer untouched." << llendl; + } + // + // If the user has specified a alternate settings file name. // Load it now before loading the user_settings/settings.xml if(clp.hasOption("settings")) @@ -4682,6 +4709,12 @@ void LLAppViewer::handleLoginComplete() } mOnLoginCompleted(); + // Singu Note: Due to MAINT-4001, we must do this here, it lives in LLSidepanelInventory::updateInbox upstream. + // Consolidate Received items + // We shouldn't have to do that but with a client/server system relying on a "well known folder" convention, + // things can get messy and conventions broken. This call puts everything back together in its right place. + LLUUID id(gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, true)); + if (id.notNull()) gInventory.consolidateForType(id, LLFolderType::FT_INBOX); writeDebugInfo(); } diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index c923462fd..a8e2454f4 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -133,11 +133,13 @@ LLAppViewerLinux::~LLAppViewerLinux() bool LLAppViewerLinux::init() { +#if !GLIB_CHECK_VERSION(2, 32, 0) // g_thread_init() must be called before *any* use of glib, *and* // before any mutexes are held, *and* some of our third-party // libraries likes to use glib functions; in short, do this here // really early in app startup! if (!g_thread_supported ()) g_thread_init (NULL); +#endif bool success = LLAppViewer::init(); @@ -277,7 +279,9 @@ bool LLAppViewerLinux::initSLURLHandler() return false; // failed } +#if !GLIB_CHECK_VERSION(2, 36, 0) g_type_init(); +#endif //ViewerAppAPI *api_server = (ViewerAppAPI*) g_object_new(viewerappapi_get_type(), NULL); @@ -297,7 +301,9 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) DBusGConnection *bus; GError *error = NULL; +#if !GLIB_CHECK_VERSION(2, 36, 0) g_type_init(); +#endif bus = lldbus_g_bus_get (DBUS_BUS_SESSION, &error); if (bus) diff --git a/indra/newview/llassetuploadqueue.cpp b/indra/newview/llassetuploadqueue.cpp index f0d0fa761..97c73b64c 100644 --- a/indra/newview/llassetuploadqueue.cpp +++ b/indra/newview/llassetuploadqueue.cpp @@ -75,10 +75,10 @@ public: delete mData; } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + /*virtual*/ void httpFailure(void) { - llwarns << "Error: " << reason << llendl; - LLUpdateTaskInventoryResponder::error(statusNum, reason); + llwarns << "Error: " << mReason << llendl; + LLUpdateTaskInventoryResponder::httpFailure(); LLAssetUploadQueue *queue = mSupplier->get(); if (queue) { @@ -86,15 +86,15 @@ public: } } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { - LLUpdateTaskInventoryResponder::result(content); + LLUpdateTaskInventoryResponder::httpSuccess(); LLAssetUploadQueue *queue = mSupplier->get(); if (queue) { // Responder is reused across 2 phase upload, // so only start next upload after 2nd phase complete. - std::string state = content["state"]; + std::string state = mContent["state"]; if(state == "complete") { queue->request(&mSupplier); diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 004152f46..16dd0d4e5 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -223,12 +223,12 @@ LLAssetUploadResponder::~LLAssetUploadResponder() } // virtual -void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason) +void LLAssetUploadResponder::httpFailure(void) { - llinfos << "LLAssetUploadResponder::error " << statusNum - << " reason: " << reason << llendl; + llinfos << "LLAssetUploadResponder::error " << mStatus + << " reason: " << mReason << llendl; LLSD args; - switch(statusNum) + switch(mStatus) { case 400: args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName); @@ -248,15 +248,15 @@ void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason) } //virtual -void LLAssetUploadResponder::result(const LLSD& content) +void LLAssetUploadResponder::httpSuccess(void) { lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl; - std::string state = content["state"]; + std::string state = mContent["state"]; if (state == "upload") { - uploadUpload(content); + uploadUpload(mContent); } else if (state == "complete") { @@ -264,14 +264,14 @@ void LLAssetUploadResponder::result(const LLSD& content) if (mFileName.empty()) { // rename the file in the VFS to the actual asset id - // llinfos << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << llendl; - gVFS->renameFile(mVFileID, mAssetType, content["new_asset"].asUUID(), mAssetType); + // llinfos << "Changing uploaded asset UUID to " << mContent["new_asset"].asUUID() << llendl; + gVFS->renameFile(mVFileID, mAssetType, mContent["new_asset"].asUUID(), mAssetType); } - uploadComplete(content); + uploadComplete(mContent); } else { - uploadFailure(content); + uploadFailure(mContent); } } @@ -332,13 +332,13 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( } // virtual -void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason) +void LLNewAgentInventoryResponder::httpFailure(void) { if (mCallBack) { (*mCallBack)(false, mUserData); } - LLAssetUploadResponder::error(statusNum, reason); + LLAssetUploadResponder::httpFailure(); //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE); } @@ -498,9 +498,9 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content) } } -void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason) +void LLSendTexLayerResponder::httpFailure(void) { - llinfos << "status: " << statusNum << " reason: " << reason << llendl; + llinfos << "status: " << mStatus << " reason: " << mReason << llendl; // Invoke the original callback with an error result LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); @@ -1020,20 +1020,17 @@ LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResp delete mImpl; } -void LLNewAgentInventoryVariablePriceResponder::errorWithContent( - U32 statusNum, - const std::string& reason, - const LLSD& content) +void LLNewAgentInventoryVariablePriceResponder::httpFailure(void) { lldebugs - << "LLNewAgentInventoryVariablePrice::error " << statusNum - << " reason: " << reason << llendl; + << "LLNewAgentInventoryVariablePrice::error " << mStatus + << " reason: " << mReason << llendl; - if ( content.has("error") ) + if ( mContent.has("error") ) { static const std::string _ERROR = "error"; - mImpl->onTransportError(content[_ERROR]); + mImpl->onTransportError(mContent[_ERROR]); } else { @@ -1041,7 +1038,7 @@ void LLNewAgentInventoryVariablePriceResponder::errorWithContent( } } -void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content) +void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) { // Parse out application level errors and the appropriate // responses for them @@ -1056,13 +1053,13 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content) static const std::string _RSVP = "rsvp"; // Check for application level errors - if (content.has(_ERROR)) + if (mContent.has(_ERROR)) { - onApplicationLevelError(content[_ERROR]); + onApplicationLevelError(mContent[_ERROR]); return; } - std::string state = content[_STATE]; + std::string state = mContent[_STATE]; LLAssetType::EType asset_type = mImpl->getAssetType(); if (_COMPLETE == state) @@ -1071,11 +1068,11 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content) if (mImpl->getFilename().empty()) { // rename the file in the VFS to the actual asset id - // llinfos << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << llendl; + // llinfos << "Changing uploaded asset UUID to " << mContent["new_asset"].asUUID() << llendl; gVFS->renameFile( mImpl->getVFileID(), asset_type, - content["new_asset"].asUUID(), + mContent["new_asset"].asUUID(), asset_type); } @@ -1086,8 +1083,8 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content) mImpl->getFolderID(), mImpl->getItemName(), mImpl->getItemDescription(), - content, - content[_UPLOAD_PRICE].asInteger()); + mContent, + mContent[_UPLOAD_PRICE].asInteger()); // TODO* Add bulk (serial) uploading or add // a super class of this that does so @@ -1095,9 +1092,9 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content) else if ( _CONFIRM_UPLOAD == state ) { showConfirmationDialog( - content[_UPLOAD_PRICE].asInteger(), - content[_RESOURCE_COST].asInteger(), - content[_RSVP].asString()); + mContent[_UPLOAD_PRICE].asInteger(), + mContent[_RESOURCE_COST].asInteger(), + mContent[_RSVP].asString()); } else { diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index bdcf41390..2c2b87152 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -61,8 +61,8 @@ public: const std::string& file_name, LLAssetType::EType asset_type); ~LLAssetUploadResponder(); - /*virtual*/ void error(U32 statusNum, const std::string& reason); - /*virtual*/ void result(const LLSD& content); + /*virtual*/ void httpFailure(void); + /*virtual*/ void httpSuccess(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return assetUploadResponder_timeout; } virtual void uploadUpload(const LLSD& content); @@ -91,7 +91,7 @@ public: const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type); - /*virtual*/ void error(U32 statusNum, const std::string& reason); + /*virtual*/ void httpFailure(void); virtual void uploadComplete(const LLSD& content); virtual void uploadFailure(const LLSD& content); /*virtual*/ char const* getName(void) const { return "LLNewAgentInventoryResponder"; } @@ -116,11 +116,8 @@ public: const LLSD& inventory_info); virtual ~LLNewAgentInventoryVariablePriceResponder(); - /*virtual*/ void errorWithContent( - U32 statusNum, - const std::string& reason, - const LLSD& content); - /*virtual*/ void result(const LLSD& content); + /*virtual*/ void httpFailure(void); + /*virtual*/ void httpSuccess(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return newAgentInventoryVariablePriceResponder_timeout; } virtual void onApplicationLevelError( @@ -148,7 +145,7 @@ public: ~LLSendTexLayerResponder(); /*virtual*/ void uploadComplete(const LLSD& content); - /*virtual*/ void error(U32 statusNum, const std::string& reason); + /*virtual*/ void httpFailure(void); /*virtual*/ char const* getName(void) const { return "LLSendTexLayerResponder"; } LLBakedUploadData * mBakedUploadData; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index d9c5e9153..fae1b7c3d 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -37,6 +37,7 @@ #include "llagent.h" #include "llcallingcard.h" // for LLAvatarTracker #include "llfloateravatarinfo.h" +#include "llfloatergroupbulkban.h" #include "llfloatergroupinvite.h" #include "llfloatergroups.h" #include "llfloaterwebprofile.h" @@ -506,8 +507,12 @@ void LLAvatarActions::on_avatar_name_cache_teleport_request(const LLUUID& id, co { LLSD notification; notification["uuid"] = id; - //notification["NAME_SLURL"] = LLSLURL("agent", id, "about").getSLURLString(); std::string name; +// [RLVa:KB] - Checked: 2014-03-31 (Catznip-3.6) + if (!RlvActions::canShowName(RlvActions::SNC_TELEPORTREQUEST)) + name = RlvStrings::getAnonym(av_name.getLegacyName()); + else +// [RLVa:KB] LLAvatarNameCache::getPNSName(av_name, name); notification["NAME"] = name; LLSD payload; @@ -743,6 +748,24 @@ bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response, return false; } +// Ban from group functions +void callback_ban_from_group(const LLUUID& group, uuid_vec_t& ids) +{ + LLFloaterGroupBulkBan::showForGroup(group, &ids); +} + +void ban_from_group(const uuid_vec_t& ids) +{ + if (LLFloaterGroupPicker* widget = LLFloaterGroupPicker::showInstance(ids.front())) // It'd be cool if LLSD could be formed from uuid_vec_t + { + widget->center(); + widget->setPowersMask(GP_GROUP_BAN_ACCESS); + widget->removeNoneOption(); + widget->setSelectGroupCallback(boost::bind(callback_ban_from_group, _1, ids)); + } +} +// + // static void LLAvatarActions::callback_invite_to_group(LLUUID group_id, LLUUID id) { diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 8c38b0597..c56e02654 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -640,7 +640,8 @@ void LLChatBar::onInputEditorFocusLost() // static void LLChatBar::onInputEditorGainFocus() { - LLFloaterChat::setHistoryCursorAndScrollToEnd(); + if (gSavedSettings.getBOOL("LiruLegacyScrollToEnd")) + LLFloaterChat::setHistoryCursorAndScrollToEnd(); } // static diff --git a/indra/newview/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp index a218e2b4e..dfbc63114 100644 --- a/indra/newview/llclassifiedstatsresponder.cpp +++ b/indra/newview/llclassifiedstatsresponder.cpp @@ -50,16 +50,16 @@ mClassifiedID(classified_id) { } /*virtual*/ -void LLClassifiedStatsResponder::result(const LLSD& content) +void LLClassifiedStatsResponder::httpSuccess(void) { - S32 teleport = content["teleport_clicks"].asInteger(); - S32 map = content["map_clicks"].asInteger(); - S32 profile = content["profile_clicks"].asInteger(); - S32 search_teleport = content["search_teleport_clicks"].asInteger(); - S32 search_map = content["search_map_clicks"].asInteger(); - S32 search_profile = content["search_profile_clicks"].asInteger(); + S32 teleport = mContent["teleport_clicks"].asInteger(); + S32 map = mContent["map_clicks"].asInteger(); + S32 profile = mContent["profile_clicks"].asInteger(); + S32 search_teleport = mContent["search_teleport_clicks"].asInteger(); + S32 search_map = mContent["search_map_clicks"].asInteger(); + S32 search_profile = mContent["search_profile_clicks"].asInteger(); - LLPanelClassified* classified_panelp = (LLPanelClassified*)mClassifiedPanelHandle.get(); + LLPanelClassifiedInfo* classified_panelp = (LLPanelClassifiedInfo*)mClassifiedPanelHandle.get(); if(classified_panelp) { @@ -73,10 +73,9 @@ void LLClassifiedStatsResponder::result(const LLSD& content) } /*virtual*/ -void LLClassifiedStatsResponder::error(U32 status, const std::string& reason) +void LLClassifiedStatsResponder::httpFailure(void) { - llinfos << "LLClassifiedStatsResponder::error(" - << status << ": " << reason << ")" << llendl; + llinfos << "httpFailure: " << dumpResponse() << llendl; } diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h index d44d43f78..4eacd3b61 100644 --- a/indra/newview/llclassifiedstatsresponder.h +++ b/indra/newview/llclassifiedstatsresponder.h @@ -45,9 +45,9 @@ class LLClassifiedStatsResponder : public LLHTTPClient::ResponderWithResult public: LLClassifiedStatsResponder(LLHandle classified_panel_handle, LLUUID classified_id); //If we get back a normal response, handle it here - /*virtual*/ void result(const LLSD& content); + /*virtual*/ void httpSuccess(void); //If we get back an error (not found, etc...), handle it here - /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return classifiedStatsResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLClassifiedStatsResponder"; } diff --git a/indra/newview/llcrashlogger.cpp b/indra/newview/llcrashlogger.cpp index cf06a402d..3a2a8c742 100644 --- a/indra/newview/llcrashlogger.cpp +++ b/indra/newview/llcrashlogger.cpp @@ -56,23 +56,23 @@ public: { } - virtual void error(U32 status, const std::string& reason) + virtual void httpFailure(void) { - llwarns << "Crash report sending failed: " << reason << llendl; + llwarns << "Crash report sending failed: " << mReason << llendl; } - virtual void result(const LLSD& content) + virtual void httpSuccess(void) { std::string msg = "Crash report successfully sent"; - if (content.has("message")) + if (mContent.has("message")) { - msg += ": " + content["message"].asString(); + msg += ": " + mContent["message"].asString(); } llinfos << msg << llendl; - if (content.has("report_id")) + if (mContent.has("report_id")) { - gSavedSettings.setS32("CrashReportID", content["report_id"].asInteger()); + gSavedSettings.setS32("CrashReportID", mContent["report_id"].asInteger()); } } @@ -396,7 +396,7 @@ void LLCrashLogger::checkCrashDump() if (pref == 2) return; //never send mCrashHost = gSavedSettings.getString("CrashHostUrl"); - std::string dumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug"; + std::string dumpDir = gDirUtilp->getDumpDir(); // Do we have something to send, and somewhere to send it if (!mCrashHost.empty() && miniDumpExists(dumpDir)) diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp index e2cc5a153..7609358b5 100644 --- a/indra/newview/llcurrencyuimanager.cpp +++ b/indra/newview/llcurrencyuimanager.cpp @@ -265,9 +265,9 @@ bool LLCurrencyUIManager::Impl::checkTransaction() return false; } - if (mResponder->result_code() != CURLE_OK || mResponder->http_status() < 200 || mResponder->http_status() >= 400) + if (mResponder->result_code() != CURLE_OK || mResponder->getStatus() < 200 || mResponder->getStatus() >= 400) { - setError(mResponder->reason(), mResponder->getURL()); + setError(mResponder->getReason(), mResponder->getURL()); } else { switch (mTransactionType) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 78170275b..56fe132d3 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -179,7 +179,7 @@ LLVOVolume* LLDrawable::getVOVolume() const } } -const LLMatrix4& LLDrawable::getRenderMatrix() const +const LLMatrix4a& LLDrawable::getRenderMatrix() const { return isRoot() ? getWorldMatrix() : getParent()->getWorldMatrix(); } @@ -565,6 +565,7 @@ F32 LLDrawable::updateXform(BOOL undamped) dist_squared = dist_vec_squared(new_pos, target_pos); LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot); + // FIXME: This can be negative! It is be possible for some rots to 'cancel out' pos or size changes. dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f; LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt); @@ -588,6 +589,15 @@ F32 LLDrawable::updateXform(BOOL undamped) } } } + else + { + // The following fixes MAINT-1742 but breaks vehicles similar to MAINT-2275 + // dist_squared = dist_vec_squared(old_pos, target_pos); + + // The following fixes MAINT-2247 but causes MAINT-2275 + //dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; + //dist_squared += dist_vec_squared(old_scale, target_scale); + } LLVector3 vec = mCurrentScale-target_scale; @@ -682,17 +692,7 @@ BOOL LLDrawable::updateMove() makeActive(); - BOOL done; - - if (isState(MOVE_UNDAMPED)) - { - done = updateMoveUndamped(); - } - else - { - done = updateMoveDamped(); - } - return done; + return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped(); } BOOL LLDrawable::updateMoveUndamped() @@ -709,7 +709,6 @@ BOOL LLDrawable::updateMoveUndamped() } mVObjp->clearChanged(LLXform::MOVED); - return TRUE; } @@ -833,7 +832,6 @@ void LLDrawable::updateTexture() if (getVOVolume()) { - //getVOVolume()->mFaceMappingChanged = TRUE; gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE); } } @@ -1153,8 +1151,8 @@ BOOL LLDrawable::isVisible() const // Spatial Partition Bridging Drawable //======================================= -LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) -: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) +LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) : + LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) { mBridge = this; mDrawable = root; @@ -1211,8 +1209,7 @@ void LLSpatialBridge::updateSpatialExtents() LLVector4a size = root->mBounds[1]; //VECTORIZE THIS - LLMatrix4a mat; - mat.loadu(mDrawable->getXform()->getWorldMatrix()); + const LLMatrix4a& mat = mDrawable->getXform()->getWorldMatrix(); LLVector4a t; t.splat(0.f); @@ -1242,12 +1239,9 @@ void LLSpatialBridge::updateSpatialExtents() scale.mul(size); mat.rotate(scale, v[3]); - LLVector4a& newMin = mExtents[0]; LLVector4a& newMax = mExtents[1]; - newMin = newMax = center; - for (U32 i = 0; i < 4; i++) { LLVector4a delta; @@ -1279,27 +1273,35 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) { LLCamera ret = camera; LLXformMatrix* mat = mDrawable->getXform(); - LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix(); + const LLVector4a& center = mat->getWorldMatrix().getRow<3>(); - LLVector3 delta = ret.getOrigin() - center; - LLQuaternion rot = ~mat->getRotation(); + LLQuaternion2 invRot; + invRot.setConjugate( LLQuaternion2(mat->getRotation()) ); - delta *= rot; - LLVector3 lookAt = ret.getAtAxis(); - LLVector3 up_axis = ret.getUpAxis(); - LLVector3 left_axis = ret.getLeftAxis(); + LLVector4a delta; + delta.load3(ret.getOrigin().mV); + delta.sub(center); - lookAt *= rot; - up_axis *= rot; - left_axis *= rot; + LLVector4a lookAt; + lookAt.load3(ret.getAtAxis().mV); + LLVector4a up_axis; - if (!delta.isFinite()) + up_axis.load3(ret.getUpAxis().mV); + LLVector4a left_axis; + left_axis.load3(ret.getLeftAxis().mV); + + delta.setRotated(invRot, delta); + lookAt.setRotated(invRot, lookAt); + up_axis.setRotated(invRot, up_axis); + left_axis.setRotated(invRot, left_axis); + + if (!delta.isFinite3()) { - delta.clearVec(); + delta.clear(); } - ret.setOrigin(delta); - ret.setAxes(lookAt, left_axis, up_axis); + ret.setOrigin(LLVector3(delta.getF32ptr())); + ret.setAxes(LLVector3(lookAt.getF32ptr()), LLVector3(left_axis.getF32ptr()), LLVector3(up_axis.getF32ptr())); return ret; } @@ -1419,16 +1421,17 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* group->rebound(); LLVector4a center; - center.setAdd(mExtents[0], mExtents[1]); + const LLVector4a* exts = getSpatialExtents(); + center.setAdd(exts[0], exts[1]); center.mul(0.5f); LLVector4a size; - size.setSub(mExtents[1], mExtents[0]); + size.setSub(exts[1], exts[0]); size.mul(0.5f); if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) || LLPipeline::sImpostorRender || (camera_in.AABBInFrustumNoFarClip(center, size) && - AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist))) + AABBSphereIntersect(exts[0], exts[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist))) { if (!LLPipeline::sImpostorRender && !LLPipeline::sShadowRender && @@ -1591,12 +1594,17 @@ const LLVector3 LLDrawable::getPositionAgent() const { if (isActive()) { - LLVector3 pos(0,0,0); if (!isRoot()) { - pos = mVObjp->getPosition(); + LLVector4a pos; + pos.load3(mVObjp->getPosition().mV); + getRenderMatrix().affineTransform(pos,pos); + return LLVector3(pos.getF32ptr()); + } + else + { + return LLVector3(getRenderMatrix().getRow<3>().getF32ptr()); } - return pos * getRenderMatrix(); } else { diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 421d6b23b..97ad55d5b 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -110,8 +110,8 @@ public: const LLViewerObject *getVObj() const { return mVObjp; } LLVOVolume* getVOVolume() const; // cast mVObjp tp LLVOVolume if OK - const LLMatrix4& getWorldMatrix() const { return mXform.getWorldMatrix(); } - const LLMatrix4& getRenderMatrix() const; + const LLMatrix4a& getWorldMatrix() const { return mXform.getWorldMatrix(); } + const LLMatrix4a& getRenderMatrix() const; void setPosition(LLVector3 v) const { } const LLVector3& getPosition() const { return mXform.getPosition(); } const LLVector3& getWorldPosition() const { return mXform.getPositionW(); } @@ -305,7 +305,7 @@ private: //aligned members LL_ALIGN_16(LLVector4a mPositionGroup); public: - LLXformMatrix mXform; + LL_ALIGN_16(LLXformMatrix mXform); // vis data LLPointer mParent; diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 90701c0f4..3a936eaf8 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -297,17 +297,15 @@ LLViewerTexture *LLFacePool::getTexture() void LLFacePool::removeFaceReference(LLFace *facep) { - if (facep->getReferenceIndex() != -1) + S32 idx = facep->getReferenceIndex(); + if (idx != -1) { - if (facep->getReferenceIndex() != (S32)mReferences.size()) - { - LLFace *back = mReferences.back(); - mReferences[facep->getReferenceIndex()] = back; - back->setReferenceIndex(facep->getReferenceIndex()); - } - mReferences.pop_back(); + facep->setReferenceIndex(-1); + std::vector::iterator face_it(mReferences.begin() + idx); + std::vector::iterator iter = vector_replace_with_last(mReferences, face_it); + if(iter != mReferences.end()) + (*iter)->setReferenceIndex(idx); } - facep->setReferenceIndex(-1); } void LLFacePool::addFaceReference(LLFace *facep) @@ -449,7 +447,7 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params) if (params.mModelMatrix) { llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); - gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix); + gGL.multMatrix(*params.mModelMatrix); } gPipeline.mMatrixOpCount++; } @@ -484,7 +482,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba tex_setup = true; gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gGL.loadMatrix(*params.mTextureMatrix); gPipeline.mTextureMatrixOps++; } } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 74ee302a6..2e2bf3aac 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -515,7 +515,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) tex_setup = true; gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gGL.loadMatrix(*params.mTextureMatrix); gPipeline.mTextureMatrixOps++; } } diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index dacc26422..0c6102f20 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -155,16 +155,9 @@ void LLDrawPoolAvatar::prerender() } } -LLMatrix4& LLDrawPoolAvatar::getModelView() +const LLMatrix4a& LLDrawPoolAvatar::getModelView() { - static LLMatrix4 ret; - - ret.initRows(LLVector4(gGLModelView+0), - LLVector4(gGLModelView+4), - LLVector4(gGLModelView+8), - LLVector4(gGLModelView+12)); - - return ret; + return gGLModelView; } //----------------------------------------------------------------------------- @@ -1333,7 +1326,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) { LLMatrix4 rot_mat; LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + LLMatrix4 cfr(OGL_TO_CFR_ROTATION.getF32ptr()); rot_mat *= cfr; LLVector4 wind; @@ -1390,16 +1383,11 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer U16 offset = 0; - LLMatrix4 mat_vert = skin->mBindShapeMatrix; - glh::matrix4f m((F32*) mat_vert.mMatrix); - m = m.inverse().transpose(); - - F32 mat3[] = - { m.m[0], m.m[1], m.m[2], - m.m[4], m.m[5], m.m[6], - m.m[8], m.m[9], m.m[10] }; - - LLMatrix3 mat_normal(mat3); + LLMatrix4a mat_vert; + mat_vert.loadu(skin->mBindShapeMatrix); + LLMatrix4a mat_inv_trans = mat_vert; + mat_inv_trans.invert(); + mat_inv_trans.transpose(); //let getGeometryVolume know if alpha should override shiny U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture()); @@ -1414,7 +1402,7 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer } //llinfos << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << llendl; - face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); + face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_inv_trans, offset, true); buffer->flush(); } @@ -1540,8 +1528,10 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) } if (joint) { - mat[i] = skin->mInvBindMatrix[i]; - mat[i] *= joint->getWorldMatrix(); + LLMatrix4a tmp; + tmp.loadu((F32*)skin->mInvBindMatrix[i].mMatrix); + tmp.setMul(joint->getWorldMatrix(),tmp); + mat[i] = LLMatrix4(tmp.getF32ptr()); } } @@ -1665,7 +1655,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) if (face->mTextureMatrix && vobj->mTexAnimMode) { gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix); + gGL.loadMatrix(*face->mTextureMatrix); buff->setBuffer(data_mask); buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); gGL.loadIdentity(); diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index af06c4836..bf4a14754 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -68,7 +68,7 @@ public: LLDrawPoolAvatar(); - static LLMatrix4& getModelView(); + static const LLMatrix4a& getModelView(); /*virtual*/ LLDrawPool *instancePool(); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index f0d7b4241..0a0a2d610 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -373,11 +373,7 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di { if (!invisible && shader ) { - LLMatrix4 mat; - mat.initRows(LLVector4(gGLModelView+0), - LLVector4(gGLModelView+4), - LLVector4(gGLModelView+8), - LLVector4(gGLModelView+12)); + LLMatrix4 mat(gGLModelView.getF32ptr()); LLVector3 vec = LLVector3(gShinyOrigin) * mat; LLVector4 vec4(vec, gShinyOrigin.mV[3]); shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); @@ -521,11 +517,7 @@ void LLDrawPoolBump::beginFullbrightShiny() LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { - LLMatrix4 mat; - mat.initRows(LLVector4(gGLModelView+0), - LLVector4(gGLModelView+4), - LLVector4(gGLModelView+8), - LLVector4(gGLModelView+12)); + LLMatrix4 mat(gGLModelView.getF32ptr()); shader->bind(); LLVector3 vec = LLVector3(gShinyOrigin) * mat; LLVector4 vec4(vec, gShinyOrigin.mV[3]); @@ -1497,16 +1489,16 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL { gGL.getTexUnit(1)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gGL.loadMatrix(*params.mTextureMatrix); } gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gGL.loadMatrix(*params.mTextureMatrix); gPipeline.mTextureMatrixOps++; } - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gGL.loadMatrix(*params.mTextureMatrix); gPipeline.mTextureMatrixOps++; tex_setup = true; diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index d1b508065..6b2998617 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -187,7 +187,7 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, gGL.matrixMode(LLRender::MM_TEXTURE); } - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gGL.loadMatrix(*params.mTextureMatrix); gPipeline.mTextureMatrixOps++; tex_setup = true; diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index eb2738078..456fc3301 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -314,8 +314,11 @@ void LLDrawPoolTerrain::drawLoop() { LLFace *facep = *iter; - LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix); - + LLMatrix4a* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix); + if(model_matrix && model_matrix->isIdentity()) + { + model_matrix = NULL; + } if (model_matrix != gGLLastMatrix) { llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); @@ -323,7 +326,7 @@ void LLDrawPoolTerrain::drawLoop() gGL.loadMatrix(gGLModelView); if (model_matrix) { - gGL.multMatrix((GLfloat*) model_matrix->mMatrix); + gGL.multMatrix(*model_matrix); } gPipeline.mMatrixOpCount++; } diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index bb2fb09eb..392522913 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -104,24 +104,46 @@ void LLDrawPoolTree::render(S32 pass) LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1); LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f); - static LLCachedControl sRenderAnimateTrees("RenderAnimateTrees", false); - if (sRenderAnimateTrees) - { - renderTree(); - } - else gGL.getTexUnit(sDiffTex)->bind(mTexturep); - + for (std::vector::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; + if(face->getViewerObject()) + { + LLVOTree* pTree = dynamic_cast(face->getViewerObject()); + if(pTree && !pTree->mDrawList.empty() ) + { + LLMatrix4a* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); + + gGL.loadMatrix(gGLModelView); + gGL.multMatrix(*model_matrix); + gPipeline.mMatrixOpCount++; + + for(std::vector >::iterator iter2 = pTree->mDrawList.begin(); + iter2 != pTree->mDrawList.end(); iter2++) + { + LLDrawInfo& params = *iter2->get(); + gGL.pushMatrix(); + gGL.multMatrix(*params.mModelMatrix); + gPipeline.mMatrixOpCount++; + params.mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + gGL.popMatrix(); + } + continue; + } + } LLVertexBuffer* buff = face->getVertexBuffer(); if(buff) { - LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); - + LLMatrix4a* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); + if(model_matrix && model_matrix->isIdentity()) + { + model_matrix = NULL; + } if (model_matrix != gGLLastMatrix) { gGLLastMatrix = model_matrix; @@ -129,7 +151,7 @@ void LLDrawPoolTree::render(S32 pass) if (model_matrix) { llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); - gGL.multMatrix((GLfloat*) model_matrix->mMatrix); + gGL.multMatrix(*model_matrix); } gPipeline.mMatrixOpCount++; } @@ -209,130 +231,6 @@ void LLDrawPoolTree::endShadowPass(S32 pass) gDeferredTreeShadowProgram.unbind(); } -// -void LLDrawPoolTree::renderTree(BOOL selecting) -{ - LLGLState normalize(GL_NORMALIZE, TRUE); - - // Bind the texture for this tree. - gGL.getTexUnit(sDiffTex)->bind(mTexturep.get(), TRUE); - - U32 indices_drawn = 0; - - gGL.matrixMode(LLRender::MM_MODELVIEW); - - for (std::vector::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *face = *iter; - LLDrawable *drawablep = face->getDrawable(); - - if (drawablep->isDead() || !face->getVertexBuffer()) - { - continue; - } - - face->getVertexBuffer()->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - U16* indicesp = (U16*) face->getVertexBuffer()->getIndicesPointer(); - - // Render each of the trees - LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get(); - - LLColor4U color(255,255,255,255); - - if (!selecting || treep->mGLName != 0) - { - if (selecting) - { - S32 name = treep->mGLName; - - color = LLColor4U((U8)(name >> 16), (U8)(name >> 8), (U8)name, 255); - } - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - //gGL.pushMatrix(); - - LLMatrix4 matrix(gGLModelView); - - // Translate to tree base HACK - adjustment in Z plants tree underground - const LLVector3 &pos_agent = treep->getPositionAgent(); - //gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); - LLMatrix4 trans_mat; - trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); - trans_mat *= matrix; - - // Rotate to tree position and bend for current trunk/wind - // Note that trunk stiffness controls the amount of bend at the trunk as - // opposed to the crown of the tree - // - const F32 TRUNK_STIFF = 22.f; - - LLQuaternion rot = - LLQuaternion(treep->mTrunkBend.magVec()*TRUNK_STIFF*DEG_TO_RAD, LLVector4(treep->mTrunkBend.mV[VX], treep->mTrunkBend.mV[VY], 0)) * - LLQuaternion(90.f*DEG_TO_RAD, LLVector4(0,0,1)) * - treep->getRotation(); - - LLMatrix4 rot_mat(rot); - rot_mat *= trans_mat; - - F32 radius = treep->getScale().magVec()*0.05f; - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = - scale_mat.mMatrix[1][1] = - scale_mat.mMatrix[2][2] = radius; - - scale_mat *= rot_mat; - - //TO-DO: Make these set-able? - const F32 THRESH_ANGLE_FOR_BILLBOARD = 7.5f; //Made LoD now a little less aggressive here -Shyotl - const F32 BLEND_RANGE_FOR_BILLBOARD = 1.5f; - - F32 droop = treep->mDroop + 25.f*(1.f - treep->mTrunkBend.magVec()); - - S32 stop_depth = 0; - F32 app_angle = treep->getAppAngle()*LLVOTree::sTreeFactor; - F32 alpha = 1.0; - S32 trunk_LOD = LLVOTree::sMAX_NUM_TREE_LOD_LEVELS; - - for (S32 j = 0; j < 4; j++) - { - - if (app_angle > LLVOTree::sLODAngles[j]) - { - trunk_LOD = j; - break; - } - } - if(trunk_LOD >= LLVOTree::sMAX_NUM_TREE_LOD_LEVELS) - { - continue ; //do not render. - } - - if (app_angle < (THRESH_ANGLE_FOR_BILLBOARD - BLEND_RANGE_FOR_BILLBOARD)) - { - // - // Draw only the billboard - // - // Only the billboard, can use closer to normal alpha func. - stop_depth = -1; - LLFacePool::LLOverrideFaceColor clr(this, color); - indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); - } - else // if (app_angle > (THRESH_ANGLE_FOR_BILLBOARD + BLEND_RANGE_FOR_BILLBOARD)) - { - // - // Draw only the full geometry tree - // - LLFacePool::LLOverrideFaceColor clr(this, color); - indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); - } - - //gGL.popMatrix(); - } - } -}// - BOOL LLDrawPoolTree::verify() const { /* BOOL ok = TRUE; diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 12f91ea67..daebb322b 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -293,11 +293,10 @@ void LLDrawPoolWater::render(S32 pass) gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); - LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); - LLMatrix4 camera_rot(camera_mat.getMat3()); + LLMatrix4a camera_rot = LLViewerCamera::getInstance()->getModelview(); + camera_rot.extractRotation_affine(); camera_rot.invert(); - - gGL.loadMatrix((F32 *)camera_rot.mMatrix); + gGL.loadMatrix(camera_rot); gGL.matrixMode(LLRender::MM_MODELVIEW); LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot); @@ -727,7 +726,7 @@ void LLDrawPoolWater::shade() gGL.getTexUnit(diffTex)->bind(face->getTexture()); sNeedsReflectionUpdate = TRUE; - + if (water->getUseTexture() || !water->getIsEdgePatch()) { sNeedsDistortionUpdate = TRUE; diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 864975460..83047aa81 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -154,7 +154,8 @@ void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) cons // the windlight sky dome works most conveniently in a coordinate system // where Y is up, so permute our basis vectors accordingly. - gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); + static const LLMatrix4a rot = gGL.genRot(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); + gGL.rotatef(rot); gGL.scalef(0.333f, 0.333f, 0.333f); diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp index 2b4494473..09c05f3af 100644 --- a/indra/newview/llestateinfomodel.cpp +++ b/indra/newview/llestateinfomodel.cpp @@ -118,16 +118,16 @@ class LLEstateChangeInfoResponder : public LLHTTPClient::ResponderWithResult public: // if we get a normal response, handle it here - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { llinfos << "Committed estate info" << llendl; LLEstateInfoModel::instance().notifyCommit(); } // if we get an error response - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { - llwarns << "Failed to commit estate info (" << status << "): " << reason << llendl; + llwarns << "Failed to commit estate info (" << mStatus << "): " << mReason << llendl; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return estateChangeInfoResponder_timeout; } diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index 604f8a7c8..52892c35f 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -73,8 +73,8 @@ namespace void handleMessage(const LLSD& content); - /*virtual*/ void error(U32 status, const std::string& reason); - /*virtual*/ void result(const LLSD& content); + /*virtual*/ void httpFailure(void); + /*virtual*/ void httpSuccess(void); /*virtual*/ bool is_event_poll(void) const { return true; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return eventPollResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLEventPollResponder"; } @@ -179,13 +179,13 @@ namespace } //virtual - void LLEventPollResponder::error(U32 status, const std::string& reason) + void LLEventPollResponder::httpFailure(void) { if (mDone) return; // A HTTP_BAD_GATEWAY (502) error is our standard timeout response // we get this when there are no events. - if ( status == HTTP_BAD_GATEWAY ) + if ( mStatus == HTTP_BAD_GATEWAY ) { mErrorCount = 0; makeRequest(); @@ -199,12 +199,12 @@ namespace + mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC , this); - llwarns << "Unexpected HTTP error. status: " << status << ", reason: " << reason << llendl; + llwarns << "Unexpected HTTP error. status: " << mStatus << ", reason: " << mReason << llendl; } else { llwarns << "LLEventPollResponder::error: <" << mCount << "> got " - << status << ": " << reason + << mStatus << ": " << mReason << (mDone ? " -- done" : "") << llendl; stop(); @@ -226,25 +226,25 @@ namespace } //virtual - void LLEventPollResponder::result(const LLSD& content) + void LLEventPollResponder::httpSuccess(void) { lldebugs << "LLEventPollResponder::result <" << mCount << ">" - << (mDone ? " -- done" : "") << ll_pretty_print_sd(content) << llendl; + << (mDone ? " -- done" : "") << ll_pretty_print_sd(mContent) << llendl; if (mDone) return; mErrorCount = 0; - if (!content.get("events") || - !content.get("id")) + if (!mContent.get("events") || + !mContent.get("id")) { //llwarns << "received event poll with no events or id key" << llendl; makeRequest(); return; } - mAcknowledge = content["id"]; - LLSD events = content["events"]; + mAcknowledge = mContent["id"]; + LLSD events = mContent["events"]; if(mAcknowledge.isUndefined()) { diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 9263b63da..86b840c03 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -69,7 +69,6 @@ BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]) - /* For each vertex, given: B - binormal @@ -207,7 +206,7 @@ void LLFace::destroy() if (mTextureMatrix) { - delete mTextureMatrix; + ll_aligned_free_16(mTextureMatrix); mTextureMatrix = NULL; if (mDrawablep.notNull()) @@ -398,6 +397,7 @@ void LLFace::setSize(S32 num_vertices, const S32 num_indices, bool align) //allocate vertices in blocks of 4 for alignment num_vertices = (num_vertices + 0x3) & ~0x3; } + if (mGeomCount != num_vertices || mIndicesCount != num_indices) { @@ -493,7 +493,11 @@ void LLFace::updateCenterAgent() { if (mDrawablep->isActive()) { - mCenterAgent = mCenterLocal * getRenderMatrix(); + LLVector4a local_pos; + local_pos.load3(mCenterLocal.mV); + + getRenderMatrix().affineTransform(local_pos,local_pos); + mCenterAgent.set(local_pos.getF32ptr()); } else { @@ -521,15 +525,21 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) gGL.getTexUnit(0)->bind(imagep); gGL.pushMatrix(); + + const LLMatrix4a* model_matrix = NULL; if (mDrawablep->isActive()) { - gGL.multMatrix((GLfloat*)mDrawablep->getRenderMatrix().mMatrix); + model_matrix = &(mDrawablep->getRenderMatrix()); } else { - gGL.multMatrix((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); + model_matrix = &mDrawablep->getRegion()->mRenderMatrix; } - + if(model_matrix && !model_matrix->isIdentity()) + { + gGL.multMatrix(*model_matrix); + } + if (mDrawablep->isState(LLDrawable::RIGGED)) { LLVOVolume* volume = mDrawablep->getVOVolume(); @@ -540,7 +550,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { LLGLEnable offset(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.f, -1.f); - gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); + gGL.multMatrix(volume->getRelativeXform()); const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset()); // Singu Note: Implementation changed to utilize a VBO, avoiding fixed functions unless required @@ -808,14 +818,14 @@ bool less_than_max_mag(const LLVector4a& vec) } BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, - const LLMatrix4& mat_vert_in, BOOL global_volume) + const LLMatrix4a& mat_vert_in, BOOL global_volume) { //get bounding box if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) { //VECTORIZE THIS - LLMatrix4a mat_vert; - mat_vert.loadu(mat_vert_in); + const LLMatrix4a& mat_vert = mat_vert_in; + //mat_vert.loadu(mat_vert_in); LLVector4a min,max; @@ -956,9 +966,9 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& po if (mTextureMatrix) // if we have a texture matrix, use it { - LLVector3 tc3(tc); - tc3 = tc3 * *mTextureMatrix; - tc = LLVector2(tc3); + LLVector4a tc4(tc.mV[VX],tc.mV[VY],0.f); + mTextureMatrix->affineTransform(tc4,tc4); + tc.set(tc4.getF32ptr()); } else // otherwise use the texture entry parameters @@ -975,7 +985,7 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& po // by planarProjection(). This is needed to match planar texgen parameters. void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const { - const LLMatrix4& vol_mat = getWorldMatrix(); + const LLMatrix4a& vol_mat = getWorldMatrix(); const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset); const LLVector4a& normal4a = vf.mNormals[0]; const LLVector4a& tangent = vf.mTangents[0]; @@ -994,13 +1004,20 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po F32 ang = acos(projected_binormal.mV[VY]); ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang; - //VECTORIZE THIS - LLVector3 binormal(binormal4a.getF32ptr()); - LLVector3 normal(normal4a.getF32ptr()); - binormal.rotVec(ang, normal); - LLQuaternion local_rot( binormal % normal, binormal, normal ); - *face_rot = local_rot * vol_mat.quaternion(); - *face_pos = vol_mat.getTranslation(); + LLMatrix4a rot = gGL.genRot(ang, normal4a); + rot.rotate(binormal4a, binormal4a); + + LLVector4a x_axis; + x_axis.setCross3(binormal4a, normal4a); + + LLQuaternion2 local_rot(LLQuaternion( LLVector3(x_axis.getF32ptr()), LLVector3(binormal4a.getF32ptr()), LLVector3(normal4a.getF32ptr()) )); + + LLMatrix4 vol_mat2(vol_mat.getF32ptr()); + + local_rot.mul(LLQuaternion2(vol_mat2.quaternion())); + + *face_rot = LLQuaternion(local_rot.getVector4a().getF32ptr()); + face_pos->set(vol_mat.getRow().getF32ptr()); } // Returns the necessary texture transform to align this face's TE to align_to's TE @@ -1083,7 +1100,7 @@ bool LLFace::canRenderAsMask() static const LLCachedControl auto_mask_max_rmse("SHAutoMaskMaxRMSE",.09f); if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask - (!getViewerObject()->isAttachment() && getTexture()->getIsAlphaMask(use_rmse_auto_mask ? auto_mask_max_rmse : -1.f))) // texture actually qualifies for masking (lazily recalculated but expensive) + (getTexture()->getIsAlphaMask((!getViewerObject()->isAttachment() && use_rmse_auto_mask) ? auto_mask_max_rmse : -1.f))) // texture actually qualifies for masking (lazily recalculated but expensive) { if (LLPipeline::sRenderDeferred) { @@ -1202,7 +1219,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_PLANAR("Quick Planar"); BOOL LLFace::getGeometryVolume(const LLVolume& volume, const S32 &f, - const LLMatrix4& mat_vert_in, const LLMatrix3& mat_norm_in, + const LLMatrix4a& mat_vert_in, const LLMatrix4a& mat_norm_in, const U16 &index_offset, bool force_rebuild) { @@ -1311,7 +1328,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, }; llassert(tep->getShiny() <= 3); - color.mV[3] = U8 (alpha[tep->getShiny()] * 255); } } @@ -1350,8 +1366,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - LLMatrix4a mat_normal; - mat_normal.loadu(mat_norm_in); + const LLMatrix4a& mat_normal = mat_norm_in; F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; bool do_xform = false; @@ -1410,7 +1425,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr; gGL.pushMatrix(); - gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix); + gGL.loadMatrix(mat_vert_in); if (rebuild_pos) { @@ -1525,7 +1540,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0); - gGL.popMatrix(); if (cur_shader) @@ -1552,7 +1566,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLQuaternion bump_quat; if (mDrawablep->isActive()) { - bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); + bump_quat = LLQuaternion(LLMatrix4(mDrawablep->getRenderMatrix().getF32ptr())); } if (bump_code) @@ -1714,16 +1728,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, else { //do tex mat, no texgen, no atlas, no bump for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); + { //LLVector4a& norm = vf.mNormals[i]; //LLVector4a& center = *(vf.mCenter); - - LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); - tmp = tmp * *mTextureMatrix; - tc.mV[0] = tmp.mV[0]; - tc.mV[1] = tmp.mV[1]; - *tex_coords0++ = tc; + LLVector4a tc(vf.mTexCoords[i].mV[VX],vf.mTexCoords[i].mV[VY],0.f); + mTextureMatrix->affineTransform(tc,tc); + (tex_coords0++)->set(tc.getF32ptr()); } } } @@ -1741,12 +1751,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, vec.mul(scalea); planarProjection(tc, norm, center, vec); - LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); - tmp = tmp * *mTextureMatrix; - tc.mV[0] = tmp.mV[0]; - tc.mV[1] = tmp.mV[1]; - - *tex_coords0++ = tc; + LLVector4a tmp(tc.mV[VX],tc.mV[VY],0.f); + mTextureMatrix->affineTransform(tmp,tmp); + (tex_coords0++)->set(tmp.getF32ptr()); } } else @@ -1856,10 +1863,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (tex_mode && mTextureMatrix) { - LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); - tmp = tmp * *mTextureMatrix; - tc.mV[0] = tmp.mV[0]; - tc.mV[1] = tmp.mV[1]; + LLVector4a tmp(tc.mV[VX],tc.mV[VY],0.f); + mTextureMatrix->affineTransform(tmp,tmp); + tc.set(tmp.getF32ptr()); } else { @@ -1937,8 +1943,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); - LLMatrix4a mat_vert; - mat_vert.loadu(mat_vert_in); + const LLMatrix4a& mat_vert = mat_vert_in; F32* dst = (F32*) vert.get(); F32* end_f32 = dst+mGeomCount*4; @@ -2055,10 +2060,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVObjp->getVolume()->genTangents(f); - LLVector4Logical mask; - mask.clear(); - mask.setElement<3>(); - LLVector4a* src = vf.mTangents; LLVector4a* end = vf.mTangents+num_vertices; @@ -2067,7 +2068,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector4a tangent_out; mat_normal.rotate(*src, tangent_out); tangent_out.normalize3fast(); - tangent_out.setSelectWithMask(mask, *src, tangent_out); + tangent_out.copyComponent<3>(*src); tangent_out.store4a(tangents); src++; @@ -2385,8 +2386,6 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist) return 0.f ; } - //F32 camera_relative_speed = camera_moving_speed * (lookAt * LLViewerCamera::getInstance()->getVelocityDir()) ; - S32 i = 0 ; for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i); i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; @@ -2427,16 +2426,7 @@ BOOL LLFace::verify(const U32* indices_array) const BOOL ok = TRUE; if( mVertexBuffer.isNull() ) - { - if( mGeomCount ) - { - // This happens before teleports as faces are torn down. - // Stop the crash in DEV-31893 with a null pointer check, - // but present this info. - // To clean up the log, the geometry could be cleared, or the - // face could otherwise be marked for no ::verify. - //AIFIXME: llinfos << "Face with no vertex buffer and " << mGeomCount << " mGeomCount" << llendl; - } + { //no vertex buffer, face is implicitly valid return TRUE; } @@ -2542,7 +2532,7 @@ S32 LLFace::pushVertices(const U16* index_array) const return mIndicesCount; } -const LLMatrix4& LLFace::getRenderMatrix() const +const LLMatrix4a& LLFace::getRenderMatrix() const { return mDrawablep->getRenderMatrix(); } @@ -2558,7 +2548,7 @@ S32 LLFace::renderElements(const U16 *index_array) const else { gGL.pushMatrix(); - gGL.multMatrix((float*)getRenderMatrix().mMatrix); + gGL.multMatrix(getRenderMatrix()); ret = pushVertices(index_array); gGL.popMatrix(); } @@ -2618,7 +2608,10 @@ LLVector3 LLFace::getPositionAgent() const } else { - return mCenterLocal * getRenderMatrix(); + LLVector4a center_local; + center_local.load3(mCenterLocal.mV); + getRenderMatrix().affineTransform(center_local,center_local); + return LLVector3(center_local.getF32ptr()); } } diff --git a/indra/newview/llface.h b/indra/newview/llface.h index feae55853..946098bae 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -100,8 +100,8 @@ public: LLFace(LLDrawable* drawablep, LLViewerObject* objp) { init(drawablep, objp); } ~LLFace() { destroy(); } - const LLMatrix4& getWorldMatrix() const { return mVObjp->getWorldMatrix(mXform); } - const LLMatrix4& getRenderMatrix() const; + const LLMatrix4a& getWorldMatrix() const { return mVObjp->getWorldMatrix(mXform); } + const LLMatrix4a& getRenderMatrix() const; U32 getIndicesCount() const { return mIndicesCount; }; S32 getIndicesStart() const { return mIndicesIndex; }; U16 getGeomCount() const { return mGeomCount; } // vertex count for this face @@ -173,7 +173,7 @@ public: bool canRenderAsMask(); // logic helper BOOL getGeometryVolume(const LLVolume& volume, const S32 &f, - const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, + const LLMatrix4a& mat_vert, const LLMatrix4a& mat_normal, const U16 &index_offset, bool force_rebuild = false); @@ -196,7 +196,7 @@ public: void setSize(S32 numVertices, S32 num_indices = 0, bool align = false); - BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,const LLMatrix4& mat, BOOL global_volume = FALSE); + BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,const LLMatrix4a& mat, BOOL global_volume = FALSE); void init(LLDrawable* drawablep, LLViewerObject* objp); void destroy(); @@ -239,7 +239,7 @@ public: static U32 getRiggedDataMask(U32 type); public: //aligned members - LLVector4a mExtents[2]; + LL_ALIGN_16(LLVector4a mExtents[2]); private: F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ); @@ -258,9 +258,7 @@ public: F32 mLastUpdateTime; F32 mLastSkinTime; F32 mLastMoveTime; - LLMatrix4* mTextureMatrix; - LLMatrix4* mSpecMapMatrix; - LLMatrix4* mNormalMapMatrix; + LLMatrix4a* mTextureMatrix; LLDrawInfo* mDrawInfo; bool mShinyInAlpha; diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 3f34abc1d..cf97d4e82 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -80,17 +80,12 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD LLVolumeImplFlexible::~LLVolumeImplFlexible() { - S32 end_idx = sInstanceList.size()-1; - - if (end_idx != mInstanceIndex) - { - sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; - sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; - sUpdateDelay[mInstanceIndex] = sUpdateDelay[end_idx]; - } - - sInstanceList.pop_back(); - sUpdateDelay.pop_back(); + std::vector::iterator flex_it(sInstanceList.begin() + mInstanceIndex); + std::vector::iterator iter = vector_replace_with_last(sInstanceList, flex_it); + if(iter != sInstanceList.end()) + (*iter)->mInstanceIndex = mInstanceIndex; + std::vector::iterator update_it(sUpdateDelay.begin() + mInstanceIndex); + vector_replace_with_last(sUpdateDelay, update_it); } //static @@ -883,35 +878,38 @@ LLQuaternion LLVolumeImplFlexible::getEndRotation() void LLVolumeImplFlexible::updateRelativeXform(bool force_identity) { - LLQuaternion delta_rot; - LLVector3 delta_pos, delta_scale; + LLVOVolume* vo = (LLVOVolume*) mVO; bool use_identity = vo->mDrawable->isSpatialRoot() || force_identity; + vo->mRelativeXform.setIdentity(); + //matrix from local space to parent relative/global space - delta_rot = use_identity ? LLQuaternion() : vo->mDrawable->getRotation(); - delta_pos = use_identity ? LLVector3(0,0,0) : vo->mDrawable->getPosition(); - delta_scale = LLVector3(1,1,1); + LLVector4a delta_pos; + LLQuaternion2 delta_rot; + if(use_identity) + { + delta_pos.set(0,0,0,1.f); + delta_rot.getVector4aRw() = delta_pos; + } + else + { + delta_pos.load3(vo->mDrawable->getPosition().mV,1.f); + delta_rot.getVector4aRw().loadua(vo->mDrawable->getRotation().mQ); + vo->mRelativeXform.getRow<0>().setRotated(delta_rot,vo->mRelativeXform.getRow<0>()); + vo->mRelativeXform.getRow<1>().setRotated(delta_rot,vo->mRelativeXform.getRow<1>()); + vo->mRelativeXform.getRow<2>().setRotated(delta_rot,vo->mRelativeXform.getRow<2>()); + } - // Vertex transform (4x4) - LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot; - LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot; - LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot; + vo->mRelativeXform.setRow<3>(delta_pos); - vo->mRelativeXform.initRows(LLVector4(x_axis, 0.f), - LLVector4(y_axis, 0.f), - LLVector4(z_axis, 0.f), - LLVector4(delta_pos, 1.f)); - - x_axis.normVec(); - y_axis.normVec(); - z_axis.normVec(); - - vo->mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); + vo->mRelativeXformInvTrans = vo->mRelativeXform; + vo->mRelativeXformInvTrans.invert(); + vo->mRelativeXformInvTrans.transpose(); } -const LLMatrix4& LLVolumeImplFlexible::getWorldMatrix(LLXformMatrix* xform) const +const LLMatrix4a& LLVolumeImplFlexible::getWorldMatrix(LLXformMatrix* xform) const { return xform->getWorldMatrix(); } diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h index d8b322546..8768a13dc 100644 --- a/indra/newview/llflexibleobject.h +++ b/indra/newview/llflexibleobject.h @@ -98,7 +98,7 @@ private: bool isVolumeUnique() const { return true; } bool isVolumeGlobal() const { return true; } bool isActive() const { return true; } - const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const; + const LLMatrix4a& getWorldMatrix(LLXformMatrix* xform) const; void updateRelativeXform(bool force_identity); void doFlexibleUpdate(); // Called to update the simulation void doFlexibleRebuild(); // Called to rebuild the geometry diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index f02fece9c..312296fa5 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -268,7 +268,7 @@ LLFloaterAbout::LLFloaterAbout() 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)"); + support.append("RLV Version: " + (RlvActions::isRlvEnabled() ? RlvStrings::getVersionAbout() : "(disabled)")); // [/RLVa:KB] support.append("\n\n"); diff --git a/indra/newview/llfloateravatar.cpp b/indra/newview/llfloateravatar.cpp new file mode 100644 index 000000000..15033c997 --- /dev/null +++ b/indra/newview/llfloateravatar.cpp @@ -0,0 +1,65 @@ +/** + * @file llfloateravatar.h + * @author Leyla Farazha + * @brief floater for the avatar changer + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ + +/** + * Floater that appears when buying an object, giving a preview + * of its contents and their permissions. + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloateravatar.h" +#include "llmediactrl.h" +#include "lluictrlfactory.h" +#include "llweb.h" + + +LLFloaterAvatar::LLFloaterAvatar(const LLSD& key) + : LLFloater(key) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar.xml", NULL, false); +} + +LLFloaterAvatar::~LLFloaterAvatar() +{ +} + +BOOL LLFloaterAvatar::postBuild() +{ + enableResizeCtrls(true, true, false); + LLMediaCtrl* avatar_picker = findChild("avatar_picker_contents"); + if (avatar_picker) + { + avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); + std::string url = gSavedSettings.getString("AvatarPickerURL"); + url = LLWeb::expandURLSubstitutions(url, LLSD()); + avatar_picker->navigateTo(url, "text/html"); + } + return TRUE; +} + + diff --git a/indra/newview/llfloateravatar.h b/indra/newview/llfloateravatar.h new file mode 100644 index 000000000..10327cf1f --- /dev/null +++ b/indra/newview/llfloateravatar.h @@ -0,0 +1,44 @@ +/** + * @file llfloateravatar.h + * @author Leyla Farazha + * @brief floater for the avatar changer + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ + +#ifndef LL_FLOATER_AVATAR_H +#define LL_FLOATER_AVATAR_H + +#include "llfloater.h" + +class LLFloaterAvatar: + public LLFloater +, public LLFloaterSingleton +{ + friend class LLUISingleton >; +private: + LLFloaterAvatar(const LLSD& key); + /*virtual*/ ~LLFloaterAvatar(); + /*virtual*/ BOOL postBuild(); +}; + +#endif diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 566159cc1..d798540e8 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -554,7 +554,7 @@ void LLFloaterAvatarList::updateAvatarList() // Announce position F32 dist((position - mypos).magVec()); - entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), avatarp, dist < LFSimFeatureHandler::getInstance()->sayRange(), dist < LFSimFeatureHandler::getInstance()->shoutRange()); + entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position) || !(LLWorld::getInstance()->positionRegionValidGlobal(position)), avatarp, dist < LFSimFeatureHandler::getInstance()->sayRange(), dist < LFSimFeatureHandler::getInstance()->shoutRange()); // Mark as typing if they are typing if (avatarp && avatarp->isTyping()) entry->setActivity(LLAvatarListEntry::ACTIVITY_TYPING); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 718750b5f..7bc196997 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -419,24 +419,24 @@ public: LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { } - /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) + /*virtual*/ void httpCompleted(void) { //std::ostringstream ss; - //LLSDSerialize::toPrettyXML(content, ss); + //LLSDSerialize::toPrettyXML(mContent, ss); //llinfos << ss.str() << llendl; // in case of invalid characters, the avatar picker returns a 400 // just set it to process so it displays 'not found' - if (isGoodStatus(status) || status == 400) + if (isGoodStatus(mStatus) || mStatus == 400) { if (LLFloaterAvatarPicker::instanceExists()) { - LLFloaterAvatarPicker::getInstance()->processResponse(mQueryID, content); + LLFloaterAvatarPicker::getInstance()->processResponse(mQueryID, mContent); } } else { - llwarns << "avatar picker failed " << status << " reason " << reason << llendl; + llwarns << "avatar picker failed " << mStatus << " reason " << mReason << llendl; } } diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 02468dd65..b955e31fb 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -863,9 +863,9 @@ bool LLFloaterBuyLandUI::checkTransaction() return false; } - if (mResponder->result_code() != CURLE_OK || mResponder->http_status() < 200 || mResponder->http_status() >= 400) + if (mResponder->result_code() != CURLE_OK || mResponder->getStatus() < 200 || mResponder->getStatus() >= 400) { - tellUserError(mResponder->reason(), mResponder->getURL()); + tellUserError(mResponder->getReason(), mResponder->getURL()); } else { switch (mTransactionType) diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 251397fa6..f4f1ceec6 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1269,7 +1269,7 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata) 0, LLFolderType::FT_NONE, LLInventoryType::IT_ANIMATION, - LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(), + LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), name, callback, expected_upload_cost, userdata); } diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h index deae420fb..c775f4135 100644 --- a/indra/newview/llfloaterbvhpreview.h +++ b/indra/newview/llfloaterbvhpreview.h @@ -40,13 +40,24 @@ class LLVOAvatar; class LLViewerJointMesh; +LL_ALIGN_PREFIX(16) class LLPreviewAnimation : public LLViewerDynamicTexture { public: virtual ~LLPreviewAnimation(); public: - LLPreviewAnimation(S32 width, S32 height); + LLPreviewAnimation(S32 width, S32 height); + + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } /*virtual*/ S8 getType() const ; @@ -69,7 +80,7 @@ protected: LLVector3 mCameraOffset; LLVector3 mCameraRelPos; LLPointer mDummyAvatar; -}; +} LL_ALIGN_POSTFIX(16); class LLFloaterBvhPreview : public LLFloaterNameDesc { diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 348b9235a..664cdd19d 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -336,16 +336,13 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) // static void LLFloaterChat::setHistoryCursorAndScrollToEnd() { - LLViewerTextEditor* history_editor = LLFloaterChat::getInstance(LLSD())->getChild("Chat History Editor"); - LLViewerTextEditor* history_editor_with_mute = LLFloaterChat::getInstance(LLSD())->getChild("Chat History Editor with mute"); - - if (history_editor) + if (LLViewerTextEditor* editor = getInstance()->findChild("Chat History Editor")) { - history_editor->setCursorAndScrollToEnd(); + editor->setCursorAndScrollToEnd(); } - if (history_editor_with_mute) + if (LLViewerTextEditor* editor = getInstance()->findChild("Chat History Editor with mute")) { - history_editor_with_mute->setCursorAndScrollToEnd(); + editor->setCursorAndScrollToEnd(); } } diff --git a/indra/newview/llfloaterclassified.cpp b/indra/newview/llfloaterclassified.cpp index f695da399..9ce3439bd 100644 --- a/indra/newview/llfloaterclassified.cpp +++ b/indra/newview/llfloaterclassified.cpp @@ -106,7 +106,7 @@ void LLFloaterClassifiedInfo::displayClassifiedInfo(const LLUUID& classified_id) void* LLFloaterClassifiedInfo::createClassifiedDetail(void* userdata) { LLFloaterClassifiedInfo *self = (LLFloaterClassifiedInfo*)userdata; - self->mClassifiedPanel = new LLPanelClassified(true, true); + self->mClassifiedPanel = new LLPanelClassifiedInfo(true, true); self->mClassifiedPanel->childSetValue("classified_url", self->mClassifiedID); return self->mClassifiedPanel; } diff --git a/indra/newview/llfloaterclassified.h b/indra/newview/llfloaterclassified.h index 732a5584a..d049467b4 100644 --- a/indra/newview/llfloaterclassified.h +++ b/indra/newview/llfloaterclassified.h @@ -2,7 +2,7 @@ * @file llfloaterclassified.h * @brief Classified information as shown in a floating window from * secondlife:// command handler. - * Just a wrapper for LLPanelClassified. + * Just a wrapper for LLPanelClassifiedInfo. * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -37,7 +37,7 @@ #include "llfloater.h" -class LLPanelClassified; +class LLPanelClassifiedInfo; class LLFloaterClassifiedInfo : LLFloater { @@ -53,7 +53,7 @@ public: private: - LLPanelClassified* mClassifiedPanel; + LLPanelClassifiedInfo* mClassifiedPanel; LLUUID mClassifiedID; }; diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index fdba40110..30cf75dc9 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -90,20 +90,6 @@ BOOL edit_wearable_for_teens(LLWearableType::EType type) } } -//////////////////////////////////////////////////////////////////////////// - -void updateAvatarHeightDisplay() -{ - if (LLFloaterCustomize::instanceExists() && isAgentAvatarValid()) - { - F32 avatar_size = (gAgentAvatarp->mBodySize.mV[VZ]) + (F32)0.17; //mBodySize is actually quite a bit off. - LLFloaterCustomize::getInstance()->getChild("HeightTextM")->setValue(llformat("%.2f", avatar_size) + "m"); - F32 feet = avatar_size / 0.3048; - F32 inches = (feet - (F32)((U32)feet)) * 12.0; - LLFloaterCustomize::getInstance()->getChild("HeightTextI")->setValue(llformat("%d'%d\"", (U32)feet, (U32)inches)); - } - } - ///////////////////////////////////////////////////////////////////// // LLFloaterCustomize @@ -117,7 +103,7 @@ struct WearablePanelData LLFloaterCustomize::LLFloaterCustomize() : LLFloater(std::string("customize")), - mScrollingPanelList( NULL ), + mScrollingPanelList(new LLScrollingPanelList(std::string("panel_list"), LLRect())), mInventoryObserver(NULL), mCurrentWearableType(LLWearableType::WT_INVALID) { @@ -168,8 +154,10 @@ LLFloaterCustomize::~LLFloaterCustomize() // virtual BOOL LLFloaterCustomize::postBuild() { + mMakeOutfitBtn = getChild("Make Outfit"); getChild("Make Outfit")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnMakeOutfit, this)); - getChild("Save Outfit")->setCommitCallback(boost::bind(&LLAppearanceMgr::updateBaseOutfit, LLAppearanceMgr::getInstance())); + mSaveOutfitBtn = getChild("Save Outfit"); + mSaveOutfitBtn->setCommitCallback(boost::bind(&LLAppearanceMgr::updateBaseOutfit, LLAppearanceMgr::getInstance())); refreshCurrentOutfitName(); // Initialize tooltip for save outfit button getChild("Ok")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnOk, this)); getChild("Cancel")->setCommitCallback(boost::bind(&LLFloater::onClickClose, this)); @@ -179,41 +167,46 @@ BOOL LLFloaterCustomize::postBuild() getChild("Export")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnExport, this)); // Tab container - LLTabContainer* tab_container = getChild("customize tab container"); - if(tab_container) + if (mTabContainer = getChild("customize tab container")) { - tab_container->setCommitCallback(boost::bind(&LLFloaterCustomize::onTabChanged, this, _2)); - tab_container->setValidateCallback(boost::bind(&LLFloaterCustomize::onTabPrecommit, this, _1, _2)); + mTabContainer->setCommitCallback(boost::bind(&LLFloaterCustomize::onTabChanged, this, _2)); + mTabContainer->setValidateCallback(boost::bind(&LLFloaterCustomize::onTabPrecommit, this, _1, _2)); } // Remove underwear panels for teens if (gAgent.isTeen()) { - if (tab_container) + if (mTabContainer) { - LLPanel* panel = tab_container->getPanelByName("Undershirt"); - if (panel) tab_container->removeTabPanel(panel); - panel = tab_container->getPanelByName("Underpants"); - if (panel) tab_container->removeTabPanel(panel); + LLPanel* panel = mTabContainer->getPanelByName("Undershirt"); + if (panel) mTabContainer->removeTabPanel(panel); + panel = mTabContainer->getPanelByName("Underpants"); + if (panel) mTabContainer->removeTabPanel(panel); } } - + // Scrolling Panel - initScrollingPanelList(); - + if (LLScrollContainer* scroll_container = getChild("panel_container")) + { + scroll_container->setScrolledView(mScrollingPanelList); + scroll_container->addChild(mScrollingPanelList); + } + + mMetricHeight = getChildView("HeightTextM"); + mImperialHeight = getChildView("HeightTextI"); + return TRUE; } void LLFloaterCustomize::refreshCurrentOutfitName(const std::string& name) { - LLUICtrl* save_outfit_btn = getChild("Save Outfit"); // Set current outfit status (wearing/unsaved). bool dirty = LLAppearanceMgr::getInstance()->isOutfitDirty(); //std::string cof_status_str = getString(dirty ? "Unsaved Changes" : "Now Wearing"); //mOutfitStatus->setText(cof_status_str); - save_outfit_btn->setEnabled(dirty); // No use saving unless dirty + mSaveOutfitBtn->setEnabled(dirty); // No use saving unless dirty - if (name == "") + if (name.empty()) { std::string outfit_name; if (LLAppearanceMgr::getInstance()->getBaseOutfitName(outfit_name)) @@ -221,22 +214,22 @@ void LLFloaterCustomize::refreshCurrentOutfitName(const std::string& name) //mCurrentLookName->setText(outfit_name); LLStringUtil::format_map_t args; args["[OUTFIT]"] = outfit_name; - save_outfit_btn->setToolTip(getString("Save changes to", args)); + mSaveOutfitBtn->setToolTip(getString("Save changes to", args)); return; } std::string string_name = gAgentWearables.isCOFChangeInProgress() ? "Changing outfits" : "No Outfit"; //mCurrentLookName->setText(getString(string_name)); - save_outfit_btn->setToolTip(getString(string_name)); + mSaveOutfitBtn->setToolTip(getString(string_name)); //mOpenOutfitBtn->setEnabled(FALSE); - save_outfit_btn->setEnabled(false); // Can't save right now + mSaveOutfitBtn->setEnabled(false); // Can't save right now } else { //mCurrentLookName->setText(name); LLStringUtil::format_map_t args; args["[OUTFIT]"] = name; - save_outfit_btn->setToolTip(getString("Save changes to", args)); + mSaveOutfitBtn->setToolTip(getString("Save changes to", args)); // Can't just call update verbs since the folder link may not have been created yet. //mOpenOutfitBtn->setEnabled(TRUE); } @@ -305,7 +298,7 @@ void LLFloaterCustomize::setCurrentWearableType( LLWearableType::EType type, boo if(mWearablePanelList[type_int]) { std::string panelname = mWearablePanelList[type_int]->getName(); - childShowTab("customize tab container", panelname); + mTabContainer->selectTabByName(panelname); switchToDefaultSubpart(); } @@ -589,7 +582,14 @@ void LLFloaterCustomize::draw() // arrives. Figure out some way to avoid this if possible. updateInventoryUI(); - updateAvatarHeightDisplay(); + if (isAgentAvatarValid()) + { + F32 avatar_size = (gAgentAvatarp->mBodySize.mV[VZ]) + (F32)0.17; //mBodySize is actually quite a bit off. + mMetricHeight->setValue(llformat("%.2f", avatar_size) + "m"); + F32 feet = avatar_size / 0.3048; + F32 inches = (feet - (F32)((U32)feet)) * 12.0; + mImperialHeight->setValue(llformat("%d'%d\"", (U32)feet, (U32)inches)); + } LLScrollingPanelParam::sUpdateDelayFrames = 0; @@ -670,20 +670,6 @@ const S32 LINE_HEIGHT = 16; const S32 HEADER_PAD = 8; const S32 HEADER_HEIGHT = 3 * (LINE_HEIGHT + LLFLOATER_VPAD) + (2 * LLPANEL_BORDER_WIDTH) + HEADER_PAD; -void LLFloaterCustomize::initScrollingPanelList() -{ - LLScrollContainer* scroll_container = - getChild("panel_container"); - // LLScrollingPanelList's do not import correctly -// mScrollingPanelList = LLUICtrlFactory::getScrollingPanelList(this, "panel_list"); - mScrollingPanelList = new LLScrollingPanelList(std::string("panel_list"), LLRect()); - if (scroll_container) - { - scroll_container->setScrolledView(mScrollingPanelList); - scroll_container->addChild(mScrollingPanelList); - } -} - void LLFloaterCustomize::wearablesChanged(LLWearableType::EType type) { llassert( type < LLWearableType::WT_COUNT ); @@ -878,11 +864,9 @@ void LLFloaterCustomize::updateInventoryUI() { panel->setUIPermissions(perm_mask, is_complete); } - //BOOL is_vis = panel && item && is_complete && (perm_mask & PERM_MODIFY); - //childSetVisible("panel_container", is_vis); } } - childSetEnabled("Make Outfit", all_complete); + mMakeOutfitBtn->setEnabled(all_complete); } diff --git a/indra/newview/llfloatercustomize.h b/indra/newview/llfloatercustomize.h index 3a7d09909..c7246e5fc 100644 --- a/indra/newview/llfloatercustomize.h +++ b/indra/newview/llfloatercustomize.h @@ -69,10 +69,6 @@ public: private: - // Initialization - void initWearablePanels(); - void initScrollingPanelList(); - // Destruction void delayedClose(bool proceed, bool app_quitting); @@ -123,6 +119,9 @@ private: LLScrollingPanelList* mScrollingPanelList; LLScrollContainer* mScrollContainer; + LLView *mMetricHeight, *mImperialHeight; + LLUICtrl *mMakeOutfitBtn, *mSaveOutfitBtn; + LLTabContainer* mTabContainer; LLPointer mResetParams; LLInventoryObserver* mInventoryObserver; diff --git a/indra/newview/llfloaterdestinations.cpp b/indra/newview/llfloaterdestinations.cpp new file mode 100644 index 000000000..219df67ce --- /dev/null +++ b/indra/newview/llfloaterdestinations.cpp @@ -0,0 +1,77 @@ +/** + * @file llfloaterdestinations.h + * @author Leyla Farazha + * @brief floater for the destinations guide + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ + +/** + * Floater that appears when buying an object, giving a preview + * of its contents and their permissions. + */ + +#include "llviewerprecompiledheaders.h" + +#include "lfsimfeaturehandler.h" +#include "llfloaterdestinations.h" +#include "llmediactrl.h" +#include "lluictrlfactory.h" +#include "llweb.h" + + +LLFloaterDestinations::LLFloaterDestinations(const LLSD& key) + : LLFloater(key) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_destinations.xml", NULL, false); +} + +LLFloaterDestinations::~LLFloaterDestinations() +{ +} + +BOOL LLFloaterDestinations::postBuild() +{ + enableResizeCtrls(true, true, false); + LLMediaCtrl* destinations = getChild("destination_guide_contents"); + if (destinations) + { + destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); + std::string url = gSavedSettings.getString("DestinationGuideURL"); + changeURL(destinations, url); + LFSimFeatureHandler::instance().setDestinationGuideURLCallback(boost::bind(&LLFloaterDestinations::changeURL, this, destinations, _1)); + } + return TRUE; +} + +void LLFloaterDestinations::changeURL(LLMediaCtrl* destinations, const std::string& url) +{ + if (url.empty()) + { + close(); + return; + } + + destinations->navigateTo(LLWeb::expandURLSubstitutions(url, LLSD()), "text/html"); +} + + diff --git a/indra/newview/llfloaterdestinations.h b/indra/newview/llfloaterdestinations.h new file mode 100644 index 000000000..619960a1c --- /dev/null +++ b/indra/newview/llfloaterdestinations.h @@ -0,0 +1,45 @@ +/** + * @file llfloaterdestinations.h + * @author Leyla Farazha + * @brief floater for the destinations guide + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ + +#ifndef LL_FLOATER_DESTINATIONS_H +#define LL_FLOATER_DESTINATIONS_H + +#include "llfloater.h" + +class LLFloaterDestinations : + public LLFloater +, public LLFloaterSingleton +{ + friend class LLUISingleton >; +private: + LLFloaterDestinations(const LLSD& key); + /*virtual*/ ~LLFloaterDestinations(); + /*virtual*/ BOOL postBuild(); + void changeURL(class LLMediaCtrl* destinations, const std::string& url); +}; + +#endif diff --git a/indra/newview/llfloaterdirectory.cpp b/indra/newview/llfloaterdirectory.cpp index 64f721dd3..ce2f71e16 100644 --- a/indra/newview/llfloaterdirectory.cpp +++ b/indra/newview/llfloaterdirectory.cpp @@ -53,12 +53,26 @@ #include "lluictrlfactory.h" #include "hippogridmanager.h" +#include "lfsimfeaturehandler.h" #include "llenvmanager.h" #include "llnotificationsutil.h" #include "llviewerregion.h" const char* market_panel = "market_panel"; +void set_tab_visible(LLTabContainer* container, LLPanel* tab, bool visible, LLPanel* prev_tab) +{ + if (visible) + { + if (prev_tab) + container->lockTabs(container->getIndexForPanel(prev_tab) + 1); + container->addTabPanel(tab, tab->getLabel(), false, 0, false, LLTabContainer::START); + if (prev_tab) + container->unlockTabs(); + } + else container->removeTabPanel(tab); +} + class LLPanelDirMarket : public LLPanelDirFind { public: @@ -205,10 +219,7 @@ LLFloaterDirectory::LLFloaterDirectory(const std::string& name) mPanelClassifiedp = NULL; // Build the floater with our tab panel classes - - bool enableWebSearch = gHippoGridManager->getConnectedGrid()->isSecondLife() || - !gHippoGridManager->getConnectedGrid()->getSearchUrl().empty(); - bool enableClassicAllSearch = !gHippoGridManager->getConnectedGrid()->isSecondLife(); + bool secondlife = gHippoGridManager->getConnectedGrid()->isSecondLife(); LLCallbackMap::map_t factory_map; factory_map["classified_panel"] = LLCallbackMap(createClassified, this); @@ -218,15 +229,13 @@ LLFloaterDirectory::LLFloaterDirectory(const std::string& name) factory_map["people_panel"] = LLCallbackMap(createPeople, this); factory_map["groups_panel"] = LLCallbackMap(createGroups, this); factory_map[market_panel] = LLCallbackMap(LLPanelDirMarket::create, this); - if (enableWebSearch) + factory_map["find_all_panel"] = LLCallbackMap(createFindAll, this); + factory_map["showcase_panel"] = LLCallbackMap(createShowcase, this); + if (secondlife) { - // web search and showcase only for SecondLife - factory_map["find_all_panel"] = LLCallbackMap(createFindAll, this); - factory_map["showcase_panel"] = LLCallbackMap(createShowcase, this); - if (!enableClassicAllSearch) factory_map["web_panel"] = LLCallbackMap(createWebPanel, this); + factory_map["web_panel"] = LLCallbackMap(createWebPanel, this); } - - if (enableClassicAllSearch) + else { factory_map["find_all_old_panel"] = LLCallbackMap(createFindAllOld, this); } @@ -240,28 +249,33 @@ LLFloaterDirectory::LLFloaterDirectory(const std::string& name) factory_map["Panel Avatar"] = LLCallbackMap(createPanelAvatar, this); - if (enableWebSearch) - { - mCommitCallbackRegistrar.add("Search.WebFloater", boost::bind(&LLFloaterSearch::open, boost::bind(LLFloaterSearch::getInstance))); - if (enableClassicAllSearch) - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_directory3.xml", &factory_map); - else - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_directory.xml", &factory_map); - } - else - { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_directory2.xml", &factory_map); - } + mCommitCallbackRegistrar.add("Search.WebFloater", boost::bind(&LLFloaterSearch::open, boost::bind(LLFloaterSearch::getInstance))); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_directory.xml", &factory_map); moveResizeHandlesToFront(); - if(mPanelAvatarp) + if (mPanelAvatarp) { mPanelAvatarp->selectTab(0); } LLTabContainer* container = getChild("Directory Tabs"); - if (enableClassicAllSearch) + if (secondlife) { + container->removeTabPanel(getChild("find_all_old_panel")); // Not used + } + else + { + container->removeTabPanel(getChild("web_panel")); // Not needed + LLPanel* panel(getChild("find_all_panel")); + LLPanel* prev_tab(getChild("find_all_old_panel")); + LFSimFeatureHandler& inst(LFSimFeatureHandler::instance()); + set_tab_visible(container, panel, !inst.searchURL().empty(), prev_tab); + inst.setSearchURLCallback(boost::bind(set_tab_visible, container, panel, !boost::bind(&std::string::empty, _1), prev_tab)); + panel = getChild("showcase_panel"); + prev_tab = getChild("events_panel"); + set_tab_visible(container, panel, !inst.destinationGuideURL().empty(), prev_tab); + inst.setDestinationGuideURLCallback(boost::bind(set_tab_visible, container, panel, !boost::bind(&std::string::empty, _1), prev_tab)); + LLPanelDirMarket* marketp = static_cast(container->getPanelByName(market_panel)); container->removeTabPanel(marketp); // Until we get a MarketPlace URL, tab is removed. marketp->handleRegionChange(container); @@ -361,7 +375,7 @@ void *LLFloaterDirectory::createFindAllOld(void* userdata) void* LLFloaterDirectory::createClassifiedDetail(void* userdata) { LLFloaterDirectory *self = (LLFloaterDirectory*)userdata; - self->mPanelClassifiedp = new LLPanelClassified(true, false); + self->mPanelClassifiedp = new LLPanelClassifiedInfo(true, false); self->mPanelClassifiedp->setVisible(FALSE); return self->mPanelClassifiedp; } @@ -439,9 +453,20 @@ void LLFloaterDirectory::requestClassifieds() } } +void LLFloaterDirectory::searchInAll(const std::string& search_text) +{ + LLPanelDirFindAllInterface::search(sInstance->mFindAllPanel, search_text); + performQueryOn2("classified_panel", search_text); + performQueryOn2("events_panel", search_text); + performQueryOn2("groups_panel", search_text); + performQueryOn2("people_panel", search_text); + performQueryOn2("places_panel", search_text); + sInstance->open(); +} + void LLFloaterDirectory::showFindAll(const std::string& search_text) { - showPanel("find_all_panel"); + showPanel(LFSimFeatureHandler::instance().searchURL().empty() ? "find_all_old_panel" : "find_all_panel"); LLPanelDirFindAllInterface::search(sInstance->mFindAllPanel, search_text); } @@ -524,6 +549,12 @@ void LLFloaterDirectory::showPlaces(const std::string& search_text) void LLFloaterDirectory::performQueryOn(const std::string& name, const std::string& search_text) { showPanel(name); + performQueryOn2(name, search_text); +} + +//static +void LLFloaterDirectory::performQueryOn2(const std::string& name, const std::string& search_text) +{ if (search_text.empty()) return; // We're done here. LLPanelDirBrowser* panel = sInstance->getChild(name); panel->getChild("name")->setValue(search_text); @@ -572,12 +603,16 @@ void LLFloaterDirectory::toggleFind(void*) if (!sInstance) { std::string panel = gSavedSettings.getString("LastFindPanel"); - bool hasWebSearch = gHippoGridManager->getConnectedGrid()->isSecondLife() || - !gHippoGridManager->getConnectedGrid()->getSearchUrl().empty(); - if (hasWebSearch && (panel == "find_all_panel" || panel == "showcase_panel")) + if (!gHippoGridManager->getConnectedGrid()->isSecondLife()) { - panel = "find_all_old_panel"; + LFSimFeatureHandler& inst(LFSimFeatureHandler::instance()); + if (panel == "web_panel" + || (inst.searchURL().empty() && panel == "find_all_panel") + || (inst.destinationGuideURL().empty() && panel == "showcase_panel")) + panel = "find_all_old_panel"; } + else if (panel == "find_all_old_panel") panel = "find_all_panel"; + showPanel(panel); // HACK: force query for today's events diff --git a/indra/newview/llfloaterdirectory.h b/indra/newview/llfloaterdirectory.h index b4cbf1f18..0f5f1b501 100644 --- a/indra/newview/llfloaterdirectory.h +++ b/indra/newview/llfloaterdirectory.h @@ -54,7 +54,7 @@ class LLPanelAvatar; class LLPanelEvent; class LLPanelGroup; class LLPanelPlace; -class LLPanelClassified; +class LLPanelClassifiedInfo; // Floater to find people, places, things class LLFloaterDirectory : public LLFloater @@ -71,6 +71,7 @@ public: // Outside UI widgets can spawn this floater with various tabs // selected. + static void searchInAll(const std::string& search_text); static void showFindAll(const std::string& search_text); static void showClassified(const LLUUID& classified_id); static void showClassified(const std::string& search_text = ""); @@ -92,6 +93,7 @@ public: private: static void performQueryOn(const std::string& name, const std::string& search_text); + static void performQueryOn2(const std::string& name, const std::string& search_text); static void showPanel(const std::string& tabname); /*virtual*/ void onClose(bool app_quitting); void focusCurrentPanel(); @@ -131,7 +133,7 @@ public: LLPanel* mPanelGroupHolderp; LLPanelPlace* mPanelPlacep; LLPanelPlace* mPanelPlaceSmallp; - LLPanelClassified* mPanelClassifiedp; + LLPanelClassifiedInfo* mPanelClassifiedp; static S32 sOldSearchCount; // debug static S32 sNewSearchCount; // debug diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp index c28501932..09f6ff402 100644 --- a/indra/newview/llfloaterenvsettings.cpp +++ b/indra/newview/llfloaterenvsettings.cpp @@ -62,6 +62,7 @@ LLFloaterEnvSettings::LLFloaterEnvSettings() : LLFloater(std::string("Environmen // load it up initCallbacks(); + syncMenu(); } LLFloaterEnvSettings::~LLFloaterEnvSettings() @@ -99,14 +100,14 @@ void LLFloaterEnvSettings::initCallbacks(void) void LLFloaterEnvSettings::syncMenu() { LLSliderCtrl* sldr; - sldr = sEnvSettings->getChild("EnvTimeSlider"); + sldr = getChild("EnvTimeSlider"); // sync the clock F32 val = (F32)LLWLParamManager::getInstance()->mAnimator.getDayTime(); std::string timeStr = timeToString(val); LLTextBox* textBox; - textBox = sEnvSettings->getChild("EnvTimeText"); + textBox = getChild("EnvTimeText"); textBox->setValue(timeStr); @@ -125,7 +126,7 @@ void LLFloaterEnvSettings::syncMenu() LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); // sync water params LLColor4 col = param_mgr->getFogColor(); - LLColorSwatchCtrl* colCtrl = sEnvSettings->getChild("EnvWaterColor"); + LLColorSwatchCtrl* colCtrl = getChild("EnvWaterColor"); col.mV[3] = 1.0f; colCtrl->set(col); @@ -182,6 +183,11 @@ LLFloaterEnvSettings* LLFloaterEnvSettings::instance() void LLFloaterEnvSettings::show() { if (RlvActions::hasBehaviour(RLV_BHVR_SETENV)) return; + if (!sEnvSettings) // Liru TODO: Remove this when UI Overhaul merges, it will no longer be an issue. + { + sEnvSettings = new LLFloaterEnvSettings(); + return; // Will now be visible, don't change that. + } LLFloaterEnvSettings* envSettings = instance(); envSettings->syncMenu(); diff --git a/indra/newview/llfloaterexploreanimations.h b/indra/newview/llfloaterexploreanimations.h index 95d97c050..bb3b91469 100644 --- a/indra/newview/llfloaterexploreanimations.h +++ b/indra/newview/llfloaterexploreanimations.h @@ -49,7 +49,7 @@ private: protected: void draw(); - LLPreviewAnimation mAnimPreview; + LL_ALIGN_16(LLPreviewAnimation mAnimPreview); LLRect mPreviewRect; S32 mLastMouseX; S32 mLastMouseY; diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index 7e2ad97c3..bd5cf9d07 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -34,32 +34,24 @@ #include "llfloatergesture.h" -#include "lldir.h" #include "llinventory.h" #include "llmultigesture.h" #include "llagent.h" -#include "llviewerwindow.h" -#include "llbutton.h" -#include "llcombobox.h" -#include "llgesturemgr.h" #include "llfloaterinventory.h" +#include "llfloaterperms.h" +#include "llgesturemgr.h" #include "llinventorymodel.h" #include "llinventorypanel.h" #include "llkeyboard.h" -#include "lllineeditor.h" #include "llpreviewgesture.h" -#include "llresizehandle.h" -#include "llscrollbar.h" -#include "llscrollcontainer.h" #include "llscrolllistctrl.h" -#include "lltextbox.h" #include "lluictrlfactory.h" #include "llviewergesture.h" -#include "llviewertexturelist.h" #include "llviewerinventory.h" +#include "llviewertexturelist.h" +#include "llviewerwindow.h" #include "llvoavatar.h" -#include "llviewercontrol.h" // static LLFloaterGesture* LLFloaterGesture::sInstance = NULL; @@ -367,27 +359,38 @@ void LLFloaterGesture::onClickPlay(void* data) class GestureShowCallback : public LLInventoryCallback { public: - GestureShowCallback(std::string &title) - { - mTitle = title; - } void fire(const LLUUID &inv_item) { - LLPreviewGesture::show(mTitle, inv_item, LLUUID::null); + LLPreviewGesture::show("Gesture: New Gesture", inv_item, LLUUID::null); + + LLInventoryItem* item = gInventory.getItem(inv_item); + if (item) + { + LLPermissions perm = item->getPermissions(); + perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Gestures")); + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures")); + item->setPermissions(perm); + item->updateServer(FALSE); + } } -private: - std::string mTitle; }; // static void LLFloaterGesture::onClickNew(void* data) { - std::string title("Gesture: "); - title.append("New Gesture"); - LLPointer cb = new GestureShowCallback(title); - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - LLUUID::null, LLTransactionID::tnull, "New Gesture", "", LLAssetType::AT_GESTURE, - LLInventoryType::IT_GESTURE, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb); + LLPointer cb = new GestureShowCallback(); + create_inventory_item(gAgent.getID(), + gAgent.getSessionID(), + LLUUID::null, + LLTransactionID::tnull, + "New Gesture", + "", + LLAssetType::AT_GESTURE, + LLInventoryType::IT_GESTURE, + NOT_WEARABLE, + LLFloaterPerms::getNextOwnerPerms("Gestures"), + cb); } diff --git a/indra/newview/llfloatergroupbulkban.cpp b/indra/newview/llfloatergroupbulkban.cpp new file mode 100644 index 000000000..37b53980b --- /dev/null +++ b/indra/newview/llfloatergroupbulkban.cpp @@ -0,0 +1,131 @@ +/** +* @file llfloatergroupbulkban.cpp +* @brief Floater to ban Residents from a group. +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, 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$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatergroupbulkban.h" +#include "llpanelgroupbulkban.h" +#include "lltrans.h" +#include "lldraghandle.h" + +const LLRect FGB_RECT(0, 320, 210, 0); + +class LLFloaterGroupBulkBan::impl +{ +public: + impl(const LLUUID& group_id) : mGroupID(group_id), mBulkBanPanelp(NULL) {} + ~impl() {} + + static void closeFloater(void* data); + +public: + LLUUID mGroupID; + LLPanelGroupBulkBan* mBulkBanPanelp; + + static std::map sInstances; +}; + +// +// Globals +// +std::map LLFloaterGroupBulkBan::impl::sInstances; + +void LLFloaterGroupBulkBan::impl::closeFloater(void* data) +{ + LLFloaterGroupBulkBan* floaterp = (LLFloaterGroupBulkBan*)data; + if(floaterp) + floaterp->close(); +} + +//----------------------------------------------------------------------------- +// Implementation +//----------------------------------------------------------------------------- +LLFloaterGroupBulkBan::LLFloaterGroupBulkBan(const std::string& name, + const LLRect &rect, + const std::string& title, + const LLUUID& group_id) +: LLFloater(name, rect, title) +{ + S32 floater_header_size = LLFLOATER_HEADER_SIZE; + LLRect contents(getRect()); + contents.mTop -= floater_header_size; + + mImpl = new impl(group_id); + mImpl->mBulkBanPanelp = new LLPanelGroupBulkBan(group_id); + + setTitle(mImpl->mBulkBanPanelp->getString("GroupBulkBan")); + mImpl->mBulkBanPanelp->setCloseCallback(impl::closeFloater, this); + mImpl->mBulkBanPanelp->setRect(contents); + + addChild(mImpl->mBulkBanPanelp); +} + +LLFloaterGroupBulkBan::~LLFloaterGroupBulkBan() +{ + if(mImpl->mGroupID.notNull()) + { + impl::sInstances.erase(mImpl->mGroupID); + } + + delete mImpl->mBulkBanPanelp; + delete mImpl; +} + +void LLFloaterGroupBulkBan::showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids) +{ + // Make sure group_id isn't null + if (group_id.isNull()) + { + llwarns << "LLFloaterGroupInvite::showForGroup with null group_id!" << llendl; + return; + } + + // If we don't have a floater for this group, create one. + LLFloaterGroupBulkBan* fgb = get_if_there(impl::sInstances, + group_id, + (LLFloaterGroupBulkBan*)NULL); + if (!fgb) + { + fgb = new LLFloaterGroupBulkBan("groupban", + FGB_RECT, + "Group Ban", + group_id); + fgb->getDragHandle()->setTitle(fgb->mImpl->mBulkBanPanelp->getString("GroupBulkBan")); + + impl::sInstances[group_id] = fgb; + + fgb->mImpl->mBulkBanPanelp->clear(); + } + + if (agent_ids != NULL) + { + fgb->mImpl->mBulkBanPanelp->addUsers(*agent_ids); + } + + fgb->center(); + fgb->open(); + fgb->mImpl->mBulkBanPanelp->update(); +} diff --git a/indra/newview/llfloatergroupbulkban.h b/indra/newview/llfloatergroupbulkban.h new file mode 100644 index 000000000..5eb29b1b6 --- /dev/null +++ b/indra/newview/llfloatergroupbulkban.h @@ -0,0 +1,51 @@ + /** +* @file llfloatergroupbulkban.h +* @brief This floater is a wrapper for LLPanelGroupBulkBan, which +* is used to ban Residents from a specific group. +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, 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$ +*/ + +#ifndef LL_LLFLOATERGROUPBULKBAN_H +#define LL_LLFLOATERGROUPBULKBAN_H + +#include "llfloater.h" +#include "lluuid.h" + +class LLFloaterGroupBulkBan : public LLFloater +{ +public: + virtual ~LLFloaterGroupBulkBan(); + + static void showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids = NULL); + +protected: + LLFloaterGroupBulkBan(const std::string& name, + const LLRect& rect, + const std::string& title, + const LLUUID& group_id = LLUUID::null); + + class impl; + impl* mImpl; +}; + +#endif // LL_LLFLOATERGROUPBULKBAN_H diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 00d31dd1c..8cb6681ba 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -231,21 +231,20 @@ BOOL LLPanelGroups::postBuild() void LLPanelGroups::enableButtons() { - LLCtrlListInterface *group_list = childGetListInterface("group list"); + getChildView("Create")->setEnabled(gAgent.mGroups.count() < gHippoLimits->getMaxAgentGroups()); + LLScrollListCtrl* group_list = getChild("group list"); + if (!group_list) return; LLUUID group_id; - if (group_list) + if (group_list->getNumSelected() == 1) { group_id = group_list->getCurrentID(); - } - - if(group_id != gAgent.getGroupID()) - { - getChildView("Activate")->setEnabled(TRUE); + getChildView("Activate")->setEnabled(group_id != gAgent.getGroupID()); } else { getChildView("Activate")->setEnabled(FALSE); } + if (group_id.notNull()) { getChildView("Info")->setEnabled(TRUE); @@ -258,7 +257,6 @@ void LLPanelGroups::enableButtons() getChildView("IM")->setEnabled(FALSE); getChildView("Leave")->setEnabled(FALSE); } - getChildView("Create")->setEnabled(gAgent.mGroups.count() < gHippoLimits->getMaxAgentGroups()); getChildView("Invite...")->setEnabled(group_id.notNull() && gAgent.hasPowerInGroup(group_id, GP_MEMBER_INVITE)); } diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index c2186450a..0acb80fd8 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -52,6 +52,16 @@ protected: public: LLImagePreviewSculpted(S32 width, S32 height); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + /*virtual*/ S8 getType() const ; void setPreviewTarget(LLImageRaw *imagep, F32 distance); @@ -85,6 +95,16 @@ protected: public: LLImagePreviewAvatar(S32 width, S32 height); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + /*virtual*/ S8 getType() const ; void setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male); diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index ba9233d65..5bf957992 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -52,7 +52,7 @@ //LLFloaterInspect* LLFloaterInspect::sInstance = NULL; -LLFloaterInspect::LLFloaterInspect() +LLFloaterInspect::LLFloaterInspect(const LLSD&) : LLFloater(std::string("Inspect Object")), mDirty(FALSE) { @@ -91,12 +91,6 @@ LLFloaterInspect::~LLFloaterInspect(void) } } -// static -void LLFloaterInspect::showInstance() -{ - getInstance()->open(); -} - void LLFloaterInspect::onOpen() { BOOL forcesel = LLSelectMgr::getInstance()->setForceSelection(TRUE); diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h index f977f5403..5e19d8df3 100644 --- a/indra/newview/llfloaterinspect.h +++ b/indra/newview/llfloaterinspect.h @@ -44,12 +44,11 @@ class LLObjectSelection; class LLScrollListCtrl; class LLUICtrl; -class LLFloaterInspect : public LLFloater, public LLSingleton, public LLVOInventoryListener +class LLFloaterInspect : public LLFloater, public LLFloaterSingleton, public LLVOInventoryListener { - friend class LLSingleton; + friend class LLUISingleton >; public: - static void showInstance(); // static void show(void* ignored = NULL); void onOpen(); virtual BOOL postBuild(); @@ -73,7 +72,7 @@ protected: // private: - LLFloaterInspect(); + LLFloaterInspect(const LLSD&); virtual ~LLFloaterInspect(void); LLSafeHandle mObjectSelection; diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index c067b78a7..2795ce016 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -126,7 +126,7 @@ BOOL LLFloaterJoystick::postBuild() mCheckFlycamEnabled = getChild("JoystickFlycamEnabled"); childSetCommitCallback("JoystickFlycamEnabled",onCommitJoystickEnabled,this); - childSetAction("SpaceNavigatorDefaults", onClickRestoreSNDefaults, this); + getChild("Default")->setCommitCallback(boost::bind(&LLFloaterJoystick::onClickDefault, this, _2)); childSetAction("cancel_btn", onClickCancel, this); childSetAction("ok_btn", onClickOK, this); @@ -301,9 +301,14 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel) } } -void LLFloaterJoystick::onClickRestoreSNDefaults(void *joy_panel) +S32 get_joystick_type(); +void LLFloaterJoystick::onClickDefault(const LLSD& val) { - setSNDefaults(); + S32 type(val.asInteger()); + if (val.isUndefined()) // If button portion, set to default for device. + if ((type = get_joystick_type()) == -1) // Invalid/No device + return; + LLViewerJoystick::getInstance()->setSNDefaults(type); } void LLFloaterJoystick::onClickCancel(void *joy_panel) @@ -332,8 +337,3 @@ void LLFloaterJoystick::onClickOK(void *joy_panel) } } } - -void LLFloaterJoystick::setSNDefaults() -{ - LLViewerJoystick::getInstance()->setSNDefaults(); -} diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index 3ce647e5b..07b4b49c7 100644 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -49,11 +49,10 @@ public: virtual void apply(); // Apply the changed values. virtual void cancel(); // Cancel the changed values. virtual void draw(); - static void setSNDefaults(); private: static void onCommitJoystickEnabled(LLUICtrl*, void*); - static void onClickRestoreSNDefaults(void*); + void onClickDefault(const LLSD& val); static void onClickCancel(void*); static void onClickOK(void*); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 8dfa195f4..d76a43566 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -257,6 +257,8 @@ LLFloaterLand::~LLFloaterLand() // public void LLFloaterLand::refresh() { + if (LLViewerParcelMgr::getInstance()->selectionEmpty()) + LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); mPanelGeneral->refresh(); mPanelObjects->refresh(); mPanelOptions->refresh(); @@ -2397,7 +2399,7 @@ BOOL LLPanelLandAccess::postBuild() childSetCommitCallback("public_access", onCommitPublicAccess, this); childSetCommitCallback("limit_payment", onCommitAny, this); childSetCommitCallback("limit_age_verified", onCommitAny, this); - childSetCommitCallback("GroupCheck", onCommitAny, this); + childSetCommitCallback("GroupCheck", onCommitGroupCheck, this); childSetCommitCallback("PassCheck", onCommitAny, this); childSetCommitCallback("pass_combo", onCommitAny, this); childSetCommitCallback("PriceSpin", onCommitAny, this); @@ -2562,11 +2564,11 @@ void LLPanelLandAccess::refresh() } BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST); - getChild("PassCheck")->setValue(use_pass ); + getChild("PassCheck")->setValue(use_pass); LLCtrlSelectionInterface* passcombo = childGetSelectionInterface("pass_combo"); if (passcombo) { - if (public_access || !use_pass || !use_group) + if (public_access || !use_pass) { passcombo->selectByValue("anyone"); } @@ -2661,12 +2663,11 @@ void LLPanelLandAccess::refresh_ui() { getChildView("GroupCheck")->setEnabled(can_manage_allowed); } - BOOL group_access = getChild("GroupCheck")->getValue().asBoolean(); BOOL sell_passes = getChild("PassCheck")->getValue().asBoolean(); getChildView("PassCheck")->setEnabled(can_manage_allowed); if (sell_passes) { - getChildView("pass_combo")->setEnabled(group_access && can_manage_allowed); + getChildView("pass_combo")->setEnabled(can_manage_allowed); getChildView("PriceSpin")->setEnabled(can_manage_allowed); getChildView("HoursSpin")->setEnabled(can_manage_allowed); } @@ -2731,6 +2732,32 @@ void LLPanelLandAccess::onCommitPublicAccess(LLUICtrl *ctrl, void *userdata) onCommitAny(ctrl, userdata); } +void LLPanelLandAccess::onCommitGroupCheck(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandAccess *self = (LLPanelLandAccess *)userdata; + LLParcel* parcel = self->mParcel->getParcel(); + if (!parcel) + { + return; + } + + BOOL use_pass_list = !self->getChild("public_access")->getValue().asBoolean(); + BOOL use_access_group = self->getChild("GroupCheck")->getValue().asBoolean(); + LLCtrlSelectionInterface* passcombo = self->childGetSelectionInterface("pass_combo"); + if (passcombo) + { + if (use_access_group && use_pass_list) + { + if (passcombo->getSelectedValue().asString() == "group") + { + passcombo->selectByValue("anyone"); + } + } + } + + onCommitAny(ctrl, userdata); +} + // static void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) { @@ -2769,14 +2796,14 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) { use_access_list = TRUE; use_pass_list = self->getChild("PassCheck")->getValue().asBoolean(); - if (use_access_group && use_pass_list) + LLCtrlSelectionInterface* passcombo = self->childGetSelectionInterface("pass_combo"); + if (passcombo) { - LLCtrlSelectionInterface* passcombo = self->childGetSelectionInterface("pass_combo"); - if (passcombo) + if (use_access_group && use_pass_list) { if (passcombo->getSelectedValue().asString() == "group") { - use_access_list = FALSE; + use_access_group = FALSE; } } } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 7c7316513..72e906a65 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -383,6 +383,7 @@ public: static void onCommitPublicAccess(LLUICtrl* ctrl, void *userdata); static void onCommitAny(LLUICtrl* ctrl, void *userdata); + static void onCommitGroupCheck(LLUICtrl* ctrl, void *userdata); static void onClickRemoveAccess(void*); static void onClickRemoveBanned(void*); diff --git a/indra/newview/llfloatermediafilter.cpp b/indra/newview/llfloatermediafilter.cpp new file mode 100644 index 000000000..3b636484b --- /dev/null +++ b/indra/newview/llfloatermediafilter.cpp @@ -0,0 +1,120 @@ +/* + * @file llfloatermediafilter.cpp + * @brief Stupid floater for listing junk + * @author Cinder Biscuits + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloatermediafilter.h" + +#include "llnotificationsutil.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "lltrans.h" +#include "lluictrlfactory.h" + +void on_add_to_list(bool white); +bool handle_add_callback(const LLSD& notification, const LLSD& response, const bool& white); +// TODO: Maybe add removal confirmation? +//bool handle_remove_callback(const LLSD& notification, const LLSD& response); + +LLFloaterMediaFilter::LLFloaterMediaFilter(const LLSD& key) +: LLFloater(key) +{ + mCommitCallbackRegistrar.add("MediaFilter.OnAdd", boost::bind(on_add_to_list, boost::bind(&LLSD::asBoolean, _2))); + mCommitCallbackRegistrar.add("MediaFilter.OnRemove", boost::bind(&LLFloaterMediaFilter::onRemoveFromList, this, boost::bind(&LLSD::asBoolean, _2))); + mMediaListConnection = LLMediaFilter::getInstance()->setMediaListUpdateCallback(boost::bind(&LLFloaterMediaFilter::updateLists, this, _1)); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_lists.xml", NULL, false); +} + +LLFloaterMediaFilter::~LLFloaterMediaFilter() +{ + if (mMediaListConnection.connected()) + mMediaListConnection.disconnect(); +} + +BOOL LLFloaterMediaFilter::postBuild() +{ + mWhitelist = getChild("whitelist"); + mBlacklist = getChild("blacklist"); + updateLists(LLMediaFilter::WHITELIST); + updateLists(LLMediaFilter::BLACKLIST); + mWhitelist->setCommitOnSelectionChange(true); + mBlacklist->setCommitOnSelectionChange(true); + mWhitelist->setCommitCallback(boost::bind(&LLFloaterMediaFilter::enableButton, this, getChildView("remove_whitelist"), mWhitelist)); + mBlacklist->setCommitCallback(boost::bind(&LLFloaterMediaFilter::enableButton, this, getChildView("remove_blacklist"), mBlacklist)); + + return TRUE; +} + +void LLFloaterMediaFilter::updateLists(LLMediaFilter::EMediaList list_type) +{ + bool white(list_type == LLMediaFilter::WHITELIST); + const LLMediaFilter& inst(LLMediaFilter::instance()); + const LLMediaFilter::string_list_t& list = white ? inst.getWhiteList() : inst.getBlackList(); + LLScrollListCtrl* scroll(white ? mWhitelist : mBlacklist); + scroll->clearRows(); + for (LLMediaFilter::string_list_t::const_iterator itr = list.begin(); itr != list.end(); ++itr) + { + LLSD element; + element["columns"][0]["column"] = "list"; + element["columns"][0]["value"] = (*itr); + scroll->addElement(element); + } + enableButton(getChildView(white ? "remove_whitelist" : "remove_blacklist"), scroll); +} + +void LLFloaterMediaFilter::enableButton(LLView* btn, const LLScrollListCtrl* scroll) +{ + btn->setEnabled(!scroll->isEmpty() && scroll->getFirstSelected()); +} + +void on_add_to_list(bool white) +{ + LLSD args; + args["LIST"] = LLTrans::getString(white ? "MediaFilterWhitelist" : "MediaFilterBlacklist"); + LLNotificationsUtil::add("AddToMediaList", args, LLSD(), boost::bind(handle_add_callback, _1, _2, white)); +} + +void LLFloaterMediaFilter::onRemoveFromList(bool white) +{ + std::vector selected = (white ? mWhitelist : mBlacklist)->getAllSelected(); + LLMediaFilter::string_vec_t domains; + for (std::vector::iterator itr = selected.begin(); itr != selected.end(); ++itr) + { + domains.push_back((*itr)->getColumn(0)->getValue().asString()); + } + LLMediaFilter::getInstance()->removeFromMediaList(domains, white ? LLMediaFilter::WHITELIST : LLMediaFilter::BLACKLIST); +} + +bool handle_add_callback(const LLSD& notification, const LLSD& response, const bool& white) +{ + if (LLNotificationsUtil::getSelectedOption(notification, response) == 0) + { + LLMediaFilter::instance().addToMediaList(response["url"].asString(), white ? LLMediaFilter::WHITELIST : LLMediaFilter::BLACKLIST); + } + return false; +} diff --git a/indra/newview/llfloatermediafilter.h b/indra/newview/llfloatermediafilter.h new file mode 100644 index 000000000..6ee23bbab --- /dev/null +++ b/indra/newview/llfloatermediafilter.h @@ -0,0 +1,55 @@ +/* + * @file LLFloaterMediaFilter.h + * @brief Stupid floater for listing junk + * @author Cinder Biscuits + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_FLOATERMEDIAFILTER_H +#define LL_FLOATERMEDIAFILTER_H + +#include "llfloater.h" +#include "llmediafilter.h" + +class LLScrollListCtrl; + +class LLFloaterMediaFilter : public LLFloater, public LLFloaterSingleton +{ + friend class LLUISingleton >; +public: + LLFloaterMediaFilter(const LLSD& key); + BOOL postBuild(); +private: + ~LLFloaterMediaFilter(); + void updateLists(LLMediaFilter::EMediaList list); + void enableButton(LLView* btn, const LLScrollListCtrl* scroll); + void onRemoveFromList(bool white); + + LLScrollListCtrl* mWhitelist; + LLScrollListCtrl* mBlacklist; + boost::signals2::connection mMediaListConnection; +}; + +#endif // LL_FLOATERMEDIAFILTER_H diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 159a25a21..26f4c136c 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1594,9 +1594,11 @@ bool LLModelLoader::doLoadModel() mesh_scale *= normalized_transformation; normalized_transformation = mesh_scale; - glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix); - inv_mat = inv_mat.inverse(); - LLMatrix4 inverse_normalized_transformation(inv_mat.m); + LLMatrix4a inv_mat; + inv_mat.loadu(normalized_transformation); + inv_mat.invert(); + + LLMatrix4 inverse_normalized_transformation(inv_mat.getF32ptr()); domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix(); @@ -5135,9 +5137,10 @@ BOOL LLModelPreview::render() } gGL.pushMatrix(); - LLMatrix4 mat = instance.mTransform; + LLMatrix4a mat; + mat.loadu((F32*)instance.mTransform.mMatrix); - gGL.multMatrix((GLfloat*) mat.mMatrix); + gGL.multMatrix(mat); for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) { @@ -5218,9 +5221,10 @@ BOOL LLModelPreview::render() } gGL.pushMatrix(); - LLMatrix4 mat = instance.mTransform; + LLMatrix4a mat; + mat.loadu((F32*)instance.mTransform.mMatrix); - gGL.multMatrix((GLfloat*) mat.mMatrix); + gGL.multMatrix(mat); bool render_mesh = true; @@ -5325,9 +5329,10 @@ BOOL LLModelPreview::render() } gGL.pushMatrix(); - LLMatrix4 mat = instance.mTransform; + LLMatrix4a mat; + mat.loadu((F32*)instance.mTransform.mMatrix); - gGL.multMatrix((GLfloat*) mat.mMatrix); + gGL.multMatrix(mat); LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 8ac80d41a..46e290dcb 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -311,6 +311,16 @@ public: LLModelPreview(S32 width, S32 height, LLFloater* fmp); virtual ~LLModelPreview(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + void resetPreviewTarget(); void setPreviewTarget(F32 distance); void setTexture(U32 name) { mTextureName = name; } diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index 3d0645b7c..465b7d376 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -176,11 +176,14 @@ void LLFloaterNameDesc::onBtnOK() S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). void *nruserdata = NULL; std::string display_name = LLStringUtil::null; + upload_new_resource(mFilenameAndPath, // file getChild("name_form")->getValue().asString(), getChild("description_form")->getValue().asString(), 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(), + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), display_name, callback, expected_upload_cost, nruserdata); close(false); } diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp new file mode 100644 index 000000000..2f4d5954c --- /dev/null +++ b/indra/newview/llfloaterobjectweights.cpp @@ -0,0 +1,276 @@ +/** + * @file llfloaterobjectweights.cpp + * @brief Object weights advanced view floater + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llfloaterobjectweights.h" + +#include "llparcel.h" + +#include "lltextbox.h" +#include "lluictrlfactory.h" + +#include "llagent.h" +#include "llfloatertools.h" // Singu Note: For placement beside the tools floater when it is opened. +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" + +// virtual +bool LLCrossParcelFunctor::apply(LLViewerObject* obj) +{ + // Add the root object box. + mBoundingBox.addBBoxAgent(LLBBox(obj->getPositionRegion(), obj->getRotationRegion(), obj->getScale() * -0.5f, obj->getScale() * 0.5f).getAxisAligned()); + + // Extend the bounding box across all the children. + LLViewerObject::const_child_list_t children = obj->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); + iter != children.end(); iter++) + { + LLViewerObject* child = *iter; + mBoundingBox.addBBoxAgent(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); + } + + bool result = false; + + LLViewerRegion* region = obj->getRegion(); + if (region) + { + std::vector boxes; + boxes.push_back(mBoundingBox); + result = region->objectsCrossParcel(boxes); + } + + return result; +} + +LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key) +: LLFloater(key), + mSelectedObjects(NULL), + mSelectedPrims(NULL), + mSelectedDownloadWeight(NULL), + mSelectedPhysicsWeight(NULL), + mSelectedServerWeight(NULL), + mSelectedDisplayWeight(NULL), + mSelectedOnLand(NULL), + mRezzedOnLand(NULL), + mRemainingCapacity(NULL), + mTotalCapacity(NULL) +{ + //buildFromFile("floater_tools.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_object_weights.xml", NULL, false); +} + +LLFloaterObjectWeights::~LLFloaterObjectWeights() +{ +} + +// virtual +BOOL LLFloaterObjectWeights::postBuild() +{ + mSelectedObjects = getChild("objects"); + mSelectedPrims = getChild("prims"); + + mSelectedDownloadWeight = getChild("download"); + mSelectedPhysicsWeight = getChild("physics"); + mSelectedServerWeight = getChild("server"); + mSelectedDisplayWeight = getChild("display"); + + mSelectedOnLand = getChild("selected"); + mRezzedOnLand = getChild("rezzed_on_land"); + mRemainingCapacity = getChild("remaining_capacity"); + mTotalCapacity = getChild("total_capacity"); + + return TRUE; +} + +// virtual +void LLFloaterObjectWeights::onOpen() +{ + const LLRect& tools_rect = gFloaterTools->getRect(); + setOrigin(tools_rect.mRight, tools_rect.mTop - getRect().getHeight()); + refresh(); + updateLandImpacts(LLViewerParcelMgr::getInstance()->getFloatingParcelSelection()->getParcel()); +} + +// virtual +void LLFloaterObjectWeights::onWeightsUpdate(const SelectionCost& selection_cost) +{ + mSelectedDownloadWeight->setText(llformat("%.2f", selection_cost.mNetworkCost)); + mSelectedPhysicsWeight->setText(llformat("%.2f", selection_cost.mPhysicsCost)); + mSelectedServerWeight->setText(llformat("%.2f", selection_cost.mSimulationCost)); + + S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost(); + mSelectedDisplayWeight->setText(llformat("%d", render_cost)); + + toggleWeightsLoadingIndicators(false); +} + +//virtual +void LLFloaterObjectWeights::setErrorStatus(U32 status, const std::string& reason) +{ + const std::string text = getString("nothing_selected"); + + mSelectedDownloadWeight->setText(text); + mSelectedPhysicsWeight->setText(text); + mSelectedServerWeight->setText(text); + mSelectedDisplayWeight->setText(text); + + toggleWeightsLoadingIndicators(false); +} + +void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel) +{ + if (!parcel || LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + updateIfNothingSelected(); + } + else + { + S32 rezzed_prims = parcel->getSimWidePrimCount(); + S32 total_capacity = parcel->getSimWideMaxPrimCapacity(); + + mRezzedOnLand->setText(llformat("%d", rezzed_prims)); + mRemainingCapacity->setText(llformat("%d", total_capacity - rezzed_prims)); + mTotalCapacity->setText(llformat("%d", total_capacity)); + + toggleLandImpactsLoadingIndicators(false); + } +} + +void LLFloaterObjectWeights::refresh() +{ + LLSelectMgr* sel_mgr = LLSelectMgr::getInstance(); + + if (sel_mgr->getSelection()->isEmpty()) + { + updateIfNothingSelected(); + } + else + { + S32 prim_count = sel_mgr->getSelection()->getObjectCount(); + S32 link_count = sel_mgr->getSelection()->getRootObjectCount(); + F32 prim_equiv = sel_mgr->getSelection()->getSelectedLinksetCost(); + + mSelectedObjects->setText(llformat("%d", link_count)); + mSelectedPrims->setText(llformat("%d", prim_count)); + mSelectedOnLand->setText(llformat("%.1d", (S32)prim_equiv)); + + LLCrossParcelFunctor func; + if (sel_mgr->getSelection()->applyToRootObjects(&func, true)) + { + // Some of the selected objects cross parcel bounds. + // We don't display object weights and land impacts in this case. + const std::string text = getString("nothing_selected"); + + mRezzedOnLand->setText(text); + mRemainingCapacity->setText(text); + mTotalCapacity->setText(text); + + toggleLandImpactsLoadingIndicators(false); + } + + LLViewerRegion* region = gAgent.getRegion(); + if (region && region->capabilitiesReceived()) + { + for (LLObjectSelection::valid_root_iterator iter = sel_mgr->getSelection()->valid_root_begin(); + iter != sel_mgr->getSelection()->valid_root_end(); ++iter) + { + LLAccountingCostManager::getInstance()->addObject((*iter)->getObject()->getID()); + } + + std::string url = region->getCapability("ResourceCostSelected"); + if (!url.empty()) + { + // Update the transaction id before the new fetch request + generateTransactionID(); + + LLAccountingCostManager::getInstance()->fetchCosts(Roots, url, getObserverHandle()); + toggleWeightsLoadingIndicators(true); + } + } + else + { + //LL_WARNS() << "Failed to get region capabilities" << LL_ENDL; + llwarns << "Failed to get region capabilities" << llendl; + } + } +} + +// virtual +void LLFloaterObjectWeights::generateTransactionID() +{ + mTransactionID.generate(); +} + +void LLFloaterObjectWeights::toggleWeightsLoadingIndicators(bool visible) +{ + /* Singu TODO: LLLoadingIndicator + childSetVisible("download_loading_indicator", visible); + childSetVisible("physics_loading_indicator", visible); + childSetVisible("server_loading_indicator", visible); + childSetVisible("display_loading_indicator", visible); + */ + + mSelectedDownloadWeight->setVisible(!visible); + mSelectedPhysicsWeight->setVisible(!visible); + mSelectedServerWeight->setVisible(!visible); + mSelectedDisplayWeight->setVisible(!visible); +} + +void LLFloaterObjectWeights::toggleLandImpactsLoadingIndicators(bool visible) +{ + /* Singu TODO: LLLoadingIndicator + childSetVisible("selected_loading_indicator", visible); + childSetVisible("rezzed_on_land_loading_indicator", visible); + childSetVisible("remaining_capacity_loading_indicator", visible); + childSetVisible("total_capacity_loading_indicator", visible); + */ + + mSelectedOnLand->setVisible(!visible); + mRezzedOnLand->setVisible(!visible); + mRemainingCapacity->setVisible(!visible); + mTotalCapacity->setVisible(!visible); +} + +void LLFloaterObjectWeights::updateIfNothingSelected() +{ + const std::string text = getString("nothing_selected"); + + mSelectedObjects->setText(text); + mSelectedPrims->setText(text); + + mSelectedDownloadWeight->setText(text); + mSelectedPhysicsWeight->setText(text); + mSelectedServerWeight->setText(text); + mSelectedDisplayWeight->setText(text); + + mSelectedOnLand->setText(text); + mRezzedOnLand->setText(text); + mRemainingCapacity->setText(text); + mTotalCapacity->setText(text); + + toggleWeightsLoadingIndicators(false); + toggleLandImpactsLoadingIndicators(false); +} diff --git a/indra/newview/llfloaterobjectweights.h b/indra/newview/llfloaterobjectweights.h new file mode 100644 index 000000000..018627824 --- /dev/null +++ b/indra/newview/llfloaterobjectweights.h @@ -0,0 +1,94 @@ +/** + * @file llfloaterobjectweights.h + * @brief Object weights advanced view floater + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ + +#ifndef LL_LLFLOATEROBJECTWEIGHTS_H +#define LL_LLFLOATEROBJECTWEIGHTS_H + +#include "llfloater.h" + +#include "llaccountingcostmanager.h" +#include "llselectmgr.h" + +class LLParcel; +class LLTextBox; + +/** + * struct LLCrossParcelFunctor + * + * A functor that checks whether a bounding box for all + * selected objects crosses a region or parcel bounds. + */ +struct LLCrossParcelFunctor : public LLSelectedObjectFunctor +{ + /*virtual*/ bool apply(LLViewerObject* obj); + +private: + LLBBox mBoundingBox; +}; + + +class LLFloaterObjectWeights : public LLFloater, LLAccountingCostObserver +, public LLFloaterSingleton +{ +public: + LOG_CLASS(LLFloaterObjectWeights); + + LLFloaterObjectWeights(const LLSD& key); + ~LLFloaterObjectWeights(); + + /*virtual*/ BOOL postBuild(); + + /*virtual*/ void onOpen(); + + /*virtual*/ void onWeightsUpdate(const SelectionCost& selection_cost); + /*virtual*/ void setErrorStatus(U32 status, const std::string& reason); + + void updateLandImpacts(const LLParcel* parcel); + void refresh(); + +private: + /*virtual*/ void generateTransactionID(); + + void toggleWeightsLoadingIndicators(bool visible); + void toggleLandImpactsLoadingIndicators(bool visible); + + void updateIfNothingSelected(); + + LLTextBox *mSelectedObjects; + LLTextBox *mSelectedPrims; + + LLTextBox *mSelectedDownloadWeight; + LLTextBox *mSelectedPhysicsWeight; + LLTextBox *mSelectedServerWeight; + LLTextBox *mSelectedDisplayWeight; + + LLTextBox *mSelectedOnLand; + LLTextBox *mRezzedOnLand; + LLTextBox *mRemainingCapacity; + LLTextBox *mTotalCapacity; +}; + +#endif //LL_LLFLOATEROBJECTWEIGHTS_H diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index df815fd2f..aa6b76c87 100644 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -1,7 +1,7 @@ /** * @file llfloaterperms.cpp * @brief Asset creation permission preferences. - * @author Coco + * @author Jonathan Yap * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -33,152 +33,57 @@ #include "llviewerprecompiledheaders.h" #include "lfsimfeaturehandler.h" +#include "llagent.h" #include "llcheckboxctrl.h" #include "llfloaterperms.h" #include "llnotificationsutil.h" #include "llviewercontrol.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "lluictrlfactory.h" #include "llpermissions.h" #include "hippogridmanager.h" -namespace -{ - bool everyone_export; - void handle_checkboxes(LLUICtrl* ctrl, const LLSD& value) - { - LLPanel* view = static_cast(ctrl->getParent()); - if (ctrl->getName() == "everyone_export") - { - view->childSetEnabled("next_owner_copy", !value); - view->childSetEnabled("next_owner_modify", !value); - view->childSetEnabled("next_owner_transfer", !value); - } - else - { - if (ctrl->getName() == "next_owner_copy") - { - if (!value) // Implements fair use - gSavedSettings.setBOOL("NextOwnerTransfer", true); - view->childSetEnabled("next_owner_transfer", value); - } - if (!value) // If any of these are unchecked, export can no longer be checked. - view->childSetEnabled("everyone_export", false); - else - view->childSetEnabled("everyone_export", LFSimFeatureHandler::instance().simSupportsExport() && (LLFloaterPerms::getNextOwnerPerms() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); - } - } -} +extern class AIHTTPTimeoutPolicy floaterPermsResponder_timeout; -LLFloaterPerms::LLFloaterPerms(const LLSD& seed) -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); -} - -BOOL LLFloaterPerms::postBuild() -{ - //handle_checkboxes - { - bool export_support = LFSimFeatureHandler::instance().simSupportsExport(); - const U32 next_owner_perms = getNextOwnerPerms(); - childSetEnabled("everyone_export", export_support && (next_owner_perms & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); - if (gHippoGridManager->getCurrentGrid()->isSecondLife()) - childSetVisible("everyone_export", false); - - if (!(next_owner_perms & PERM_COPY)) - { - childSetEnabled("next_owner_transfer", false); - } - else if (export_support) - { - bool export_off = !gSavedPerAccountSettings.getBOOL("EveryoneExport"); - childSetEnabled("next_owner_copy", export_off); - childSetEnabled("next_owner_modify", export_off); - childSetEnabled("next_owner_transfer", export_off); - } - else // Set EveryoneExport false, just in case. - gSavedPerAccountSettings.setBOOL("EveryoneExport", false); - } - childSetAction("help", onClickHelp, this); - childSetAction("ok", onClickOK, this); - childSetAction("cancel", onClickCancel, this); - getChild("next_owner_copy")->setCommitCallback(handle_checkboxes); - getChild("next_owner_modify")->setCommitCallback(handle_checkboxes); - getChild("next_owner_transfer")->setCommitCallback(handle_checkboxes); - getChild("everyone_export")->setCommitCallback(handle_checkboxes); - - refresh(); - - return TRUE; -} - -//static -void LLFloaterPerms::onClickOK(void* data) -{ - LLFloaterPerms* self = static_cast(data); - self->ok(); - self->close(); -} - -//static -void LLFloaterPerms::onClickCancel(void* data) -{ - LLFloaterPerms* self = static_cast(data); - self->cancel(); - self->close(); -} - -void LLFloaterPerms::ok() -{ - refresh(); // Changes were already applied to saved settings. Refreshing internal values makes it official. -} - -void LLFloaterPerms::cancel() -{ - gSavedSettings.setBOOL("ShareWithGroup", mShareWithGroup); - gSavedSettings.setBOOL("EveryoneCopy", mEveryoneCopy); - gSavedSettings.setBOOL("NextOwnerCopy", mNextOwnerCopy); - gSavedSettings.setBOOL("NextOwnerModify", mNextOwnerModify); - gSavedSettings.setBOOL("NextOwnerTransfer", mNextOwnerTransfer); - gSavedPerAccountSettings.setBOOL("EveryoneExport", everyone_export); -} - -void LLFloaterPerms::refresh() -{ - mShareWithGroup = gSavedSettings.getBOOL("ShareWithGroup"); - mEveryoneCopy = gSavedSettings.getBOOL("EveryoneCopy"); - mNextOwnerCopy = gSavedSettings.getBOOL("NextOwnerCopy"); - mNextOwnerModify = gSavedSettings.getBOOL("NextOwnerModify"); - mNextOwnerTransfer = gSavedSettings.getBOOL("NextOwnerTransfer"); - everyone_export = gSavedPerAccountSettings.getBOOL("EveryoneExport"); -} - -void LLFloaterPerms::onClose(bool app_quitting) -{ - // Cancel any unsaved changes before closing. - // Note: when closed due to the OK button this amounts to a no-op. - cancel(); - LLFloater::onClose(app_quitting); -} - -//static +//static U32 LLFloaterPerms::getGroupPerms(std::string prefix) -{ - return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY : PERM_NONE; +{ + return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY | PERM_MOVE | PERM_MODIFY : PERM_NONE; } -//static +//static U32 LLFloaterPerms::getEveryonePerms(std::string prefix) { U32 flags = PERM_NONE; - if (LFSimFeatureHandler::instance().simSupportsExport() && prefix.empty() && gSavedPerAccountSettings.getBOOL("EveryoneExport")) // TODO: Bulk enable export? + if (prefix != "Bulk" && LFSimFeatureHandler::instance().simSupportsExport() && prefix.empty() && gSavedPerAccountSettings.getBOOL(prefix+"EveryoneExport")) // Singu TODO: Bulk? flags |= PERM_EXPORT; if (gSavedSettings.getBOOL(prefix+"EveryoneCopy")) flags |= PERM_COPY; return flags; } -//static +//static +U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix) +{ + // Sets bits for permissions that are off + U32 flags = PERM_MOVE; + if (!gSavedSettings.getBOOL(prefix+"NextOwnerCopy")) + { + flags |= PERM_COPY; + } + if (!gSavedSettings.getBOOL(prefix+"NextOwnerModify")) + { + flags |= PERM_MODIFY; + } + if (!gSavedSettings.getBOOL(prefix+"NextOwnerTransfer")) + { + flags |= PERM_TRANSFER; + } + return flags; +} + +//static U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix) { U32 flags = PERM_MOVE; @@ -197,9 +102,232 @@ U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix) return flags; } - -//static -void LLFloaterPerms::onClickHelp(void* data) +namespace { - LLNotificationsUtil::add("ClickUploadHelpPermissions"); + void handle_checkboxes(LLView* view, const std::string& ctrl_name, const LLSD& value, const std::string& type) + { + if (ctrl_name == type+"everyone_export") + { + view->getChildView(type+"next_owner_copy")->setEnabled(!value); + view->getChildView(type+"next_owner_modify")->setEnabled(!value); + view->getChildView(type+"next_owner_transfer")->setEnabled(!value); + } + else + { + if (ctrl_name == type+"next_owner_copy") + { + if (!value) // Implements fair use + gSavedSettings.setBOOL(type+"NextOwnerTransfer", true); + view->getChildView(type+"next_owner_transfer")->setEnabled(value); + } + if (!value) // If any of these are unchecked, export can no longer be checked. + view->getChildView(type+"everyone_export")->setEnabled(false); + else + view->getChildView(type+"everyone_export")->setEnabled(LFSimFeatureHandler::instance().simSupportsExport() && (LLFloaterPerms::getNextOwnerPerms(type) & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); + } + } +} + +static bool mCapSent = false; + +LLFloaterPermsDefault::LLFloaterPermsDefault(const LLSD& seed) + : LLFloater() +{ + mCommitCallbackRegistrar.add("PermsDefault.OK", boost::bind(&LLFloaterPermsDefault::onClickOK, this)); + mCommitCallbackRegistrar.add("PermsDefault.Cancel", boost::bind(&LLFloaterPermsDefault::onClickCancel, this)); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); +} + +// String equivalents of enum Categories - initialization order must match enum order! +const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] = +{ + "Objects", + "Uploads", + "Scripts", + "Notecards", + "Gestures", + "Wearables" +}; + +void LLFloaterPermsDefault::initCheckboxes(bool export_support, const std::string& type) +{ + const U32 next_owner_perms = LLFloaterPerms::getNextOwnerPerms(type); + getChildView(type + "everyone_export")->setEnabled(export_support && (next_owner_perms & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); + + if (!(next_owner_perms & PERM_COPY)) + { + getChildView(type + "next_owner_transfer")->setEnabled(false); + } + else if (export_support) + { + bool export_off = !gSavedPerAccountSettings.getBOOL(type+"EveryoneExport"); + getChildView(type + "next_owner_copy")->setEnabled(export_off); + getChildView(type + "next_owner_modify")->setEnabled(export_off); + getChildView(type + "next_owner_transfer")->setEnabled(export_off); + } + else // Set type+EveryoneExport false, just in case. + gSavedPerAccountSettings.setBOOL(type+"EveryoneExport", false); +} + +BOOL LLFloaterPermsDefault::postBuild() +{ + //handle_checkboxes + bool export_support = LFSimFeatureHandler::instance().simSupportsExport(); + bool is_sl = gHippoGridManager->getCurrentGrid()->isSecondLife(); + for (S32 i = 0; i < CAT_LAST; ++i) + { + const std::string& type(sCategoryNames[i]); + initCheckboxes(export_support, type); + commit_callback_t handle_checks(boost::bind(handle_checkboxes, this, boost::bind(&LLView::getName, _1), _2, type)); + getChild(type + "next_owner_copy")->setCommitCallback(handle_checks); + getChild(type + "next_owner_modify")->setCommitCallback(handle_checks); + getChild(type + "next_owner_transfer")->setCommitCallback(handle_checks); + if (is_sl) + getChildView(type + "everyone_export")->setVisible(false); + else + getChild(type + "everyone_export")->setCommitCallback(handle_checks); + } + if (is_sl) + { + LLView* view(getChildView("ExportationLabel")); + S32 shift(view->getRect().getWidth()); // Determine size of export area + LLRect rect(getRect()); + rect.mRight -= shift; + setRect(rect); // Cut off the export side + view->setVisible(false); // Hide label + // Move bottom buttons over so they look nice. + shift /= -2; + view = getChildView("ok"); + rect = view->getRect(); + rect.translate(shift, 0); + view->setRect(rect); + view = getChildView("cancel"); + rect = view->getRect(); + rect.translate(shift, 0); + view->setRect(rect); + } + + refresh(); + + return TRUE; +} + +void LLFloaterPermsDefault::onClickOK() +{ + ok(); + close(); +} + +void LLFloaterPermsDefault::onClickCancel() +{ + cancel(); + close(); +} + +class LLFloaterPermsResponder : public LLHTTPClient::ResponderWithResult +{ +public: + LLFloaterPermsResponder() : LLHTTPClient::ResponderWithResult() {} +private: + static std::string sPreviousReason; + + void httpFailure(void) + { + // Prevent 404s from annoying the user all the tme + if (mStatus == HTTP_NOT_FOUND) + LL_INFOS("FloaterPermsResponder") << "Failed to send default permissions to simulator. 404, reason: " << mReason << LL_ENDL; + else + // + // Do not display the same error more than once in a row + if (mReason != sPreviousReason) + { + sPreviousReason = mReason; + LLSD args; + args["REASON"] = mReason; + LLNotificationsUtil::add("DefaultObjectPermissions", args); + } + } + void httpSuccess(void) + { + // Since we have had a successful POST call be sure to display the next error message + // even if it is the same as a previous one. + sPreviousReason = ""; + mCapSent = true; + LL_INFOS("FloaterPermsResponder") << "Sent default permissions to simulator" << LL_ENDL; + } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy() const { return floaterPermsResponder_timeout; } + /*virtual*/ char const* getName() const { return "LLFloaterPermsResponder"; } +}; + +std::string LLFloaterPermsResponder::sPreviousReason; + +void LLFloaterPermsDefault::sendInitialPerms() +{ + if (!mCapSent) + { + updateCap(); + } +} + +void LLFloaterPermsDefault::updateCap() +{ + std::string object_url = gAgent.getRegion()->getCapability("AgentPreferences"); + + if (!object_url.empty()) + { + LLSD report = LLSD::emptyMap(); + report["default_object_perm_masks"]["Group"] = + (LLSD::Integer)LLFloaterPerms::getGroupPerms(sCategoryNames[CAT_OBJECTS]); + report["default_object_perm_masks"]["Everyone"] = + (LLSD::Integer)LLFloaterPerms::getEveryonePerms(sCategoryNames[CAT_OBJECTS]); + report["default_object_perm_masks"]["NextOwner"] = + (LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]); + + LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder()); + } +} + +void LLFloaterPermsDefault::ok() +{ + // Changes were already applied to saved settings. + // Refreshing internal values makes it official. + refresh(); + + // We know some setting has changed but not which one. Just in case it was a setting for + // object permissions tell the server what the values are. + updateCap(); +} + +void LLFloaterPermsDefault::cancel() +{ + for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++) + { + gSavedSettings.setBOOL(sCategoryNames[iter]+"ShareWithGroup", mShareWithGroup[iter]); + gSavedSettings.setBOOL(sCategoryNames[iter]+"EveryoneCopy", mEveryoneCopy[iter]); + gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerCopy", mNextOwnerCopy[iter]); + gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerModify", mNextOwnerModify[iter]); + gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerTransfer", mNextOwnerTransfer[iter]); + gSavedPerAccountSettings.setBOOL(sCategoryNames[iter]+"EveryoneExport", mEveryoneExport[iter]); + } +} + +void LLFloaterPermsDefault::refresh() +{ + for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++) + { + mShareWithGroup[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"ShareWithGroup"); + mEveryoneCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"EveryoneCopy"); + mNextOwnerCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerCopy"); + mNextOwnerModify[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerModify"); + mNextOwnerTransfer[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerTransfer"); + mEveryoneExport[iter] = gSavedPerAccountSettings.getBOOL(sCategoryNames[iter]+"EveryoneExport"); + } +} + +void LLFloaterPermsDefault::onClose(bool app_quitting) +{ + // Cancel any unsaved changes before closing. + // Note: when closed due to the OK button this amounts to a no-op. + cancel(); + LLFloater::onClose(app_quitting); } diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h index 9193b5983..52c3159d2 100644 --- a/indra/newview/llfloaterperms.h +++ b/indra/newview/llfloaterperms.h @@ -36,35 +36,55 @@ #include "llfloater.h" -class LLFloaterPerms : public LLFloater, public LLFloaterSingleton +namespace LLFloaterPerms { - friend class LLUISingleton >; + // Convenience methods to get current permission preference bitfields from saved settings: + U32 getEveryonePerms(std::string prefix=""); // prefix + "EveryoneCopy" + U32 getGroupPerms(std::string prefix=""); // prefix + "ShareWithGroup" + U32 getNextOwnerPerms(std::string prefix=""); // bitfield for prefix + "NextOwner" + "Copy", "Modify", and "Transfer" + U32 getNextOwnerPermsInverted(std::string prefix=""); +} + +class LLFloaterPermsDefault : public LLFloater, public LLFloaterSingleton +{ + friend class LLUISingleton >; public: /*virtual*/ void onClose(bool app_quitting = false); /*virtual*/ BOOL postBuild(); + void initCheckboxes(bool export_support, const std::string& type); void ok(); void cancel(); - static void onClickOK(void*); - static void onClickCancel(void*); - // Convenience methods to get current permission preference bitfields from saved settings: - static U32 getEveryonePerms(std::string prefix=""); // prefix + "EveryoneCopy" - static U32 getGroupPerms(std::string prefix=""); // prefix + "ShareWithGroup" - static U32 getNextOwnerPerms(std::string prefix=""); // bitfield for prefix + "NextOwner" + "Copy", "Modify", and "Transfer" + void onClickOK(); + void onClickCancel(); + static void sendInitialPerms(); + static void updateCap(); + + // Update instantiation of sCategoryNames in the .cpp file to match if you change this! + enum Categories + { + CAT_OBJECTS, + CAT_UPLOADS, + CAT_SCRIPTS, + CAT_NOTECARDS, + CAT_GESTURES, + CAT_WEARABLES, + CAT_LAST + }; private: - LLFloaterPerms(const LLSD& seed); + LLFloaterPermsDefault(const LLSD& seed); void refresh(); - /// callback for the menus help button - static void onClickHelp(void* data); + static const std::string sCategoryNames[CAT_LAST]; - BOOL // cached values only for implementing cancel. - mShareWithGroup, - mEveryoneCopy, - mNextOwnerCopy, - mNextOwnerModify, - mNextOwnerTransfer; + // cached values only for implementing cancel. + bool mShareWithGroup[CAT_LAST]; + bool mEveryoneCopy[CAT_LAST]; + bool mEveryoneExport[CAT_LAST]; + bool mNextOwnerCopy[CAT_LAST]; + bool mNextOwnerModify[CAT_LAST]; + bool mNextOwnerTransfer[CAT_LAST]; }; #endif diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index 16321763a..b9b6ef517 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -258,9 +258,9 @@ public: LLAssetUploadResponder::uploadFailure(content); LLFloaterSnapshot::savePostcardDone(false, mSnapshotIndex); } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + /*virtual*/ void httpFailure(void) { - LLAssetUploadResponder::error(statusNum, reason); + LLAssetUploadResponder::httpFailure(); LLFloaterSnapshot::savePostcardDone(false, mSnapshotIndex); } /*virtual*/ char const* getName(void) const { return "LLSendPostcardResponder"; } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index b6d3d5e81..403b04099 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -338,17 +338,18 @@ void LLPreferenceCore::setPersonalInfo(const std::string& visibility, bool im_vi mPrefsIM->setPersonalInfo(visibility, im_via_email, email); } -void LLPreferenceCore::refreshEnabledGraphics() -{ - mDisplayPanel->refreshEnabledState(); -} - ////////////////////////////////////////////// // LLFloaterPreference +void reset_to_default(const std::string& control) +{ + LLUI::getControlControlGroup(control).getControl(control)->resetToDefault(true); +} + LLFloaterPreference::LLFloaterPreference() { mExitWithoutSaving = false; + mCommitCallbackRegistrar.add("Prefs.Reset", boost::bind(reset_to_default, _2)); LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preferences.xml"); } @@ -365,23 +366,13 @@ BOOL LLFloaterPreference::postBuild() return FALSE; } - mAboutBtn = getChild("About..."); - mAboutBtn->setClickedCallback(onClickAbout, this); - - mApplyBtn = getChild("Apply"); - mApplyBtn->setClickedCallback(onBtnApply, this); - - mCancelBtn = getChild("Cancel"); - mCancelBtn->setClickedCallback(onBtnCancel, this); + getChild("About...")->setCommitCallback(boost::bind(LLFloaterAbout::show, (void*)0)); + getChild("Apply")->setCommitCallback(boost::bind(&LLFloaterPreference::onBtnApply, this)); + getChild("Cancel")->setCommitCallback(boost::bind(&LLFloaterPreference::onBtnCancel, this)); + getChild("OK")->setCommitCallback(boost::bind(&LLFloaterPreference::onBtnOK, this)); + + mPreferenceCore = new LLPreferenceCore(getChild("pref core"), getChild("OK")); - mOKBtn = getChild("OK"); - mOKBtn->setClickedCallback(onBtnOK, this); - - mPreferenceCore = new LLPreferenceCore( - getChild("pref core"), - getChild("OK") - ); - sInstance = this; return TRUE; @@ -396,13 +387,13 @@ LLFloaterPreference::~LLFloaterPreference() void LLFloaterPreference::apply() { - this->mPreferenceCore->apply(); + mPreferenceCore->apply(); } void LLFloaterPreference::cancel() { - this->mPreferenceCore->cancel(); + mPreferenceCore->cancel(); } @@ -431,19 +422,11 @@ void LLFloaterPreference::show(void*) } -// static -void LLFloaterPreference::onClickAbout(void*) -{ - LLFloaterAbout::show(NULL); -} - -// static -void LLFloaterPreference::onBtnOK( void* userdata ) +void LLFloaterPreference::onBtnOK() { - LLFloaterPreference *fp =(LLFloaterPreference *)userdata; // commit any outstanding text entry - if (fp->hasFocus()) + if (hasFocus()) { LLUICtrl* cur_focus = dynamic_cast(gFocusMgr.getKeyboardFocus()); if (cur_focus->acceptsTextInput()) @@ -452,17 +435,12 @@ void LLFloaterPreference::onBtnOK( void* userdata ) } } - if (fp->canClose()) + if (canClose()) { - fp->apply(); - fp->close(false); + apply(); + close(false); gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - - std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); - // save all settings, even if equals defaults - // Singu Note: crash settings no longer separate - // gCrashSettings.saveToFile(crash_settings_filename, FALSE); } else { @@ -473,12 +451,9 @@ void LLFloaterPreference::onBtnOK( void* userdata ) LLPanelLogin::updateLocationSelectorsVisibility(); } - -// static -void LLFloaterPreference::onBtnApply( void* userdata ) +void LLFloaterPreference::onBtnApply() { - LLFloaterPreference *fp =(LLFloaterPreference *)userdata; - if (fp->hasFocus()) + if (hasFocus()) { LLUICtrl* cur_focus = dynamic_cast(gFocusMgr.getKeyboardFocus()); if (cur_focus && cur_focus->acceptsTextInput()) @@ -486,7 +461,7 @@ void LLFloaterPreference::onBtnApply( void* userdata ) cur_focus->onCommit(); } } - fp->apply(); + apply(); LLPanelLogin::updateLocationSelectorsVisibility(); } @@ -504,10 +479,9 @@ void LLFloaterPreference::onClose(bool app_quitting) // static -void LLFloaterPreference::onBtnCancel( void* userdata ) +void LLFloaterPreference::onBtnCancel() { - LLFloaterPreference *fp =(LLFloaterPreference *)userdata; - if (fp->hasFocus()) + if (hasFocus()) { LLUICtrl* cur_focus = dynamic_cast(gFocusMgr.getKeyboardFocus()); if (cur_focus->acceptsTextInput()) @@ -515,7 +489,7 @@ void LLFloaterPreference::onBtnCancel( void* userdata ) cur_focus->onCommit(); } } - fp->close(); // side effect will also cancel any unsaved changes. + close(); // side effect will also cancel any unsaved changes. } @@ -528,11 +502,6 @@ void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_ } } -void LLFloaterPreference::refreshEnabledGraphics() -{ - sInstance->mPreferenceCore->refreshEnabledGraphics(); -} - //static void LLFloaterPreference::switchTab(S32 i) { diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index ea6a0e0fd..e16f40cb6 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -76,9 +76,6 @@ public: void setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email); static void onTabChanged(LLUICtrl* ctrl); - - // refresh all the graphics preferences menus - void refreshEnabledGraphics(); private: LLTabContainer *mTabContainer; @@ -113,9 +110,6 @@ public: // static data update, called from message handler static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email); - - // refresh all the graphics preferences menus - static void refreshEnabledGraphics(); static void switchTab(S32 i); @@ -129,16 +123,11 @@ protected: /*virtual*/ void onClose(bool app_quitting); - LLButton* mAboutBtn; - LLButton *mOKBtn; - LLButton *mCancelBtn; - LLButton *mApplyBtn; bool mExitWithoutSaving; - static void onClickAbout(void*); - static void onBtnOK(void*); - static void onBtnCancel(void*); - static void onBtnApply(void*); + void onBtnOK(); + void onBtnCancel(); + void onBtnApply(); static LLFloaterPreference* sInstance; }; diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp index 0418dc180..39404fa20 100644 --- a/indra/newview/llfloaterregiondebugconsole.cpp +++ b/indra/newview/llfloaterregiondebugconsole.cpp @@ -73,14 +73,14 @@ namespace const std::string CONSOLE_NOT_SUPPORTED( "This region does not support the simulator console."); - // This responder handles the initial response. Unless error() is called + // This responder handles the initial response. Unless httpFailure() is called // we assume that the simulator has received our request. Error will be // called if this request times out. // class AsyncConsoleResponder : public LLHTTPClient::ResponderIgnoreBody { public: - /*virtual*/ void error(U32 status, const std::string& reason) { sConsoleReplySignal(UNABLE_TO_SEND_COMMAND); } + /*virtual*/ void httpFailure(void) { sConsoleReplySignal(UNABLE_TO_SEND_COMMAND); } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return asyncConsoleResponder_timeout; } /*virtual*/ char const* getName(void) const { return "AsyncConsoleResponder"; } }; @@ -92,7 +92,7 @@ namespace { } - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { if (mOutput) { @@ -102,12 +102,12 @@ namespace } } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { if (mOutput) { mOutput->appendText( - content.asString() + PROMPT, false, false); + mContent.asString() + PROMPT, false, false); } } diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index da8aaedd4..7df8e5272 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -412,6 +412,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) panel->getChild("block_terraform_check")->setValue((region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE ); panel->getChild("block_fly_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE ); + panel->getChild("block_fly_over_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLYOVER) ? TRUE : FALSE ); panel->getChild("allow_damage_check")->setValue((region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE ); panel->getChild("restrict_pushobject")->setValue((region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE ); panel->getChild("allow_land_resell_check")->setValue((region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE ); @@ -712,6 +713,7 @@ BOOL LLPanelRegionGeneralInfo::postBuild() // Enable the "Apply" button if something is changed. JC initCtrl("block_terraform_check"); initCtrl("block_fly_check"); + initCtrl("block_fly_over_check"); initCtrl("allow_damage_check"); initCtrl("allow_land_resell_check"); initCtrl("allow_parcel_changes_check"); @@ -877,6 +879,7 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate() { body["block_terraform"] = getChild("block_terraform_check")->getValue(); body["block_fly"] = getChild("block_fly_check")->getValue(); + body["block_fly_over"] = getChild("block_fly_over_check")->getValue(); body["allow_damage"] = getChild("allow_damage_check")->getValue(); body["allow_land_resell"] = getChild("allow_land_resell_check")->getValue(); body["agent_limit"] = getChild("agent_limit_spin")->getValue(); @@ -2341,7 +2344,7 @@ public: } // if we get a normal response, handle it here - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { LL_INFOS("Windlight") << "Successfully committed estate info" << llendl; @@ -2352,10 +2355,10 @@ public: } // if we get an error response - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { llinfos << "LLEstateChangeInfoResponder::error [status:" - << status << "]: " << reason << llendl; + << mStatus << "]: " << mReason << llendl; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return estateChangeInfoResponder_timeout; } diff --git a/indra/newview/llfloaterregionrestarting.cpp b/indra/newview/llfloaterregionrestarting.cpp index 35af32390..84e5ea934 100644 --- a/indra/newview/llfloaterregionrestarting.cpp +++ b/indra/newview/llfloaterregionrestarting.cpp @@ -37,14 +37,49 @@ // For emergency teleports #include "llinventorymodel.h" +#include "lllandmarklist.h" +#include "llviewerregion.h" +#include "llworldmap.h" void emergency_teleport() { static const LLCachedControl landmark(gSavedPerAccountSettings, "EmergencyTeleportLandmark"); if (landmark().empty()) return; - const LLUUID id(landmark); + LLUUID id(landmark); if (id.isNull()) return; - if (LLViewerInventoryItem* item = gInventory.getItem(id)) - gAgent.teleportViaLandmark(item->getAssetUUID()); + bool use_backup = false; + LLViewerInventoryItem* item = gInventory.getItem(id); + if (item) + { + if (LLLandmark* lm = gLandmarkList.getAsset(item->getAssetUUID())) + { + if (LLViewerRegion* region = gAgent.getRegion()) + use_backup = !lm->getRegionID(id) || id == region->getRegionID(); // LM's Region id null or same as current region + if (!use_backup) + { + LLVector3d pos_global; + if (lm->getGlobalPos(pos_global)) + { + if (LLSimInfo* sim_info = LLWorldMap::instance().simInfoFromPosGlobal(pos_global)) + { + use_backup = sim_info->isDown(); + } + } + else use_backup = true; // No coords, this will fail! + } + } + else use_backup = true; + } + else use_backup = true; + + if (use_backup) // Something is wrong with the first provided landmark, fallback. + { + static const LLCachedControl landmark(gSavedPerAccountSettings, "EmergencyTeleportLandmarkBackup"); + if (landmark().empty()) return; + if (!id.set(landmark)) return; + if (!(item = gInventory.getItem(id))) return; + } + + gAgent.teleportViaLandmark(item->getAssetUUID()); } // diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 31cf83c4a..19cc09f55 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -723,12 +723,12 @@ class LLUserReportResponder : public LLHTTPClient::ResponderWithResult public: LLUserReportResponder() { } - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { // *TODO do some user messaging here LLUploadDialog::modalUploadFinished(); } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { // we don't care about what the server returns LLUploadDialog::modalUploadFinished(); diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index e7bf31312..9451908c7 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -184,27 +184,27 @@ void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr) // Responders ///---------------------------------------------------------------------------- -void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content) +void fetchScriptLimitsRegionInfoResponder::httpSuccess(void) { //we don't need to test with a fake response here (shouldn't anyway) #ifdef DUMP_REPLIES_TO_LLINFOS - LLSDNotationStreamer notation_streamer(content); + LLSDNotationStreamer notation_streamer(mContent); std::ostringstream nice_llsd; nice_llsd << notation_streamer; OSMessageBox(nice_llsd.str(), "main cap response:", 0); - llinfos << "main cap response:" << content << llendl; + llinfos << "main cap response:" << mContent << llendl; #endif // at this point we have an llsd which should contain ether one or two urls to the services we want. // first we look for the details service: - if(content.has("ScriptResourceDetails")) + if(mContent.has("ScriptResourceDetails")) { - LLHTTPClient::get(content["ScriptResourceDetails"], new fetchScriptLimitsRegionDetailsResponder(mInfo)); + LLHTTPClient::get(mContent["ScriptResourceDetails"], new fetchScriptLimitsRegionDetailsResponder(mInfo)); } else { @@ -216,18 +216,18 @@ void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content) } // then the summary service: - if(content.has("ScriptResourceSummary")) + if(mContent.has("ScriptResourceSummary")) { - LLHTTPClient::get(content["ScriptResourceSummary"], new fetchScriptLimitsRegionSummaryResponder(mInfo)); + LLHTTPClient::get(mContent["ScriptResourceSummary"], new fetchScriptLimitsRegionSummaryResponder(mInfo)); } } -void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string& reason) +void fetchScriptLimitsRegionInfoResponder::httpFailure(void) { - llwarns << "fetchScriptLimitsRegionInfoResponder error [status:" << status << "]: " << reason << llendl; + llwarns << "fetchScriptLimitsRegionInfoResponder error [status:" << mStatus << "]: " << mReason << llendl; } -void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) +void fetchScriptLimitsRegionSummaryResponder::httpSuccess(void) { #ifdef USE_FAKE_RESPONSES @@ -265,7 +265,7 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) #else - const LLSD& content = content_ref; + const LLSD& content = mContent; #endif @@ -309,12 +309,12 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) } } -void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::string& reason) +void fetchScriptLimitsRegionSummaryResponder::httpFailure(void) { - llwarns << "fetchScriptLimitsRegionSummaryResponder error [status:" << status << "]: " << reason << llendl; + llwarns << "fetchScriptLimitsRegionSummaryResponder error [status:" << mStatus << "]: " << mReason << llendl; } -void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref) +void fetchScriptLimitsRegionDetailsResponder::httpSuccess(void) { #ifdef USE_FAKE_RESPONSES /* @@ -374,7 +374,7 @@ result (map) #else - const LLSD& content = content_ref; + const LLSD& content = mContent; #endif @@ -418,12 +418,12 @@ result (map) } } -void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::string& reason) +void fetchScriptLimitsRegionDetailsResponder::httpFailure(void) { - llwarns << "fetchScriptLimitsRegionDetailsResponder error [status:" << status << "]: " << reason << llendl; + llwarns << "fetchScriptLimitsRegionDetailsResponder error [status:" << mStatus << "]: " << mReason << llendl; } -void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref) +void fetchScriptLimitsAttachmentInfoResponder::httpSuccess(void) { #ifdef USE_FAKE_RESPONSES @@ -456,13 +456,13 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref) summary["used"] = used; fake_content["summary"] = summary; - fake_content["attachments"] = content_ref["attachments"]; + fake_content["attachments"] = mContent["attachments"]; const LLSD& content = fake_content; #else - const LLSD& content = content_ref; + const LLSD& content = mContent; #endif @@ -514,9 +514,9 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref) } } -void fetchScriptLimitsAttachmentInfoResponder::error(U32 status, const std::string& reason) +void fetchScriptLimitsAttachmentInfoResponder::httpFailure(void) { - llwarns << "fetchScriptLimitsAttachmentInfoResponder error [status:" << status << "]: " << reason << llendl; + llwarns << "fetchScriptLimitsAttachmentInfoResponder error [status:" << mStatus << "]: " << mReason << llendl; } ///---------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index a31d49629..bb2dd244e 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -90,8 +90,8 @@ class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::ResponderWithRe public: fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {}; - void result(const LLSD& content); - void error(U32 status, const std::string& reason); + void httpSuccess(void); + void httpFailure(void); public: /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsRegionInfoResponder_timeout; } /*virtual*/ char const* getName(void) const { return "fetchScriptLimitsRegionInfoResponder"; } @@ -105,8 +105,8 @@ class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::ResponderWit public: fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {}; - void result(const LLSD& content); - void error(U32 status, const std::string& reason); + void httpSuccess(void); + void httpFailure(void); public: /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsRegionSummaryResponder_timeout; } /*virtual*/ char const* getName(void) const { return "fetchScriptLimitsRegionSummaryResponder"; } @@ -120,8 +120,8 @@ class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::ResponderWit public: fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {}; - void result(const LLSD& content); - void error(U32 status, const std::string& reason); + void httpSuccess(void); + void httpFailure(void); public: /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsRegionDetailsResponder_timeout; } /*virtual*/ char const* getName(void) const { return "fetchScriptLimitsRegionDetailsResponder"; } @@ -135,8 +135,8 @@ class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::ResponderWi public: fetchScriptLimitsAttachmentInfoResponder() {}; - void result(const LLSD& content); - void error(U32 status, const std::string& reason); + void httpSuccess(void); + void httpFailure(void); public: /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsAttachmentInfoResponder_timeout; } /*virtual*/ char const* getName(void) const { return "fetchScriptLimitsAttachmentInfoResponder"; } diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index b9cf179d2..67e9421a5 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -144,6 +144,7 @@ BOOL LLFloaterSearch::postBuild() setRectControl("FloaterSearchRect"); applyRectControl(); search(SearchQuery()); + gSavedSettings.getControl("SearchURL")->getSignal()->connect(boost::bind(&LLFloaterSearch::search, this, SearchQuery())); return TRUE; } @@ -160,7 +161,9 @@ void LLFloaterSearch::showInstance(const SearchQuery& search, bool web) else { const std::string category(search.category()); - if (category.empty() || category == "all") + if (category.empty()) + LLFloaterDirectory::searchInAll(search.query); + else if (category == "all") LLFloaterDirectory::showFindAll(search.query); else if (category == "people") LLFloaterDirectory::showPeople(search.query); diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 09463f049..266beb7ce 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -1434,8 +1434,8 @@ void LLSnapshotLivePreview::saveTexture() LLFolderType::FT_SNAPSHOT_CATEGORY, LLInventoryType::IT_SNAPSHOT, PERM_ALL, // Note: Snapshots to inventory is a special case of content upload - LLFloaterPerms::getGroupPerms(), // that is more permissive than other uploads - LLFloaterPerms::getEveryonePerms(), + LLFloaterPerms::getGroupPerms("Uploads"), // that is more permissive than other uploads + LLFloaterPerms::getEveryonePerms("Uploads"), "Snapshot : " + pos_string, callback, expected_upload_cost, user_data, &LLSnapshotLivePreview::saveTextureDone2)) { @@ -2692,7 +2692,6 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data) } } - //static void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data) { @@ -2704,14 +2703,11 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data) } } - - // Sets the named size combo to "custom" mode. // static void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname) { LLComboBox* combo = floater->getChild(comboname); - combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index storeAspectSetting(combo, comboname); } @@ -2954,25 +2950,25 @@ BOOL LLFloaterSnapshot::postBuild() childSetCommitCallback("keep_aspect", Impl::onClickKeepAspect, this); childSetCommitCallback("ui_check", Impl::onClickUICheck, this); - childSetValue("ui_check", gSavedSettings.getBOOL("RenderUIInSnapshot")); + getChild("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot")); childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this); - childSetValue("hud_check", gSavedSettings.getBOOL("RenderHUDInSnapshot")); + getChild("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot")); childSetCommitCallback("keep_open_check", Impl::onClickKeepOpenCheck, this); childSetValue("keep_open_check", !gSavedSettings.getBOOL("CloseSnapshotOnKeep")); childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this); - childSetValue("layer_types", "colors"); - childSetEnabled("layer_types", FALSE); + getChild("layer_types")->setValue("colors"); + getChildView("layer_types")->setEnabled(FALSE); childSetValue("snapshot_width", gSavedSettings.getS32(lastSnapshotWidthName())); childSetValue("snapshot_height", gSavedSettings.getS32(lastSnapshotHeightName())); - childSetValue("freeze_time_check", gSavedSettings.getBOOL("SnapshotOpenFreezeTime")); + getChild("freeze_time_check")->setValue(gSavedSettings.getBOOL("SnapshotOpenFreezeTime")); childSetCommitCallback("freeze_time_check", Impl::onCommitFreezeTime, this); - childSetValue("auto_snapshot_check", gSavedSettings.getBOOL("AutoSnapshot")); + getChild("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot")); childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this); childSetCommitCallback("temp_check", Impl::onClickTemporaryImage, this); @@ -3037,7 +3033,7 @@ void LLFloaterSnapshot::draw() S32 offset_y = (thumb_area.mBottom + thumb_area.mTop - previewp->getThumbnailHeight()) / 2; gGL.matrixMode(LLRender::MM_MODELVIEW); - gl_rect_2d(thumb_area, LLColor4::grey4, true); + gl_rect_2d(thumb_area, LLColor4::transparent, true); gl_draw_scaled_image(offset_x, offset_y, previewp->getThumbnailWidth(), previewp->getThumbnailHeight(), previewp->getThumbnailImage(), LLColor4::white); diff --git a/indra/newview/llfloaterteleporthistory.cpp b/indra/newview/llfloaterteleporthistory.cpp index b3a6bad0c..2293b7875 100644 --- a/indra/newview/llfloaterteleporthistory.cpp +++ b/indra/newview/llfloaterteleporthistory.cpp @@ -107,22 +107,10 @@ void LLFloaterTeleportHistory::addPendingEntry(std::string regionName, S16 x, S1 // Set pending entry timestamp - U32 utc_time; - utc_time = time_corrected(); - struct tm* internal_time; - internal_time = utc_to_pacific_time(utc_time, gPacificDaylightTime); + struct tm* internal_time = utc_to_pacific_time(time_corrected(), gPacificDaylightTime); + timeStructToFormattedString(internal_time, gSavedSettings.getString("ShortDateFormat") + gSavedSettings.getString("LongTimeFormat"), mPendingTimeString); // check if we are in daylight savings time - std::string timeZone = " PST"; - if (gPacificDaylightTime) - { - timeZone = " PDT"; - } -#ifdef LOCALIZED_TIME - timeStructToFormattedString(internal_time, gSavedSettings.getString("LongTimeFormat"), mPendingTimeString); - mPendingTimeString += timeZone; -#else - mPendingTimeString = llformat("%02d:%02d:%02d", internal_time->tm_hour, internal_time->tm_min, internal_time->tm_sec) + timeZone; -#endif + mPendingTimeString += gPacificDaylightTime ? " PDT" : " PST"; // Set pending region name mPendingRegionName = regionName; diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index a690b42e5..5f27490cc 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -47,6 +47,7 @@ #include "llfloaterbuildoptions.h" #include "llfloatermediasettings.h" #include "llfloateropenobject.h" +#include "llfloaterobjectweights.h" #include "llfocusmgr.h" #include "llmediaentry.h" #include "llmediactrl.h" @@ -99,7 +100,6 @@ // Globals LLFloaterTools *gFloaterTools = NULL; - const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] = { std::string("General"), // PANEL_GENERAL, @@ -124,10 +124,27 @@ void commit_radio_group_focus(LLUICtrl* ctrl); void commit_radio_group_move(LLUICtrl* ctrl); void commit_radio_group_edit(LLUICtrl* ctrl); void commit_radio_group_land(LLUICtrl* ctrl); - void commit_slider_zoom(LLUICtrl *ctrl); void commit_select_tool(LLUICtrl *ctrl, void *data); +/** + * Class LLLandImpactsObserver + * + * An observer class to monitor parcel selection and update + * the land impacts data from a parcel containing the selected object. + */ +class LLLandImpactsObserver : public LLParcelObserver +{ +public: + virtual void changed() + { + LLFloaterTools* tools_floater = gFloaterTools; + if(tools_floater) + { + tools_floater->updateLandImpacts(); + } + } +}; //static void* LLFloaterTools::createPanelPermissions(void* data) @@ -249,13 +266,13 @@ BOOL LLFloaterTools::postBuild() mRadioStretch = getChild("radio stretch"); mRadioSelectFace = getChild("radio select face"); mRadioAlign = getChild("radio align"); + mBtnGridOptions = getChild("Options..."); mTitleMedia = getChild("title_media"); mCheckSelectIndividual = getChild("checkbox edit linked parts"); getChild("checkbox edit linked parts")->setValue((BOOL)gSavedSettings.getBOOL("EditLinkedParts")); mCheckSnapToGrid = getChild("checkbox snap to grid"); getChild("checkbox snap to grid")->setValue((BOOL)gSavedSettings.getBOOL("SnapEnabled")); - mBtnGridOptions = getChild("Options..."); mCheckStretchUniform = getChild("checkbox uniform"); getChild("checkbox uniform")->setValue((BOOL)gSavedSettings.getBOOL("ScaleUniform")); mCheckStretchTexture = getChild("checkbox stretch textures"); @@ -267,6 +284,7 @@ BOOL LLFloaterTools::postBuild() mCheckShowHighlight = getChild("checkbox show highlight"); mCheckActualRoot = getChild("checkbox actual root"); + // // Create Buttons // @@ -283,7 +301,7 @@ BOOL LLFloaterTools::postBuild() } } if ((mComboTreesGrass = findChild("trees_grass"))) - childSetCommitCallback("trees_grass", onSelectTreesGrass, (void*)0); + mComboTreesGrass->setCommitCallback(boost::bind(&LLFloaterTools::onSelectTreesGrass, this)); mCheckCopySelection = getChild("checkbox copy selection"); getChild("checkbox copy selection")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopySelection")); mCheckSticky = getChild("checkbox sticky"); @@ -303,7 +321,6 @@ BOOL LLFloaterTools::postBuild() mSliderDozerSize = getChild("slider brush size"); getChild("slider brush size")->setValue(gSavedSettings.getF32("LandBrushSize")); - mSliderDozerForce = getChild("slider force"); // the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here getChild("slider force")->setValue(log10(gSavedSettings.getF32("LandBrushForce"))); @@ -404,6 +421,8 @@ LLFloaterTools::LLFloaterTools() mPanelFace(NULL), mPanelLandInfo(NULL), + mLandImpactsObserver(NULL), + mDirty(TRUE), mNeedMediaTitle(TRUE) { @@ -434,12 +453,24 @@ LLFloaterTools::LLFloaterTools() mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this)); mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this)); + mLandImpactsObserver = new LLLandImpactsObserver(); + LLViewerParcelMgr::getInstance()->addObserver(mLandImpactsObserver); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",&factory_map,FALSE); + if (LLTextBox* text = findChild("selection_count")) + { + text->setClickedCallback(boost::bind(LLFloaterObjectWeights::toggleInstance, LLSD())); + text->setColor(gSavedSettings.getColor4("HTMLLinkColor")); + } } LLFloaterTools::~LLFloaterTools() { // children automatically deleted + gFloaterTools = NULL; + + LLViewerParcelMgr::getInstance()->removeObserver(mLandImpactsObserver); + delete mLandImpactsObserver; } void LLFloaterTools::setStatusText(const std::string& text) @@ -480,62 +511,114 @@ void LLFloaterTools::refresh() // Refresh object and prim count labels LLLocale locale(LLLocale::USER_LOCALE); - // Added in Link Num value -HgB - S32 object_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount(); - S32 prim_count = LLSelectMgr::getInstance()->getEditSelection()->getObjectCount(); - std::string value_string; - std::string desc_string; - if ((gSavedSettings.getBOOL("EditLinkedParts"))&&(prim_count == 1)) //Selecting a single prim in "Edit Linked" mode, show link number +#if 0 + if (!gMeshRepo.meshRezEnabled()) { - desc_string = "Link number:"; + std::string obj_count_string; + LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); + getChild("selection_count")->setTextArg("[OBJ_COUNT]", obj_count_string); + std::string prim_count_string; + LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); + getChild("selection_count")->setTextArg("[PRIM_COUNT]", prim_count_string); - LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - if (selected && selected->getRootEdit()) + // calculate selection rendering cost + if (sShowObjectCost) { - LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren(); - if (children.empty()) + std::string prim_cost_string; + S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost(); + LLResMgr::getInstance()->getIntegerString(prim_cost_string, render_cost); + getChild("RenderingCost")->setTextArg("[COUNT]", prim_cost_string); + } + + // disable the object and prim counts if nothing selected + bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty(); + getChildView("obj_count")->setEnabled(have_selection); + getChildView("prim_count")->setEnabled(have_selection); + getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost); + } + else +#endif + { + F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost(); + S32 link_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount(); + + // Added in Link Num value -HgB + S32 prim_count = LLSelectMgr::getInstance()->getEditSelection()->getObjectCount(); + std::string value_string; + if ((prim_count == 1) && gSavedSettings.getBOOL("EditLinkedParts")) //Selecting a single prim in "Edit Linked" mode, show link number + { + childSetTextArg("link_num_obj_count", "[DESC]", std::string("Link number:")); + + LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (selected && selected->getRootEdit()) { - value_string = "0"; // An unlinked prim is "link 0". - } - else - { - children.push_front(selected->getRootEdit()); // need root in the list too - S32 index = 0; - for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter) + LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren(); + if (children.empty()) { - index++; - if ((*iter)->isSelected()) + value_string = "0"; // An unlinked prim is "link 0". + } + else + { + children.push_front(selected->getRootEdit()); // need root in the list too + S32 index = 1; + for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter, ++index) { - LLResMgr::getInstance()->getIntegerString(value_string, index); - break; + if ((*iter)->isSelected()) + { + LLResMgr::getInstance()->getIntegerString(value_string, index); + break; + } } } } } - } - else - { - desc_string = "Selected objects:"; - LLResMgr::getInstance()->getIntegerString(value_string, object_count); - } - childSetTextArg("link_num_obj_count", "[DESC]", desc_string); - childSetTextArg("link_num_obj_count", "[NUM]", value_string); + else + { + childSetTextArg("link_num_obj_count", "[DESC]", std::string("Selected objects:")); + LLResMgr::getInstance()->getIntegerString(value_string, link_count); + } + childSetTextArg("link_num_obj_count", "[NUM]", value_string); - LLStringUtil::format_map_t selection_args; - selection_args["COUNT"] = llformat("%.1d", (S32)prim_count); - if(gMeshRepo.meshRezEnabled()) - { - F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost(); - LLStringUtil::format_map_t prim_equiv_args; - prim_equiv_args["SEL_WEIGHT"] = llformat("%.0f", link_cost); - selection_args["PE_STRING"] = getString("status_selectprimequiv", prim_equiv_args); + /* Singu Note: We're not using this yet because we have no place to put it + LLCrossParcelFunctor func; + if (LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true)) + { + // Selection crosses parcel bounds. + // We don't display remaining land capacity in this case. + const LLStringExplicit empty_str(""); + childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", empty_str); + } + else + */ + { + LLViewerObject* selected_object = mObjectSelection->getFirstObject(); + if (selected_object) + { + // Select a parcel at the currently selected object's position. + LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal()); + } + else + { + //LL_WARNS() << "Failed to get selected object" << LL_ENDL; + } + } + + LLStringUtil::format_map_t selection_args; + selection_args["OBJ_COUNT"] = llformat("%.1d", prim_count); + selection_args["LAND_IMPACT"] = llformat("%.1d", (S32)link_cost); + + std::ostringstream selection_info; + + selection_info << getString("status_selectcount", selection_args); + + getChild("selection_count")->setText(selection_info.str()); + + bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); + childSetVisible("selection_count", have_selection); + //childSetVisible("remaining_capacity", have_selection); + childSetVisible("selection_empty", !have_selection); } - else - { - selection_args["PE_STRING"] = ""; - } - std::string prim_count_string = getString("status_selectcount",selection_args); - childSetText("prim_count", prim_count_string); + // Refresh child tabs mPanelPermissions->refresh(); @@ -546,6 +629,12 @@ void LLFloaterTools::refresh() refreshMedia(); mPanelContents->refresh(); mPanelLandInfo->refresh(); + + // Refresh the advanced weights floater + if (LLFloaterObjectWeights::instanceVisible()) + { + LLFloaterObjectWeights::getInstance()->refresh(); + } } void LLFloaterTools::draw() @@ -606,8 +695,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioZoom ->setVisible( focus_visible ); mRadioOrbit ->setVisible( focus_visible ); mRadioPan ->setVisible( focus_visible ); - childSetVisible("slider zoom", focus_visible); - childSetEnabled("slider zoom", gCameraBtnZoom); + getChildView("slider zoom")->setVisible(focus_visible); + getChildView("slider zoom")->setEnabled(gCameraBtnZoom); mRadioZoom ->set(!gCameraBtnOrbit && !gCameraBtnPan && @@ -625,7 +714,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) (mask == (MASK_PAN | MASK_ALT)) ); // multiply by correction factor because volume sliders go [0, 0.5] - childSetValue( "slider zoom", gAgentCamera.getCameraZoomFraction() * 0.5f); + getChild("slider zoom")->setValue(gAgentCamera.getCameraZoomFraction() * 0.5f); // Move buttons BOOL move_visible = (tool == LLToolGrab::getInstance()); @@ -699,7 +788,6 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) case SELECT_TYPE_HUD: mComboGridMode->add(getString("grid_screen_text")); mComboGridMode->add(getString("grid_local_text")); - //mComboGridMode->add(getString("grid_reference_text")); break; case SELECT_TYPE_WORLD: mComboGridMode->add(getString("grid_world_text")); @@ -772,10 +860,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) if (mBtnLand) mBtnLand ->setToggleState( land_visible ); - // mRadioEditLand ->set( tool == LLToolBrushLand::getInstance() ); if (mRadioSelectLand) mRadioSelectLand->set( tool == LLToolSelectLand::getInstance() ); - // mRadioEditLand ->setVisible( land_visible ); if (mRadioSelectLand) mRadioSelectLand->setVisible( land_visible ); S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction"); @@ -810,6 +896,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioDozerRevert ->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 5); mRadioDozerRevert ->setVisible( land_visible ); } + if (mBtnApplyToSelection) { mBtnApplyToSelection->setVisible( land_visible ); @@ -826,9 +913,14 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mSliderDozerForce ->setVisible( land_visible ); getChildView("Strength:")->setVisible( land_visible); } - - childSetVisible("link_num_obj_count", !land_visible); - childSetVisible("prim_count", !land_visible); + + bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); + + getChildView("link_num_obj_count")->setVisible(!land_visible && have_selection); + getChildView("selection_count")->setVisible(!land_visible && have_selection); + //getChildView("remaining_capacity")->setVisible(!land_visible && have_selection); + getChildView("selection_empty")->setVisible(!land_visible && !have_selection); + static const LLCachedControl mini("LiruMiniBuildFloater"); mTab->setVisible(!mini && !land_visible); getChildView("mini_button")->setVisible(!land_visible); @@ -909,9 +1001,12 @@ void LLFloaterTools::onClose(bool app_quitting) // gMenuBarView->setItemVisible(std::string("Tools"), FALSE); // gMenuBarView->arrange(); - + if(LLFloaterMediaSettings::instanceExists()) LLFloaterMediaSettings::getInstance()->close(); + + // hide the advanced object weights floater + LLFloaterObjectWeights::hideInstance(); } void LLFloaterTools::showPanel(EInfoPanel panel) @@ -922,7 +1017,6 @@ void LLFloaterTools::showPanel(EInfoPanel panel) void click_popup_info(void*) { -// gBuildView->setPropertiesPanelOpen(TRUE); } void click_popup_done(void*) @@ -1094,7 +1188,6 @@ void commit_grid_mode(LLUICtrl *ctrl) void LLFloaterTools::onClickGridOptions() { - //LLFloaterTools* floaterp = (LLFloaterTools*)data; LLFloaterBuildOptions::show(NULL); // RN: this makes grid options dependent on build tools window //floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE); @@ -1176,6 +1269,39 @@ bool LLFloaterTools::selectedMediaEditable() return selected_Media_editable; } + +void LLFloaterTools::updateLandImpacts() +{ + LLParcel *parcel = mParcelSelection->getParcel(); + if (!parcel) + { + return; + } + + /* Singu Note: We're not using this yet because we have no place to put it + S32 rezzed_prims = parcel->getSimWidePrimCount(); + S32 total_capacity = parcel->getSimWideMaxPrimCapacity(); + + std::string remaining_capacity_str = ""; + + bool show_mesh_cost = gMeshRepo.meshRezEnabled(); + if (show_mesh_cost) + { + LLStringUtil::format_map_t remaining_capacity_args; + remaining_capacity_args["LAND_CAPACITY"] = llformat("%d", total_capacity - rezzed_prims); + remaining_capacity_str = getString("status_remaining_capacity", remaining_capacity_args); + } + + childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", remaining_capacity_str); + */ + + // Update land impacts info in the weights floater + if (LLFloaterObjectWeights::instanceVisible()) + { + LLFloaterObjectWeights::getInstance()->updateLandImpacts(parcel); + } +} + void LLFloaterTools::getMediaState() { LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); @@ -1962,10 +2088,9 @@ void LLFloaterTools::updateMediaSettings() mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; } -// static -void LLFloaterTools::onSelectTreesGrass(LLUICtrl*, void*) +void LLFloaterTools::onSelectTreesGrass() { - const std::string &selected = gFloaterTools->mComboTreesGrass->getValue(); + const std::string& selected = mComboTreesGrass->getValue(); LLPCode pcode = LLToolPlacer::getObjectType(); if (pcode == LL_PCODE_LEGACY_TREE) { diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 3a6d2cbfb..73c13f558 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -53,6 +53,7 @@ class LLMediaCtrl; class LLTool; class LLParcelSelection; class LLObjectSelection; +class LLLandImpactsObserver; typedef LLSafeHandle LLObjectSelectionHandle; @@ -110,6 +111,7 @@ public: void updateMediaTitle(); void navigateToTitleMedia( const std::string url ); bool selectedMediaEditable(); + void updateLandImpacts(); LLPanelFace* getPanelFace() { return mPanelFace; } @@ -178,7 +180,6 @@ public: LLCheckBoxCtrl *mCheckCopyRotates; // Land buttons -// LLCheckBoxCtrl *mRadioEditLand; LLCheckBoxCtrl *mRadioSelectLand; LLCheckBoxCtrl *mRadioDozerFlatten; @@ -202,18 +203,21 @@ public: LLPanelFace *mPanelFace; LLPanelLandInfo *mPanelLandInfo; + LLLandImpactsObserver* mLandImpactsObserver; + LLParcelSelectionHandle mParcelSelection; LLObjectSelectionHandle mObjectSelection; LLMediaCtrl *mTitleMedia; bool mNeedMediaTitle; + private: BOOL mDirty; std::map mStatusText; + void onSelectTreesGrass(); void updateTreeGrassCombo(bool visible); - static void onSelectTreesGrass(LLUICtrl*, void*); protected: LLSD mMediaSettings; }; diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index eb70ca59f..8a6d9bcce 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -112,20 +112,20 @@ class LLIamHere : public LLHTTPClient::ResponderWithResult mParent = parentIn; }; - /*virtual*/ void result( const LLSD& content ) + /*virtual*/ void httpSuccess(void) { if ( mParent ) mParent->setSiteIsAlive( true ); }; - /*virtual*/ void error( U32 status, const std::string& reason ) + /*virtual*/ void httpFailure(void) { if ( mParent ) { // *HACK: For purposes of this alive check, 302 Found // (aka Moved Temporarily) is considered alive. The web site // redirects this link to a "cache busting" temporary URL. JC - bool alive = (status == HTTP_FOUND); + bool alive = (mStatus == HTTP_FOUND); mParent->setSiteIsAlive( alive ); } }; diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index 65171b007..9965b4cf3 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -65,21 +65,21 @@ public: LLHandle mParent; - /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(void) { - if (200 <= status && status < 300) + if (isGoodStatus(mStatus)) { std::string media_type; - if (headers.getFirstValue("content-type", media_type)) + if (mReceivedHeaders.getFirstValue("content-type", media_type)) { std::string::size_type idx1 = media_type.find_first_of(";"); std::string mime_type = media_type.substr(0, idx1); - completeAny(status, mime_type); + completeAny(mStatus, mime_type); return; } - llwarns << "LLMediaTypeResponder::completedHeaders: OK HTTP status (" << status << ") but no Content-Type! Received headers: " << headers << llendl; + llwarns << "LLMediaTypeResponder::completedHeaders: OK HTTP status (" << mStatus << ") but no Content-Type! Received headers: " << mReceivedHeaders << llendl; } - completeAny(status, "none/none"); + completeAny(mStatus, "none/none"); } void completeAny(U32 status, const std::string& mime_type) diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 7494e9b90..8e36725c8 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1570,18 +1570,17 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) if((mSelectedItems.size() > 0) && mScrollContainer) { LLFolderViewItem* last_selected = getCurSelectedItem(); + bool shift_select = mask & MASK_SHIFT; + LLFolderViewItem* next = last_selected->getNextOpenNode(); - if (!mKeyboardSelection) + if (!mKeyboardSelection || (!shift_select && (!next || next == last_selected))) { setSelection(last_selected, FALSE, TRUE); mKeyboardSelection = TRUE; } - LLFolderViewItem* next = NULL; - if (mask & MASK_SHIFT) + if (shift_select) { - // don't shift select down to children of folders (they are implicitly selected through parent) - next = last_selected->getNextOpenNode(FALSE); if (next) { if (next->isSelected()) @@ -1598,7 +1597,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) } else { - next = last_selected->getNextOpenNode(); if( next ) { if (next == last_selected) @@ -1634,18 +1632,18 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) if((mSelectedItems.size() > 0) && mScrollContainer) { LLFolderViewItem* last_selected = mSelectedItems.back(); + bool shift_select = mask & MASK_SHIFT; + // don't shift select down to children of folders (they are implicitly selected through parent) + LLFolderViewItem* prev = last_selected->getPreviousOpenNode(!shift_select); - if (!mKeyboardSelection) + if (!mKeyboardSelection || (!shift_select && prev == this)) { setSelection(last_selected, FALSE, TRUE); mKeyboardSelection = TRUE; } - LLFolderViewItem* prev = NULL; - if (mask & MASK_SHIFT) + if (shift_select) { - // don't shift select down to children of folders (they are implicitly selected through parent) - prev = last_selected->getPreviousOpenNode(FALSE); if (prev) { if (prev->isSelected()) @@ -1662,7 +1660,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) } else { - prev = last_selected->getPreviousOpenNode(); if( prev ) { if (prev == this) diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index f94872837..517266097 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -1358,6 +1358,10 @@ BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) { S32 in_len = in_str.length(); +#ifdef MATCH_COMMON_CHARS + std::string rest_of_match = ""; + std::string buf = ""; +#endif item_map_t::iterator it; for (it = mActive.begin(); it != mActive.end(); ++it) { @@ -1365,22 +1369,71 @@ BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) if (gesture) { const std::string& trigger = gesture->getTrigger(); - - if (in_len > (S32)trigger.length()) - { - // too short, bail out - continue; - } - - std::string trigger_trunc = trigger; - LLStringUtil::truncate(trigger_trunc, in_len); - if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) +#ifdef MATCH_COMMON_CHARS + //return whole trigger, if received text equals to it + if (!LLStringUtil::compareInsensitive(in_str, trigger)) { *out_str = trigger; return TRUE; } +#else + if (in_len > (S32)trigger.length()) continue; // too short, bail out +#endif + + //return common chars, if more than one trigger matches the prefix + std::string trigger_trunc = trigger; + LLStringUtil::truncate(trigger_trunc, in_len); + if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) + { +#ifndef MATCH_COMMON_CHARS + *out_str = trigger; + return TRUE; +#else + if (rest_of_match.compare("") == 0) + { + rest_of_match = trigger.substr(in_str.size()); + } + std::string cur_rest_of_match = trigger.substr(in_str.size()); + buf = ""; + U32 i=0; + + while (igetRegionFlag(REGION_FLAGS_BLOCK_FLYOVER)) { collision_height = BAN_HEIGHT; } diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index da27ac259..c93dbaa9d 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -90,7 +90,6 @@ public: // CP_TODO: get the value we pass in via the XUI name // of the tab instead of using a literal like this LLFloaterMyFriends::showInstance( 1 ); - return true; } return false; @@ -123,6 +122,77 @@ public: }; LLGroupHandler gGroupHandler; +// This object represents a pending request for specified group member information +// which is needed to check whether avatar can leave group +class LLFetchGroupMemberData : public LLGroupMgrObserver +{ +public: + LLFetchGroupMemberData(const LLUUID& group_id) : + mGroupId(group_id), + mRequestProcessed(false), + LLGroupMgrObserver(group_id) + { + llinfos << "Sending new group member request for group_id: "<< group_id << llendl; + LLGroupMgr* mgr = LLGroupMgr::getInstance(); + // register ourselves as an observer + mgr->addObserver(this); + // send a request + mgr->sendGroupPropertiesRequest(group_id); + mgr->sendCapGroupMembersRequest(group_id); + } + + ~LLFetchGroupMemberData() + { + if (!mRequestProcessed) + { + // Request is pending + llwarns << "Destroying pending group member request for group_id: " + << mGroupId << llendl; + } + // Remove ourselves as an observer + LLGroupMgr::getInstance()->removeObserver(this); + } + + void changed(LLGroupChange gc) + { + if (gc == GC_PROPERTIES && !mRequestProcessed) + { + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId); + if (!gdatap) + { + llwarns << "LLGroupMgr::getInstance()->getGroupData() was NULL" << llendl; + } + else if (!gdatap->isMemberDataComplete()) + { + llwarns << "LLGroupMgr::getInstance()->getGroupData()->isMemberDataComplete() was FALSE" << llendl; + processGroupData(); + mRequestProcessed = true; + } + } + } + + LLUUID getGroupId() { return mGroupId; } + virtual void processGroupData() = 0; +protected: + LLUUID mGroupId; +private: + bool mRequestProcessed; +}; + +class LLFetchLeaveGroupData : public LLFetchGroupMemberData +{ +public: + LLFetchLeaveGroupData(const LLUUID& group_id) + : LLFetchGroupMemberData(group_id) + {} + void processGroupData() + { + LLGroupActions::processLeaveGroupDataResponse(mGroupId); + } +}; + +LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL; + // static void LLGroupActions::search() { @@ -226,27 +296,55 @@ bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response) void LLGroupActions::leave(const LLUUID& group_id) { // if (group_id.isNull()) -// return; // [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))) ) - return; // [/RLVa:KB] + { + return; + } - S32 count = gAgent.mGroups.count(); - S32 i; - for (i = 0; i < count; ++i) + LLGroupData group_data; + if (gAgent.getGroupData(group_id, group_data)) { - if(gAgent.mGroups.get(i).mID == group_id) - break; + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); + if (!gdatap || !gdatap->isMemberDataComplete()) + { + if (gFetchLeaveGroupData != NULL) + { + delete gFetchLeaveGroupData; + gFetchLeaveGroupData = NULL; + } + gFetchLeaveGroupData = new LLFetchLeaveGroupData(group_id); } - if (i < count) + else + { + processLeaveGroupDataResponse(group_id); + } + } +} + +//static +void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id) +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); + LLUUID agent_id = gAgent.getID(); + LLGroupMgrGroupData::member_list_t::iterator mit = gdatap->mMembers.find(agent_id); + //get the member data for the group + if ( mit != gdatap->mMembers.end() ) { - LLSD args; - args["GROUP"] = gAgent.mGroups.get(i).mName; - LLSD payload; - payload["group_id"] = group_id; - LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup); + LLGroupMemberData* member_data = (*mit).second; + + if ( member_data && member_data->isOwner() && gdatap->mMemberCount == 1) + { + LLNotificationsUtil::add("OwnerCannotLeaveGroup"); + return; + } } + LLSD args; + args["GROUP"] = gdatap->mName; + LLSD payload; + payload["group_id"] = group_id; + LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup); } // static @@ -287,7 +385,6 @@ void LLGroupActions::inspect(const LLUUID& group_id) openGroupProfile(group_id); } - // static void LLGroupActions::show(const LLUUID& group_id) { diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index b59fbbe40..0cce7460b 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -124,8 +124,15 @@ public: private: static bool onJoinGroup(const LLSD& notification, const LLSD& response); static bool onLeaveGroup(const LLSD& notification, const LLSD& response); + + /** + * This function is called by LLFetchLeaveGroupData upon receiving a response to a group + * members data request. + */ + static void processLeaveGroupDataResponse(const LLUUID group_id); static LLFloaterGroupInfo* openGroupProfile(const LLUUID& group_id); + + friend class LLFetchLeaveGroupData; }; #endif // LL_LLGROUPACTIONS_H - diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index bc75b0f7d..1acafb160 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -232,11 +232,11 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) : mMemberCount(0), mRoleCount(0), mReceivedRoleMemberPairs(0), - mMemberDataComplete(FALSE), - mRoleDataComplete(FALSE), - mRoleMemberDataComplete(FALSE), - mGroupPropertiesDataComplete(FALSE), - mPendingRoleMemberRequest(FALSE), + mMemberDataComplete(false), + mRoleDataComplete(false), + mRoleMemberDataComplete(false), + mGroupPropertiesDataComplete(false), + mPendingRoleMemberRequest(false), mAccessTime(0.0f) { mMemberVersion.generate(); @@ -425,7 +425,7 @@ void LLGroupMgrGroupData::removeMemberData() delete mi->second; } mMembers.clear(); - mMemberDataComplete = FALSE; + mMemberDataComplete = false; mMemberVersion.generate(); } @@ -447,8 +447,8 @@ void LLGroupMgrGroupData::removeRoleData() } mRoles.clear(); mReceivedRoleMemberPairs = 0; - mRoleDataComplete = FALSE; - mRoleMemberDataComplete = FALSE; + mRoleDataComplete = false; + mRoleMemberDataComplete = false; } void LLGroupMgrGroupData::removeRoleMemberData() @@ -472,7 +472,7 @@ void LLGroupMgrGroupData::removeRoleMemberData() } mReceivedRoleMemberPairs = 0; - mRoleMemberDataComplete = FALSE; + mRoleMemberDataComplete = false; } LLGroupMgrGroupData::~LLGroupMgrGroupData() @@ -609,6 +609,11 @@ void LLGroupMgrGroupData::recalcAgentPowers(const LLUUID& agent_id) } } +bool LLGroupMgrGroupData::isSingleMemberNotOwner() +{ + return mMembers.size() == 1 && !mMembers.begin()->second->isOwner(); +} + bool packRoleUpdateMessageBlock(LLMessageSystem* msg, const LLUUID& group_id, const LLUUID& role_id, @@ -825,6 +830,20 @@ void LLGroupMgrGroupData::cancelRoleChanges() // Clear out all changes! mRoleChanges.clear(); } + +void LLGroupMgrGroupData::createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data) +{ + mBanList[ban_id] = ban_data; +} + +void LLGroupMgrGroupData::removeBanEntry(const LLUUID& ban_id) +{ + mBanList.erase(ban_id); +} + + + + // // LLGroupMgr // @@ -1039,12 +1058,12 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount) { - group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberDataComplete = true; group_datap->mMemberRequestID.setNull(); // We don't want to make role-member data requests until we have all the members if (group_datap->mPendingRoleMemberRequest) { - group_datap->mPendingRoleMemberRequest = FALSE; + group_datap->mPendingRoleMemberRequest = false; LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID); } } @@ -1114,7 +1133,7 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) group_datap->mMemberCount = num_group_members; group_datap->mRoleCount = num_group_roles + 1; // Add the everyone role. - group_datap->mGroupPropertiesDataComplete = TRUE; + group_datap->mGroupPropertiesDataComplete = true; group_datap->mChanged = TRUE; LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES); @@ -1189,12 +1208,12 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) if (group_datap->mRoles.size() == (U32)group_datap->mRoleCount) { - group_datap->mRoleDataComplete = TRUE; + group_datap->mRoleDataComplete = true; group_datap->mRoleDataRequestID.setNull(); // We don't want to make role-member data requests until we have all the role data if (group_datap->mPendingRoleMemberRequest) { - group_datap->mPendingRoleMemberRequest = FALSE; + group_datap->mPendingRoleMemberRequest = false; LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID); } } @@ -1306,7 +1325,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) } } - group_datap->mRoleMemberDataComplete = TRUE; + group_datap->mRoleMemberDataComplete = true; group_datap->mRoleMembersRequestID.setNull(); } @@ -1934,30 +1953,169 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, class AIHTTPTimeoutPolicy; +extern AIHTTPTimeoutPolicy groupBanDataResponder_timeout; extern AIHTTPTimeoutPolicy groupMemberDataResponder_timeout; +// Responder class for capability group management +class GroupBanDataResponder : public LLHTTPClient::ResponderWithResult +{ +public: + GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh=false); + virtual ~GroupBanDataResponder() {} + virtual void httpSuccess(); + virtual void httpFailure(); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return groupBanDataResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "GroupBanDataResponder"; } +private: + LLUUID mGroupID; + BOOL mForceRefresh; +}; + +GroupBanDataResponder::GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh) : + mGroupID(gropup_id), + mForceRefresh(force_refresh) +{} + +void GroupBanDataResponder::httpFailure() +{ + LL_WARNS("GrpMgr") << "Error receiving group member data [status:" + << mStatus << "]: " << mContent << LL_ENDL; +} + +void GroupBanDataResponder::httpSuccess() +{ + if (mContent.size()) + { + if (mContent.has("ban_list")) + { + // group ban data received + LLGroupMgr::processGroupBanRequest(mContent); + mForceRefresh = false; + } + } + if (mForceRefresh) + { + // no ban data received, refreshing data successful operation + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); + } +} + +void LLGroupMgr::sendGroupBanRequest( EBanRequestType request_type, + const LLUUID& group_id, + U32 ban_action, /* = BAN_NO_ACTION */ + const std::vector ban_list) /* = std::vector() */ +{ + LLViewerRegion* currentRegion = gAgent.getRegion(); + if (!currentRegion) + { + LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL; + return; + } + + // Check to make sure we have our capabilities + if (!currentRegion->capabilitiesReceived()) + { + LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL; + return; + } + + // Get our capability + std::string cap_url = currentRegion->getCapability("GroupAPIv1"); + if (cap_url.empty()) + { + return; + } + cap_url += "?group_id=" + group_id.asString(); + + LLSD body = LLSD::emptyMap(); + body["ban_action"] = (LLSD::Integer)(ban_action & ~BAN_UPDATE); + // Add our list of potential banned residents to the list + body["ban_ids"] = LLSD::emptyArray(); + LLSD ban_entry; + + uuid_vec_t::const_iterator iter = ban_list.begin(); + for(;iter != ban_list.end(); ++iter) + { + ban_entry = (*iter); + body["ban_ids"].append(ban_entry); + } + + LLHTTPClient::ResponderPtr grp_ban_responder = new GroupBanDataResponder(group_id, ban_action & BAN_UPDATE); + switch(request_type) + { + case REQUEST_GET: + LLHTTPClient::get(cap_url, grp_ban_responder); + break; + case REQUEST_POST: + LLHTTPClient::post(cap_url, body, grp_ban_responder); + break; + case REQUEST_PUT: + case REQUEST_DEL: + break; + } +} + + +void LLGroupMgr::processGroupBanRequest(const LLSD& content) +{ + // Did we get anything in content? + if (!content.size()) + { + LL_WARNS("GrpMgr") << "No group member data received." << LL_ENDL; + return; + } + + LLUUID group_id = content["group_id"].asUUID(); + + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); + if (!gdatap) + return; + + LLSD::map_const_iterator i = content["ban_list"].beginMap(); + LLSD::map_const_iterator iEnd = content["ban_list"].endMap(); + for(;i != iEnd; ++i) + { + const LLUUID ban_id(i->first); + LLSD ban_entry(i->second); + + LLGroupBanData ban_data; + if (ban_entry.has("ban_date")) + { + ban_data.mBanDate = ban_entry["ban_date"].asDate(); + // TODO: Ban Reason + } + + gdatap->createBanEntry(ban_id, ban_data); + } + + gdatap->mChanged = TRUE; + LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST); +} + + + // Responder class for capability group management class GroupMemberDataResponder : public LLHTTPClient::ResponderWithResult { public: GroupMemberDataResponder() {} virtual ~GroupMemberDataResponder() {} - /*virtual*/ void result(const LLSD& pContent); - /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return groupMemberDataResponder_timeout; } /*virtual*/ char const* getName(void) const { return "GroupMemberDataResponder"; } private: LLSD mMemberData; }; -void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason) +void GroupMemberDataResponder::httpFailure(void) { LL_WARNS("GrpMgr") << "Error receiving group member data." << LL_ENDL; } -void GroupMemberDataResponder::result(const LLSD& content) +void GroupMemberDataResponder::httpSuccess(void) { - LLGroupMgr::processCapGroupMembersRequest(content); + LLGroupMgr::processCapGroupMembersRequest(mContent); } @@ -2090,6 +2248,22 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) online_status, is_owner); + LLGroupMemberData* member_old = group_datap->mMembers[member_id]; + if (member_old && group_datap->mRoleMemberDataComplete) + { + LLGroupMemberData::role_list_t::iterator rit = member_old->roleBegin(); + LLGroupMemberData::role_list_t::iterator end = member_old->roleEnd(); + + for ( ; rit != end; ++rit) + { + data->addRole((*rit).first, (*rit).second); + } + } + else + { + group_datap->mRoleMemberDataComplete = false; + } + group_datap->mMembers[member_id] = data; } @@ -2104,12 +2278,12 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) if (group_datap->mTitles.size() < 1) LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id); - group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberDataComplete = true; group_datap->mMemberRequestID.setNull(); // Make the role-member data request - if (group_datap->mPendingRoleMemberRequest) + if (group_datap->mPendingRoleMemberRequest || !group_datap->mRoleMemberDataComplete) { - group_datap->mPendingRoleMemberRequest = FALSE; + group_datap->mPendingRoleMemberRequest = false; LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id); } diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index 5a40d3a2e..bf40bbcaa 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -33,7 +33,21 @@ #include #include +// Forward Declarations class LLMessageSystem; +class LLGroupRoleData; +class LLGroupMgr; + +enum LLGroupChange +{ + GC_PROPERTIES, + GC_MEMBER_DATA, + GC_ROLE_DATA, + GC_ROLE_MEMBER_DATA, + GC_TITLES, + GC_BANLIST, + GC_ALL +}; class LLGroupMgrObserver { @@ -54,8 +68,6 @@ public: virtual void changed(const LLUUID& group_id, LLGroupChange gc) = 0; }; -class LLGroupRoleData; - class LLGroupMemberData { friend class LLGroupMgrGroupData; @@ -190,6 +202,17 @@ struct lluuid_pair_less } }; + +struct LLGroupBanData +{ + LLGroupBanData() : mBanDate() {} + ~LLGroupBanData() {} + + LLDate mBanDate; + // TODO: std::string ban_reason; +}; + + struct LLGroupTitle { std::string mTitle; @@ -197,8 +220,6 @@ struct LLGroupTitle BOOL mSelected; }; -class LLGroupMgr; - class LLGroupMgrGroupData { friend class LLGroupMgr; @@ -228,26 +249,38 @@ public: void recalcAllAgentPowers(); void recalcAgentPowers(const LLUUID& agent_id); - BOOL isMemberDataComplete() { return mMemberDataComplete; } - BOOL isRoleDataComplete() { return mRoleDataComplete; } - BOOL isRoleMemberDataComplete() { return mRoleMemberDataComplete; } - BOOL isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } + bool isMemberDataComplete() { return mMemberDataComplete; } + bool isRoleDataComplete() { return mRoleDataComplete; } + bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; } + bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } + + bool isSingleMemberNotOwner(); F32 getAccessTime() const { return mAccessTime; } void setAccessed(); const LLUUID& getMemberVersion() const { return mMemberVersion; } + + void clearBanList() { mBanList.clear(); } + void getBanList(const LLUUID& ban_i, const LLGroupBanData& ban_data = LLGroupBanData()); + const LLGroupBanData& getBanEntry(const LLUUID& ban_id) { return mBanList[ban_id]; } + + void createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data = LLGroupBanData()); + void removeBanEntry(const LLUUID& ban_id); + + public: typedef std::map member_list_t; typedef std::map role_list_t; typedef std::map change_map_t; typedef std::map role_data_map_t; + typedef std::map ban_list_t; + member_list_t mMembers; role_list_t mRoles; - - change_map_t mRoleMemberChanges; role_data_map_t mRoleChanges; + ban_list_t mBanList; std::vector mTitles; @@ -277,12 +310,12 @@ private: LLUUID mTitlesRequestID; U32 mReceivedRoleMemberPairs; - BOOL mMemberDataComplete; - BOOL mRoleDataComplete; - BOOL mRoleMemberDataComplete; - BOOL mGroupPropertiesDataComplete; + bool mMemberDataComplete; + bool mRoleDataComplete; + bool mRoleMemberDataComplete; + bool mGroupPropertiesDataComplete; - BOOL mPendingRoleMemberRequest; + bool mPendingRoleMemberRequest; F32 mAccessTime; // Generate a new ID every time mMembers @@ -309,6 +342,23 @@ class LLGroupMgr : public LLSingleton { LOG_CLASS(LLGroupMgr); +public: + enum EBanRequestType + { + REQUEST_GET = 0, + REQUEST_POST, + REQUEST_PUT, + REQUEST_DEL + }; + + enum EBanRequestAction + { + BAN_NO_ACTION = 0, + BAN_CREATE = 1, + BAN_DELETE = 2, + BAN_UPDATE = 4 + }; + public: LLGroupMgr(); ~LLGroupMgr(); @@ -343,6 +393,13 @@ public: static void sendGroupMemberEjects(const LLUUID& group_id, uuid_vec_t& member_ids); + static void sendGroupBanRequest(EBanRequestType request_type, + const LLUUID& group_id, + U32 ban_action = BAN_NO_ACTION, + const uuid_vec_t ban_list = uuid_vec_t()); + + static void processGroupBanRequest(const LLSD& content); + void sendCapGroupMembersRequest(const LLUUID& group_id); static void processCapGroupMembersRequest(const LLSD& content); @@ -387,4 +444,3 @@ private: #endif - diff --git a/indra/newview/llgroupnotify.cpp b/indra/newview/llgroupnotify.cpp index 5d31f8acb..c432ca547 100644 --- a/indra/newview/llgroupnotify.cpp +++ b/indra/newview/llgroupnotify.cpp @@ -258,7 +258,7 @@ LLGroupNotifyBox::LLGroupNotifyBox(const std::string& subject, mNextBtn = btn; S32 btn_width = 80; - S32 wide_btn_width = 120; + S32 wide_btn_width = 136; LLRect btn_rect; x = 3 * HPAD; diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp index a78285816..ca7bdb26b 100644 --- a/indra/newview/llhomelocationresponder.cpp +++ b/indra/newview/llhomelocationresponder.cpp @@ -39,7 +39,7 @@ #include "llagent.h" #include "llviewerregion.h" -void LLHomeLocationResponder::result( const LLSD& content ) +void LLHomeLocationResponder::httpSuccess(void) { LLVector3 agent_pos; bool error = true; @@ -48,48 +48,48 @@ void LLHomeLocationResponder::result( const LLSD& content ) // was the call to /agent//home-location successful? // If not, we keep error set to true - if( ! content.has("success") ) + if( ! mContent.has("success") ) { break; } - if( 0 != strncmp("true", content["success"].asString().c_str(), 4 ) ) + if( 0 != strncmp("true", mContent["success"].asString().c_str(), 4 ) ) { break; } // did the simulator return a "justified" home location? // If no, we keep error set to true - if( ! content.has( "HomeLocation" ) ) + if( ! mContent.has( "HomeLocation" ) ) { break; } - if( ! content["HomeLocation"].has("LocationPos") ) + if( ! mContent["HomeLocation"].has("LocationPos") ) { break; } - if( ! content["HomeLocation"]["LocationPos"].has("X") ) + if( ! mContent["HomeLocation"]["LocationPos"].has("X") ) { break; } - agent_pos.mV[VX] = content["HomeLocation"]["LocationPos"]["X"].asInteger(); + agent_pos.mV[VX] = mContent["HomeLocation"]["LocationPos"]["X"].asInteger(); - if( ! content["HomeLocation"]["LocationPos"].has("Y") ) + if( ! mContent["HomeLocation"]["LocationPos"].has("Y") ) { break; } - agent_pos.mV[VY] = content["HomeLocation"]["LocationPos"]["Y"].asInteger(); + agent_pos.mV[VY] = mContent["HomeLocation"]["LocationPos"]["Y"].asInteger(); - if( ! content["HomeLocation"]["LocationPos"].has("Z") ) + if( ! mContent["HomeLocation"]["LocationPos"].has("Z") ) { break; } - agent_pos.mV[VZ] = content["HomeLocation"]["LocationPos"]["Z"].asInteger(); + agent_pos.mV[VZ] = mContent["HomeLocation"]["LocationPos"]["Z"].asInteger(); error = false; } while( 0 ); @@ -103,8 +103,8 @@ void LLHomeLocationResponder::result( const LLSD& content ) } } -void LLHomeLocationResponder::error( U32 status, const std::string& reason ) +void LLHomeLocationResponder::httpFailure(void) { - llinfos << "received error(" << reason << ")" << llendl; + llinfos << "httpFailure: " << dumpResponse() << llendl; } diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h index 9ffffc304..ef680bdfb 100644 --- a/indra/newview/llhomelocationresponder.h +++ b/indra/newview/llhomelocationresponder.h @@ -44,8 +44,8 @@ extern AIHTTPTimeoutPolicy homeLocationResponder_timeout; /* Typedef, Enum, Class, Struct, etc. */ class LLHomeLocationResponder : public LLHTTPClient::ResponderWithResult { - /*virtual*/ void result( const LLSD& content ); - /*virtual*/ void error( U32 status, const std::string& reason ); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return homeLocationResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLHomeLocationResponder"; } }; diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index 9f6acb60b..d653c8283 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -49,6 +49,7 @@ #include "llxmltree.h" // +#include "llavatarnamecache.h" #include "llresmgr.h" #include "llhudrender.h" #include "llviewerwindow.h" @@ -532,10 +533,26 @@ void LLHUDEffectLookAt::render() gGL.vertex3f(0.f, 0.f, -1.f); gGL.vertex3f(0.f, 0.f, 1.f); + static const LLCachedControl lookAtLines(gSavedSettings, "AlchemyLookAtLines", false); + if (lookAtLines) + { + const std::string targname = (*mAttentions)[mTargetType].mName; + if (targname != "None" && targname != "Idle" && targname != "AutoListen") + { + LLVector3 dist = (mSourceObject->getWorldPosition() - mTargetPos) * 10/3; + gGL.vertex3f(0.f, 0.f, 0.f); + gGL.vertex3f(dist.mV[VX], dist.mV[VY], dist.mV[VZ] + 0.5f); + } + } } gGL.end(); gGL.popMatrix(); // - const std::string text = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->getFullname(); + static const LLCachedControl lookAtNames("LookAtNameSystem"); + if (lookAtNames < 0) return; + std::string text; + if (!LLAvatarNameCache::getPNSName(static_cast(mSourceObject.get())->getID(), text, lookAtNames)) return; + if (text.length() > 9 && 0 == text.compare(text.length() - 9, 9, " Resident")) + text.erase(text.length() - 9); LLVector3 offset = gAgentCamera.getCameraPositionAgent() - target; offset.normalize(); LLVector3 shadow_offset = offset * 0.49f; diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index e9b720d24..4c4173705 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -56,8 +56,6 @@ void hud_render_utf8text(const std::string &str, const LLVector3 &pos_agent, hud_render_text(wstr, pos_agent, font, style, shadow, x_offset, y_offset, color, orthographic); } -int glProjectf(const LLVector3& object, const F32* modelview, const F32* projection, const LLRect& viewport, LLVector3& windowCoordinate); - void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, const LLFontGL &font, const U8 style, @@ -115,7 +113,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, const LLRect& world_view_rect = gViewerWindow->getWorldViewRectRaw(); - glProjectf(render_pos, gGLModelView, gGLProjection, world_view_rect, window_coordinates); + gGL.projectf(render_pos, gGLModelView, gGLProjection, world_view_rect, window_coordinates); //fonts all render orthographically, set up projection`` gGL.matrixMode(LLRender::MM_PROJECTION); diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 7a4b11c86..da0f11280 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -172,10 +172,10 @@ public: mAgents = agents_to_invite; } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + /*virtual*/ void httpFailure(void) { //try an "old school" way. - if ( statusNum == 400 ) + if ( mStatus == 400 ) { start_deprecated_conference_chat( mTempSessionID, @@ -347,6 +347,7 @@ LLFloaterIMPanel::LLFloaterIMPanel( case IM_SESSION_P2P_INVITE: mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mLogLabel, mOtherParticipantUUID); LLAvatarTracker::instance().addParticularFriendObserver(mOtherParticipantUUID, this); + mDing = gSavedSettings.getBOOL("LiruNewMessageSoundIMsOn"); break; default: llwarns << "Unknown session type" << llendl; @@ -634,10 +635,10 @@ public: mSessionID = session_id; } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + /*virtual*/ void httpFailure(void) { llwarns << "Error inviting all agents to session [status:" - << statusNum << "]: " << reason << llendl; + << mStatus << "]: " << mReason << llendl; //throw something back to the viewer here? } @@ -1030,7 +1031,8 @@ void LLFloaterIMPanel::onClickToggleActiveSpeakers(const LLSD& value) void LLFloaterIMPanel::onInputEditorFocusReceived() { - mHistoryEditor->setCursorAndScrollToEnd(); + if (gSavedSettings.getBOOL("LiruLegacyScrollToEnd")) + mHistoryEditor->setCursorAndScrollToEnd(); } void LLFloaterIMPanel::onInputEditorKeystroke(LLLineEditor* caller) diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 4a06dd1c8..ac24627c5 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -117,7 +117,7 @@ public: mInvitiationType = invitation_type; } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { if ( gIMMgr) { @@ -137,7 +137,7 @@ public: //but unfortunately, our base that we are receiving here //may not be the most up to date. It was accurate at //some point in time though. - speaker_mgr->setSpeakers(content); + speaker_mgr->setSpeakers(mContent); //we now have our base of users in the session //that was accurate at some point, but maybe not now @@ -167,10 +167,10 @@ public: } } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + /*virtual*/ void httpFailure(void) { llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:" - << statusNum << "]: " << reason << llendl; + << mStatus << "]: " << mReason << llendl; //throw something back to the viewer here? if ( gIMMgr ) { @@ -181,7 +181,7 @@ public: if ( floaterp ) { - if ( 404 == statusNum ) + if ( 404 == mStatus ) { std::string error_string; error_string = "session_does_not_exist_error"; @@ -448,8 +448,8 @@ void LLIMMgr::addMessage( // create IM window as necessary if(!floater) { - // Return now if we're blocking this group's chat - if (getIgnoreGroup(session_id) && gAgent.isInGroup(session_id)) + // Return now if we're blocking this group's chat or conferences + if (gAgent.isInGroup(session_id) ? getIgnoreGroup(session_id) : dialog != IM_NOTHING_SPECIAL && dialog != IM_SESSION_P2P_INVITE && gSavedSettings.getBOOL("LiruBlockConferences")) return; std::string name = (session_name.size() > 1) ? session_name : from; @@ -1423,6 +1423,17 @@ public: }; +void leave_group_chat(const LLUUID& from_id, const LLUUID& session_id) +{ + // Tell the server we've left group chat + std::string name; + gAgent.buildFullname(name); + pack_instant_message(gMessageSystem, gAgentID, false, gAgentSessionID, from_id, + name, LLStringUtil::null, IM_ONLINE, IM_SESSION_LEAVE, session_id); + gAgent.sendReliableMessage(); + gIMMgr->removeSession(session_id); +} + class LLViewerChatterBoxInvitation : public LLHTTPNode { public: @@ -1535,13 +1546,7 @@ public: { if (gIMMgr->getIgnoreGroup(session_id)) { - // Tell the server we've left group chat - std::string name; - gAgent.buildFullname(name); - pack_instant_message(gMessageSystem, gAgentID, false, gAgent.getSessionID(), from_id, - name, LLStringUtil::null, IM_ONLINE, IM_SESSION_LEAVE, session_id); - gAgent.sendReliableMessage(); - gIMMgr->removeSession(session_id); + leave_group_chat(from_id, session_id); return; } else if (gSavedSettings.getBOOL("OptionShowGroupNameInChatIM")) @@ -1555,6 +1560,11 @@ public: } else { + if (from_id != session_id && gSavedSettings.getBOOL("LiruBlockConferences")) // from and session are equal for IMs only. + { + leave_group_chat(from_id, session_id); + return; + } prepend_msg = std::string("IM: "); } chat.mText = prepend_msg + name + separator_string + saved + message.substr(message_offset); diff --git a/indra/newview/llinventoryactions.cpp b/indra/newview/llinventoryactions.cpp index bb69789b5..5e2729820 100644 --- a/indra/newview/llinventoryactions.cpp +++ b/indra/newview/llinventoryactions.cpp @@ -34,6 +34,7 @@ #include "llagentwearables.h" #include "llappearancemgr.h" +#include "llfloaterperms.h" #include "llfoldervieweventlistener.h" #include "llimview.h" #include "llinventorybridge.h" @@ -304,7 +305,7 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type, parent_id, LLAssetType::AT_LSL_TEXT, LLInventoryType::IT_LSL, - PERM_MOVE | PERM_TRANSFER); + LLFloaterPerms::getNextOwnerPerms("Scripts")); } else if ("notecard" == type) { @@ -313,7 +314,7 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type, parent_id, LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, - PERM_ALL); + LLFloaterPerms::getNextOwnerPerms("Notecards")); } else if ("gesture" == type) { @@ -322,7 +323,7 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type, parent_id, LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, - PERM_ALL); + LLFloaterPerms::getNextOwnerPerms("Gestures")); } else if ("outfit" == type || ("update outfit" == type && !LLAppearanceMgr::getInstance()->updateBaseOutfit())) // If updateBaseOutfit fails, prompt to make a new outfit { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 323263d76..67b991607 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -85,7 +85,7 @@ #include "hippogridmanager.h" -// [RLVa:KB] +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) #include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] @@ -114,21 +114,6 @@ struct LLMoveInv using namespace LLOldEvents; -// Helpers -// bug in busy count inc/dec right now, logic is complex... do we really need it? -void inc_busy_count() -{ -// gViewerWindow->getWindow()->incBusyCount(); -// check balance of these calls if this code is changed to ever actually -// *do* something! -} -void dec_busy_count() -{ -// gViewerWindow->getWindow()->decBusyCount(); -// check balance of these calls if this code is changed to ever actually -// *do* something! -} - // Function declarations void remove_inventory_category_from_avatar(LLInventoryCategory* category); void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id); @@ -181,7 +166,6 @@ public: { if (clear_observer) { - dec_busy_count(); gInventory.removeObserver(this); delete this; } @@ -242,9 +226,15 @@ LLFolderType::EType LLInvFVBridge::getPreferredType() const // Folders don't have creation dates. time_t LLInvFVBridge::getCreationDate() const { - return 0; + /*LLInventoryObject* objectp = getInventoryObject(); + if (objectp) + { + return objectp->getCreationDate(); + }*/ + return (time_t)0; } + // Can be destroyed (or moved to trash) BOOL LLInvFVBridge::isItemRemovable() const { @@ -459,6 +449,11 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArrayupdateItem(item); + } } // notify inventory observers. @@ -1686,16 +1681,17 @@ BOOL LLItemBridge::isItemRenameable() const return FALSE; } + if (isInboxFolder()) + { + return FALSE; + } + // [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g if ( (rlv_handler_t::isEnabled()) && (!RlvFolderLocks::instance().canRenameItem(mUUID)) ) { return FALSE; } // [/RLVa:KB] - if (isInboxFolder()) - { - return FALSE; - } return (item->getPermissions().allowModifyBy(gAgent.getID())); } @@ -1733,7 +1729,6 @@ BOOL LLItemBridge::removeItem() return FALSE; } - // move it to the trash LLPreview::hide(mUUID, TRUE); LLInventoryModel* model = getInventoryModel(); @@ -1874,7 +1869,10 @@ BOOL LLFolderBridge::isItemMovable() const LLInventoryObject* obj = getInventoryObject(); if(obj) { - return (!LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType())); + // If it's a protected type folder, we can't move it + if (LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType())) + return FALSE; + return TRUE; } return FALSE; } @@ -2591,7 +2589,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer) llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl; if (clear_observer) { - dec_busy_count(); gInventory.removeObserver(this); delete this; } @@ -2605,7 +2602,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer) // could notify observers and throw us into an infinite loop. if (clear_observer) { - dec_busy_count(); gInventory.removeObserver(this); delete this; } @@ -2667,7 +2663,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer) { // it's all on its way - add an observer, and the inventory // will call done for us when everything is here. - inc_busy_count(); gInventory.addObserver(outfit); } */ @@ -2686,7 +2681,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer) { // it's all on its way - add an observer, and the inventory // will call done for us when everything is here. - inc_busy_count(); gInventory.addObserver(categories); } } @@ -2806,6 +2800,17 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) modifyOutfit(FALSE); return; } +#if SUPPORT_ENSEMBLES + else if ("wearasensemble" == action) + { + LLInventoryModel* model = getInventoryModel(); + if(!model) return; + LLViewerInventoryCategory* cat = getCategory(); + if(!cat) return; + LLAppearanceMgr::instance().addEnsembleLink(cat,true); + return; + } +#endif else if ("addtooutfit" == action) { modifyOutfit(TRUE); @@ -2943,12 +2948,7 @@ LLFolderType::EType LLFolderBridge::getPreferredType() const // Icons for folders are based on the preferred type LLUIImagePtr LLFolderBridge::getIcon() const { - LLFolderType::EType preferred_type = LLFolderType::FT_NONE; - LLViewerInventoryCategory* cat = getCategory(); - if(cat) - { - preferred_type = cat->getPreferredType(); - } + LLFolderType::EType preferred_type(getPreferredType()); // Singu Note: Duplicate code return getIcon(preferred_type); } @@ -2956,9 +2956,6 @@ LLUIImagePtr LLFolderBridge::getIcon() const LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type) { return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE)); - /*case LLAssetType::AT_MESH: - control = "inv_folder_mesh.tga"; - break;*/ } LLUIImagePtr LLFolderBridge::getOpenIcon() const @@ -3319,7 +3316,16 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) mItems.push_back(std::string("New Clothes")); mItems.push_back(std::string("New Body Parts")); } - +#if SUPPORT_ENSEMBLES + // Changing folder types is an unfinished unsupported feature + // and can lead to unexpected behavior if enabled. + mItems.push_back(std::string("Change Type")); + const LLViewerInventoryCategory *cat = getCategory(); + if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) + { + mDisabledItems.push_back(std::string("Change Type")); + } +#endif getClipboardEntries(false, mItems, mDisabledItems, flags); } else @@ -3387,7 +3393,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags) LLFolderType::EType type = category->getPreferredType(); const bool is_system_folder = LLFolderType::lookupIsProtectedType(type); // calling card related functionality for folders. -// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-3.0.0a) | Added: Catznip-2.4.0e +// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-2.4) const bool is_outfit = (type == LLFolderType::FT_OUTFIT); // [/SL:KB] @@ -3449,7 +3455,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags) mDisabledItems.push_back(std::string("Remove From Outfit")); } // if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID)) -// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-3.0.0a) | Added: Catznip-2.4.0e +// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-2.4) if ( ((is_outfit) && (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))) || ((!is_outfit) && (gAgentWearables.isCOFChangeInProgress())) ) // [/SL:KB] @@ -3495,7 +3501,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) else { // it's all on its way - add an observer, and the inventory will call done for us when everything is here. - inc_busy_count(); gInventory.addObserver(fetch); } } @@ -3849,7 +3854,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, const BOOL move_is_into_favorites = (mUUID == favorites_id); const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id); - const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); //(mUUID == outbox_id); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_item->getUUID(), outbox_id); LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); @@ -3870,10 +3875,6 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, switch (inv_item->getActualType()) { - //case LLFolderType::FT_ROOT_CATEGORY: - // is_movable = FALSE; - // break; - case LLAssetType::AT_CATEGORY: is_movable = !LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)inv_item)->getPreferredType()); break; @@ -3989,6 +3990,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } // If an item is being dragged between windows, unselect everything in the active window // so that we don't follow the selection to its new location (which is very annoying). + // RN: a better solution would be to deselect automatically when an item is moved + // and then select any item that is dropped only in the panel that it is dropped in if (active_panel && (destination_panel != active_panel)) { active_panel->unSelectAll(); @@ -4215,15 +4218,6 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, return accept; } -// +=================================================+ -// | LLTextureBridge | -// +=================================================+ - -LLUIImagePtr LLTextureBridge::getIcon() const -{ - return LLInventoryIcon::getIcon(LLAssetType::AT_TEXTURE, mInvType); -} - void open_texture(const LLUUID& item_id, const std::string& title, BOOL show_keep_discard, @@ -4261,6 +4255,15 @@ void open_texture(const LLUUID& item_id, } } +// +=================================================+ +// | LLTextureBridge | +// +=================================================+ + +LLUIImagePtr LLTextureBridge::getIcon() const +{ + return LLInventoryIcon::getIcon(LLAssetType::AT_TEXTURE, mInvType); +} + void LLTextureBridge::openItem() { LLViewerInventoryItem* item = getItem(); @@ -4865,26 +4868,6 @@ void open_notecard(LLViewerInventoryItem* inv_item, if(take_focus) preview->setFocus(TRUE); // Force to be entirely onscreen. gFloaterView->adjustToFitScreen(preview, FALSE); - - //if (source_id.notNull()) - //{ - // // look for existing tabbed view for content from same source - // LLPreview* existing_preview = LLPreview::getPreviewForSource(source_id); - // if (existing_preview) - // { - // // found existing preview from this source - // // is it already hosted in a multi-preview window? - // LLMultiPreview* preview_hostp = (LLMultiPreview*)existing_preview->getHost(); - // if (!preview_hostp) - // { - // // create new multipreview if it doesn't exist - // LLMultiPreview* preview_hostp = new LLMultiPreview(existing_preview->getRect()); - // preview_hostp->addFloater(existing_preview); - // } - // // add this preview to existing host - // preview_hostp->addFloater(preview); - // } - //} } } @@ -5261,7 +5244,7 @@ std::string LLObjectBridge::getLabelSuffix() const LLStringUtil::format_map_t args; args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name); - if(gRlvAttachmentLocks.canDetach(getItem())) + if (gRlvAttachmentLocks.canDetach(getItem())) return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args); else return LLItemBridge::getLabelSuffix() + LLTrans::getString("LockedOnAttachmentPoint", args); @@ -5271,9 +5254,11 @@ std::string LLObjectBridge::getLabelSuffix() const void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment, bool replace) { -// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.1a) | Added: RLVa-1.2.1a +// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.1) // If no attachment point was specified, try looking it up from the item name - if ( (rlv_handler_t::isEnabled()) && (!attachment) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) + static LLCachedControl fRlvDeprecateAttachPt(gSavedSettings, "RLVaDebugDeprecateExplicitPoint", false); + if ( (rlv_handler_t::isEnabled()) && (!fRlvDeprecateAttachPt) && + (!attachment) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) { attachment = RlvAttachPtLookup::getAttachPoint(item); } @@ -5313,19 +5298,23 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach if (replace && (attachment && attachment->getNumObjects() > 0)) { -// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a +// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.1) // Block if we can't "replace wear" what's currently there if ( (rlv_handler_t::isEnabled()) && ((gRlvAttachmentLocks.canAttach(attachment) & RLV_WEAR_REPLACE) == 0) ) + { return; + } // [/RLVa:KB] LLNotificationsUtil::add("ReplaceAttachment", LLSD(), payload, confirm_attachment_rez); } else { -// [RLVa:KB] - Checked: 2010-08-07 (RLVa-1.2.0i) | Modified: RLVa-1.2.0i +// [RLVa:KB] - Checked: 2010-08-07 (RLVa-1.2.0) // Block wearing anything on a non-attachable attachment point if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.isLockedAttachmentPoint(attach_pt, RLV_LOCK_ADD)) ) + { return; + } // [/RLVa:KB] LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); } @@ -5576,15 +5565,6 @@ void remove_inventory_category_from_avatar( LLInventoryCategory* category ) remove_inventory_category_from_avatar_step2(TRUE, category->getUUID() ); } -//struct OnRemoveStruct -//{ -// LLUUID mUUID; -// OnRemoveStruct(const LLUUID& uuid): -// mUUID(uuid) -// { -// } -//}; - void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id) { @@ -5840,13 +5820,6 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Wearable And Object Separator")); items.push_back(std::string("Wearable Edit")); -/*// [RLVa:KB] - Checked: 2011-09-16 (RLVa-1.1.4a) | Added: RLVa-1.1.4a - if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(item)) ) - { - disabled_items.push_back(std::string("Wearable And Object Wear")); - disabled_items.push_back(std::string("Wearable Edit")); - } -// [/RLVa:KB]*/ bool not_modifiable = !item || !gAgentWearables.isWearableModifiable(item->getUUID()); if (((flags & FIRST_SELECTED_ITEM) == 0) || not_modifiable) @@ -5868,10 +5841,6 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { case LLAssetType::AT_CLOTHING: items.push_back(std::string("Take Off")); -/*// [RLVa:KB] - Checked: 2011-09-16 (RLVa-1.1.4a) | Added: RLVa-1.1.4a - if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(item)) ) - disabled_items.push_back(std::string("Take Off")); -// [/RLVa:KB]*/ // Fallthrough since clothing and bodypart share wear options case LLAssetType::AT_BODYPART: if (get_is_item_worn(item->getUUID())) @@ -5956,19 +5925,19 @@ void LLWearableBridge::onWearOnAvatar(void* user_data) void LLWearableBridge::wearOnAvatar() { - // Note: This test is not in any other viewer and it seriously harms Singularity: - // On many opensim grids people start without a base outfit: they are not wearing - // anything (no shape, skin, eyes or hair). Even if one of those is missing, which - // ALSO happens due to (another) bug specific to Singularity (namely wearing a - // pre-multiwear wearable that is erroneously marked as 'shape' and causes the - // current shape to be removed), the user is eternally stuck as cloud since they - // are not ALLOWED to add the body parts that are missing BECAUSE they are missing?! - // The only way to recover from that is then to install another viewer and log in - // with that - go figure. - // - // Nevertheless, I won't break this test without good reason (although, again, no - // other viewer has it - so it can't be that serious) and therefore will only - // change it that users CAN wear body parts if those are missing :p (see below). + // Note: This test is not in any other viewer and it seriously harms Singularity: + // On many opensim grids people start without a base outfit: they are not wearing + // anything (no shape, skin, eyes or hair). Even if one of those is missing, which + // ALSO happens due to (another) bug specific to Singularity (namely wearing a + // pre-multiwear wearable that is erroneously marked as 'shape' and causes the + // current shape to be removed), the user is eternally stuck as cloud since they + // are not ALLOWED to add the body parts that are missing BECAUSE they are missing?! + // The only way to recover from that is then to install another viewer and log in + // with that - go figure. + // + // Nevertheless, I won't break this test without good reason (although, again, no + // other viewer has it - so it can't be that serious) and therefore will only + // change it that users CAN wear body parts if those are missing :p (see below). #if 0 // TODO: investigate wearables may not be loaded at this point EXT-8231 // Don't wear anything until initial wearables are loaded, can @@ -5983,15 +5952,15 @@ void LLWearableBridge::wearOnAvatar() LLViewerInventoryItem* item = getItem(); if (item) { - // - // Don't wear anything until initial wearables are loaded unless the user tries to replace - // a body part, which might be missing and be the REASON that areWearablesLoaded() returns false. - if ((item->getType() != LLAssetType::AT_BODYPART && !gAgentWearables.areWearablesLoaded())) - { - LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); - return; - } - // + // + // Don't wear anything until initial wearables are loaded unless the user tries to replace + // a body part, which might be missing and be the REASON that areWearablesLoaded() returns false. + if ((item->getType() != LLAssetType::AT_BODYPART && !gAgentWearables.areWearablesLoaded())) + { + LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); + return; + } + // LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true); } } @@ -6101,62 +6070,6 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data) return FALSE; } -// static -//void LLWearableBridge::onRemoveFromAvatar(void* user_data) -//{ -// LLWearableBridge* self = (LLWearableBridge*)user_data; -// if(!self) return; -// if(get_is_item_worn(self->mUUID)) -// { -// LLViewerInventoryItem* item = self->getItem(); -// if (item) -// { -// LLUUID parent_id = item->getParentUUID(); -// LLWearableList::instance().getAsset(item->getAssetUUID(), -// item->getName(), -// item->getType(), -// onRemoveFromAvatarArrived, -// new OnRemoveStruct(LLUUID(self->mUUID))); -// } -// } -//} - -// static -//void LLWearableBridge::onRemoveFromAvatarArrived(LLViewerWearable* wearable, -// void* userdata) -//{ -// OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata; -// const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID); -// [RLVa:KB] - Checked: 2010-03-20 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a -// if ( (rlv_handler_t::isEnabled()) && ((!wearable) || (!gRlvWearableLocks.canRemove(gInventory.getItem(item_id)))) ) -// { -// delete on_remove_struct; -// return; -// } -// [/RLVa:KB] -// if(wearable) -// { -// if( get_is_item_worn( item_id ) ) -// { -// LLWearableType::EType type = wearable->getType(); -// -// if( !(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES ) ) //&& -// //!((!gAgent.isTeen()) && ( type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT )) ) -// { -// bool do_remove_all = false; -// U32 index = gAgentWearables.getWearableIndex(wearable); -// gAgentWearables.removeWearable( type, do_remove_all, index ); -// } -// } -// } -// -// // Find and remove this item from the COF. -// LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false); -// gInventory.notifyObservers(); -// -// delete on_remove_struct; -//} - void LLWearableBridge::removeFromAvatar() { if (get_is_item_worn(mUUID)) diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 4b2466f89..5ad486bad 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -541,24 +541,24 @@ public: { } - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { - LL_WARNS("InvAPI") << "CreateInventoryCategory failed. status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL; + LL_WARNS("InvAPI") << "CreateInventoryCategory failed. status = " << mStatus << ", reason = \"" << mReason << "\"" << LL_ENDL; } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { //Server has created folder. - LLUUID category_id = content["folder_id"].asUUID(); + LLUUID category_id = mContent["folder_id"].asUUID(); // Add the category to the internal representation LLPointer cat = new LLViewerInventoryCategory( category_id, - content["parent_id"].asUUID(), - (LLFolderType::EType)content["type"].asInteger(), - content["name"].asString(), + mContent["parent_id"].asUUID(), + (LLFolderType::EType)mContent["type"].asInteger(), + mContent["name"].asString(), gAgent.getID() ); cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL); cat->setDescendentCount(0); @@ -568,7 +568,7 @@ public: if (mCallback && mData) { - mCallback(content, mData); + mCallback(mContent, mData); } } @@ -1469,12 +1469,12 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent) } // If we get back a normal response, handle it here -void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content) +void LLInventoryModel::fetchInventoryResponder::httpSuccess(void) { start_new_inventory_observer(); /*LLUUID agent_id; - agent_id = content["agent_id"].asUUID(); + agent_id = mContent["agent_id"].asUUID(); if(agent_id != gAgent.getID()) { llwarns << "Got a inventory update for the wrong agent: " << agent_id @@ -1483,13 +1483,13 @@ void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content) }*/ item_array_t items; update_map_t update; - S32 count = content["items"].size(); + S32 count = mContent["items"].size(); LLUUID folder_id; // Does this loop ever execute more than once? for(S32 i = 0; i < count; ++i) { LLPointer titem = new LLViewerInventoryItem; - titem->unpackMessage(content["items"][i]); + titem->unpackMessage(mContent["items"][i]); lldebugs << "LLInventoryModel::messageUpdateCore() item id:" << titem->getUUID() << llendl; @@ -1529,10 +1529,10 @@ void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content) } //If we get back an error (not found, etc...), handle it here -void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::string& reason) +void LLInventoryModel::fetchInventoryResponder::httpFailure(void) { llinfos << "fetchInventory::error " - << status << ": " << reason << llendl; + << mStatus << ": " << mReason << llendl; gInventory.notifyObservers(); } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 259b08f87..a7136cb5a 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -87,8 +87,8 @@ public: { public: fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; - /*virtual*/ void result(const LLSD& content); - /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchInventoryResponder_timeout; } /*virtual*/ char const* getName(void) const { return "fetchInventoryResponder"; } @@ -523,7 +523,6 @@ public: // File I/O //-------------------------------------------------------------------- protected: - friend class LLLocalInventory; static bool loadFromFile(const std::string& filename, cat_array_t& categories, item_array_t& items, diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 6a828db9b..e6b2a72cb 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -393,21 +393,21 @@ class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInvento { public: LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {}; - /*virtual*/ void result(const LLSD& content); - /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchItemResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLInventoryModelFetchItemResponder"; } }; -void LLInventoryModelFetchItemResponder::result( const LLSD& content ) +void LLInventoryModelFetchItemResponder::httpSuccess(void) { - LLInventoryModel::fetchInventoryResponder::result(content); + LLInventoryModel::fetchInventoryResponder::httpSuccess(); LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } -void LLInventoryModelFetchItemResponder::error( U32 status, const std::string& reason ) +void LLInventoryModelFetchItemResponder::httpFailure(void) { - LLInventoryModel::fetchInventoryResponder::error(status, reason); + LLInventoryModel::fetchInventoryResponder::httpFailure(); LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } @@ -418,8 +418,8 @@ class LLInventoryModelFetchDescendentsResponder : public LLHTTPClient::Responder mRequestSD(request_sd), mRecursiveCatUUIDs(recursive_cats) {}; - /*virtual*/ void result(const LLSD& content); - /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchDescendentsResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLInventoryModelFetchDescendentsResponder"; } @@ -432,14 +432,14 @@ private: }; // If we get back a normal response, handle it here. -void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content) +void LLInventoryModelFetchDescendentsResponder::httpSuccess(void) { LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); - if (content.has("folders")) + if (mContent.has("folders")) { - for(LLSD::array_const_iterator folder_it = content["folders"].beginArray(); - folder_it != content["folders"].endArray(); + for(LLSD::array_const_iterator folder_it = mContent["folders"].beginArray(); + folder_it != mContent["folders"].endArray(); ++folder_it) { LLSD folder_sd = *folder_it; @@ -535,10 +535,10 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content) } } - if (content.has("bad_folders")) + if (mContent.has("bad_folders")) { - for(LLSD::array_const_iterator folder_it = content["bad_folders"].beginArray(); - folder_it != content["bad_folders"].endArray(); + for(LLSD::array_const_iterator folder_it = mContent["bad_folders"].beginArray(); + folder_it != mContent["bad_folders"].endArray(); ++folder_it) { LLSD folder_sd = *folder_it; @@ -561,16 +561,16 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content) } //If we get back an error (not found, etc...), handle it here -void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason) +void LLInventoryModelFetchDescendentsResponder::httpFailure(void) { LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); llinfos << "LLInventoryModelFetchDescendentsResponder::error " - << status << ": " << reason << llendl; + << mStatus << ": " << mReason << llendl; fetcher->incrFetchCount(-1); - if (is_internal_http_error_that_warrants_a_retry(status)) // timed out + if (is_internal_http_error_that_warrants_a_retry(mStatus)) // timed out { for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray(); folder_it != mRequestSD["folders"].endArray(); diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 7a7c9b147..9adffa9ef 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -589,6 +589,14 @@ 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.get()); + if (mInventory) + { + const LLUUID trash_id = mInventory->findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (trash_id != model_item->getParentUUID() && (mask & LLInventoryObserver::INTERNAL) && new_parent->isOpen()) + { + setSelection(item_id, FALSE); + } + } } else { diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 6f014f598..b04c0260e 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -183,9 +183,12 @@ void LLManipRotate::render() LLMatrix4 mat; mat.initRows(a, b, c, LLVector4(0.f, 0.f, 0.f, 1.f)); - gGL.multMatrix( &mat.mMatrix[0][0] ); + LLMatrix4a mata; + mata.loadu((F32*)mat.mMatrix); + gGL.multMatrix( mata ); - gGL.rotatef( -90, 0.f, 1.f, 0.f); + static const LLMatrix4a rot = gGL.genRot(-90, 0.f, 1.f, 0.f); + gGL.rotatef(rot); LLColor4 color; if (mManipPart == LL_ROT_ROLL || mHighlightedPart == LL_ROT_ROLL) { @@ -253,7 +256,8 @@ void LLManipRotate::render() mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); gGL.pushMatrix(); { - gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); + static const LLMatrix4a rot = gGL.genRot( 90.f, 1.f, 0.f, 0.f ); + gGL.rotatef(rot); gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]); renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f), LLColor4( 0.f, 1.f, 0.f, 0.3f)); } @@ -264,7 +268,8 @@ void LLManipRotate::render() mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); gGL.pushMatrix(); { - gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); + static const LLMatrix4a rot = gGL.genRot( 90.f, 0.f, 1.f, 0.f ); + gGL.rotatef( rot ); gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]); renderActiveRing( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f), LLColor4( 1.f, 0.f, 0.f, 0.3f)); } @@ -308,7 +313,8 @@ void LLManipRotate::render() gGL.pushMatrix(); { - gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); + static const LLMatrix4a rot = gGL.genRot( 90.f, 1.f, 0.f, 0.f ); + gGL.rotatef( rot ); if (mHighlightedPart == LL_ROT_Y) { mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); @@ -326,7 +332,8 @@ void LLManipRotate::render() gGL.pushMatrix(); { - gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); + static const LLMatrix4a rot = gGL.genRot( 90.f, 0.f, 1.f, 0.f ); + gGL.rotatef( rot ); if (mHighlightedPart == LL_ROT_X) { mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index c3b21429c..3ef134ee0 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -54,23 +54,21 @@ #include "llviewerobject.h" #include "llviewerregion.h" #include "llviewerwindow.h" -#include "llwindow.h" #include "llhudrender.h" #include "llworld.h" #include "v2math.h" #include "llvoavatar.h" #include "llmeshrepository.h" +#include "lltrans.h" #include "hippolimits.h" - const F32 MAX_MANIP_SELECT_DISTANCE_SQUARED = 11.f * 11.f; const F32 SNAP_GUIDE_SCREEN_OFFSET = 0.05f; const F32 SNAP_GUIDE_SCREEN_LENGTH = 0.7f; const F32 SELECTED_MANIPULATOR_SCALE = 1.2f; const F32 MANIPULATOR_SCALE_HALF_LIFE = 0.07f; -const S32 NUM_MANIPULATORS = 14; -const LLManip::EManipPart MANIPULATOR_IDS[NUM_MANIPULATORS] = +const LLManip::EManipPart MANIPULATOR_IDS[LLManipScale::NUM_MANIPULATORS] = { LLManip::LL_CORNER_NNN, LLManip::LL_CORNER_NNP, @@ -88,6 +86,25 @@ const LLManip::EManipPart MANIPULATOR_IDS[NUM_MANIPULATORS] = LLManip::LL_FACE_NEGZ }; + +F32 get_default_max_prim_scale(bool is_flora) +{ + return gHippoLimits->getMaxPrimScale(); + /* Singu Note: We must check with the grid + // a bit of a hack, but if it's foilage, we don't want to use the + // new larger scale which would result in giant trees and grass + if (gMeshRepo.meshRezEnabled() && + !is_flora) + { + return DEFAULT_MAX_PRIM_SCALE; + } + else + { + return DEFAULT_MAX_PRIM_SCALE_NO_MESH; + } + */ +} + // static void LLManipScale::setUniform(BOOL b) { @@ -129,18 +146,16 @@ inline void LLManipScale::conditionalHighlight( U32 part, const LLColor4* highli LLColor4 default_highlight( 1.f, 1.f, 1.f, 1.f ); LLColor4 default_normal( 0.7f, 0.7f, 0.7f, 0.6f ); LLColor4 invisible(0.f, 0.f, 0.f, 0.f); - F32 manipulator_scale = 1.f; for (S32 i = 0; i < NUM_MANIPULATORS; i++) { if((U32)MANIPULATOR_IDS[i] == part) { - manipulator_scale = mManipulatorScales[i]; + mScaledBoxHandleSize = mManipulatorScales[i] * mBoxHandleSize[i]; break; } } - mScaledBoxHandleSize = mBoxHandleSize * manipulator_scale; if (mManipPart != (S32)LL_NO_PART && mManipPart != (S32)part) { gGL.color4fv( invisible.mV ); @@ -167,7 +182,6 @@ void LLManipScale::handleSelect() LLManipScale::LLManipScale( LLToolComposite* composite ) : LLManip( std::string("Scale"), composite ), - mBoxHandleSize( 1.f ), mScaledBoxHandleSize( 1.f ), mLastMouseX( -1 ), mLastMouseY( -1 ), @@ -176,21 +190,22 @@ LLManipScale::LLManipScale( LLToolComposite* composite ) mScaleSnapUnit1(1.f), mScaleSnapUnit2(1.f), mSnapRegimeOffset(0.f), + mTickPixelSpacing1(0.f), + mTickPixelSpacing2(0.f), mSnapGuideLength(0.f), - mInSnapRegime(FALSE), - mScaleSnapValue(0.f) + mSnapRegime(SNAP_REGIME_NONE), + mScaleSnappedValue(0.f) { - mManipulatorScales = new F32[NUM_MANIPULATORS]; for (S32 i = 0; i < NUM_MANIPULATORS; i++) { mManipulatorScales[i] = 1.f; + mBoxHandleSize[i] = 1.f; } } LLManipScale::~LLManipScale() { for_each(mProjectedManipulators.begin(), mProjectedManipulators.end(), DeletePointer()); - delete[] mManipulatorScales; } void LLManipScale::render() @@ -200,7 +215,8 @@ void LLManipScale::render() LLGLDepthTest gls_depth(GL_TRUE); LLGLEnable gl_blend(GL_BLEND); LLGLEnable gls_alpha_test(GL_ALPHA_TEST); - + LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + if( canAffectSelection() ) { gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -221,42 +237,48 @@ void LLManipScale::render() if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { - mBoxHandleSize = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); - mBoxHandleSize /= gAgentCamera.mHUDCurZoom; + for (S32 i = 0; i < NUM_MANIPULATORS; i++) + { + mBoxHandleSize[i] = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + mBoxHandleSize[i] /= gAgentCamera.mHUDCurZoom; + } } else { - F32 range_squared = dist_vec_squared(gAgentCamera.getCameraPositionAgent(), center_agent); - F32 range_from_agent_squared = dist_vec_squared(gAgent.getPositionAgent(), center_agent); - - // Don't draw manip if object too far away - if (gSavedSettings.getBOOL("LimitSelectDistance")) + for (S32 i = 0; i < NUM_MANIPULATORS; i++) { - F32 max_select_distance = gSavedSettings.getF32("MaxSelectDistance"); - if (range_from_agent_squared > max_select_distance * max_select_distance) + LLVector3 manipulator_pos = bbox.localToAgent(unitVectorToLocalBBoxExtent(partToUnitVector(MANIPULATOR_IDS[i]), bbox)); + F32 range_squared = dist_vec_squared(gAgentCamera.getCameraPositionAgent(), manipulator_pos); + F32 range_from_agent_squared = dist_vec_squared(gAgent.getPositionAgent(), manipulator_pos); + + // Don't draw manip if object too far away + if (gSavedSettings.getBOOL("LimitSelectDistance")) { - return; + F32 max_select_distance = gSavedSettings.getF32("MaxSelectDistance"); + if (range_from_agent_squared > max_select_distance * max_select_distance) + { + return; + } } - } - if (range_squared > 0.001f * 0.001f) - { - // range != zero - F32 fraction_of_fov = BOX_HANDLE_BASE_SIZE / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); - F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians - mBoxHandleSize = (F32) sqrtf(range_squared) * tan(apparent_angle) * BOX_HANDLE_BASE_FACTOR; - } - else - { - // range == zero - mBoxHandleSize = BOX_HANDLE_BASE_FACTOR; + if (range_squared > 0.001f * 0.001f) + { + // range != zero + F32 fraction_of_fov = BOX_HANDLE_BASE_SIZE / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians + mBoxHandleSize[i] = (F32) sqrtf(range_squared) * tan(apparent_angle) * BOX_HANDLE_BASE_FACTOR; + } + else + { + // range == zero + mBoxHandleSize[i] = BOX_HANDLE_BASE_FACTOR; + } } } //////////////////////////////////////////////////////////////////////// // Draw bounding box - LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); LLVector3 pos_agent = bbox.getPositionAgent(); LLQuaternion rot = bbox.getRotation(); @@ -379,6 +401,7 @@ BOOL LLManipScale::handleMouseUp(S32 x, S32 y, MASK mask) // Might have missed last update due to UPDATE_DELAY timing LLSelectMgr::getInstance()->sendMultipleUpdate( mLastUpdateFlags ); + //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); } return LLManip::handleMouseUp(x, y, mask); @@ -398,11 +421,11 @@ BOOL LLManipScale::handleHover(S32 x, S32 y, MASK mask) { drag( x, y ); } - lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipScale (active)" << llendl; + LL_DEBUGS("UserInput") << "hover handled by LLManipScale (active)" << LL_ENDL; } else { - mInSnapRegime = FALSE; + mSnapRegime = SNAP_REGIME_NONE; // not dragging... highlightManipulators(x, y); } @@ -410,7 +433,7 @@ BOOL LLManipScale::handleHover(S32 x, S32 y, MASK mask) // Patch up textures, if possible. LLSelectMgr::getInstance()->adjustTexturesByScale(FALSE, getStretchTextures()); - gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLSCALE); + gViewerWindow->setCursor(UI_CURSOR_TOOLSCALE); return TRUE; } @@ -429,7 +452,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) { LLVector4 translation(bbox.getPositionAgent()); transform.initRotTrans(bbox.getRotation(), translation); - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + LLMatrix4 cfr(OGL_TO_CFR_ROTATION.getF32ptr()); transform *= cfr; LLMatrix4 window_scale; F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom; @@ -440,8 +463,8 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) } else { - LLMatrix4 projMatrix = LLViewerCamera::getInstance()->getProjection(); - LLMatrix4 modelView = LLViewerCamera::getInstance()->getModelview(); + LLMatrix4 projMatrix( LLViewerCamera::getInstance()->getProjection().getF32ptr() ); + LLMatrix4 modelView( LLViewerCamera::getInstance()->getModelview().getF32ptr() ); transform.initAll(LLVector3(1.f, 1.f, 1.f), bbox.getRotation(), bbox.getPositionAgent()); transform *= modelView; @@ -497,19 +520,19 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) mHighlightedPart = LL_NO_PART; - for (minpulator_list_t::iterator iter = mProjectedManipulators.begin(); + for (manipulator_list_t::iterator iter = mProjectedManipulators.begin(); iter != mProjectedManipulators.end(); ++iter) { ManipulatorHandle* manipulator = *iter; { - manip2d.setVec(manipulator->mPosition.mV[VX] * half_width, manipulator->mPosition.mV[VY] * half_height); + manip2d.set(manipulator->mPosition.mV[VX] * half_width, manipulator->mPosition.mV[VY] * half_height); delta = manip2d - mousePos; - if (delta.magVecSquared() < MAX_MANIP_SELECT_DISTANCE_SQUARED) + if (delta.lengthSquared() < MAX_MANIP_SELECT_DISTANCE_SQUARED) { mHighlightedPart = manipulator->mManipID; - //llinfos << "Tried: " << mHighlightedPart << llendl; + //LL_INFOS() << "Tried: " << mHighlightedPart << LL_ENDL; break; } } @@ -528,7 +551,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) } } - lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipScale (inactive)" << llendl; + LL_DEBUGS("UserInput") << "hover handled by LLManipScale (inactive)" << LL_ENDL; } @@ -662,32 +685,32 @@ void LLManipScale::renderFaces( const LLBBox& bbox ) { case 0: conditionalHighlight( LL_FACE_POSZ, &z_highlight_color, &z_normal_color ); - renderAxisHandle( ctr, LLVector3( ctr.mV[VX], ctr.mV[VY], max.mV[VZ] ) ); + renderAxisHandle( LL_FACE_POSZ, ctr, LLVector3( ctr.mV[VX], ctr.mV[VY], max.mV[VZ] ) ); break; case 1: conditionalHighlight( LL_FACE_POSX, &x_highlight_color, &x_normal_color ); - renderAxisHandle( ctr, LLVector3( max.mV[VX], ctr.mV[VY], ctr.mV[VZ] ) ); + renderAxisHandle( LL_FACE_POSX, ctr, LLVector3( max.mV[VX], ctr.mV[VY], ctr.mV[VZ] ) ); break; case 2: conditionalHighlight( LL_FACE_POSY, &y_highlight_color, &y_normal_color ); - renderAxisHandle( ctr, LLVector3( ctr.mV[VX], max.mV[VY], ctr.mV[VZ] ) ); + renderAxisHandle( LL_FACE_POSY, ctr, LLVector3( ctr.mV[VX], max.mV[VY], ctr.mV[VZ] ) ); break; case 3: conditionalHighlight( LL_FACE_NEGX, &x_highlight_color, &x_normal_color ); - renderAxisHandle( ctr, LLVector3( min.mV[VX], ctr.mV[VY], ctr.mV[VZ] ) ); + renderAxisHandle( LL_FACE_NEGX, ctr, LLVector3( min.mV[VX], ctr.mV[VY], ctr.mV[VZ] ) ); break; case 4: conditionalHighlight( LL_FACE_NEGY, &y_highlight_color, &y_normal_color ); - renderAxisHandle( ctr, LLVector3( ctr.mV[VX], min.mV[VY], ctr.mV[VZ] ) ); + renderAxisHandle( LL_FACE_NEGY, ctr, LLVector3( ctr.mV[VX], min.mV[VY], ctr.mV[VZ] ) ); break; case 5: conditionalHighlight( LL_FACE_NEGZ, &z_highlight_color, &z_normal_color ); - renderAxisHandle( ctr, LLVector3( ctr.mV[VX], ctr.mV[VY], min.mV[VZ] ) ); + renderAxisHandle( LL_FACE_NEGZ, ctr, LLVector3( ctr.mV[VX], ctr.mV[VY], min.mV[VZ] ) ); break; } } @@ -697,10 +720,10 @@ void LLManipScale::renderFaces( const LLBBox& bbox ) void LLManipScale::renderEdges( const LLBBox& bbox ) { LLVector3 extent = bbox.getExtentLocal(); - F32 edge_width = mBoxHandleSize * .6f; for( U32 part = LL_EDGE_MIN; part <= LL_EDGE_MAX; part++ ) { + F32 edge_width = mBoxHandleSize[part] * .6f; LLVector3 direction = edgeToUnitVector( part ); LLVector3 center_to_edge = unitVectorToLocalBBoxExtent( direction, bbox ); @@ -761,14 +784,14 @@ void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z ) } -void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& end ) +void LLManipScale::renderAxisHandle( U32 part, const LLVector3& start, const LLVector3& end ) { if( getShowAxes() ) { // Draws a single "jacks" style handle: a long, retangular box from start to end. LLVector3 offset_start = end - start; - offset_start.normVec(); - offset_start = start + mBoxHandleSize * offset_start; + offset_start.normalize(); + offset_start = start + mBoxHandleSize[part] * offset_start; LLVector3 delta = end - offset_start; LLVector3 pos = offset_start + 0.5f * delta; @@ -777,9 +800,9 @@ void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& en { gGL.translatef( pos.mV[VX], pos.mV[VY], pos.mV[VZ] ); gGL.scalef( - mBoxHandleSize + llabs(delta.mV[VX]), - mBoxHandleSize + llabs(delta.mV[VY]), - mBoxHandleSize + llabs(delta.mV[VZ])); + mBoxHandleSize[part] + llabs(delta.mV[VX]), + mBoxHandleSize[part] + llabs(delta.mV[VY]), + mBoxHandleSize[part] + llabs(delta.mV[VZ])); gBox.render(); } gGL.popMatrix(); @@ -790,7 +813,7 @@ void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& en } } - +// General scale call void LLManipScale::drag( S32 x, S32 y ) { if( (LL_FACE_MIN <= (S32)mManipPart) @@ -798,8 +821,7 @@ void LLManipScale::drag( S32 x, S32 y ) { dragFace( x, y ); } - else - if( (LL_CORNER_MIN <= (S32)mManipPart) + else if( (LL_CORNER_MIN <= (S32)mManipPart) && ((S32)mManipPart <= LL_CORNER_MAX) ) { dragCorner( x, y ); @@ -825,123 +847,86 @@ void LLManipScale::drag( S32 x, S32 y ) gAgentCamera.clearFocusObject(); } -// Scale around the +// Scale on three axis simultaneously void LLManipScale::dragCorner( S32 x, S32 y ) { - LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); - // Suppress scale if mouse hasn't moved. if (x == mLastMouseX && y == mLastMouseY) { - // sendUpdates(TRUE,TRUE,TRUE); return; } - mLastMouseX = x; mLastMouseY = y; - LLVector3d drag_start_point_global = mDragStartPointGlobal; - LLVector3d drag_start_center_global = mDragStartCenterGlobal; - LLVector3 drag_start_point_agent = gAgent.getPosAgentFromGlobal(drag_start_point_global); - LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(drag_start_center_global); + LLVector3 drag_start_point_agent = gAgent.getPosAgentFromGlobal(mDragStartPointGlobal); + LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(mDragStartCenterGlobal); LLVector3d drag_start_dir_d; - drag_start_dir_d.setVec(drag_start_point_global - drag_start_center_global); - LLVector3 drag_start_dir_f; - drag_start_dir_f.setVec(drag_start_dir_d); + drag_start_dir_d.set(mDragStartPointGlobal - mDragStartCenterGlobal); F32 s = 0; F32 t = 0; - nearestPointOnLineFromMouse(x, y, drag_start_center_agent, drag_start_point_agent, s, t ); - F32 drag_start_dist = dist_vec(drag_start_point_agent, drag_start_center_agent); - if( s <= 0 ) // we only care about intersections in front of the camera { return; } + mDragPointGlobal = lerp(mDragStartCenterGlobal, mDragStartPointGlobal, t); - LLVector3d drag_point_global = drag_start_center_global + t * drag_start_dir_d; - - F32 scale_factor = t; - + LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + F32 scale_factor = 1.f; + F32 max_scale = partToMaxScale(mManipPart, bbox); + F32 min_scale = partToMinScale(mManipPart, bbox); BOOL uniform = LLManipScale::getUniform(); - if( !uniform ) - { - scale_factor = 0.5f + (scale_factor * 0.5f); - } - // check for snapping - LLVector3 drag_center_agent = gAgent.getPosAgentFromGlobal(drag_point_global); LLVector3 mouse_on_plane1; - getMousePointOnPlaneAgent(mouse_on_plane1, x, y, drag_center_agent, mScalePlaneNormal1); + getMousePointOnPlaneAgent(mouse_on_plane1, x, y, mScaleCenter, mScalePlaneNormal1); + mouse_on_plane1 -= mScaleCenter; + LLVector3 mouse_on_plane2; - getMousePointOnPlaneAgent(mouse_on_plane2, x, y, drag_center_agent, mScalePlaneNormal2); - LLVector3 mouse_dir_1 = mouse_on_plane1 - mScaleCenter; - LLVector3 mouse_dir_2 = mouse_on_plane2 - mScaleCenter; - LLVector3 mouse_to_scale_line_1 = mouse_dir_1 - projected_vec(mouse_dir_1, mScaleDir); - LLVector3 mouse_to_scale_line_2 = mouse_dir_2 - projected_vec(mouse_dir_2, mScaleDir); - LLVector3 mouse_to_scale_line_dir_1 = mouse_to_scale_line_1; - mouse_to_scale_line_dir_1.normVec(); - if (mouse_to_scale_line_dir_1 * mSnapGuideDir1 < 0.f) - { - // need to keep sign of mouse offset wrt to snap guide direction - mouse_to_scale_line_dir_1 *= -1.f; - } - LLVector3 mouse_to_scale_line_dir_2 = mouse_to_scale_line_2; - mouse_to_scale_line_dir_2.normVec(); - if (mouse_to_scale_line_dir_2 * mSnapGuideDir2 < 0.f) - { - // need to keep sign of mouse offset wrt to snap guide direction - mouse_to_scale_line_dir_2 *= -1.f; - } + getMousePointOnPlaneAgent(mouse_on_plane2, x, y, mScaleCenter, mScalePlaneNormal2); + mouse_on_plane2 -= mScaleCenter; - F32 snap_dir_dot_mouse_offset1 = mSnapGuideDir1 * mouse_to_scale_line_dir_1; - F32 snap_dir_dot_mouse_offset2 = mSnapGuideDir2 * mouse_to_scale_line_dir_2; - - F32 dist_from_scale_line_1 = mouse_to_scale_line_1 * mouse_to_scale_line_dir_1; - F32 dist_from_scale_line_2 = mouse_to_scale_line_2 * mouse_to_scale_line_dir_2; - - F32 max_scale = partToMaxScale(mManipPart, bbox); - F32 min_scale = partToMinScale(mManipPart, bbox); + LLVector3 projected_drag_pos1 = inverse_projected_vec(mScaleDir, orthogonal_component(mouse_on_plane1, mSnapGuideDir1)); + LLVector3 projected_drag_pos2 = inverse_projected_vec(mScaleDir, orthogonal_component(mouse_on_plane2, mSnapGuideDir2)); BOOL snap_enabled = gSavedSettings.getBOOL("SnapEnabled"); - if (snap_enabled && dist_from_scale_line_1 > mSnapRegimeOffset * snap_dir_dot_mouse_offset1) + if (snap_enabled && (mouse_on_plane1 - projected_drag_pos1) * mSnapGuideDir1 > mSnapRegimeOffset) { - mInSnapRegime = TRUE; - LLVector3 projected_drag_pos = mouse_on_plane1 - (dist_from_scale_line_1 / snap_dir_dot_mouse_offset1) * mSnapGuideDir1; - F32 drag_dist = (projected_drag_pos - mScaleCenter) * mScaleDir; + F32 drag_dist = mScaleDir * projected_drag_pos1; // Projecting the drag position allows for negative results, vs using the length which will result in a "reverse scaling" bug. - F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); + F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + projected_drag_pos1, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); F32 snap_dist = mScaleSnapUnit1 / (2.f * cur_subdivisions); F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit1 / cur_subdivisions); - mScaleSnapValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale); + mScaleSnappedValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale); + scale_factor = mScaleSnappedValue / dist_vec(drag_start_point_agent, drag_start_center_agent); + mScaleSnappedValue /= mScaleSnapUnit1 * 2.f; + mSnapRegime = SNAP_REGIME_UPPER; - scale_factor = mScaleSnapValue / drag_start_dist; if( !uniform ) { scale_factor *= 0.5f; } } - else if (snap_enabled && dist_from_scale_line_2 > mSnapRegimeOffset * snap_dir_dot_mouse_offset2) + else if (snap_enabled && (mouse_on_plane2 - projected_drag_pos2) * mSnapGuideDir2 > mSnapRegimeOffset ) { - mInSnapRegime = TRUE; - LLVector3 projected_drag_pos = mouse_on_plane2 - (dist_from_scale_line_2 / snap_dir_dot_mouse_offset2) * mSnapGuideDir2; - F32 drag_dist = (projected_drag_pos - mScaleCenter) * mScaleDir; + F32 drag_dist = mScaleDir * projected_drag_pos2; // Projecting the drag position allows for negative results, vs using the length which will result in a "reverse scaling" bug. - F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos, mScaleDir, mScaleSnapUnit2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); + F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + projected_drag_pos2, mScaleDir, mScaleSnapUnit2, mTickPixelSpacing2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); F32 snap_dist = mScaleSnapUnit2 / (2.f * cur_subdivisions); F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit2 / cur_subdivisions); - mScaleSnapValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale); + mScaleSnappedValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale); + scale_factor = mScaleSnappedValue / dist_vec(drag_start_point_agent, drag_start_center_agent); + mScaleSnappedValue /= mScaleSnapUnit2 * 2.f; + mSnapRegime = SNAP_REGIME_LOWER; - scale_factor = mScaleSnapValue / drag_start_dist; if( !uniform ) { scale_factor *= 0.5f; @@ -949,14 +934,18 @@ void LLManipScale::dragCorner( S32 x, S32 y ) } else { - mInSnapRegime = FALSE; + mSnapRegime = SNAP_REGIME_NONE; + scale_factor = t; + if (!uniform) + { + scale_factor = 0.5f + (scale_factor * 0.5f); + } } - F32 max_prim_scale = gHippoLimits->getMaxPrimScale(); - F32 min_prim_scale = gHippoLimits->getMinPrimScale(); + F32 MIN_PRIM_SCALE = gHippoLimits->getMinPrimScale(); - F32 max_scale_factor = max_prim_scale / min_prim_scale; - F32 min_scale_factor = min_prim_scale / max_prim_scale; + F32 max_scale_factor = get_default_max_prim_scale() / MIN_PRIM_SCALE; + F32 min_scale_factor = MIN_PRIM_SCALE / get_default_max_prim_scale(); // find max and min scale factors that will make biggest object hit max absolute scale and smallest object hit min absolute scale for (LLObjectSelection::iterator iter = mObjectSelection->begin(); @@ -971,10 +960,10 @@ void LLManipScale::dragCorner( S32 x, S32 y ) { const LLVector3& scale = selectNode->mSavedScale; - F32 cur_max_scale_factor = llmin( max_prim_scale / scale.mV[VX], max_prim_scale / scale.mV[VY], max_prim_scale / scale.mV[VZ] ); + F32 cur_max_scale_factor = llmin( get_default_max_prim_scale(LLPickInfo::isFlora(cur)) / scale.mV[VX], get_default_max_prim_scale(LLPickInfo::isFlora(cur)) / scale.mV[VY], get_default_max_prim_scale(LLPickInfo::isFlora(cur)) / scale.mV[VZ] ); max_scale_factor = llmin( max_scale_factor, cur_max_scale_factor ); - F32 cur_min_scale_factor = llmax( min_prim_scale / scale.mV[VX], min_prim_scale / scale.mV[VY], min_prim_scale / scale.mV[VZ] ); + F32 cur_min_scale_factor = llmax( MIN_PRIM_SCALE / scale.mV[VX], MIN_PRIM_SCALE / scale.mV[VY], MIN_PRIM_SCALE / scale.mV[VZ] ); min_scale_factor = llmax( min_scale_factor, cur_min_scale_factor ); } } @@ -1056,19 +1045,14 @@ void LLManipScale::dragCorner( S32 x, S32 y ) rebuild(cur); } } - - - - mDragPointGlobal = drag_point_global; } - +// Scale on a single axis void LLManipScale::dragFace( S32 x, S32 y ) { // Suppress scale if mouse hasn't moved. if (x == mLastMouseX && y == mLastMouseY) { - // sendUpdates(TRUE,TRUE,FALSE); return; } @@ -1081,9 +1065,9 @@ void LLManipScale::dragFace( S32 x, S32 y ) LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(drag_start_center_global); LLVector3d drag_start_dir_d; - drag_start_dir_d.setVec(drag_start_point_global - drag_start_center_global); + drag_start_dir_d.set(drag_start_point_global - drag_start_center_global); LLVector3 drag_start_dir_f; - drag_start_dir_f.setVec(drag_start_dir_d); + drag_start_dir_f.set(drag_start_dir_d); LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); @@ -1127,26 +1111,26 @@ void LLManipScale::dragFace( S32 x, S32 y ) if (snap_enabled && dist_from_scale_line > mSnapRegimeOffset) { - mInSnapRegime = TRUE; + mSnapRegime = static_cast(SNAP_REGIME_UPPER | SNAP_REGIME_LOWER); // A face drag doesn't have split regimes. if (dist_along_scale_line > max_drag_dist) { - mScaleSnapValue = max_drag_dist; + mScaleSnappedValue = max_drag_dist; LLVector3 clamp_point = mScaleCenter + max_drag_dist * mScaleDir; - drag_delta.setVec(clamp_point - drag_start_point_agent); + drag_delta.set(clamp_point - drag_start_point_agent); } else if (dist_along_scale_line < min_drag_dist) { - mScaleSnapValue = min_drag_dist; + mScaleSnappedValue = min_drag_dist; LLVector3 clamp_point = mScaleCenter + min_drag_dist * mScaleDir; - drag_delta.setVec(clamp_point - drag_start_point_agent); + drag_delta.set(clamp_point - drag_start_point_agent); } else { F32 drag_dist = scale_center_to_mouse * mScaleDir; - F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + mScaleDir * drag_dist, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); + F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + mScaleDir * drag_dist, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); F32 snap_dist = mScaleSnapUnit1 / (2.f * cur_subdivisions); F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit1 / cur_subdivisions); relative_snap_dist -= snap_dist; @@ -1160,7 +1144,7 @@ void LLManipScale::dragFace( S32 x, S32 y ) drag_dist - max_drag_dist, drag_dist - min_drag_dist); - mScaleSnapValue = drag_dist - relative_snap_dist; + mScaleSnappedValue = (drag_dist - relative_snap_dist) / (mScaleSnapUnit1 * 2.f); if (llabs(relative_snap_dist) < snap_dist) { @@ -1176,7 +1160,7 @@ void LLManipScale::dragFace( S32 x, S32 y ) } else { - mInSnapRegime = FALSE; + mSnapRegime = SNAP_REGIME_NONE; } LLVector3 dir_agent; @@ -1259,7 +1243,7 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto S32 axis_index = axis.mV[0] ? 0 : (axis.mV[1] ? 1 : 2 ); LLVector3 delta_local = end_local - start_local; - F32 delta_local_mag = delta_local.magVec(); + F32 delta_local_mag = delta_local.length(); LLVector3 dir_local; if (delta_local_mag == 0.f) { @@ -1272,7 +1256,7 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto F32 denom = axis * dir_local; F32 desired_delta_size = is_approx_zero(denom) ? 0.f : (delta_local_mag / denom); // in meters - F32 desired_scale = llclamp(selectNode->mSavedScale.mV[axis_index] + desired_delta_size, gHippoLimits->getMinPrimScale(), gHippoLimits->getMaxPrimScale()); + F32 desired_scale = llclamp(selectNode->mSavedScale.mV[axis_index] + desired_delta_size, gHippoLimits->getMinPrimScale(), get_default_max_prim_scale(LLPickInfo::isFlora(cur))); // propagate scale constraint back to position offset desired_delta_size = desired_scale - selectNode->mSavedScale.mV[axis_index]; // propagate constraint back to position @@ -1285,7 +1269,7 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto { LLVector3 delta_pos_local = axis * (0.5f * desired_delta_size); LLVector3d delta_pos_global; - delta_pos_global.setVec(cur_bbox.localToAgent( delta_pos_local ) - cur_bbox.getCenterAgent()); + delta_pos_global.set(cur_bbox.localToAgent( delta_pos_local ) - cur_bbox.getCenterAgent()); LLVector3 cur_pos = cur->getPositionEdit(); if (cur->isRootEdit() && !cur->isAttachment()) @@ -1343,7 +1327,7 @@ void LLManipScale::renderGuidelinesPart( const LLBBox& bbox ) } guideline_end -= guideline_start; - guideline_end.normVec(); + guideline_end.normalize(); guideline_end *= gAgent.getRegion()->getWidth(); guideline_end += guideline_start; @@ -1364,26 +1348,27 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) LLQuaternion grid_rotation; LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + bool uniform = LLManipScale::getUniform(); + LLVector3 box_corner_agent = bbox.localToAgent(unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox )); - mScaleCenter = getUniform() ? bbox.getCenterAgent() : bbox.localToAgent(unitVectorToLocalBBoxExtent( -1.f * partToUnitVector( mManipPart ), bbox )); + mScaleCenter = uniform ? bbox.getCenterAgent() : bbox.localToAgent(unitVectorToLocalBBoxExtent( -1.f * partToUnitVector( mManipPart ), bbox )); mScaleDir = box_corner_agent - mScaleCenter; - mScaleDir.normVec(); + mScaleDir.normalize(); if(mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { mSnapRegimeOffset = SNAP_GUIDE_SCREEN_OFFSET / gAgentCamera.mHUDCurZoom; - } else { - F32 object_distance = dist_vec(mScaleCenter, LLViewerCamera::getInstance()->getOrigin()); + F32 object_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstance()->getOrigin()); mSnapRegimeOffset = (SNAP_GUIDE_SCREEN_OFFSET * gViewerWindow->getWorldViewWidthRaw() * object_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio(); } LLVector3 cam_at_axis; F32 snap_guide_length; if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { - cam_at_axis.setVec(1.f, 0.f, 0.f); + cam_at_axis.set(1.f, 0.f, 0.f); snap_guide_length = SNAP_GUIDE_SCREEN_LENGTH / gAgentCamera.mHUDCurZoom; } else @@ -1396,18 +1381,17 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) mSnapGuideLength = snap_guide_length / llmax(0.1f, (llmin(mSnapGuideDir1 * cam_at_axis, mSnapGuideDir2 * cam_at_axis))); LLVector3 off_axis_dir = mScaleDir % cam_at_axis; - off_axis_dir.normVec(); + off_axis_dir.normalize(); if( (LL_FACE_MIN <= (S32)mManipPart) && ((S32)mManipPart <= LL_FACE_MAX) ) { - LLVector3 object_scale = bbox.getMaxLocal(); - object_scale.scaleVec(off_axis_dir * ~bbox.getRotation()); - object_scale.abs(); - if (object_scale.mV[VX] > object_scale.mV[VY] && object_scale.mV[VX] > object_scale.mV[VZ]) + LLVector3 bbox_relative_cam_dir = off_axis_dir * ~bbox.getRotation(); + bbox_relative_cam_dir.abs(); + if (bbox_relative_cam_dir.mV[VX] > bbox_relative_cam_dir.mV[VY] && bbox_relative_cam_dir.mV[VX] > bbox_relative_cam_dir.mV[VZ]) { mSnapGuideDir1 = LLVector3::x_axis * bbox.getRotation(); } - else if (object_scale.mV[VY] > object_scale.mV[VZ]) + else if (bbox_relative_cam_dir.mV[VY] > bbox_relative_cam_dir.mV[VZ]) { mSnapGuideDir1 = LLVector3::y_axis * bbox.getRotation(); } @@ -1417,7 +1401,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) } LLVector3 scale_snap = grid_scale; - mScaleSnapUnit1 = scale_snap.scaleVec(partToUnitVector( mManipPart )).magVec(); + mScaleSnapUnit1 = scale_snap.scaleVec(partToUnitVector( mManipPart )).length(); mScaleSnapUnit2 = mScaleSnapUnit1; mSnapGuideDir1 *= mSnapGuideDir1 * LLViewerCamera::getInstance()->getUpAxis() > 0.f ? 1.f : -1.f; mSnapGuideDir2 = mSnapGuideDir1 * -1.f; @@ -1426,7 +1410,6 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) } else if( (LL_CORNER_MIN <= (S32)mManipPart) && ((S32)mManipPart <= LL_CORNER_MAX) ) { - LLVector3 local_scale_dir = partToUnitVector( mManipPart ); LLVector3 local_camera_dir; if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { @@ -1434,74 +1417,133 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) } else { - local_camera_dir = (LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent()) * ~bbox.getRotation(); - local_camera_dir.normVec(); - } - local_scale_dir -= projected_vec(local_scale_dir, local_camera_dir); - local_scale_dir.normVec(); - LLVector3 x_axis_proj_camera = LLVector3::x_axis - projected_vec(LLVector3::x_axis, local_camera_dir); - x_axis_proj_camera.normVec(); - LLVector3 y_axis_proj_camera = LLVector3::y_axis - projected_vec(LLVector3::y_axis, local_camera_dir); - y_axis_proj_camera.normVec(); - LLVector3 z_axis_proj_camera = LLVector3::z_axis - projected_vec(LLVector3::z_axis, local_camera_dir); - z_axis_proj_camera.normVec(); - F32 x_axis_proj = llabs(local_scale_dir * x_axis_proj_camera); - F32 y_axis_proj = llabs(local_scale_dir * y_axis_proj_camera); - F32 z_axis_proj = llabs(local_scale_dir * z_axis_proj_camera); - - if (x_axis_proj > y_axis_proj && x_axis_proj > z_axis_proj) - { - mSnapGuideDir1 = LLVector3::y_axis; - mScaleSnapUnit2 = grid_scale.mV[VY]; - mSnapGuideDir2 = LLVector3::z_axis; - mScaleSnapUnit1 = grid_scale.mV[VZ]; - } - else if (y_axis_proj > z_axis_proj) - { - mSnapGuideDir1 = LLVector3::x_axis; - mScaleSnapUnit2 = grid_scale.mV[VX]; - mSnapGuideDir2 = LLVector3::z_axis; - mScaleSnapUnit1 = grid_scale.mV[VZ]; - } - else - { - mSnapGuideDir1 = LLVector3::x_axis; - mScaleSnapUnit2 = grid_scale.mV[VX]; - mSnapGuideDir2 = LLVector3::y_axis; - mScaleSnapUnit1 = grid_scale.mV[VY]; + local_camera_dir = (LLViewerCamera::getInstance()->getOrigin() - box_corner_agent) * ~bbox.getRotation(); + local_camera_dir.normalize(); } - LLVector3 snap_guide_flip(1.f, 1.f, 1.f); + LLVector3 axis_flip; switch (mManipPart) { case LL_CORNER_NNN: + axis_flip.set(1.f, 1.f, 1.f); break; case LL_CORNER_NNP: - snap_guide_flip.setVec(1.f, 1.f, -1.f); + axis_flip.set(1.f, 1.f, -1.f); break; case LL_CORNER_NPN: - snap_guide_flip.setVec(1.f, -1.f, 1.f); + axis_flip.set(1.f, -1.f, 1.f); break; case LL_CORNER_NPP: - snap_guide_flip.setVec(1.f, -1.f, -1.f); + axis_flip.set(1.f, -1.f, -1.f); break; case LL_CORNER_PNN: - snap_guide_flip.setVec(-1.f, 1.f, 1.f); + axis_flip.set(-1.f, 1.f, 1.f); break; case LL_CORNER_PNP: - snap_guide_flip.setVec(-1.f, 1.f, -1.f); + axis_flip.set(-1.f, 1.f, -1.f); break; case LL_CORNER_PPN: - snap_guide_flip.setVec(-1.f, -1.f, 1.f); + axis_flip.set(-1.f, -1.f, 1.f); break; case LL_CORNER_PPP: - snap_guide_flip.setVec(-1.f, -1.f, -1.f); + axis_flip.set(-1.f, -1.f, -1.f); break; default: break; } - mSnapGuideDir1.scaleVec(snap_guide_flip); - mSnapGuideDir2.scaleVec(snap_guide_flip); + + // account for which side of the object the camera is located and negate appropriate axes + local_camera_dir.scaleVec(axis_flip); + + // normalize to object scale + LLVector3 bbox_extent = bbox.getExtentLocal(); + local_camera_dir.scaleVec(LLVector3(1.f / bbox_extent.mV[VX], 1.f / bbox_extent.mV[VY], 1.f / bbox_extent.mV[VZ])); + + S32 scale_face = -1; + + if ((local_camera_dir.mV[VX] > 0.f) == (local_camera_dir.mV[VY] > 0.f)) + { + if ((local_camera_dir.mV[VZ] > 0.f) == (local_camera_dir.mV[VY] > 0.f)) + { + LLVector3 local_camera_dir_abs = local_camera_dir; + local_camera_dir_abs.abs(); + // all neighboring faces of bbox are pointing towards camera or away from camera + // use largest magnitude face for snap guides + if (local_camera_dir_abs.mV[VX] > local_camera_dir_abs.mV[VY]) + { + if (local_camera_dir_abs.mV[VX] > local_camera_dir_abs.mV[VZ]) + { + scale_face = VX; + } + else + { + scale_face = VZ; + } + } + else // y > x + { + if (local_camera_dir_abs.mV[VY] > local_camera_dir_abs.mV[VZ]) + { + scale_face = VY; + } + else + { + scale_face = VZ; + } + } + } + else + { + // z axis facing opposite direction from x and y relative to camera, use x and y for snap guides + scale_face = VZ; + } + } + else // x and y axes are facing in opposite directions relative to camera + { + if ((local_camera_dir.mV[VZ] > 0.f) == (local_camera_dir.mV[VY] > 0.f)) + { + // x axis facing opposite direction from y and z relative to camera, use y and z for snap guides + scale_face = VX; + } + else + { + // y axis facing opposite direction from x and z relative to camera, use x and z for snap guides + scale_face = VY; + } + } + + switch(scale_face) + { + case VX: + // x axis face being scaled, use y and z for snap guides + mSnapGuideDir1 = LLVector3::y_axis.scaledVec(axis_flip); + mScaleSnapUnit1 = grid_scale.mV[VZ]; + mSnapGuideDir2 = LLVector3::z_axis.scaledVec(axis_flip); + mScaleSnapUnit2 = grid_scale.mV[VY]; + break; + case VY: + // y axis facing being scaled, use x and z for snap guides + mSnapGuideDir1 = LLVector3::x_axis.scaledVec(axis_flip); + mScaleSnapUnit1 = grid_scale.mV[VZ]; + mSnapGuideDir2 = LLVector3::z_axis.scaledVec(axis_flip); + mScaleSnapUnit2 = grid_scale.mV[VX]; + break; + case VZ: + // z axis facing being scaled, use x and y for snap guides + mSnapGuideDir1 = LLVector3::x_axis.scaledVec(axis_flip); + mScaleSnapUnit1 = grid_scale.mV[VY]; + mSnapGuideDir2 = LLVector3::y_axis.scaledVec(axis_flip); + mScaleSnapUnit2 = grid_scale.mV[VX]; + break; + default: + mSnapGuideDir1.setZero(); + mScaleSnapUnit1 = 0.f; + + mSnapGuideDir2.setZero(); + mScaleSnapUnit2 = 0.f; + break; + } + mSnapGuideDir1.rotVec(bbox.getRotation()); mSnapGuideDir2.rotVec(bbox.getRotation()); mSnapDir1 = -1.f * mSnapGuideDir2; @@ -1509,13 +1551,22 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) } mScalePlaneNormal1 = mSnapGuideDir1 % mScaleDir; - mScalePlaneNormal1.normVec(); + mScalePlaneNormal1.normalize(); mScalePlaneNormal2 = mSnapGuideDir2 % mScaleDir; - mScalePlaneNormal2.normVec(); + mScalePlaneNormal2.normalize(); mScaleSnapUnit1 = mScaleSnapUnit1 / (mSnapDir1 * mScaleDir); mScaleSnapUnit2 = mScaleSnapUnit2 / (mSnapDir2 * mScaleDir); + + mTickPixelSpacing1 = llround((F32)MIN_DIVISION_PIXEL_WIDTH / (mScaleDir % mSnapGuideDir1).length()); + mTickPixelSpacing2 = llround((F32)MIN_DIVISION_PIXEL_WIDTH / (mScaleDir % mSnapGuideDir2).length()); + + if (uniform) + { + mScaleSnapUnit1 *= 0.5f; + mScaleSnapUnit2 *= 0.5f; + } } void LLManipScale::renderSnapGuides(const LLBBox& bbox) @@ -1526,7 +1577,6 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) return; } - F32 max_subdivisions = sGridMaxSubdivisionLevel; static const LLCachedControl grid_alpha("GridOpacity",1.f); F32 max_point_on_scale_line = partToMaxScale(mManipPart, bbox); @@ -1540,9 +1590,9 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) LLColor4 tick_color = setupSnapGuideRenderPass(pass); gGL.begin(LLRender::LINES); - LLVector3 line_mid = mScaleCenter + (mScaleSnapValue * mScaleDir) + (mSnapGuideDir1 * mSnapRegimeOffset); - LLVector3 line_start = line_mid - (mScaleDir * (llmin(mScaleSnapValue, mSnapGuideLength * 0.5f))); - LLVector3 line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnapValue, mSnapGuideLength * 0.5f)); + LLVector3 line_mid = mScaleCenter + (mScaleSnappedValue * mScaleDir) + (mSnapGuideDir1 * mSnapRegimeOffset); + LLVector3 line_start = line_mid - (mScaleDir * (llmin(mScaleSnappedValue, mSnapGuideLength * 0.5f))); + LLVector3 line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnappedValue, mSnapGuideLength * 0.5f)); gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f); gGL.vertex3fv(line_start.mV); @@ -1552,9 +1602,9 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f); gGL.vertex3fv(line_end.mV); - line_mid = mScaleCenter + (mScaleSnapValue * mScaleDir) + (mSnapGuideDir2 * mSnapRegimeOffset); - line_start = line_mid - (mScaleDir * (llmin(mScaleSnapValue, mSnapGuideLength * 0.5f))); - line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnapValue, mSnapGuideLength * 0.5f)); + line_mid = mScaleCenter + (mScaleSnappedValue * mScaleDir) + (mSnapGuideDir2 * mSnapRegimeOffset); + line_start = line_mid - (mScaleDir * (llmin(mScaleSnappedValue, mSnapGuideLength * 0.5f))); + line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnappedValue, mSnapGuideLength * 0.5f)); gGL.vertex3fv(line_start.mV); gGL.color4fv(tick_color.mV); gGL.vertex3fv(line_mid.mV); @@ -1567,31 +1617,38 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) { LLGLDepthTest gls_depth(GL_FALSE); - F32 dist_grid_axis = (drag_point - mScaleCenter) * mScaleDir; + F32 dist_grid_axis = llmax(0.f, (drag_point - mScaleCenter) * mScaleDir); + + F32 smallest_subdivision1 = mScaleSnapUnit1 / sGridMaxSubdivisionLevel; + F32 smallest_subdivision2 = mScaleSnapUnit2 / sGridMaxSubdivisionLevel; + + F32 dist_scale_units_1 = dist_grid_axis / smallest_subdivision1; + F32 dist_scale_units_2 = dist_grid_axis / smallest_subdivision2; + // find distance to nearest smallest grid unit - F32 grid_offset1 = fmodf(dist_grid_axis, mScaleSnapUnit1 / max_subdivisions); - F32 grid_offset2 = fmodf(dist_grid_axis, mScaleSnapUnit2 / max_subdivisions); + F32 grid_multiple1 = llfloor(dist_scale_units_1); + F32 grid_multiple2 = llfloor(dist_scale_units_2); + F32 grid_offset1 = fmodf(dist_grid_axis, smallest_subdivision1); + F32 grid_offset2 = fmodf(dist_grid_axis, smallest_subdivision2); // how many smallest grid units are we away from largest grid scale? - S32 sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 / sGridMinSubdivisionLevel) / (mScaleSnapUnit1 / max_subdivisions)); - S32 sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 / sGridMinSubdivisionLevel) / (mScaleSnapUnit2 / max_subdivisions)); + S32 sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 / sGridMinSubdivisionLevel) / smallest_subdivision1); + S32 sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 / sGridMinSubdivisionLevel) / smallest_subdivision2); - S32 num_ticks_per_side1 = llmax(1, lltrunc(0.5f * mSnapGuideLength / (mScaleSnapUnit1 / max_subdivisions))); - S32 num_ticks_per_side2 = llmax(1, lltrunc(0.5f * mSnapGuideLength / (mScaleSnapUnit2 / max_subdivisions))); - F32 dist_scale_units_1 = dist_grid_axis / (mScaleSnapUnit1 / max_subdivisions); - F32 dist_scale_units_2 = dist_grid_axis / (mScaleSnapUnit2 / max_subdivisions); + S32 num_ticks_per_side1 = llmax(1, lltrunc(0.5f * mSnapGuideLength / smallest_subdivision1)); + S32 num_ticks_per_side2 = llmax(1, lltrunc(0.5f * mSnapGuideLength / smallest_subdivision2)); S32 ticks_from_scale_center_1 = lltrunc(dist_scale_units_1); S32 ticks_from_scale_center_2 = lltrunc(dist_scale_units_2); - S32 max_ticks1 = llceil(max_point_on_scale_line / (mScaleSnapUnit1 / max_subdivisions) - dist_scale_units_1); - S32 max_ticks2 = llceil(max_point_on_scale_line / (mScaleSnapUnit2 / max_subdivisions) - dist_scale_units_2); + S32 max_ticks1 = llceil(max_point_on_scale_line / smallest_subdivision1 - dist_scale_units_1); + S32 max_ticks2 = llceil(max_point_on_scale_line / smallest_subdivision2 - dist_scale_units_2); S32 start_tick = 0; S32 stop_tick = 0; - if (mInSnapRegime) + if (mSnapRegime != SNAP_REGIME_NONE) { // draw snap guide line gGL.begin(LLRender::LINES); - LLVector3 snap_line_center = mScaleCenter + (mScaleSnapValue * mScaleDir); + LLVector3 snap_line_center = bbox.localToAgent(unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox )); LLVector3 snap_line_start = snap_line_center + (mSnapGuideDir1 * mSnapRegimeOffset); LLVector3 snap_line_end = snap_line_center + (mSnapGuideDir2 * mSnapRegimeOffset); @@ -1613,22 +1670,22 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) LLVector3 arrow_span = mScaleDir; arrow_dir = snap_line_start - snap_line_center; - arrow_dir.normVec(); - gGL.vertex3fv((snap_line_start + arrow_dir * mBoxHandleSize).mV); - gGL.vertex3fv((snap_line_start + arrow_span * mBoxHandleSize).mV); - gGL.vertex3fv((snap_line_start - arrow_span * mBoxHandleSize).mV); + arrow_dir.normalize(); + gGL.vertex3fv((snap_line_start + arrow_dir * mSnapRegimeOffset * 0.1f).mV); + gGL.vertex3fv((snap_line_start + arrow_span * mSnapRegimeOffset * 0.1f).mV); + gGL.vertex3fv((snap_line_start - arrow_span * mSnapRegimeOffset * 0.1f).mV); arrow_dir = snap_line_end - snap_line_center; - arrow_dir.normVec(); - gGL.vertex3fv((snap_line_end + arrow_dir * mBoxHandleSize).mV); - gGL.vertex3fv((snap_line_end + arrow_span * mBoxHandleSize).mV); - gGL.vertex3fv((snap_line_end - arrow_span * mBoxHandleSize).mV); + arrow_dir.normalize(); + gGL.vertex3fv((snap_line_end + arrow_dir * mSnapRegimeOffset * 0.1f).mV); + gGL.vertex3fv((snap_line_end + arrow_span * mSnapRegimeOffset * 0.1f).mV); + gGL.vertex3fv((snap_line_end - arrow_span * mSnapRegimeOffset * 0.1f).mV); } gGL.end(); } LLVector2 screen_translate_axis(llabs(mScaleDir * LLViewerCamera::getInstance()->getLeftAxis()), llabs(mScaleDir * LLViewerCamera::getInstance()->getUpAxis())); - screen_translate_axis.normVec(); + screen_translate_axis.normalize(); S32 tick_label_spacing = llround(screen_translate_axis * sTickLabelSpacing); @@ -1644,17 +1701,17 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) for (S32 i = start_tick; i <= stop_tick; i++) { F32 alpha = (1.f - (1.f * ((F32)llabs(i) / (F32)num_ticks_per_side1))); - LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit1 / max_subdivisions * (F32)i - grid_offset1)); + LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple1 + i) * smallest_subdivision1); - F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); + F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); - if (fmodf((F32)(i + sub_div_offset_1), (max_subdivisions / cur_subdivisions)) != 0.f) + if (fmodf((F32)(i + sub_div_offset_1), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f) { continue; } F32 tick_scale = 1.f; - for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) + for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) { if (fmodf((F32)(i + sub_div_offset_1), division_level) == 0.f) { @@ -1677,17 +1734,17 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) for (S32 i = start_tick; i <= stop_tick; i++) { F32 alpha = (1.f - (1.f * ((F32)llabs(i) / (F32)num_ticks_per_side2))); - LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit2 / max_subdivisions * (F32)i - grid_offset2)); + LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple2 + i) * smallest_subdivision2); - F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); + F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, mTickPixelSpacing2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); - if (fmodf((F32)(i + sub_div_offset_2), (max_subdivisions / cur_subdivisions)) != 0.f) + if (fmodf((F32)(i + sub_div_offset_2), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f) { continue; } F32 tick_scale = 1.f; - for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) + for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) { if (fmodf((F32)(i + sub_div_offset_2), division_level) == 0.f) { @@ -1705,21 +1762,21 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) gGL.end(); } - // render tick labels + // render upper tick labels start_tick = -(llmin(ticks_from_scale_center_1, num_ticks_per_side1)); stop_tick = llmin(max_ticks1, num_ticks_per_side1); F32 grid_resolution = mObjectSelection->getSelectType() == SELECT_TYPE_HUD ? 0.25f : llmax(gSavedSettings.getF32("GridResolution"), 0.001f); - S32 label_sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 * 32.f) / (mScaleSnapUnit1 / max_subdivisions)); - S32 label_sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 * 32.f) / (mScaleSnapUnit2 / max_subdivisions)); + S32 label_sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 * 32.f) / smallest_subdivision1); + S32 label_sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 * 32.f) / smallest_subdivision2); for (S32 i = start_tick; i <= stop_tick; i++) { F32 tick_scale = 1.f; F32 alpha = grid_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side1))); - LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit1 / max_subdivisions * (F32)i - grid_offset1)); + LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple1 + i) * smallest_subdivision1); - for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) + for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) { if (fmodf((F32)(i + label_sub_div_offset_1), division_level) == 0.f) { @@ -1728,39 +1785,34 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) tick_scale *= 0.7f; } - if (fmodf((F32)(i + label_sub_div_offset_1), (max_subdivisions / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, tick_label_spacing)))) == 0.f) + if (fmodf((F32)(i + label_sub_div_offset_1), (sGridMaxSubdivisionLevel / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, tick_label_spacing)))) == 0.f) { - LLVector3 text_origin = tick_pos + - (mSnapGuideDir1 * mSnapRegimeOffset * (1.f + tick_scale)); + LLVector3 text_origin = tick_pos + (mSnapGuideDir1 * mSnapRegimeOffset * (1.f + tick_scale)); EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode(); - F32 tick_val; + F32 tick_value; if (grid_mode == GRID_MODE_WORLD) { - tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit1 / grid_resolution); + tick_value = (grid_multiple1 + i) / (sGridMaxSubdivisionLevel / grid_resolution); } else { - tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit1 * 2.f); - } - - if (getUniform()) - { - tick_val *= 2.f; + tick_value = (grid_multiple1 + i) / (2.f * sGridMaxSubdivisionLevel); } F32 text_highlight = 0.8f; - if (is_approx_equal(tick_val, mScaleSnapValue) && mInSnapRegime) + // Highlight this text if the tick value matches the snapped to value, and if either the second set of ticks isn't going to be shown or cursor is in the first snap regime. + if (is_approx_equal(tick_value, mScaleSnappedValue) && (mScaleSnapUnit2 == mScaleSnapUnit1 || (mSnapRegime & SNAP_REGIME_UPPER))) { text_highlight = 1.f; } - renderTickValue(text_origin, tick_val, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha)); + renderTickValue(text_origin, tick_value, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha)); } } - // label ticks on opposite side + // label ticks on opposite side, only can happen in scaling modes that effect more than one axis and when the object's axis don't have the same scale. A differing scale indicates both conditions. if (mScaleSnapUnit2 != mScaleSnapUnit1) { start_tick = -(llmin(ticks_from_scale_center_2, num_ticks_per_side2)); @@ -1769,9 +1821,9 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) { F32 tick_scale = 1.f; F32 alpha = grid_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side2))); - LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit2 / max_subdivisions * (F32)i - grid_offset2)); + LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple2 + i) * smallest_subdivision2); - for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) + for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) { if (fmodf((F32)(i + label_sub_div_offset_2), division_level) == 0.f) { @@ -1780,35 +1832,29 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) tick_scale *= 0.7f; } - if (fmodf((F32)(i + label_sub_div_offset_2), (max_subdivisions / llmin(max_subdivisions, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, tick_label_spacing)))) == 0.f) + if (fmodf((F32)(i + label_sub_div_offset_2), (sGridMaxSubdivisionLevel / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, tick_label_spacing)))) == 0.f) { - LLVector3 text_origin = tick_pos + - (mSnapGuideDir2 * mSnapRegimeOffset * (1.f + tick_scale)); + LLVector3 text_origin = tick_pos + (mSnapGuideDir2 * mSnapRegimeOffset * (1.f + tick_scale)); EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode(); - F32 tick_val; + F32 tick_value; if (grid_mode == GRID_MODE_WORLD) { - tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit2 / grid_resolution); + tick_value = (grid_multiple2 + i) / (sGridMaxSubdivisionLevel / grid_resolution); } else { - tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit2 * 2.f); - } - - if (getUniform()) - { - tick_val *= 2.f; + tick_value = (grid_multiple2 + i) / (2.f * sGridMaxSubdivisionLevel); } F32 text_highlight = 0.8f; - if (is_approx_equal(tick_val, mScaleSnapValue) && mInSnapRegime) + if (is_approx_equal(tick_value, mScaleSnappedValue) && (mSnapRegime & SNAP_REGIME_LOWER)) { text_highlight = 1.f; } - renderTickValue(text_origin, tick_val, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha)); + renderTickValue(text_origin, tick_value, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha)); } } } @@ -1834,13 +1880,13 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) LLVector3 help_text_pos = selection_center_start + (mSnapRegimeOffset * 5.f * offset_dir); const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); - std::string help_text = "Move mouse cursor over ruler"; + std::string help_text = LLTrans::getString("manip_hint1"); LLColor4 help_text_color = LLColor4::white; help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, grid_alpha, 0.f); - hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD); - help_text = "to snap to grid"; + hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); + help_text = LLTrans::getString("manip_hint2"); help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapRegimeOffset * 0.4f; - hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD); + hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); } } } @@ -1853,13 +1899,11 @@ LLVector3 LLManipScale::partToUnitVector( S32 part ) const { return faceToUnitVector( part ); } - else - if( (LL_CORNER_MIN <= part) && (part <= LL_CORNER_MAX) ) + else if ( (LL_CORNER_MIN <= part) && (part <= LL_CORNER_MAX) ) { return cornerToUnitVector( part ); } - else - if( (LL_EDGE_MIN <= part) && (part <= LL_EDGE_MAX ) ) + else if ( (LL_EDGE_MIN <= part) && (part <= LL_EDGE_MAX ) ) { return edgeToUnitVector( part ); } @@ -1871,27 +1915,32 @@ LLVector3 LLManipScale::partToUnitVector( S32 part ) const LLVector3 LLManipScale::faceToUnitVector( S32 part ) const { llassert( (LL_FACE_MIN <= part) && (part <= LL_FACE_MAX) ); + LLVector3 vec; switch( part ) { case LL_FACE_POSX: - return LLVector3( 1.f, 0.f, 0.f ); - + vec.set( 1.f, 0.f, 0.f ); + break; case LL_FACE_NEGX: - return LLVector3( -1.f, 0.f, 0.f ); - + vec.set( -1.f, 0.f, 0.f ); + break; case LL_FACE_POSY: - return LLVector3( 0.f, 1.f, 0.f ); - + vec.set( 0.f, 1.f, 0.f ); + break; case LL_FACE_NEGY: - return LLVector3( 0.f, -1.f, 0.f ); - + vec.set( 0.f, -1.f, 0.f ); + break; case LL_FACE_POSZ: - return LLVector3( 0.f, 0.f, 1.f ); - + vec.set( 0.f, 0.f, 1.f ); + break; case LL_FACE_NEGZ: - return LLVector3( 0.f, 0.f, -1.f ); + vec.set( 0.f, 0.f, -1.f ); + break; + default: + vec.clear(); } - return LLVector3(); + + return vec; } @@ -1903,31 +1952,31 @@ LLVector3 LLManipScale::cornerToUnitVector( S32 part ) const switch(part) { case LL_CORNER_NNN: - vec.setVec(-F_SQRT3, -F_SQRT3, -F_SQRT3); + vec.set(-OO_SQRT3, -OO_SQRT3, -OO_SQRT3); break; case LL_CORNER_NNP: - vec.setVec(-F_SQRT3, -F_SQRT3, F_SQRT3); + vec.set(-OO_SQRT3, -OO_SQRT3, OO_SQRT3); break; case LL_CORNER_NPN: - vec.setVec(-F_SQRT3, F_SQRT3, -F_SQRT3); + vec.set(-OO_SQRT3, OO_SQRT3, -OO_SQRT3); break; case LL_CORNER_NPP: - vec.setVec(-F_SQRT3, F_SQRT3, F_SQRT3); + vec.set(-OO_SQRT3, OO_SQRT3, OO_SQRT3); break; case LL_CORNER_PNN: - vec.setVec(F_SQRT3, -F_SQRT3, -F_SQRT3); + vec.set(OO_SQRT3, -OO_SQRT3, -OO_SQRT3); break; case LL_CORNER_PNP: - vec.setVec(F_SQRT3, -F_SQRT3, F_SQRT3); + vec.set(OO_SQRT3, -OO_SQRT3, OO_SQRT3); break; case LL_CORNER_PPN: - vec.setVec(F_SQRT3, F_SQRT3, -F_SQRT3); + vec.set(OO_SQRT3, OO_SQRT3, -OO_SQRT3); break; case LL_CORNER_PPP: - vec.setVec(F_SQRT3, F_SQRT3, F_SQRT3); + vec.set(OO_SQRT3, OO_SQRT3, OO_SQRT3); break; default: - vec.clearVec(); + vec.clear(); } return vec; @@ -1973,7 +2022,7 @@ F32 LLManipScale::partToMaxScale( S32 part, const LLBBox &bbox ) const max_extent = bbox_extents.mV[i]; } } - max_scale_factor = bbox_extents.magVec() * gHippoLimits->getMaxPrimScale() / max_extent; + max_scale_factor = bbox_extents.length() * get_default_max_prim_scale() / max_extent; if (getUniform()) { @@ -1988,7 +2037,7 @@ F32 LLManipScale::partToMinScale( S32 part, const LLBBox &bbox ) const { LLVector3 bbox_extents = unitVectorToLocalBBoxExtent( partToUnitVector( part ), bbox ); bbox_extents.abs(); - F32 min_extent = gHippoLimits->getMaxPrimScale(); + F32 min_extent = get_default_max_prim_scale(); for (U32 i = VX; i <= VZ; i++) { if (bbox_extents.mV[i] > 0.f && bbox_extents.mV[i] < min_extent) diff --git a/indra/newview/llmanipscale.h b/indra/newview/llmanipscale.h index 521a65e49..e5a96ca0a 100644 --- a/indra/newview/llmanipscale.h +++ b/indra/newview/llmanipscale.h @@ -40,6 +40,8 @@ #include "llbbox.h" +F32 get_default_max_prim_scale(bool is_flora = false); + class LLToolComposite; class LLColor4; @@ -49,6 +51,13 @@ typedef enum e_scale_manipulator_type SCALE_MANIP_FACE } EScaleManipulatorType; +typedef enum e_snap_regimes +{ + SNAP_REGIME_NONE = 0, //!< The cursor is not in either of the snap regimes. + SNAP_REGIME_UPPER = 0x1, //!< The cursor is, non-exclusively, in the first of the snap regimes. Prefer to treat as bitmask. + SNAP_REGIME_LOWER = 0x2 //!< The cursor is, non-exclusively, in the second of the snap regimes. Prefer to treat as bitmask. +} ESnapRegimes; + class LLManipScale : public LLManip { @@ -62,7 +71,7 @@ public: ManipulatorHandle(LLVector3 pos, EManipPart id, EScaleManipulatorType type):mPosition(pos), mManipID(id), mType(type){} }; - + static const S32 NUM_MANIPULATORS = 14; LLManipScale( LLToolComposite* composite ); ~LLManipScale(); @@ -89,7 +98,7 @@ private: void renderFaces( const LLBBox& local_bbox ); void renderEdges( const LLBBox& local_bbox ); void renderBoxHandle( F32 x, F32 y, F32 z ); - void renderAxisHandle( const LLVector3& start, const LLVector3& end ); + void renderAxisHandle( U32 part, const LLVector3& start, const LLVector3& end ); void renderGuidelinesPart( const LLBBox& local_bbox ); void renderSnapGuides( const LLBBox& local_bbox ); @@ -133,34 +142,36 @@ private: }; - F32 mBoxHandleSize; // The size of the handles at the corners of the bounding box - F32 mScaledBoxHandleSize; // handle size after scaling for selection feedback + F32 mScaledBoxHandleSize; //!< Handle size after scaling for selection feedback. LLVector3d mDragStartPointGlobal; - LLVector3d mDragStartCenterGlobal; // The center of the bounding box of all selected objects at time of drag start + LLVector3d mDragStartCenterGlobal; //!< The center of the bounding box of all selected objects at time of drag start. LLVector3d mDragPointGlobal; LLVector3d mDragFarHitGlobal; S32 mLastMouseX; S32 mLastMouseY; BOOL mSendUpdateOnMouseUp; U32 mLastUpdateFlags; - typedef std::set minpulator_list_t; - minpulator_list_t mProjectedManipulators; + typedef std::set manipulator_list_t; + manipulator_list_t mProjectedManipulators; LLVector4 mManipulatorVertices[14]; - F32 mScaleSnapUnit1; // size of snap multiples for axis 1 - F32 mScaleSnapUnit2; // size of snap multiples for axis 2 - LLVector3 mScalePlaneNormal1; // normal of plane in which scale occurs that most faces camera - LLVector3 mScalePlaneNormal2; // normal of plane in which scale occurs that most faces camera - LLVector3 mSnapGuideDir1; - LLVector3 mSnapGuideDir2; - LLVector3 mSnapDir1; - LLVector3 mSnapDir2; - F32 mSnapRegimeOffset; + F32 mScaleSnapUnit1; //!< Size of snap multiples for the upper scale. + F32 mScaleSnapUnit2; //!< Size of snap multiples for the lower scale. + LLVector3 mScalePlaneNormal1; //!< Normal of plane in which scale occurs that most faces camera. + LLVector3 mScalePlaneNormal2; //!< Normal of plane in which scale occurs that most faces camera. + LLVector3 mSnapGuideDir1; //!< The direction in which the upper snap guide tick marks face. + LLVector3 mSnapGuideDir2; //!< The direction in which the lower snap guide tick marks face. + LLVector3 mSnapDir1; //!< The direction in which the upper snap guides face. + LLVector3 mSnapDir2; //!< The direction in which the lower snap guides face. + F32 mSnapRegimeOffset; //!< How far off the scale axis centerline the mouse can be before it exits/enters the snap regime. + F32 mTickPixelSpacing1; //!< The pixel spacing between snap guide tick marks for the upper scale. + F32 mTickPixelSpacing2; //!< The pixel spacing between snap guide tick marks for the lower scale. F32 mSnapGuideLength; - LLVector3 mScaleCenter; - LLVector3 mScaleDir; - F32 mScaleSnapValue; - BOOL mInSnapRegime; - F32* mManipulatorScales; + LLVector3 mScaleCenter; //!< The location of the origin of the scaling operation. + LLVector3 mScaleDir; //!< The direction of the scaling action. In face-dragging this is aligned with one of the cardinal axis relative to the prim, but in corner-dragging this is along the diagonal. + F32 mScaleSnappedValue; //!< The distance of the current position nearest the mouse location, measured along mScaleDir. Is measured either from the center or from the far face/corner depending upon whether uniform scaling is true or false respectively. + ESnapRegimes mSnapRegime; //getBBoxOfSelection(); - LLMatrix4 projMatrix = LLViewerCamera::getInstance()->getProjection(); - LLMatrix4 modelView = LLViewerCamera::getInstance()->getModelview(); + LLMatrix4 projMatrix( LLViewerCamera::getInstance()->getProjection().getF32ptr() ); + LLMatrix4 modelView( LLViewerCamera::getInstance()->getModelview().getF32ptr() ); LLVector3 object_position = getPivotPoint(); @@ -827,7 +827,7 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) relative_camera_dir = LLVector3(1.f, 0.f, 0.f) * ~grid_rotation; LLVector4 translation(object_position); transform.initRotTrans(grid_rotation, translation); - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + LLMatrix4 cfr(OGL_TO_CFR_ROTATION.getF32ptr()); transform *= cfr; LLMatrix4 window_scale; F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom; @@ -1263,7 +1263,7 @@ void LLManipTranslate::renderSnapGuides() // find distance to nearest smallest grid unit F32 offset_nearest_grid_unit = fmodf(dist_grid_axis, smallest_grid_unit_scale); // how many smallest grid units are we away from largest grid scale? - S32 sub_div_offset = llround(fmod(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() / sGridMinSubdivisionLevel) / smallest_grid_unit_scale); + S32 sub_div_offset = llround(fmodf(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() / sGridMinSubdivisionLevel) / smallest_grid_unit_scale); S32 num_ticks_per_side = llmax(1, llfloor(0.5f * guide_size_meters / smallest_grid_unit_scale)); LLGLDepthTest gls_depth(GL_FALSE); @@ -1693,12 +1693,15 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, normal = -normal; } F32 d = -(selection_center * normal); - glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d ); + LLVector4a plane(normal.mV[0], normal.mV[1], normal.mV[2], d ); - gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane); + LLMatrix4a inv_mat = gGL.getModelviewMatrix(); + inv_mat.invert(); + inv_mat.transpose(); + inv_mat.rotate4(plane,plane); static LLStaticHashedString sClipPlane("clip_plane"); - gClipProgram.uniform4fv(sClipPlane, 1, plane.v); + gClipProgram.uniform4fv(sClipPlane, 1, plane.getF32ptr()); BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES); #if ENABLE_CLASSIC_CLOUDS diff --git a/indra/newview/llmapresponders.cpp b/indra/newview/llmapresponders.cpp index eaae3e450..081ef59fd 100644 --- a/indra/newview/llmapresponders.cpp +++ b/indra/newview/llmapresponders.cpp @@ -42,11 +42,11 @@ #include "llsdserialize.h" //virtual -void LLMapLayerResponder::result(const LLSD& result) +void LLMapLayerResponder::httpSuccess(void) { - llinfos << "LLMapLayerResponder::result from capabilities" << llendl; + llinfos << "LLMapLayerResponder::mContent from capabilities" << llendl; - S32 agent_flags = result["AgentData"]["Flags"]; + S32 agent_flags = mContent["AgentData"]["Flags"]; U32 layer = flagsToLayer(agent_flags); if (layer != SIM_LAYER_COMPOSITE) @@ -60,7 +60,7 @@ void LLMapLayerResponder::result(const LLSD& result) LLWorldMap::getInstance()->mMapLayers.clear(); LLSD::array_const_iterator iter; - for(iter = result["LayerData"].beginArray(); iter != result["LayerData"].endArray(); ++iter) + for(iter = mContent["LayerData"].beginArray(); iter != mContent["LayerData"].endArray(); ++iter) { const LLSD& layer_data = *iter; diff --git a/indra/newview/llmapresponders.h b/indra/newview/llmapresponders.h index 835722348..6f6a08f5d 100644 --- a/indra/newview/llmapresponders.h +++ b/indra/newview/llmapresponders.h @@ -40,7 +40,7 @@ extern AIHTTPTimeoutPolicy mapLayerResponder_timeout; class LLMapLayerResponder : public LLHTTPClient::ResponderWithResult { - /*virtual*/ void result(const LLSD& content); + /*virtual*/ void httpSuccess(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return mapLayerResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLMapLayerResponder"; } }; diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 60d2e52c2..3fc5a166e 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -41,7 +41,7 @@ // Helpers // -static std::string getLoginUriDomain() +std::string getLoginUriDomain() { LLURI uri(gHippoGridManager->getConnectedGrid()->getLoginUri()); std::string hostname = uri.hostName(); // Ie, "login..lindenlab.com" @@ -157,29 +157,29 @@ namespace LLMarketplaceImport class LLImportPostResponder : public LLHTTPClient::ResponderWithCompleted { public: - /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) + /*virtual*/ void httpCompleted(void) { slmPostTimer.stop(); if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM POST status: " << status << llendl; - llinfos << " SLM POST reason: " << reason << llendl; - llinfos << " SLM POST content: " << content.asString() << llendl; + llinfos << " SLM POST status: " << mStatus << llendl; + llinfos << " SLM POST reason: " << mReason << llendl; + llinfos << " SLM POST content: " << mContent.asString() << llendl; llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl; } // MAINT-2301 : we determined we can safely ignore that error in that context - if (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT) + if (mStatus == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT) { if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { llinfos << " SLM POST : Ignoring time out status and treating it as success" << llendl; } - status = MarketplaceErrorCodes::IMPORT_DONE; + mStatus = MarketplaceErrorCodes::IMPORT_DONE; } - if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) + if (mStatus >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) { if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { @@ -188,10 +188,10 @@ namespace LLMarketplaceImport sMarketplaceCookie.clear(); } - sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE); + sImportInProgress = (mStatus == MarketplaceErrorCodes::IMPORT_DONE); sImportPostPending = false; - sImportResultStatus = status; - sImportId = content; + sImportResultStatus = mStatus; + sImportId = mContent; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return MPImportPostResponder_timeout; } @@ -203,9 +203,9 @@ namespace LLMarketplaceImport public: /*virtual*/ bool needsHeaders(void) const { return true; } - /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(void) { - if (status == HTTP_OK) + if (mStatus == HTTP_OK) { std::string value = get_cookie("_slm_session"); if (!value.empty()) @@ -219,39 +219,39 @@ namespace LLMarketplaceImport } } - /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) + /*virtual*/ void httpCompleted(void) { slmGetTimer.stop(); if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM GET status: " << status << llendl; - llinfos << " SLM GET reason: " << reason << llendl; - llinfos << " SLM GET content: " << content.asString() << llendl; + llinfos << " SLM GET status: " << mStatus << llendl; + llinfos << " SLM GET reason: " << mReason << llendl; + llinfos << " SLM GET content: " << mContent.asString() << llendl; llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl; } // 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_NOT_FOUND)) + if ((mStatus >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) && + (mStatus != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) && + (mStatus != MarketplaceErrorCodes::IMPORT_NOT_FOUND)) { if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM GET clearing marketplace cookie due to client or server error (" << status << " / " << reason << ")." << llendl; + llinfos << " SLM GET clearing marketplace cookie due to client or server error (" << mStatus << " / " << mReason << ")." << llendl; } sMarketplaceCookie.clear(); } - else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)) + else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (mStatus >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)) { - llinfos << " SLM GET : Got error status = " << status << ", but marketplace cookie not cleared." << llendl; + llinfos << " SLM GET : Got error status = " << mStatus << ", but marketplace cookie not cleared." << llendl; } - sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING); + sImportInProgress = (mStatus == MarketplaceErrorCodes::IMPORT_PROCESSING); sImportGetPending = false; - sImportResultStatus = status; - sImportResults = content; + sImportResultStatus = mStatus; + sImportResults = mContent; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return MPImportGetResponder_timeout; } diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index b9d5177fc..b659653fe 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -73,8 +73,8 @@ public: LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback); virtual ~LLMaterialsResponder(); - virtual void result(const LLSD& pContent); - virtual void error(U32 pStatus, const std::string& pReason); + virtual void httpSuccess(void); + virtual void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return materialsResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLMaterialsResponder"; } @@ -96,18 +96,18 @@ LLMaterialsResponder::~LLMaterialsResponder() { } -void LLMaterialsResponder::result(const LLSD& pContent) +void LLMaterialsResponder::httpSuccess(void) { LL_DEBUGS("Materials") << LL_ENDL; - mCallback(true, pContent); + mCallback(true, mContent); } -void LLMaterialsResponder::error(U32 pStatus, const std::string& pReason) +void LLMaterialsResponder::httpFailure(void) { LL_WARNS("Materials") << "\n--------------------------------------------------------------------------\n" - << mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME - << "'\n with url '" << mCapabilityURL << "' because " << pReason + << mMethod << " Error[" << mStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME + << "'\n with url '" << mCapabilityURL << "' because " << mReason << "\n--------------------------------------------------------------------------" << LL_ENDL; diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index b6a7fdb07..80ed404d3 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -593,7 +593,7 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str { mCurrentNavUrl = expanded_filename; mMediaSource->setSize(mTextureWidth, mTextureHeight); - mMediaSource->navigateTo(expanded_filename, "text/html", false); + mMediaSource->navigateTo(LLWeb::escapeURL(expanded_filename), "text/html", false); } } diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index 654cba5a0..304f7050b 100644 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -564,7 +564,7 @@ LLMediaDataClient::Responder::Responder(const request_ptr_t &request) } /*virtual*/ -void LLMediaDataClient::Responder::error(U32 status, const std::string& reason) +void LLMediaDataClient::Responder::httpFailure(void) { mRequest->stopTracking(); @@ -574,7 +574,7 @@ void LLMediaDataClient::Responder::error(U32 status, const std::string& reason) return; } - if (status == HTTP_SERVICE_UNAVAILABLE) + if (mStatus == HTTP_SERVICE_UNAVAILABLE) { F32 retry_timeout = mRequest->getRetryTimerDelay(); @@ -596,13 +596,12 @@ void LLMediaDataClient::Responder::error(U32 status, const std::string& reason) } else { - std::string msg = boost::lexical_cast(status) + ": " + reason; - LL_WARNS("LLMediaDataClient") << *mRequest << " http error(" << msg << ")" << LL_ENDL; + LL_WARNS("LLMediaDataClient") << *mRequest << " http error: " << dumpResponse() << LL_ENDL; } } /*virtual*/ -void LLMediaDataClient::Responder::result(const LLSD& content) +void LLMediaDataClient::Responder::httpSuccess(void) { mRequest->stopTracking(); @@ -612,7 +611,7 @@ void LLMediaDataClient::Responder::result(const LLSD& content) return; } - LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << " result : " << ll_print_sd(content) << LL_ENDL; + LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << " result : " << ll_print_sd(mContent) << LL_ENDL; } ////////////////////////////////////////////////////////////////////////////////////// @@ -876,7 +875,7 @@ LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestUpdate::createResp /*virtual*/ -void LLObjectMediaDataClient::Responder::result(const LLSD& content) +void LLObjectMediaDataClient::Responder::httpSuccess(void) { getRequest()->stopTracking(); @@ -888,12 +887,12 @@ void LLObjectMediaDataClient::Responder::result(const LLSD& content) // This responder is only used for GET requests, not UPDATE. - LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " GET returned: " << ll_print_sd(content) << LL_ENDL; + LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " GET returned: " << ll_print_sd(mContent) << LL_ENDL; // Look for an error - if (content.has("error")) + if (mContent.has("error")) { - const LLSD &error = content["error"]; + const LLSD &error = mContent["error"]; LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error getting media data for object: code=" << error["code"].asString() << ": " << error["message"].asString() << LL_ENDL; @@ -902,7 +901,7 @@ void LLObjectMediaDataClient::Responder::result(const LLSD& content) else { // Check the data - const LLUUID &object_id = content[LLTextureEntry::OBJECT_ID_KEY]; + const LLUUID &object_id = mContent[LLTextureEntry::OBJECT_ID_KEY]; if (object_id != getRequest()->getObject()->getID()) { // NOT good, wrong object id!! @@ -911,8 +910,8 @@ void LLObjectMediaDataClient::Responder::result(const LLSD& content) } // Otherwise, update with object media data - getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY], - content[LLTextureEntry::MEDIA_VERSION_KEY]); + getRequest()->getObject()->updateObjectMediaData(mContent[LLTextureEntry::OBJECT_MEDIA_DATA_KEY], + mContent[LLTextureEntry::MEDIA_VERSION_KEY]); } } @@ -1003,7 +1002,7 @@ LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::crea } /*virtual*/ -void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string& reason) +void LLObjectMediaNavigateClient::Responder::httpFailure(void) { getRequest()->stopTracking(); @@ -1015,14 +1014,14 @@ void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string // Bounce back (unless HTTP_SERVICE_UNAVAILABLE, in which case call base // class - if (status == HTTP_SERVICE_UNAVAILABLE) + if (mStatus == HTTP_SERVICE_UNAVAILABLE) { - LLMediaDataClient::Responder::error(status, reason); + LLMediaDataClient::Responder::httpFailure(); } else { // bounce the face back - LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: http code=" << status << LL_ENDL; + LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: http code=" << mStatus << LL_ENDL; const LLSD &payload = getRequest()->getPayload(); // bounce the face back getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]); @@ -1030,7 +1029,7 @@ void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string } /*virtual*/ -void LLObjectMediaNavigateClient::Responder::result(const LLSD& content) +void LLObjectMediaNavigateClient::Responder::httpSuccess(void) { getRequest()->stopTracking(); @@ -1040,11 +1039,11 @@ void LLObjectMediaNavigateClient::Responder::result(const LLSD& content) return; } - LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << ll_print_sd(content) << LL_ENDL; + LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << ll_print_sd(mContent) << LL_ENDL; - if (content.has("error")) + if (mContent.has("error")) { - const LLSD &error = content["error"]; + const LLSD &error = mContent["error"]; int error_code = error["code"]; if (ERROR_PERMISSION_DENIED_CODE == error_code) @@ -1065,6 +1064,6 @@ void LLObjectMediaNavigateClient::Responder::result(const LLSD& content) else { // No action required. - LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " result : " << ll_print_sd(content) << LL_ENDL; + LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " result : " << ll_print_sd(mContent) << LL_ENDL; } } diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h index 093b84468..140d248f1 100644 --- a/indra/newview/llmediadataclient.h +++ b/indra/newview/llmediadataclient.h @@ -197,9 +197,9 @@ protected: Responder(const request_ptr_t &request); //If we get back an error (not found, etc...), handle it here - virtual void error(U32 status, const std::string& reason); + virtual void httpFailure(void); //If we get back a normal response, handle it here. Default just logs it. - virtual void result(const LLSD& content); + virtual void httpSuccess(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return mediaDataClientResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLMediaDataClientResponder"; } @@ -348,7 +348,7 @@ protected: public: Responder(const request_ptr_t &request) : LLMediaDataClient::Responder(request) {} - virtual void result(const LLSD &content); + virtual void httpSuccess(void); }; private: // The Get/Update data client needs a second queue to avoid object updates starving load-ins. @@ -404,8 +404,8 @@ protected: public: Responder(const request_ptr_t &request) : LLMediaDataClient::Responder(request) {} - virtual void error(U32 status, const std::string& reason); - virtual void result(const LLSD &content); + virtual void httpFailure(void); + virtual void httpSuccess(void); private: void mediaNavigateBounceBack(); }; diff --git a/indra/newview/llmediafilter.cpp b/indra/newview/llmediafilter.cpp new file mode 100644 index 000000000..56d01e422 --- /dev/null +++ b/indra/newview/llmediafilter.cpp @@ -0,0 +1,443 @@ +/* + * @file llmediafilter.h + * @brief Hyperbalistic SLU paranoia controls + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Sione Lomu. + * Copyright (C) 2014, Cinder Roxley. + * + * 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 + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llmediafilter.h" + +#include "llaudioengine.h" +#include "llnotificationsutil.h" +#include "llparcel.h" +#include "llsdserialize.h" +#include "lltrans.h" +#include "llvieweraudio.h" +#include "llviewerparcelmgr.h" +#include "llviewerparcelmedia.h" + +const std::string MEDIALIST_XML = "medialist.xml"; +bool handle_audio_filter_callback(const LLSD& notification, const LLSD& response, const std::string& url); +bool handle_media_filter_callback(const LLSD& notification, const LLSD& response, LLParcel* parcel); +std::string extractDomain(const std::string& in_url); + +LLMediaFilter::LLMediaFilter() +: mMediaCommandQueue(0) +, mCurrentParcel(NULL) +, mMediaQueue(NULL) +, mAlertActive(false) +{ + loadMediaFilterFromDisk(); +} + +void LLMediaFilter::filterMediaUrl(LLParcel* parcel) +{ + if (!parcel) return; + const std::string& url = parcel->getMediaURL(); + if (url.empty()) + { + return; + } + + const std::string domain = extractDomain(url); + mCurrentParcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + U32 enabled = gSavedSettings.getU32("MediaFilterEnable"); + + if (enabled > 1 && (filter(domain, WHITELIST) || filter(url, WHITELIST))) + { + LL_DEBUGS("MediaFilter") << "Media filter: URL allowed by whitelist: " << url << LL_ENDL; + LLViewerParcelMedia::play(parcel); + //mAudioState = PLAY; + } + else if (enabled && (filter(domain, BLACKLIST) || filter(url, BLACKLIST))) + { + LLNotificationsUtil::add("MediaBlocked", LLSD().with("DOMAIN", domain)); + //mAudioState = STOP; + } + else if (enabled && isAlertActive()) + { + mMediaQueue = parcel; + } + else if (enabled > 1) + { + LL_DEBUGS("MediaFilter") << "Media Filter: Unhanded by lists. Toasting: " << url << LL_ENDL; + setAlertStatus(true); + LLSD args, payload; + args["MEDIA_TYPE"] = LLTrans::getString("media"); + args["URL"] = url; + args["DOMAIN"] = domain; + payload = url; + LLNotificationsUtil::add("MediaAlert", args, payload, + boost::bind(&handle_media_filter_callback, _1, _2, parcel)); + } + else + { + LL_DEBUGS("MediaFilter") << "Media Filter: Skipping filters and playing " << url << LL_ENDL; + LLViewerParcelMedia::play(parcel); + //mAudioState = PLAY; + } +} + +void LLMediaFilter::filterAudioUrl(const std::string& url) +{ + if (url.empty()) + { + gAudiop->startInternetStream(url); + return; + } + if (url == mCurrentAudioURL) return; + + const std::string domain = extractDomain(url); + mCurrentParcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + U32 enabled = gSavedSettings.getU32("MediaFilterEnable"); + + if (enabled > 1 && (filter(domain, WHITELIST) || filter(url, WHITELIST))) + { + LL_DEBUGS("MediaFilter") << "Audio filter: URL allowed by whitelist: " << url << LL_ENDL; + gAudiop->startInternetStream(url); + } + else if (enabled && (filter(domain, BLACKLIST) || filter(url, BLACKLIST))) + { + LLNotificationsUtil::add("MediaBlocked", LLSD().with("DOMAIN", domain)); + gAudiop->stopInternetStream(); + } + else if (enabled && isAlertActive()) + { + mAudioQueue = url; + } + else if (enabled > 1) + { + LL_DEBUGS("MediaFilter") << "Audio Filter: Unhanded by lists. Toasting: " << url << LL_ENDL; + setAlertStatus(true); + LLSD args, payload; + args["MEDIA_TYPE"] = LLTrans::getString("audio"); + args["URL"] = url; + args["DOMAIN"] = domain; + LLNotificationsUtil::add("MediaAlert", args, LLSD(), + boost::bind(&handle_audio_filter_callback, _1, _2, url)); + } + else + { + LL_DEBUGS("MediaFilter") << "Audio Filter: Skipping filters and playing: " << url << LL_ENDL; + gAudiop->startInternetStream(url); + } + +} + +bool LLMediaFilter::filter(const std::string& url, EMediaList list) +{ + const string_list_t& p_list = (list == WHITELIST) ? mWhiteList : mBlackList; + string_list_t::const_iterator find_itr = std::find(p_list.begin(), p_list.end(), url); + return (find_itr != p_list.end()); +} + +// List bizznizz +void LLMediaFilter::addToMediaList(const std::string& in_url, EMediaList list, bool extract) +{ + const std::string url = extract ? extractDomain(in_url) : in_url; + if (url.empty()) + { + LL_INFOS("MediaFilter") << "No url found. Can't add to list." << LL_ENDL; + return; + } + + string_list_t& p_list(list == WHITELIST ? mWhiteList : mBlackList); + // Check for duplicates + for (string_list_t::const_iterator itr = p_list.begin(); itr != p_list.end(); ++itr) + { + if (url == *itr) + { + LL_INFOS("MediaFilter") << "URL " << url << " already in list!" << LL_ENDL; + return; + } + } + p_list.push_back(url); + mMediaListUpdate(list); + saveMediaFilterToDisk(); +} + +void LLMediaFilter::removeFromMediaList(string_vec_t domains, EMediaList list) +{ + if (domains.empty()) return; + for (string_vec_t::const_iterator itr = domains.begin(); itr != domains.end(); ++itr) + (list == WHITELIST ? mWhiteList : mBlackList).remove(*itr); + mMediaListUpdate(list); + saveMediaFilterToDisk(); +} + +void LLMediaFilter::loadMediaFilterFromDisk() +{ + const std::string medialist_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, MEDIALIST_XML); + mWhiteList.clear(); + mBlackList.clear(); + + LLSD medialist; + if (LLFile::isfile(medialist_filename)) + { + llifstream medialist_xml(medialist_filename); + LLSDSerialize::fromXML(medialist, medialist_xml); + medialist_xml.close(); + } + else + LL_INFOS("MediaFilter") << medialist_filename << " not found." << LL_ENDL; + + for (LLSD::array_const_iterator p_itr = medialist.beginArray(); + p_itr != medialist.endArray(); + ++p_itr) + { + LLSD itr = (*p_itr); + /// I hate this string shit more than you could ever imagine, + /// but I'm retaining it for backwards and cross-compatibility. :| + if (itr["action"].asString() == "allow") + { + LL_DEBUGS("MediaFilter") << "Adding " << itr["domain"].asString() << " to whitelist." << LL_ENDL; + mWhiteList.push_back(itr["domain"].asString()); + } + else if (itr["action"].asString() == "deny") + { + LL_DEBUGS("MediaFilter") << "Adding " << itr["domain"].asString() << " to blacklist." << LL_ENDL; + mBlackList.push_back(itr["domain"].asString()); + } + } +} + +void medialist_to_llsd(const LLMediaFilter::string_list_t& list, LLSD& list_llsd, const LLSD& action) +{ + for (LLMediaFilter::string_list_t::const_iterator itr = list.begin(); itr != list.end(); ++itr) + { + LLSD item; + item["domain"] = *itr; + item["action"] = action; + list_llsd.append(item); + } +} + +void LLMediaFilter::saveMediaFilterToDisk() const +{ + const std::string medialist_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, MEDIALIST_XML); + + LLSD medialist_llsd; + medialist_to_llsd(mWhiteList, medialist_llsd, "allow"); // <- $*#@()&%@ + medialist_to_llsd(mBlackList, medialist_llsd, "deny"); // sigh. + + llofstream medialist; + medialist.open(medialist_filename); + LLSDSerialize::toPrettyXML(medialist_llsd, medialist); + medialist.close(); +} + +void perform_queued_command(LLMediaFilter& inst) +{ + if (U32 command = inst.getQueuedMediaCommand()) + { + if (command == PARCEL_MEDIA_COMMAND_STOP) + { + LLViewerParcelMedia::stop(); + } + else if (command == PARCEL_MEDIA_COMMAND_PAUSE) + { + LLViewerParcelMedia::pause(); + } + else if (command == PARCEL_MEDIA_COMMAND_UNLOAD) + { + LLViewerParcelMedia::stop(); + } + else if (command == PARCEL_MEDIA_COMMAND_TIME) + { + LLViewerParcelMedia::seek(LLViewerParcelMedia::sMediaCommandTime); + } + inst.setQueuedMediaCommand(0); + } +} + +bool handle_audio_filter_callback(const LLSD& notification, const LLSD& response, const std::string& url) +{ + LLMediaFilter& inst(LLMediaFilter::instance()); + inst.setAlertStatus(false); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const std::string queue = inst.getQueuedAudio(); + switch(option) + { + case 3: // Whitelist domain + inst.addToMediaList(url, LLMediaFilter::WHITELIST); + case 0: // Allow + if (gAudiop != NULL) + { + if (inst.getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel()) + { + gAudiop->startInternetStream(url); + } + } + break; + case 2: // Blacklist domain + inst.addToMediaList(url, LLMediaFilter::BLACKLIST); + case 1: // Deny + if (gAudiop != NULL) + { + if (inst.getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel()) + { + gAudiop->stopInternetStream(); + } + } + break; + /*case 4: //Whitelist url + inst.addToMediaList(url, LLMediaFilter::WHITELIST, false); + if (gAudiop != NULL) + { + if (inst.getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel()) + { + gAudiop->startInternetStream(url); + } + } + break; + case 5: //Blacklist url + inst.addToMediaList(url, LLMediaFilter::BLACKLIST, false); + if (gAudiop != NULL) + { + if (inst.getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel()) + { + gAudiop->stopInternetStream(); + } + } + break;*/ + default: + // We should never be able to get here. + llassert(option); + break; + } + if (!queue.empty()) + { + inst.clearQueuedAudio(); + inst.filterAudioUrl(queue); + } + else if (inst.getQueuedMedia()) + { + inst.clearQueuedMedia(); + LLParcel* queued_media = inst.getQueuedMedia(); + if (queued_media) + inst.filterMediaUrl(queued_media); + } + else + { + perform_queued_command(inst); + } + + return false; +} + +bool handle_media_filter_callback(const LLSD& notification, const LLSD& response, LLParcel* parcel) +{ + LLMediaFilter& inst(LLMediaFilter::instance()); + inst.setAlertStatus(false); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const std::string& url = notification["payload"].asString(); + LLParcel* queue = inst.getQueuedMedia(); + switch(option) + { + case 2: // Whitelist domain + inst.addToMediaList(url, LLMediaFilter::WHITELIST); + case 0: // Allow + if (inst.getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel()) + LLViewerParcelMedia::play(parcel); + break; + case 3: // Blacklist domain + inst.addToMediaList(url, LLMediaFilter::BLACKLIST); + case 1: // Deny + break; + case 4: //Whitelist url + inst.addToMediaList(url, LLMediaFilter::WHITELIST, false); + if (inst.getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel()) + LLViewerParcelMedia::play(parcel); + break; + case 5: + inst.addToMediaList(url, LLMediaFilter::BLACKLIST, false); + break; + default: + // We should never be able to get here. + llassert(option); + break; + } + const std::string audio_queue = inst.getQueuedAudio(); + if (queue) + { + inst.clearQueuedMedia(); + inst.filterMediaUrl(queue); + } + else if (!audio_queue.empty()) + { + inst.clearQueuedAudio(); + inst.filterAudioUrl(audio_queue); + } + else + { + perform_queued_command(inst); + } + + return false; +} + +// Local Functions +std::string extractDomain(const std::string& in_url) +{ + std::string url = in_url; + // First, find and strip any protocol prefix. + size_t pos = url.find("//"); + + if (pos != std::string::npos) + { + size_t count = url.size()-pos+2; + url = url.substr(pos+2, count); + } + + // Now, look for a / marking a local part; if there is one, + // strip it and anything after. + pos = url.find("/"); + + if (pos != std::string::npos) + { + url = url.substr(0, pos); + } + + // If there's a user{,:password}@ part, remove it, + pos = url.find("@"); + + if (pos != std::string::npos) + { + size_t count = url.size()-pos+1; + url = url.substr(pos+1, count); + } + + // Finally, find and strip away any port number. This has to be done + // after the previous step, or else the extra : for the password, + // if supplied, will confuse things. + pos = url.find(":"); + + if (pos != std::string::npos) + { + url = url.substr(0, pos); + } + + // Now map the whole thing to lowercase, since domain names aren't + // case sensitive. + std::transform(url.begin(), url.end(), url.begin(), ::tolower); + return url; +} diff --git a/indra/newview/llmediafilter.h b/indra/newview/llmediafilter.h new file mode 100644 index 000000000..4e05eaf4a --- /dev/null +++ b/indra/newview/llmediafilter.h @@ -0,0 +1,91 @@ +/* + * @file llmediafilter.h + * @brief Definitions for paranoia controls + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Sione Lomu. + * Copyright (C) 2014, Cinder Roxley. + * + * 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 + * $/LicenseInfo$ + */ + +#ifndef LL_MEDIAFILTER_H +#define LL_MEDIAFILTER_H + +class LLParcel; + +class LLMediaFilter : public LLSingleton +{ +public: + typedef enum e_media_list { + WHITELIST, + BLACKLIST + } EMediaList; + + typedef std::list string_list_t; + typedef std::vector string_vec_t; + typedef boost::signals2::signal media_list_signal_t; + boost::signals2::connection setMediaListUpdateCallback(const media_list_signal_t::slot_type& cb) + { + return mMediaListUpdate.connect(cb); + } + + LLMediaFilter(); + void filterMediaUrl(LLParcel* parcel); + void filterAudioUrl(const std::string& url); + //void filterSharedMediaUrl + + void addToMediaList(const std::string& in_url, EMediaList list, bool extract = true); + void removeFromMediaList(string_vec_t, EMediaList list); + string_list_t getWhiteList() const { return mWhiteList; } + string_list_t getBlackList() const { return mBlackList; } + U32 getQueuedMediaCommand() const { return mMediaCommandQueue; } + void setQueuedMediaCommand(U32 command) { mMediaCommandQueue = command; } + bool isAlertActive() const { return mAlertActive; } + void setAlertStatus(bool active) { mAlertActive = active; } + LLParcel* getCurrentParcel() const { return mCurrentParcel; } + LLParcel* getQueuedMedia() const { return mMediaQueue; } + void clearQueuedMedia() { mMediaQueue = NULL; } + std::string getQueuedAudio() const { return mAudioQueue; } + void clearQueuedAudio() { mAudioQueue.clear(); } + void setCurrentAudioURL(const std::string url ) { mCurrentAudioURL = url; } + void clearCurrentAudioURL() { mCurrentAudioURL.clear(); } + bool filter(const std::string& url, EMediaList list); + +private: + void loadMediaFilterFromDisk(); + void saveMediaFilterToDisk() const; + + media_list_signal_t mMediaListUpdate; + string_list_t mBlackList; + string_list_t mWhiteList; + U32 mMediaCommandQueue; + LLParcel* mCurrentParcel; + LLParcel* mMediaQueue; + std::string mAudioQueue; + std::string mCurrentAudioURL; + std::string mCurrentMediaURL; + bool mAlertActive; + //typedef enum e_audio_state { + // PLAY, + // STOP + //} EAudioState; + //EAudioState mAudioState; + +}; + +#endif // LL_MEDIAFILTER_H diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index 8dbaa756d..afb66ee77 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -47,6 +47,7 @@ #include "llfloaterabout.h" #include "llfloateractivespeakers.h" #include "llfloaterautoreplacesettings.h" +#include "llfloateravatar.h" #include "llfloateravatarlist.h" #include "llfloaterbeacons.h" #include "llfloaterblacklist.h" @@ -58,6 +59,7 @@ #include "llfloaterchatterbox.h" #include "llfloatercustomize.h" #include "llfloaterdaycycle.h" +#include "llfloaterdestinations.h" #include "llfloaterdisplayname.h" #include "llfloatereditui.h" #include "llfloaterenvsettings.h" @@ -69,10 +71,12 @@ #include "llfloaterhud.h" #include "llfloaterinspect.h" #include "llfloaterinventory.h" +#include "llfloaterjoystick.h" #include "llfloaterlagmeter.h" #include "llfloaterland.h" #include "llfloaterlandholdings.h" #include "llfloatermap.h" +#include "llfloatermediafilter.h" #include "llfloatermemleak.h" #include "llfloatermessagelog.h" #include "llfloatermute.h" @@ -111,7 +115,6 @@ #include "rlvfloaters.h" // [/RLVa:LF] #include "shfloatermediaticker.h" -#include "slfloatermediafilter.h" void handle_chat() { @@ -190,7 +193,6 @@ struct MenuFloaterDict : public LLSingleton //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)); @@ -205,6 +207,7 @@ struct MenuFloaterDict : public LLSingleton 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("show inspect", boost::bind(LLFloaterInspect::showInstance, LLSD())); 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)); @@ -219,16 +222,20 @@ struct MenuFloaterDict : public LLSingleton registerFloater ("active speakers"); registerFloater ("areasearch"); registerFloater ("autoreplace"); + registerFloater ("avatar"); registerFloater ("beacons"); registerFloater ("camera controls"); registerFloater ("chat history"); registerFloater ("communicate"); + registerFloater ("destinations"); registerFloater ("friends", 0); registerFloater ("gestures"); registerFloater ("groups", 1); registerFloater ("im"); + registerFloater ("inspect"); + registerFloater ("joystick"); registerFloater ("lag meter"); - registerFloater ("media filter"); + registerFloater ("media filter"); registerFloater ("mini map"); registerFloater ("movement controls"); registerFloater ("mute list"); @@ -236,7 +243,7 @@ struct MenuFloaterDict : public LLSingleton registerFloater ("outbox"); registerFloater ("pathfinding_characters"); registerFloater ("pathfinding_linksets"); - registerFloater ("perm prefs"); + registerFloater ("perm prefs"); registerFloater ("radar"); registerFloater ("script info"); registerFloater ("stat bar"); @@ -272,7 +279,7 @@ void show_floater(const std::string& floater_name) if (it == MenuFloaterDict::instance().mEntries.end()) // Simple codeless floater { if (LLFloater* floater = LLUICtrlFactory::getInstance()->getBuiltFloater(floater_name)) - gFloaterView->bringToFront(floater); + floater->isFrontmost() ? floater->close() : gFloaterView->bringToFront(floater); else LLUICtrlFactory::getInstance()->buildFloater(new LLFloater(), floater_name); } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index bb82041fa..4ab6515a6 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -240,9 +240,8 @@ public: } } - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer); + virtual void completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer); /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshHeaderResponder_timeout; } @@ -279,9 +278,8 @@ public: } } - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer); + virtual void completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer); /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshLODResponder_timeout; } @@ -314,9 +312,8 @@ public: } } - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer); + virtual void completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer); /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshSkinInfoResponder_timeout; } @@ -349,9 +346,8 @@ public: } } - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer); + virtual void completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer); /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshDecompositionResponder_timeout; } @@ -384,9 +380,8 @@ public: } } - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer); + virtual void completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer); /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshPhysicsShapeResponder_timeout; } @@ -459,11 +454,9 @@ public: { } - virtual void completed(U32 status, - const std::string& reason, - const LLSD& content) + virtual void httpCompleted(void) { - LLSD cc = content; + LLSD cc = mContent; if (gSavedSettings.getS32("MeshUploadFakeErrors")&1) { cc = llsd_from_file("fake_upload_error.xml"); @@ -473,7 +466,7 @@ public: LLWholeModelFeeObserver* observer = mObserverHandle.get(); - if (isGoodStatus(status) && + if (isGoodStatus(mStatus) && cc["state"].asString() == "upload") { mWholeModelUploadURL = cc["uploader"].asString(); @@ -487,12 +480,12 @@ public: else { llwarns << "fee request failed" << llendl; - log_upload_error(status,cc,"fee",mModelData["name"]); + log_upload_error(mStatus,cc,"fee",mModelData["name"]); mWholeModelUploadURL = ""; if (observer) { - observer->setModelPhysicsFeeErrorStatus(status, reason); + observer->setModelPhysicsFeeErrorStatus(mStatus, mReason); } } } @@ -517,11 +510,9 @@ public: { } - virtual void completed(U32 status, - const std::string& reason, - const LLSD& content) + virtual void httpCompleted(void) { - LLSD cc = content; + LLSD cc = mContent; if (gSavedSettings.getS32("MeshUploadFakeErrors")&2) { cc = llsd_from_file("fake_upload_error.xml"); @@ -533,7 +524,7 @@ public: // requested "mesh" asset type isn't actually the type // of the resultant object, fix it up here. - if (isGoodStatus(status) && + if (isGoodStatus(mStatus) && cc["state"].asString() == "complete") { mModelData["asset_type"] = "object"; @@ -548,7 +539,7 @@ public: { llwarns << "upload failed" << llendl; std::string model_name = mModelData["name"].asString(); - log_upload_error(status,cc,"upload",model_name); + log_upload_error(mStatus,cc,"upload",model_name); if (observer) { @@ -775,7 +766,7 @@ std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id) return http_url; } -bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) +bool LLMeshRepoThread::getMeshHeaderInfo(const LLUUID& mesh_id, const char* block_name, MeshHeaderInfo& info) { //protected by mMutex if (!mHeaderMutex) @@ -783,229 +774,141 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) return false; } - mHeaderMutex->lock(); + LLMutexLock lock(mHeaderMutex); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) { //we have no header info for this mesh, do nothing - mHeaderMutex->unlock(); return false; } - bool ret = true ; - U32 header_size = mMeshHeaderSize[mesh_id]; - - if (header_size > 0) + if ((info.mHeaderSize = mMeshHeaderSize[mesh_id]) > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger(); + info.mVersion = mMeshHeader[mesh_id]["version"].asInteger(); + info.mOffset = info.mHeaderSize + mMeshHeader[mesh_id][block_name]["offset"].asInteger(); + info.mSize = mMeshHeader[mesh_id][block_name]["size"].asInteger(); + } + return true; +} - mHeaderMutex->unlock(); +bool LLMeshRepoThread::loadInfoFromVFS(const LLUUID& mesh_id, MeshHeaderInfo& info, boost::function fn) +{ + //check VFS for mesh skin info + LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); + if (file.getSize() >= info.mOffset + info.mSize) + { + LLMeshRepository::sCacheBytesRead += info.mSize; - if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) + file.seek(info.mOffset); + U8* buffer = new U8[info.mSize]; + file.read(buffer, info.mSize); + + //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) + bool zero = true; + for (S32 i = 0; i < llmin(info.mSize, S32(1024)) && zero; ++i) { - //check VFS for mesh skin info - LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); - if (file.getSize() >= offset+size) + zero = buffer[i] > 0 ? false : true; + } + + if (!zero) + { //attempt to parse + if (fn(mesh_id, buffer, info.mSize)) { - LLMeshRepository::sCacheBytesRead += size; - file.seek(offset); - U8* buffer = new U8[size]; - file.read(buffer, size); - - //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) - bool zero = true; - for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) - { - zero = buffer[i] > 0 ? false : true; - } - - if (!zero) - { //attempt to parse - if (skinInfoReceived(mesh_id, buffer, size)) - { - delete[] buffer; - return true; - } - } - delete[] buffer; - } - - //reading from VFS failed for whatever reason, fetch from sim - AIHTTPHeaders headers("Accept", "application/octet-stream"); - - std::string http_url = constructUrl(mesh_id); - if (!http_url.empty()) - { - ret = LLHTTPClient::getByteRange(http_url, headers, offset, size, - new LLMeshSkinInfoResponder(mesh_id, offset, size)); - if (ret) - { - LLMeshRepository::sHTTPRequestCount++; - } + return true; } } + + delete[] buffer; } - else - { - mHeaderMutex->unlock(); + return false; +} + +bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) +{ + MeshHeaderInfo info; + if (!getMeshHeaderInfo(mesh_id, "skin", info)) + { + return false; + } + + if (info.mHeaderSize > 0 && info.mVersion <= MAX_MESH_VERSION && info.mOffset >= 0 && info.mSize > 0) + { + //check VFS for mesh skin info + if (loadInfoFromVFS(mesh_id, info, boost::bind(&LLMeshRepoThread::skinInfoReceived, this, _1, _2, _3 ))) + return true; + + //reading from VFS failed for whatever reason, fetch from sim + AIHTTPHeaders headers("Accept", "application/octet-stream"); + + std::string http_url = constructUrl(mesh_id); + if (!http_url.empty()) + { + if (!LLHTTPClient::getByteRange(http_url, headers, info.mOffset, info.mSize, + new LLMeshSkinInfoResponder(mesh_id, info.mOffset, info.mSize))) + return false; + LLMeshRepository::sHTTPRequestCount++; + } } //early out was not hit, effectively fetched - return ret; + return true; } bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) -{ //protected by mMutex - if (!mHeaderMutex) +{ + MeshHeaderInfo info; + if (!getMeshHeaderInfo(mesh_id, "physics_convex", info)) { return false; } - mHeaderMutex->lock(); - - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) - { //we have no header info for this mesh, do nothing - mHeaderMutex->unlock(); - return false; - } - - U32 header_size = mMeshHeaderSize[mesh_id]; - bool ret = true ; - - if (header_size > 0) + if (info.mHeaderSize > 0 && info.mVersion <= MAX_MESH_VERSION && info.mOffset >= 0 && info.mSize > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger(); + if (loadInfoFromVFS(mesh_id, info, boost::bind(&LLMeshRepoThread::decompositionReceived, this, _1, _2, _3 ))) + return true; - mHeaderMutex->unlock(); + //reading from VFS failed for whatever reason, fetch from sim + AIHTTPHeaders headers("Accept", "application/octet-stream"); - if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) - { - //check VFS for mesh skin info - LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); - if (file.getSize() >= offset+size) - { - LLMeshRepository::sCacheBytesRead += size; - - file.seek(offset); - U8* buffer = new U8[size]; - file.read(buffer, size); - - //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) - bool zero = true; - for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) - { - zero = buffer[i] > 0 ? false : true; - } - - if (!zero) - { //attempt to parse - if (decompositionReceived(mesh_id, buffer, size)) - { - delete[] buffer; - return true; - } - } - - delete[] buffer; - } - - //reading from VFS failed for whatever reason, fetch from sim - AIHTTPHeaders headers("Accept", "application/octet-stream"); - - std::string http_url = constructUrl(mesh_id); - if (!http_url.empty()) - { - ret = LLHTTPClient::getByteRange(http_url, headers, offset, size, - new LLMeshDecompositionResponder(mesh_id, offset, size)); - if(ret) - { - LLMeshRepository::sHTTPRequestCount++; - } - } + std::string http_url = constructUrl(mesh_id); + if (!http_url.empty()) + { + if (!LLHTTPClient::getByteRange(http_url, headers, info.mOffset, info.mSize, + new LLMeshDecompositionResponder(mesh_id, info.mOffset, info.mSize))) + return false; + LLMeshRepository::sHTTPRequestCount++; } } - else - { - mHeaderMutex->unlock(); - } //early out was not hit, effectively fetched - return ret; + return true; } bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) -{ //protected by mMutex - if (!mHeaderMutex) +{ + MeshHeaderInfo info; + if (!getMeshHeaderInfo(mesh_id, "physics_mesh", info)) { return false; } - mHeaderMutex->lock(); - - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) - { //we have no header info for this mesh, do nothing - mHeaderMutex->unlock(); - return false; - } - - U32 header_size = mMeshHeaderSize[mesh_id]; - bool ret = true ; - - if (header_size > 0) + if (info.mHeaderSize > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger(); - - mHeaderMutex->unlock(); - - if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) + if (info.mVersion <= MAX_MESH_VERSION && info.mOffset >= 0 && info.mSize > 0) { - //check VFS for mesh physics shape info - LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); - if (file.getSize() >= offset+size) - { - LLMeshRepository::sCacheBytesRead += size; - file.seek(offset); - U8* buffer = new U8[size]; - file.read(buffer, size); - - //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) - bool zero = true; - for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) - { - zero = buffer[i] > 0 ? false : true; - } - - if (!zero) - { //attempt to parse - if (physicsShapeReceived(mesh_id, buffer, size)) - { - delete[] buffer; - return true; - } - } - - delete[] buffer; - } + if (loadInfoFromVFS(mesh_id, info, boost::bind(&LLMeshRepoThread::physicsShapeReceived, this, _1, _2, _3 ))) + return true; //reading from VFS failed for whatever reason, fetch from sim AIHTTPHeaders headers("Accept", "application/octet-stream"); std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) - { - ret = LLHTTPClient::getByteRange(http_url, headers, offset, size, - new LLMeshPhysicsShapeResponder(mesh_id, offset, size)); - - if(ret) - { - LLMeshRepository::sHTTPRequestCount++; - } + { + if (!LLHTTPClient::getByteRange(http_url, headers, info.mOffset, info.mSize, + new LLMeshPhysicsShapeResponder(mesh_id, info.mOffset, info.mSize))) + return false; + LLMeshRepository::sHTTPRequestCount++; } } else @@ -1013,13 +916,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) physicsShapeReceived(mesh_id, NULL, 0); } } - else - { - mHeaderMutex->unlock(); - } - + //early out was not hit, effectively fetched - return ret; + return true; } //static @@ -1095,72 +994,34 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c //return false if failed to get mesh lod. bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count) -{ //protected by mMutex - if (!mHeaderMutex) +{ + LLUUID mesh_id = mesh_params.getSculptID(); + MeshHeaderInfo info; + + if (!getMeshHeaderInfo(mesh_id, header_lod[lod].c_str(), info)) { return false; } - - mHeaderMutex->lock(); - - bool retval = true; - - LLUUID mesh_id = mesh_params.getSculptID(); - - U32 header_size = mMeshHeaderSize[mesh_id]; - - if (header_size > 0) + + if (info.mHeaderSize > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger(); - mHeaderMutex->unlock(); - - if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) + if(info.mVersion <= MAX_MESH_VERSION && info.mOffset >= 0 && info.mSize > 0) { - - //check VFS for mesh asset - LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); - if (file.getSize() >= offset+size) - { - LLMeshRepository::sCacheBytesRead += size; - file.seek(offset); - U8* buffer = new U8[size]; - file.read(buffer, size); - - //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) - bool zero = true; - for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) - { - zero = buffer[i] > 0 ? false : true; - } - - if (!zero) - { //attempt to parse - if (lodReceived(mesh_params, lod, buffer, size)) - { - delete[] buffer; - return true; - } - } - - delete[] buffer; - } + if (loadInfoFromVFS(mesh_id, info, boost::bind(&LLMeshRepoThread::lodReceived, this, mesh_params, lod, _2, _3 ))) + return true; //reading from VFS failed for whatever reason, fetch from sim AIHTTPHeaders headers("Accept", "application/octet-stream"); std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) - { - retval = LLHTTPClient::getByteRange(constructUrl(mesh_id), headers, offset, size, - new LLMeshLODResponder(mesh_params, lod, offset, size)); - - if (retval) - { - LLMeshRepository::sHTTPRequestCount++; - } - count++; + { + count++; + if (!LLHTTPClient::getByteRange(constructUrl(mesh_id), headers, info.mOffset, info.mSize, + new LLMeshLODResponder(mesh_params, lod, info.mOffset, info.mSize))) + return false; + LLMeshRepository::sHTTPRequestCount++; + } else { @@ -1172,12 +1033,8 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, mUnavailableQ.push(LODRequest(mesh_params, lod)); } } - else - { - mHeaderMutex->unlock(); - } - - return retval; + + return true; } bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) @@ -1245,16 +1102,21 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size) { + AIStateMachine::StateTimer timer("lodReceived"); LLPointer volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); std::string mesh_string((char*) data, data_size); std::istringstream stream(mesh_string); + AIStateMachine::StateTimer timer2("unpackVolumeFaces"); if (volume->unpackVolumeFaces(stream, data_size)) { + AIStateMachine::StateTimer timer("getNumFaces"); if (volume->getNumFaces() > 0) { + AIStateMachine::StateTimer timer("LoadedMesh"); LoadedMesh mesh(volume, mesh_params, lod); { + AIStateMachine::StateTimer timer("LLMutexLock"); LLMutexLock lock(mMutex); mLoadedQ.push(mesh); } @@ -1544,9 +1406,9 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) result["asset_type"] = "mesh"; result["inventory_type"] = "object"; result["description"] = "(No Description)"; - result["next_owner_mask"] = LLSD::Integer(LLFloaterPerms::getNextOwnerPerms()); - result["group_mask"] = LLSD::Integer(LLFloaterPerms::getGroupPerms()); - result["everyone_mask"] = LLSD::Integer(LLFloaterPerms::getEveryonePerms()); + result["next_owner_mask"] = LLSD::Integer(LLFloaterPerms::getNextOwnerPerms("Uploads")); + result["group_mask"] = LLSD::Integer(LLFloaterPerms::getGroupPerms("Uploads")); + result["everyone_mask"] = LLSD::Integer(LLFloaterPerms::getEveryonePerms("Uploads")); res["mesh_list"] = LLSD::emptyArray(); res["texture_list"] = LLSD::emptyArray(); @@ -1887,9 +1749,8 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header) } -void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) +void LLMeshLODResponder::completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer) { mProcessed = true; @@ -1901,23 +1762,24 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, S32 data_size = buffer->countAfter(channels.in(), NULL); - if (status < 200 || status >= 400) + if (mStatus < 200 || mStatus >= 400) { - llwarns << status << ": " << reason << llendl; + llwarns << mStatus << ": " << mReason << llendl; } if (data_size < (S32)mRequestedBytes) { - if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) + if (is_internal_http_error_that_warrants_a_retry(mStatus) || mStatus == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again + AIStateMachine::StateTimer timer("loadMeshLOD"); llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD); } else { - llassert(is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint - llwarns << "Unhandled status " << status << llendl; + llassert(is_internal_http_error_that_warrants_a_retry(mStatus) || mStatus == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint + llwarns << "Unhandled status " << mStatus << llendl; } return; } @@ -1928,12 +1790,14 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, if (data_size > 0) { + AIStateMachine::StateTimer timer("readAfter"); data = new U8[data_size]; buffer->readAfter(channels.in(), NULL, data, data_size); } if (gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size)) { + AIStateMachine::StateTimer timer("FileOpen"); //good fetch from sim, write to VFS for caching LLVFile file(gVFS, mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLVFile::WRITE); @@ -1942,6 +1806,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, if (file.getSize() >= offset+size) { + AIStateMachine::StateTimer timer("WriteData"); file.seek(offset); file.write(data, size); LLMeshRepository::sCacheBytesWritten += size; @@ -1951,9 +1816,8 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, delete [] data; } -void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) +void LLMeshSkinInfoResponder::completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer) { mProcessed = true; @@ -1965,14 +1829,14 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason S32 data_size = buffer->countAfter(channels.in(), NULL); - if (status < 200 || status >= 400) + if (mStatus < 200 || mStatus >= 400) { - llwarns << status << ": " << reason << llendl; + llwarns << mStatus << ": " << mReason << llendl; } if (data_size < (S32)mRequestedBytes) { - if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) + if (is_internal_http_error_that_warrants_a_retry(mStatus) || mStatus == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again llwarns << "Timeout or service unavailable, retrying loadMeshSkinInfo() for " << mMeshID << llendl; LLMeshRepository::sHTTPRetryCount++; @@ -1980,8 +1844,8 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason } else { - llassert(is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint - llwarns << "Unhandled status " << status << llendl; + llassert(is_internal_http_error_that_warrants_a_retry(mStatus) || mStatus == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint + llwarns << "Unhandled status " << mStatus << llendl; } return; } @@ -2015,9 +1879,8 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason delete [] data; } -void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) +void LLMeshDecompositionResponder::completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer) { mProcessed = true; @@ -2028,14 +1891,14 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r S32 data_size = buffer->countAfter(channels.in(), NULL); - if (status < 200 || status >= 400) + if (mStatus < 200 || mStatus >= 400) { - llwarns << status << ": " << reason << llendl; + llwarns << mStatus << ": " << mReason << llendl; } if (data_size < (S32)mRequestedBytes) { - if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) + if (is_internal_http_error_that_warrants_a_retry(mStatus) || mStatus == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again llwarns << "Timeout or service unavailable, retrying loadMeshDecomposition() for " << mMeshID << llendl; LLMeshRepository::sHTTPRetryCount++; @@ -2043,8 +1906,8 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r } else { - llassert(is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint - llwarns << "Unhandled status " << status << llendl; + llassert(is_internal_http_error_that_warrants_a_retry(mStatus) || mStatus == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint + llwarns << "Unhandled status " << mStatus << llendl; } return; } @@ -2078,9 +1941,8 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r delete [] data; } -void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) +void LLMeshPhysicsShapeResponder::completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer) { mProcessed = true; @@ -2092,14 +1954,14 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re S32 data_size = buffer->countAfter(channels.in(), NULL); - if (status < 200 || status >= 400) + if (mStatus < 200 || mStatus >= 400) { - llwarns << status << ": " << reason << llendl; + llwarns << mStatus << ": " << mReason << llendl; } if (data_size < (S32)mRequestedBytes) { - if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) + if (is_internal_http_error_that_warrants_a_retry(mStatus) || mStatus == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again llwarns << "Timeout or service unavailable, retrying loadMeshPhysicsShape() for " << mMeshID << llendl; LLMeshRepository::sHTTPRetryCount++; @@ -2107,8 +1969,8 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re } else { - llassert(is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint - llwarns << "Unhandled status " << status << llendl; + llassert(is_internal_http_error_that_warrants_a_retry(mStatus) || mStatus == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint + llwarns << "Unhandled status " << mStatus << llendl; } return; } @@ -2142,9 +2004,8 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re delete [] data; } -void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) +void LLMeshHeaderResponder::completedRaw(LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer) { mProcessed = true; @@ -2154,11 +2015,11 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, return; } - if (status < 200 || status >= 400) + if (mStatus < 200 || mStatus >= 400) { //llwarns // << "Header responder failed with status: " - // << status << ": " << reason << llendl; + // << mStatus << ": " << mReason << llendl; // 503 (service unavailable) or HTTP_INTERNAL_ERROR_*'s. // can be due to server load and can be retried @@ -2167,10 +2028,11 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, // and (somewhat more optional than the others) retries // again after some set period of time - llassert(status == HTTP_NOT_FOUND || status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_REQUEST_TIME_OUT || is_internal_http_error_that_warrants_a_retry(status)); + llassert(mStatus == HTTP_NOT_FOUND || mStatus == HTTP_SERVICE_UNAVAILABLE || mStatus == HTTP_REQUEST_TIME_OUT || is_internal_http_error_that_warrants_a_retry(mStatus)); - if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) + if (is_internal_http_error_that_warrants_a_retry(mStatus) || mStatus == HTTP_SERVICE_UNAVAILABLE) { //retry + AIStateMachine::StateTimer timer("Retry"); llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; LLMeshRepoThread::HeaderRequest req(mMeshParams); @@ -2181,22 +2043,25 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, } else { - llwarns << "Unhandled status: " << status << llendl; + llwarns << "Unhandled status: " << mStatus << llendl; } } S32 data_size = buffer->countAfter(channels.in(), NULL); - U8* data = NULL; + static U8 data[16384]; + llassert_always(data_size <= sizeof(data)); + memset(data + data_size, 0, sizeof(data)-data_size); if (data_size > 0) { - data = new U8[data_size]; + AIStateMachine::StateTimer timer("readAfter"); buffer->readAfter(channels.in(), NULL, data, data_size); } LLMeshRepository::sBytesReceived += llmin(data_size, 4096); + AIStateMachine::StateTimer timer("headerReceived"); bool success = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size); llassert(success); @@ -2205,9 +2070,9 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, { llwarns << "Unable to parse mesh header: " - << status << ": " << reason << llendl; + << mStatus << ": " << mReason << llendl; } - else if (data && data_size > 0) + else if (data_size > 0) { //header was successfully retrieved from sim, cache in vfs LLUUID mesh_id = mMeshParams.getSculptID(); @@ -2239,33 +2104,27 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, //only allocate as much space in the VFS as is needed for the local cache data_size = llmin(data_size, bytes); + AIStateMachine::StateTimer timer("FileOpen"); LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH, LLVFile::WRITE); if (file.getMaxSize() >= bytes || file.setMaxSize(bytes)) { LLMeshRepository::sCacheBytesWritten += data_size; - file.write((const U8*) data, data_size); - - //zero out the rest of the file - U8 block[4096]; - memset(block, 0, 4096); - - while (bytes-file.tell() > 4096) + AIStateMachine::StateTimer timer("WriteData"); + S32 bytes_remaining = bytes; + while (bytes_remaining > 0) { - file.write(block, 4096); - } - - S32 remaining = bytes-file.tell(); - - if (remaining > 0) - { - file.write(block, remaining); + const S32 bytes_written = llmin(bytes_remaining, (S32)sizeof(data)); + file.write(data, bytes_written); + if (bytes_remaining == bytes && bytes_written < bytes_remaining) + { + memset(data, 0, data_size); + } + bytes_remaining -= llmin(bytes_remaining, bytes_written); } } } } - - delete [] data; } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index ab9220cdc..de26a1ba0 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -40,6 +40,8 @@ #include "lluploadfloaterobservers.h" #include "aistatemachinethread.h" +#include + class LLVOVolume; class LLMeshResponder; class LLMutex; @@ -283,6 +285,16 @@ public: }; + struct MeshHeaderInfo + { + MeshHeaderInfo() + : mHeaderSize(0), mVersion(0), mOffset(-1), mSize(0) {} + U32 mHeaderSize; + U32 mVersion; + S32 mOffset; + S32 mSize; + }; + //set of requested skin info std::set mSkinRequests; @@ -332,6 +344,9 @@ public: bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); LLSD& getMeshHeader(const LLUUID& mesh_id); + bool getMeshHeaderInfo(const LLUUID& mesh_id, const char* block_name, MeshHeaderInfo& info); + bool loadInfoFromVFS(const LLUUID& mesh_id, MeshHeaderInfo& info, boost::function fn); + void notifyLoadedMeshes(); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); @@ -450,6 +465,8 @@ public: void setWholeModelUploadURL(std::string const& whole_model_upload_url) { mWholeModelUploadURL = whole_model_upload_url; } + /*virtual*/ const char* getName() const { return "AIMeshUpload"; } + protected: // Implement AIStateMachine. /*virtual*/ const char* state_str_impl(state_type run_state) const; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 7dd948fc5..2e34271a1 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -54,7 +54,7 @@ LLNameListCtrl::LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL mNameColumnIndex(name_column_index), mAllowCallingCardDrop(false), mNameSystem(name_system), - mAvatarNameCacheConnection() + mPendingLookupsRemaining(0) { setToolTip(tooltip); } @@ -194,17 +194,30 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( else { // ...schedule a callback - // This is not correct and will likely lead to partially populated lists in cases where avatar names are not cached. - // *TODO : Change this to have 2 callbacks : one callback per list item and one for the whole list. - /* Singu Note: Indeed it does, for now let's not use it - if (mAvatarNameCacheConnection.connected()) + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) { - mAvatarNameCacheConnection.disconnect(); + it->second.disconnect(); } - mAvatarNameCacheConnection =*/ LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, item->getHandle())); - } - break; + mAvatarNameCacheConnections.erase(it); + } + mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, item->getHandle())); + + if (mPendingLookupsRemaining <= 0) + { + // BAKER TODO: + // We might get into a state where mPendingLookupsRemainig might + // go negative. So just reset it right now and figure out if it's + // possible later :) + mPendingLookupsRemaining = 0; + mNameListCompleteSignal(false); + } + mPendingLookupsRemaining++; } + break; + } default: break; } @@ -253,18 +266,35 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) { selectNthItem(idx); // not sure whether this is needed, taken from previous implementation deleteSingleItem(idx); + + mPendingLookupsRemaining--; } } void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, + std::string suffix, LLHandle item) { - //mAvatarNameCacheConnection.disconnect(); + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); + } std::string name; LLAvatarNameCache::getPNSName(av_name, name, mNameSystem); + // Append optional suffix. + if (!suffix.empty()) + { + name.append(suffix); + } + LLNameListItem* list_item = item.get(); if (list_item && list_item->getUUID() == agent_id) { @@ -276,6 +306,23 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, } } + ////////////////////////////////////////////////////////////////////////// + // BAKER - FIX NameListCtrl + //if (mPendingLookupsRemaining <= 0) + { + // We might get into a state where mPendingLookupsRemaining might + // go negative. So just reset it right now and figure out if it's + // possible later :) + //mPendingLookupsRemaining = 0; + + mNameListCompleteSignal(true); + } + //else + { + // mPendingLookupsRemaining--; + } + ////////////////////////////////////////////////////////////////////////// + dirtyColumns(); } diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 9552ff02d..7f6d3763a 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -67,6 +67,8 @@ class LLNameListCtrl : public LLScrollListCtrl, public LLInstanceTracker { public: + typedef boost::signals2::signal namelist_complete_signal_t; + typedef enum e_name_type { INDIVIDUAL, @@ -105,10 +107,14 @@ 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& name_system = "PhoenixNameSystem", const std::string& tooltip = LLStringUtil::null); virtual ~LLNameListCtrl() { - if (mAvatarNameCacheConnection.connected()) + for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) { - mAvatarNameCacheConnection.disconnect(); + if (it->second.connected()) + { + it->second.disconnect(); + } } + mAvatarNameCacheConnections.clear(); } friend class LLUICtrlFactory; public: @@ -143,13 +149,24 @@ public: void sortByName(BOOL ascending); private: - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle item); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, LLHandle item); private: S32 mNameColumnIndex; BOOL mAllowCallingCardDrop; const LLCachedControl mNameSystem; - boost::signals2::connection mAvatarNameCacheConnection; + typedef std::map avatar_name_cache_connection_map_t; + avatar_name_cache_connection_map_t mAvatarNameCacheConnections; + + S32 mPendingLookupsRemaining; + namelist_complete_signal_t mNameListCompleteSignal; + +public: + boost::signals2::connection setOnNameListCompleteCallback(boost::function onNameListCompleteCallback) + { + return mNameListCompleteSignal.connect(onNameListCompleteCallback); + } + }; diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index e81c406a3..93b204759 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -726,24 +726,30 @@ void LLNetMap::draw() if (rotate_map) { - gGL.color4fv((map_frustum_color()).mV); + LLColor4 c = map_frustum_color(); gGL.begin( LLRender::TRIANGLES ); + gGL.color4fv(c.mV); gGL.vertex2f( ctr_x, ctr_y ); + c.mV[VW] *= .1f; + gGL.color4fv(c.mV); gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); gGL.end(); } else { - gGL.color4fv((map_frustum_rotating_color()).mV); + LLColor4 c = map_frustum_rotating_color(); // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); gGL.translatef( ctr_x, ctr_y, 0 ); gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); gGL.begin( LLRender::TRIANGLES ); + gGL.color4fv(c.mV); gGL.vertex2f( 0.f, 0.f ); + c.mV[VW] *= .1f; + gGL.color4fv(c.mV); gGL.vertex2f( -half_width_pixels, far_clip_pixels ); gGL.vertex2f( half_width_pixels, far_clip_pixels ); gGL.end(); diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 9bbf00567..e20ead18d 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -479,7 +479,6 @@ void LLOverlayBar::toggleMediaPlay(void*) LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (parcel) { - LLViewerParcelMedia::sIsUserAction = true; LLViewerParcelMedia::play(parcel); } } @@ -505,7 +504,6 @@ void LLOverlayBar::toggleMusicPlay(void*) // stream is stopped, it doesn't return the right thing - commenting out for now. // if ( gAudiop->isInternetStreamPlaying() == 0 ) { - LLViewerParcelMedia::sIsUserAction = true; LLViewerParcelMedia::playStreamingMusic(parcel); } } diff --git a/indra/newview/llpanelaudioprefs.cpp b/indra/newview/llpanelaudioprefs.cpp index e61028fa8..1929e693c 100644 --- a/indra/newview/llpanelaudioprefs.cpp +++ b/indra/newview/llpanelaudioprefs.cpp @@ -89,6 +89,7 @@ LLPanelAudioPrefs::~LLPanelAudioPrefs() BOOL LLPanelAudioPrefs::postBuild() { + getChildView("filter_group")->setValue(S32(gSavedSettings.getU32("MediaFilterEnable"))); refreshValues(); // initialize member data from saved settings childSetLabelArg("currency_change_threshold", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); @@ -115,6 +116,7 @@ void LLPanelAudioPrefs::refreshValues() mPreviousMuteAudio = gSavedSettings.getBOOL("MuteAudio"); mPreviousMuteWhenMinimized = gSavedSettings.getBOOL("MuteWhenMinimized"); + gSavedSettings.setU32("MediaFilterEnable", getChildView("filter_group")->getValue().asInteger()); } void LLPanelAudioPrefs::cancel() diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 4dbb576c0..94cd97200 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -913,7 +913,7 @@ BOOL LLPanelAvatarClassified::canClose() LLTabContainer* tabs = getChild("classified tab"); for (S32 i = 0; i < tabs->getTabCount(); i++) { - LLPanelClassified* panel = (LLPanelClassified*)tabs->getPanelByIndex(i); + LLPanelClassifiedInfo* panel = (LLPanelClassifiedInfo*)tabs->getPanelByIndex(i); if (!panel->canClose()) { return FALSE; @@ -927,7 +927,7 @@ BOOL LLPanelAvatarClassified::titleIsValid() LLTabContainer* tabs = getChild("classified tab"); if ( tabs ) { - LLPanelClassified* panel = (LLPanelClassified*)tabs->getCurrentPanel(); + LLPanelClassifiedInfo* panel = (LLPanelClassifiedInfo*)tabs->getCurrentPanel(); if ( panel ) { if ( ! panel->titleIsValid() ) @@ -945,7 +945,7 @@ void LLPanelAvatarClassified::apply() LLTabContainer* tabs = getChild("classified tab"); for (S32 i = 0; i < tabs->getTabCount(); i++) { - LLPanelClassified* panel = (LLPanelClassified*)tabs->getPanelByIndex(i); + LLPanelClassifiedInfo* panel = (LLPanelClassifiedInfo*)tabs->getPanelByIndex(i); panel->apply(); } } @@ -977,7 +977,7 @@ void LLPanelAvatarClassified::processProperties(void* data, EAvatarProcessorType for(LLAvatarClassifieds::classifieds_list_t::iterator it = c_info->classifieds_list.begin(); it != c_info->classifieds_list.end(); ++it) { - LLPanelClassified* panel_classified = new LLPanelClassified(false, false); + LLPanelClassifiedInfo* panel_classified = new LLPanelClassifiedInfo(false, false); panel_classified->setClassifiedID(it->classified_id); @@ -1027,7 +1027,7 @@ bool LLPanelAvatarClassified::callbackNew(const LLSD& notification, const LLSD& S32 option = LLNotification::getSelectedOption(notification, response); if (0 == option) { - LLPanelClassified* panel_classified = new LLPanelClassified(false, false); + LLPanelClassifiedInfo* panel_classified = new LLPanelClassifiedInfo(false, false); panel_classified->initNewClassified(); LLTabContainer* tabs = getChild("classified tab"); if(tabs) @@ -1046,10 +1046,10 @@ void LLPanelAvatarClassified::onClickDelete(void* data) LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data; LLTabContainer* tabs = self->getChild("classified tab"); - LLPanelClassified* panel_classified = NULL; + LLPanelClassifiedInfo* panel_classified = NULL; if(tabs) { - panel_classified = (LLPanelClassified*)tabs->getCurrentPanel(); + panel_classified = (LLPanelClassifiedInfo*)tabs->getCurrentPanel(); } if (!panel_classified) return; @@ -1064,10 +1064,10 @@ bool LLPanelAvatarClassified::callbackDelete(const LLSD& notification, const LL { S32 option = LLNotification::getSelectedOption(notification, response); LLTabContainer* tabs = getChild("classified tab"); - LLPanelClassified* panel_classified=NULL; + LLPanelClassifiedInfo* panel_classified=NULL; if(tabs) { - panel_classified = (LLPanelClassified*)tabs->getCurrentPanel(); + panel_classified = (LLPanelClassifiedInfo*)tabs->getCurrentPanel(); } if (!panel_classified) return false; diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index de5f765cc..766cbe50c 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -82,7 +82,7 @@ const S32 PG_CONTENT = 2; const S32 DECLINE_TO_STATE = 0; //static -std::list LLPanelClassified::sAllPanels; +LLPanelClassifiedInfo::panel_list_t LLPanelClassifiedInfo::sAllPanels; // "classifiedclickthrough" // strings[0] = classified_id @@ -103,10 +103,10 @@ public: S32 teleport_clicks = atoi(strings[1].c_str()); S32 map_clicks = atoi(strings[2].c_str()); S32 profile_clicks = atoi(strings[3].c_str()); - LLPanelClassified::setClickThrough(classified_id, teleport_clicks, - map_clicks, - profile_clicks, - false); + + LLPanelClassifiedInfo::setClickThrough( + classified_id, teleport_clicks, map_clicks, profile_clicks, false); + return true; } }; @@ -143,7 +143,7 @@ public: // *TODO: separately track old search, sidebar, and new search // Right now detail HTML pages count as new search. const bool from_search = true; - LLPanelClassified::sendClassifiedClickMessage(classified_id, "teleport", from_search); + LLPanelClassifiedInfo::sendClassifiedClickMessage(classified_id, "teleport", from_search); // Invoke teleport LLMediaCtrl* web = NULL; const bool trusted_browser = true; @@ -154,7 +154,11 @@ public: LLClassifiedTeleportHandler gClassifiedTeleportHandler; */ -LLPanelClassified::LLPanelClassified(bool in_finder, bool from_search) +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPanelClassifiedInfo::LLPanelClassifiedInfo(bool in_finder, bool from_search) : LLPanel(std::string("Classified Panel")), mInFinder(in_finder), mFromSearch(from_search), @@ -202,24 +206,19 @@ LLPanelClassified::LLPanelClassified(bool in_finder, bool from_search) } // Register dispatcher - gGenericDispatcher.addHandler("classifiedclickthrough", - &sClassifiedClickThrough); + gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough); +} + +LLPanelClassifiedInfo::~LLPanelClassifiedInfo() +{ + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this); + sAllPanels.remove(this); } -LLPanelClassified::~LLPanelClassified() +void LLPanelClassifiedInfo::reset() { - if(mCreatorID.notNull()) - { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this); - } - sAllPanels.remove(this); -} - - -void LLPanelClassified::reset() -{ - if(mCreatorID.notNull()) + if (mInFinder || mCreatorID.notNull()) { LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this); } @@ -240,41 +239,40 @@ void LLPanelClassified::reset() resetDirty(); } - -BOOL LLPanelClassified::postBuild() +BOOL LLPanelClassifiedInfo::postBuild() { - mSnapshotCtrl = getChild("snapshot_ctrl"); - mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelClassified::checkDirty, this)); + mSnapshotCtrl = getChild("snapshot_ctrl"); + mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::checkDirty, this)); mSnapshotSize = mSnapshotCtrl->getRect(); - mNameEditor = getChild("given_name_editor"); + mNameEditor = getChild("given_name_editor"); mNameEditor->setMaxTextLength(DB_PARCEL_NAME_LEN); mNameEditor->setCommitOnFocusLost(TRUE); - mNameEditor->setFocusReceivedCallback(boost::bind(&LLPanelClassified::checkDirty, this)); - mNameEditor->setCommitCallback(boost::bind(&LLPanelClassified::checkDirty, this)); + mNameEditor->setFocusReceivedCallback(boost::bind(&LLPanelClassifiedInfo::checkDirty, this)); + mNameEditor->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::checkDirty, this)); mNameEditor->setPrevalidate( LLLineEditor::prevalidateASCII ); - mDescEditor = getChild("desc_editor"); + mDescEditor = getChild("desc_editor"); mDescEditor->setCommitOnFocusLost(TRUE); - mDescEditor->setFocusReceivedCallback(boost::bind(&LLPanelClassified::checkDirty, this)); - mDescEditor->setCommitCallback(boost::bind(&LLPanelClassified::checkDirty, this)); + mDescEditor->setFocusReceivedCallback(boost::bind(&LLPanelClassifiedInfo::checkDirty, this)); + mDescEditor->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::checkDirty, this)); mDescEditor->setTabsToNextField(TRUE); - mLocationEditor = getChild("location_editor"); + mLocationEditor = getChild("location_editor"); - mSetBtn = getChild( "set_location_btn"); - mSetBtn->setCommitCallback(boost::bind(&LLPanelClassified::onClickSet, this)); + mSetBtn = getChild( "set_location_btn"); + mSetBtn->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::onClickSet, this)); - mTeleportBtn = getChild( "classified_teleport_btn"); - mTeleportBtn->setCommitCallback(boost::bind(&LLPanelClassified::onClickTeleport, this)); + mTeleportBtn = getChild( "classified_teleport_btn"); + mTeleportBtn->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::onClickTeleport, this)); - mMapBtn = getChild( "classified_map_btn"); - mMapBtn->setCommitCallback(boost::bind(&LLPanelClassified::onClickMap, this)); + mMapBtn = getChild( "classified_map_btn"); + mMapBtn->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::onClickMap, this)); if(mInFinder) { mProfileBtn = getChild( "classified_profile_btn"); - mProfileBtn->setCommitCallback(boost::bind(&LLPanelClassified::onClickProfile, this)); + mProfileBtn->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::onClickProfile, this)); } mCategoryCombo = getChild( "classified_category_combo"); @@ -286,11 +284,11 @@ BOOL LLPanelClassified::postBuild() mCategoryCombo->add(iter->second, (void *)((intptr_t)iter->first), ADD_BOTTOM); } mCategoryCombo->setCurrentByIndex(0); - mCategoryCombo->setCommitCallback(boost::bind(&LLPanelClassified::checkDirty, this)); + mCategoryCombo->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::checkDirty, this)); mMatureCombo = getChild( "classified_mature_check"); mMatureCombo->setCurrentByIndex(0); - mMatureCombo->setCommitCallback(boost::bind(&LLPanelClassified::checkDirty, this)); + mMatureCombo->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::checkDirty, this)); if (gAgent.wantsPGOnly()) { // Teens don't get to set mature flag. JC @@ -301,11 +299,11 @@ BOOL LLPanelClassified::postBuild() if (!mInFinder) { mAutoRenewCheck = getChild( "auto_renew_check"); - mAutoRenewCheck->setCommitCallback(boost::bind(&LLPanelClassified::checkDirty, this)); + mAutoRenewCheck->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::checkDirty, this)); } mUpdateBtn = getChild("classified_update_btn"); - mUpdateBtn->setCommitCallback(boost::bind(&LLPanelClassified::onClickUpdate, this)); + mUpdateBtn->setCommitCallback(boost::bind(&LLPanelClassifiedInfo::onClickUpdate, this)); if (!mInFinder) { @@ -313,29 +311,29 @@ BOOL LLPanelClassified::postBuild() } resetDirty(); - return TRUE; + return TRUE; } -void LLPanelClassified::processProperties(void* data, EAvatarProcessorType type) +void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType type) { if(APT_CLASSIFIED_INFO == type) { lldebugs << "processClassifiedInfoReply()" << llendl; - + LLAvatarClassifiedInfo* c_info = static_cast(data); if(c_info && mClassifiedID == c_info->classified_id) { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID::null, this); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this); - // "Location text" is actually the original - // name that owner gave the parcel, and the location. + // "Location text" is actually the original + // name that owner gave the parcel, and the location. std::string location_text = c_info->parcel_name; if (!location_text.empty()) location_text.append(", "); - S32 region_x = llround((F32)c_info->pos_global.mdV[VX]) % REGION_WIDTH_UNITS; - S32 region_y = llround((F32)c_info->pos_global.mdV[VY]) % REGION_WIDTH_UNITS; + S32 region_x = llround((F32)c_info->pos_global.mdV[VX]) % REGION_WIDTH_UNITS; + S32 region_y = llround((F32)c_info->pos_global.mdV[VY]) % REGION_WIDTH_UNITS; S32 region_z = llround((F32)c_info->pos_global.mdV[VZ]); std::string buffer = llformat("%s (%d, %d, %d)", c_info->sim_name.c_str(), region_x, region_y, region_z); @@ -347,7 +345,7 @@ void LLPanelClassified::processProperties(void* data, EAvatarProcessorType type) tm *now=localtime(&tim); - // Found the panel, now fill in the information + // Found the panel, now fill in the information mClassifiedID = c_info->classified_id; mCreatorID = c_info->creator_id; mParcelID = c_info->parcel_id; @@ -356,10 +354,10 @@ void LLPanelClassified::processProperties(void* data, EAvatarProcessorType type) mPosGlobal = c_info->pos_global; // Update UI controls - mNameEditor->setText(c_info->name); - mDescEditor->setText(c_info->description); - mSnapshotCtrl->setImageAssetID(c_info->snapshot_id); - mLocationEditor->setText(location_text); + mNameEditor->setText(c_info->name); + mDescEditor->setText(c_info->description); + mSnapshotCtrl->setImageAssetID(c_info->snapshot_id); + mLocationEditor->setText(location_text); mLocationChanged = false; mCategoryCombo->setCurrentByIndex(c_info->category - 1); @@ -386,10 +384,10 @@ void LLPanelClassified::processProperties(void* data, EAvatarProcessorType type) resetDirty(); } - } + } } -BOOL LLPanelClassified::titleIsValid() +BOOL LLPanelClassifiedInfo::titleIsValid() { // Disallow leading spaces, punctuation, etc. that screw up // sort order. @@ -408,7 +406,7 @@ BOOL LLPanelClassified::titleIsValid() return TRUE; } -void LLPanelClassified::apply() +void LLPanelClassifiedInfo::apply() { // Apply is used for automatically saving results, so only // do that if there is a difference, and this is a save not create. @@ -418,7 +416,7 @@ void LLPanelClassified::apply() } } -bool LLPanelClassified::saveCallback(const LLSD& notification, const LLSD& response) +bool LLPanelClassifiedInfo::saveCallback(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); @@ -442,26 +440,26 @@ bool LLPanelClassified::saveCallback(const LLSD& notification, const LLSD& respo case 2: // Cancel default: - LLAppViewer::instance()->abortQuit(); + LLAppViewer::instance()->abortQuit(); break; } return false; } -BOOL LLPanelClassified::canClose() +BOOL LLPanelClassifiedInfo::canClose() { if (mForceClose || !checkDirty()) return TRUE; LLSD args; args["NAME"] = mNameEditor->getText(); - LLNotificationsUtil::add("ClassifiedSave", args, LLSD(), boost::bind(&LLPanelClassified::saveCallback, this, _1, _2)); + LLNotificationsUtil::add("ClassifiedSave", args, LLSD(), boost::bind(&LLPanelClassifiedInfo::saveCallback, this, _1, _2)); return FALSE; } // Fill in some reasonable defaults for a new classified. -void LLPanelClassified::initNewClassified() +void LLPanelClassifiedInfo::initNewClassified() { // TODO: Don't generate this on the client. mClassifiedID.generate(); @@ -490,13 +488,15 @@ void LLPanelClassified::initNewClassified() } -void LLPanelClassified::setClassifiedID(const LLUUID& id) +void LLPanelClassifiedInfo::setClassifiedID(const LLUUID& id) { mClassifiedID = id; + if (mInFinder) mCreatorID = LLUUID::null; // Singu Note: HACKS! } //static -void LLPanelClassified::setClickThrough(const LLUUID& classified_id, +void LLPanelClassifiedInfo::setClickThrough( + const LLUUID& classified_id, S32 teleport, S32 map, S32 profile, @@ -504,7 +504,7 @@ void LLPanelClassified::setClickThrough(const LLUUID& classified_id, { for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter) { - LLPanelClassified* self = *iter; + LLPanelClassifiedInfo* self = *iter; // For top picks, must match pick id if (self->mClassifiedID != classified_id) { @@ -541,23 +541,23 @@ void LLPanelClassified::setClickThrough(const LLUUID& classified_id, // Schedules the panel to request data // from the server next time it is drawn. -void LLPanelClassified::markForServerRequest() +void LLPanelClassifiedInfo::markForServerRequest() { mDataRequested = FALSE; } -std::string LLPanelClassified::getClassifiedName() +std::string LLPanelClassifiedInfo::getClassifiedName() { return mNameEditor->getText(); } -void LLPanelClassified::sendClassifiedInfoRequest() +void LLPanelClassifiedInfo::sendClassifiedInfoRequest() { if (mClassifiedID != mRequestedID) { - LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID::null, this); + LLAvatarPropertiesProcessor::getInstance()->addObserver(mCreatorID, this); LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(mClassifiedID); mDataRequested = TRUE; @@ -578,7 +578,7 @@ void LLPanelClassified::sendClassifiedInfoRequest() } } -void LLPanelClassified::sendClassifiedInfoUpdate() +void LLPanelClassifiedInfo::sendClassifiedInfoUpdate() { LLAvatarClassifiedInfo c_data; @@ -608,7 +608,7 @@ void LLPanelClassified::sendClassifiedInfoUpdate() mDirty = false; } -void LLPanelClassified::draw() +void LLPanelClassifiedInfo::draw() { refresh(); @@ -616,25 +616,25 @@ void LLPanelClassified::draw() } -void LLPanelClassified::refresh() +void LLPanelClassifiedInfo::refresh() { if (!mDataRequested) { sendClassifiedInfoRequest(); } - // Check for god mode - BOOL godlike = gAgent.isGodlike(); + // Check for god mode + BOOL godlike = gAgent.isGodlike(); BOOL is_self = (gAgent.getID() == mCreatorID); - // Set button visibility/enablement appropriately + // Set button visibility/enablement appropriately if (mInFinder) { // End user doesn't ned to see price twice, or date posted. mSnapshotCtrl->setEnabled(godlike); - if(godlike) + if (godlike) { //make it smaller, so text is more legible mSnapshotCtrl->setOrigin(20, 175); @@ -673,22 +673,22 @@ void LLPanelClassified::refresh() mMatureCombo->setEnabled(is_self); if( is_self ) - { + { if( mMatureCombo->getCurrentIndex() == 0 ) { // It's a new panel. // PG regions should have PG classifieds. AO should have mature. - + setDefaultAccessCombo(); } } - + if (mAutoRenewCheck) { mAutoRenewCheck->setEnabled(is_self); mAutoRenewCheck->setVisible(is_self); } - + mClickThroughText->setEnabled(is_self); mClickThroughText->setVisible(is_self); @@ -703,7 +703,7 @@ void LLPanelClassified::refresh() } } -void LLPanelClassified::onClickUpdate() +void LLPanelClassifiedInfo::onClickUpdate() { // Disallow leading spaces, punctuation, etc. that screw up // sort order. @@ -719,7 +719,7 @@ void LLPanelClassified::onClickUpdate() LLNotificationsUtil::add("SetClassifiedMature", LLSD(), LLSD(), - boost::bind(&LLPanelClassified::confirmMature, this, _1, _2)); + boost::bind(&LLPanelClassifiedInfo::confirmMature, this, _1, _2)); return; } @@ -728,7 +728,7 @@ void LLPanelClassified::onClickUpdate() } // Callback from a dialog indicating response to mature notification -bool LLPanelClassified::confirmMature(const LLSD& notification, const LLSD& response) +bool LLPanelClassifiedInfo::confirmMature(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); @@ -754,23 +754,23 @@ bool LLPanelClassified::confirmMature(const LLSD& notification, const LLSD& resp // Called after we have determined whether this classified has // mature content or not. -void LLPanelClassified::gotMature() +void LLPanelClassifiedInfo::gotMature() { // if already paid for, just do the update if (mPaidFor) { LLNotification::Params params("PublishClassified"); - params.functor(boost::bind(&LLPanelClassified::confirmPublish, this, _1, _2)); + params.functor(boost::bind(&LLPanelClassifiedInfo::confirmPublish, this, _1, _2)); LLNotifications::instance().forceResponse(params, 0); } else { // Ask the user how much they want to pay - new LLFloaterPriceForListing(boost::bind(&LLPanelClassified::callbackGotPriceForListing, this, _1)); + new LLFloaterPriceForListing(boost::bind(&LLPanelClassifiedInfo::callbackGotPriceForListing, this, _1)); } } -void LLPanelClassified::callbackGotPriceForListing(const std::string& text) +void LLPanelClassifiedInfo::callbackGotPriceForListing(const std::string& text) { S32 price_for_listing = strtol(text.c_str(), NULL, 10); if (price_for_listing < MINIMUM_PRICE_FOR_LISTING) @@ -789,10 +789,10 @@ void LLPanelClassified::callbackGotPriceForListing(const std::string& text) args["AMOUNT"] = llformat("%d", price_for_listing); args["CURRENCY"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol(); LLNotificationsUtil::add("PublishClassified", args, LLSD(), - boost::bind(&LLPanelClassified::confirmPublish, this, _1, _2)); + boost::bind(&LLPanelClassifiedInfo::confirmPublish, this, _1, _2)); } -void LLPanelClassified::resetDirty() +void LLPanelClassifiedInfo::resetDirty() { // Tell all the widgets to reset their dirty state since the ad was just saved if (mSnapshotCtrl) @@ -813,7 +813,7 @@ void LLPanelClassified::resetDirty() } // invoked from callbackConfirmPublish -bool LLPanelClassified::confirmPublish(const LLSD& notification, const LLSD& response) +bool LLPanelClassifiedInfo::confirmPublish(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); // Option 0 = publish @@ -839,18 +839,18 @@ bool LLPanelClassified::confirmPublish(const LLSD& notification, const LLSD& res return false; } -void LLPanelClassified::onClickTeleport() +void LLPanelClassifiedInfo::onClickTeleport() { if (!mPosGlobal.isExactlyZero()) - { + { gAgent.teleportViaLocation(mPosGlobal); gFloaterWorldMap->trackLocation(mPosGlobal); sendClassifiedClickMessage("teleport"); - } + } } -void LLPanelClassified::onClickMap() +void LLPanelClassifiedInfo::onClickMap() { gFloaterWorldMap->trackLocation(mPosGlobal); LLFloaterWorldMap::show(true); @@ -858,20 +858,20 @@ void LLPanelClassified::onClickMap() sendClassifiedClickMessage("map"); } -void LLPanelClassified::onClickProfile() +void LLPanelClassifiedInfo::onClickProfile() { LLAvatarActions::showProfile(mCreatorID); sendClassifiedClickMessage("profile"); } /* -void LLPanelClassified::onClickLandmark() +void LLPanelClassifiedInfo::onClickLandmark() { create_landmark(mNameEditor->getText(), "", mPosGlobal); } */ -void LLPanelClassified::onClickSet() +void LLPanelClassifiedInfo::onClickSet() { // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) @@ -896,9 +896,9 @@ void LLPanelClassified::onClickSet() S32 region_x = llround((F32)mPosGlobal.mdV[VX]) % REGION_WIDTH_UNITS; S32 region_y = llround((F32)mPosGlobal.mdV[VY]) % REGION_WIDTH_UNITS; S32 region_z = llround((F32)mPosGlobal.mdV[VZ]); - + location_text.append(mSimName); - location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z)); + location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z)); mLocationEditor->setText(location_text); mLocationChanged = true; @@ -912,14 +912,14 @@ void LLPanelClassified::onClickSet() } -BOOL LLPanelClassified::checkDirty() +BOOL LLPanelClassifiedInfo::checkDirty() { mDirty = FALSE; if ( mSnapshotCtrl ) mDirty |= mSnapshotCtrl->isDirty(); if ( mNameEditor ) mDirty |= mNameEditor->isDirty(); if ( mDescEditor ) mDirty |= mDescEditor->isDirty(); if ( mLocationEditor ) mDirty |= mLocationEditor->isDirty(); - if ( mLocationChanged ) mDirty |= TRUE; + if ( mLocationChanged ) mDirty |= TRUE; if ( mCategoryCombo ) mDirty |= mCategoryCombo->isDirty(); if ( mMatureCombo ) mDirty |= mMatureCombo->isDirty(); if ( mAutoRenewCheck ) mDirty |= mAutoRenewCheck->isDirty(); @@ -928,7 +928,7 @@ BOOL LLPanelClassified::checkDirty() } -void LLPanelClassified::sendClassifiedClickMessage(const std::string& type) +void LLPanelClassifiedInfo::sendClassifiedClickMessage(const std::string& type) { // You're allowed to click on your own ads to reassure yourself // that the system is working. @@ -941,7 +941,7 @@ void LLPanelClassified::sendClassifiedClickMessage(const std::string& type) body["region_name"] = mSimName; std::string url = gAgent.getRegion()->getCapability("SearchStatTracking"); - llinfos << "LLPanelClassified::sendClassifiedClickMessage via capability" << llendl; + llinfos << "LLPanelClassifiedInfo::sendClassifiedClickMessage via capability" << llendl; LLHTTPClient::post(url, body, new LLHTTPClient::ResponderIgnore); } @@ -991,7 +991,7 @@ void LLFloaterPriceForListing::buttonCore() close(); } -void LLPanelClassified::setDefaultAccessCombo() +void LLPanelClassifiedInfo::setDefaultAccessCombo() { // PG regions should have PG classifieds. AO should have mature. @@ -1010,3 +1010,5 @@ void LLPanelClassified::setDefaultAccessCombo() break; } } + +//EOF diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h index 04432edfd..36b84e6d2 100644 --- a/indra/newview/llpanelclassified.h +++ b/indra/newview/llpanelclassified.h @@ -1,6 +1,6 @@ /** * @file llpanelclassified.h - * @brief LLPanelClassified class definition + * @brief LLPanelClassifiedInfo class definition * * $LicenseInfo:firstyear=2005&license=viewergpl$ * @@ -52,11 +52,11 @@ class LLTextEditor; class LLTextureCtrl; class LLUICtrl; -class LLPanelClassified : public LLPanel, public LLAvatarPropertiesObserver +class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver { public: - LLPanelClassified(bool in_finder, bool from_search); - /*virtual*/ ~LLPanelClassified(); + LLPanelClassifiedInfo(bool in_finder, bool from_search); + /*virtual*/ ~LLPanelClassifiedInfo(); void reset(); @@ -167,7 +167,7 @@ protected: LLTextBox* mClickThroughText; LLRect mSnapshotSize; - typedef std::list panel_list_t; + typedef std::list panel_list_t; static panel_list_t sAllPanels; }; diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index c44a855b7..af7855ca3 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -36,39 +36,17 @@ #include "llpanelcontents.h" // linden library includes -#include "llerror.h" -#include "llrect.h" -#include "llstring.h" -#include "llmaterialtable.h" -#include "llfontgl.h" -#include "m3math.h" -#include "llpermissionsflags.h" -#include "lleconomy.h" -#include "material_codes.h" #include "llinventorydefines.h" // project includes -#include "llui.h" -#include "llspinctrl.h" -#include "llcheckboxctrl.h" -#include "lltextbox.h" -#include "llbutton.h" -#include "llcombobox.h" -#include "llfloaterbulkpermission.h" - #include "llagent.h" -#include "llviewerwindow.h" -#include "llviewerassettype.h" -#include "llworld.h" -#include "llviewerobject.h" -#include "llviewerregion.h" -#include "llresmgr.h" -#include "llselectmgr.h" -#include "llpreviewscript.h" -#include "lltool.h" -#include "lltoolmgr.h" -#include "lltoolcomp.h" +#include "llfloaterbulkpermission.h" +#include "llfloaterperms.h" #include "llpanelobjectinventory.h" +#include "llpreviewscript.h" +#include "llselectmgr.h" +#include "llviewerassettype.h" +#include "llviewerobject.h" // [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c) #include "rlvhandler.h" #include "rlvlocks.h" @@ -203,12 +181,14 @@ void LLPanelContents::onClickNewScript(void *userdata) LLPermissions perm; perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + + // Parameters are base, owner, everyone, group, next perm.initMasks( PERM_ALL, PERM_ALL, - PERM_NONE, - PERM_NONE, - PERM_MOVE | PERM_TRANSFER); + LLFloaterPerms::getEveryonePerms("Scripts"), + LLFloaterPerms::getGroupPerms("Scripts"), + LLFloaterPerms::getNextOwnerPerms("Scripts")); std::string desc; LLViewerAssetType::generateDescriptionFor(LLAssetType::AT_LSL_TEXT, desc); LLPointer new_item = diff --git a/indra/newview/llpaneldirfind.cpp b/indra/newview/llpaneldirfind.cpp index 2903355f5..5e132cb07 100644 --- a/indra/newview/llpaneldirfind.cpp +++ b/indra/newview/llpaneldirfind.cpp @@ -65,6 +65,7 @@ #include "llpaneldirbrowser.h" #include "hippogridmanager.h" +#include "lfsimfeaturehandler.h" #if LL_MSVC // disable boost::lexical_cast warning @@ -76,6 +77,92 @@ //--------------------------------------------------------------------------- // LLPanelDirFindAll - Google search appliance based search //--------------------------------------------------------------------------- +namespace +{ + std::string getSearchUrl() + { + return LFSimFeatureHandler::instance().searchURL(); + } + enum SearchType + { + SEARCH_ALL_EMPTY, + SEARCH_ALL_QUERY, + SEARCH_ALL_TEMPLATE + }; + std::string getSearchUrl(SearchType ty, bool is_web) + { + const std::string mSearchUrl(getSearchUrl()); + if (is_web) + { + if (gHippoGridManager->getConnectedGrid()->isSecondLife()) + { + // Second Life defaults + if (ty == SEARCH_ALL_EMPTY) + { + return gSavedSettings.getString("SearchURLDefault"); + } + else if (ty == SEARCH_ALL_QUERY) + { + return gSavedSettings.getString("SearchURLQuery"); + } + else if (ty == SEARCH_ALL_TEMPLATE) + { + return gSavedSettings.getString("SearchURLSuffix2"); + } + } + else if (!mSearchUrl.empty()) + { + // Search url sent to us in the login response + if (ty == SEARCH_ALL_EMPTY) + { + return mSearchUrl; + } + else if (ty == SEARCH_ALL_QUERY) + { + return mSearchUrl + "q=[QUERY]&s=[COLLECTION]&"; + } + else if (ty == SEARCH_ALL_TEMPLATE) + { + return "lang=[LANG]&mat=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]&dice=[DICE]"; + } + } + else + { + // OpenSim and other web search defaults + if (ty == SEARCH_ALL_EMPTY) + { + return gSavedSettings.getString("SearchURLDefaultOpenSim"); + } + else if (ty == SEARCH_ALL_QUERY) + { + return gSavedSettings.getString("SearchURLQueryOpenSim"); + } + else if (ty == SEARCH_ALL_TEMPLATE) + { + return gSavedSettings.getString("SearchURLSuffixOpenSim"); + } + } + } + else + { + // Use the old search all + if (ty == SEARCH_ALL_EMPTY) + { + return mSearchUrl + "panel=All&"; + } + else if (ty == SEARCH_ALL_QUERY) + { + return mSearchUrl + "q=[QUERY]&s=[COLLECTION]&"; + } + else if (ty == SEARCH_ALL_TEMPLATE) + { + return "lang=[LANG]&m=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]&dice=[DICE]"; + } + } + llinfos << "Illegal search URL type " << ty << llendl; + return ""; + } +} class LLPanelDirFindAll : public LLPanelDirFind @@ -90,6 +177,7 @@ public: LLPanelDirFindAll::LLPanelDirFindAll(const std::string& name, LLFloaterDirectory* floater) : LLPanelDirFind(name, floater, "find_browser") { + LFSimFeatureHandler::getInstance()->setSearchURLCallback(boost::bind(&LLPanelDirFindAll::navigateToDefaultPage, this)); } //--------------------------------------------------------------------------- @@ -264,48 +352,38 @@ void LLPanelDirFind::focus() void LLPanelDirFind::navigateToDefaultPage() { - std::string start_url = ""; + bool showcase(mBrowserName == "showcase_browser"); + std::string start_url = showcase ? LLWeb::expandURLSubstitutions(LFSimFeatureHandler::instance().destinationGuideURL(), LLSD()) : getSearchUrl(); + bool secondlife(gHippoGridManager->getConnectedGrid()->isSecondLife()); // Note: we use the web panel in OpenSim as well as Second Life -- MC - if (gHippoGridManager->getConnectedGrid()->getSearchUrl().empty() && - !gHippoGridManager->getConnectedGrid()->isSecondLife()) + if (start_url.empty() && !secondlife) { // OS-based but doesn't have its own web search url -- MC start_url = gSavedSettings.getString("SearchURLDefaultOpenSim"); } else { - if (gHippoGridManager->getConnectedGrid()->isSecondLife()) + if (!showcase) { - if (mBrowserName == "showcase_browser") - { - // note that the showcase URL in floater_directory.xml is no longer used - start_url = gSavedSettings.getString("ShowcaseURLDefault"); - } - else - { + if (secondlife) // Legacy Web Search start_url = gSavedSettings.getString("SearchURLDefault"); - } - } - else - { - // OS-based but has its own web search url -- MC - start_url = gHippoGridManager->getConnectedGrid()->getSearchUrl(); - start_url += "panel=" + getName() + "&"; - } + else // OS-based but has its own web search url -- MC + start_url += "panel=" + getName() + "&"; - if (hasChild("incmature")) - { - bool inc_pg = childGetValue("incpg").asBoolean(); - bool inc_mature = childGetValue("incmature").asBoolean(); - bool inc_adult = childGetValue("incadult").asBoolean(); - if (!(inc_pg || inc_mature || inc_adult)) + if (hasChild("incmature")) { - // if nothing's checked, just go for pg; we don't notify in - // this case because it's a default page. - inc_pg = true; + bool inc_pg = getChildView("incpg")->getValue().asBoolean(); + bool inc_mature = getChildView("incmature")->getValue().asBoolean(); + bool inc_adult = getChildView("incadult")->getValue().asBoolean(); + if (!(inc_pg || inc_mature || inc_adult)) + { + // if nothing's checked, just go for pg; we don't notify in + // this case because it's a default page. + inc_pg = true; + } + + start_url += getSearchURLSuffix(inc_pg, inc_mature, inc_adult, true); } - - start_url += getSearchURLSuffix(inc_pg, inc_mature, inc_adult, true); } } @@ -323,7 +401,7 @@ const std::string LLPanelDirFind::buildSearchURL(const std::string& search_text, std::string url; if (search_text.empty()) { - url = gHippoGridManager->getConnectedGrid()->getSearchUrl(HippoGridInfo::SEARCH_ALL_EMPTY, is_web); + url = getSearchUrl(SEARCH_ALL_EMPTY, is_web); } else { @@ -348,7 +426,7 @@ const std::string LLPanelDirFind::buildSearchURL(const std::string& search_text, "-._~$+!*'()"; std::string query = LLURI::escape(search_text_with_plus, allowed); - url = gHippoGridManager->getConnectedGrid()->getSearchUrl(HippoGridInfo::SEARCH_ALL_QUERY, is_web); + url = getSearchUrl(SEARCH_ALL_QUERY, is_web); std::string substring = "[QUERY]"; std::string::size_type where = url.find(substring); if (where != std::string::npos) @@ -373,14 +451,13 @@ const std::string LLPanelDirFind::buildSearchURL(const std::string& search_text, const std::string LLPanelDirFind::getSearchURLSuffix(bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) const { - std::string url = gHippoGridManager->getConnectedGrid()->getSearchUrl(HippoGridInfo::SEARCH_ALL_TEMPLATE, is_web); + std::string url = getSearchUrl(SEARCH_ALL_TEMPLATE, is_web); llinfos << "Suffix template " << url << llendl; if (!url.empty()) { // Note: opensim's default template (SearchURLSuffixOpenSim) is currently empty -- MC - if (gHippoGridManager->getConnectedGrid()->isSecondLife() || - !gHippoGridManager->getConnectedGrid()->getSearchUrl().empty()) + if (gHippoGridManager->getConnectedGrid()->isSecondLife() || !getSearchUrl().empty()) { // if the mature checkbox is unchecked, modify query to remove // terms with given phrase from the result set @@ -524,11 +601,14 @@ LLPanelDirFindAll* LLPanelDirFindAllInterface::create(LLFloaterDirectory* floate return new LLPanelDirFindAll("find_all_panel", floater); } +static LLPanelDirFindAllOld* sFindAllOld = NULL; // static void LLPanelDirFindAllInterface::search(LLPanelDirFindAll* panel, const std::string& search_text) { - panel->search(search_text); + bool secondlife(gHippoGridManager->getConnectedGrid()->isSecondLife()); + if (secondlife || !getSearchUrl().empty()) panel->search(search_text); + if (!secondlife && sFindAllOld) sFindAllOld->search(search_text); } // static @@ -544,6 +624,7 @@ void LLPanelDirFindAllInterface::focus(LLPanelDirFindAll* panel) LLPanelDirFindAllOld::LLPanelDirFindAllOld(const std::string& name, LLFloaterDirectory* floater) : LLPanelDirBrowser(name, floater) { + sFindAllOld = this; mMinSearchChars = 3; } @@ -565,6 +646,7 @@ BOOL LLPanelDirFindAllOld::postBuild() LLPanelDirFindAllOld::~LLPanelDirFindAllOld() { + sFindAllOld = NULL; // Children all cleaned up by default view destructor. } @@ -575,12 +657,18 @@ void LLPanelDirFindAllOld::draw() LLPanelDirBrowser::draw(); } +void LLPanelDirFindAllOld::search(const std::string& query) +{ + getChildView("name")->setValue(query); + onClickSearch(); +} + void LLPanelDirFindAllOld::onClickSearch() { if (childGetValue("name").asString().length() < mMinSearchChars) { return; - }; + } BOOL inc_pg = childGetValue("incpg").asBoolean(); BOOL inc_mature = childGetValue("incmature").asBoolean(); diff --git a/indra/newview/llpaneldirfind.h b/indra/newview/llpaneldirfind.h index 8ec0e51aa..866c330a8 100644 --- a/indra/newview/llpaneldirfind.h +++ b/indra/newview/llpaneldirfind.h @@ -99,6 +99,7 @@ public: /*virtual*/ void draw(); + void search(const std::string& query); void onClickSearch(); }; diff --git a/indra/newview/llpaneldirpopular.cpp b/indra/newview/llpaneldirpopular.cpp index ddb9d3aa5..fa678d416 100644 --- a/indra/newview/llpaneldirpopular.cpp +++ b/indra/newview/llpaneldirpopular.cpp @@ -33,11 +33,13 @@ #include "llviewerprecompiledheaders.h" #include "llpaneldirpopular.h" +#include "lfsimfeaturehandler.h" LLPanelDirPopular::LLPanelDirPopular(const std::string& name, LLFloaterDirectory* floater) : LLPanelDirFind(name, floater, "showcase_browser") { // *NOTE: This is now the "Showcase" section + LFSimFeatureHandler::instance().setSearchURLCallback(boost::bind(&LLPanelDirPopular::navigateToDefaultPage, this)); } // virtual diff --git a/indra/newview/llpaneldisplay.cpp b/indra/newview/llpaneldisplay.cpp index 0c1e60d76..1d4e23ded 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -97,15 +97,31 @@ const F32 MIN_USER_FAR_CLIP = 64.f; const S32 ASPECT_RATIO_STR_LEN = 100; +void reset_to_default(const std::string& control); +void reset_all_to_default(const LLView* panel) +{ + LLView::child_list_const_iter_t end(panel->endChild()); + for (LLView::child_list_const_iter_t i = panel->beginChild(); i != end; ++i) + { + const std::string& control_name((*i)->getControlName()); + if (control_name.empty()) continue; + if (control_name == "RenderDepthOfField") continue; // Don't touch render settings *sigh* hack + reset_to_default(control_name); + } +} + LLPanelDisplay::LLPanelDisplay() { + mCommitCallbackRegistrar.add("Graphics.ResetTab", boost::bind(reset_all_to_default, boost::bind(&LLView::getChildView, this, _2, true, false))); LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_graphics1.xml"); } +void updateSliderText(LLSliderCtrl* slider, LLTextBox* text_box); + BOOL LLPanelDisplay::postBuild() { // return to default values - getChild("Defaults")->setClickedCallback(boost::bind(&LLPanelDisplay::setHardwareDefaults)); + getChild("Defaults")->setClickedCallback(boost::bind(&LLPanelDisplay::setHardwareDefaults, this)); //============================================================================ // Resolution @@ -167,7 +183,7 @@ BOOL LLPanelDisplay::postBuild() } initWindowSizeControls(); - + if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio")) { mAspectRatio = gViewerWindow->getDisplayAspectRatio(); @@ -192,27 +208,22 @@ BOOL LLPanelDisplay::postBuild() aspect_ratio_text = llformat("%.3f", mAspectRatio); } + mCtrlAutoDetectAspect = getChild( "aspect_auto_detect"); + mCtrlAutoDetectAspect->setCommitCallback(boost::bind(&LLPanelDisplay::onCommitAutoDetectAspect,this,_2)); + mCtrlAspectRatio = getChild( "aspect_ratio"); - mCtrlAspectRatio->setTextEntryCallback(boost::bind(&LLPanelDisplay::onKeystrokeAspectRatio,this)); - mCtrlAspectRatio->setCommitCallback(boost::bind(&LLPanelDisplay::onSelectAspectRatio,this)); + mCtrlAspectRatio->setTextEntryCallback(boost::bind(&LLUICtrl::setValue, mCtrlAutoDetectAspect, false)); + mCtrlAspectRatio->setCommitCallback(boost::bind(&LLUICtrl::setValue, mCtrlAutoDetectAspect, false)); // add default aspect ratios mCtrlAspectRatio->add(aspect_ratio_text, &mAspectRatio, ADD_TOP); mCtrlAspectRatio->setCurrentByIndex(0); - mCtrlAutoDetectAspect = getChild( "aspect_auto_detect"); - mCtrlAutoDetectAspect->setCommitCallback(boost::bind(&LLPanelDisplay::onCommitAutoDetectAspect,this,_2)); - // radio performance box mCtrlSliderQuality = getChild("QualityPerformanceSelection"); mCtrlSliderQuality->setSliderMouseUpCallback(boost::bind(&LLPanelDisplay::onChangeQuality,this,_1)); mCtrlCustomSettings = getChild("CustomSettings"); - mCtrlCustomSettings->setCommitCallback(boost::bind(&LLPanelDisplay::onChangeCustom)); - - //mGraphicsBorder = getChild("GraphicsBorder"); - - // Enable Transparent Water - mCtrlTransparentWater = getChild("TransparentWater"); + mCtrlCustomSettings->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); //---------------------------------------------------------------------------- // Enable Bump/Shiny @@ -221,19 +232,19 @@ BOOL LLPanelDisplay::postBuild() //---------------------------------------------------------------------------- // Enable Reflections mCtrlReflectionDetail = getChild("ReflectionDetailCombo"); - mCtrlReflectionDetail->setCommitCallback(boost::bind(&LLPanelDisplay::onVertexShaderEnable)); + mCtrlReflectionDetail->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); // WindLight mCtrlWindLight = getChild("WindLightUseAtmosShaders"); - mCtrlWindLight->setCommitCallback(boost::bind(&LLPanelDisplay::onVertexShaderEnable)); + mCtrlWindLight->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); // Deferred mCtrlDeferred = getChild("RenderDeferred"); - mCtrlDeferred->setCommitCallback(boost::bind(&LLPanelDisplay::onVertexShaderEnable)); + mCtrlDeferred->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); mCtrlDeferredDoF = getChild("RenderDepthOfField"); - mCtrlDeferredDoF->setCommitCallback(boost::bind(&LLPanelDisplay::onVertexShaderEnable)); + mCtrlDeferredDoF->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); mCtrlShadowDetail = getChild("ShadowDetailCombo"); - mCtrlShadowDetail->setCommitCallback(boost::bind(&LLPanelDisplay::onVertexShaderEnable)); + mCtrlShadowDetail->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); //---------------------------------------------------------------------------- // Terrain Scale @@ -242,18 +253,13 @@ BOOL LLPanelDisplay::postBuild() //---------------------------------------------------------------------------- // Enable Avatar Shaders mCtrlAvatarVP = getChild("AvatarVertexProgram"); - mCtrlAvatarVP->setCommitCallback(boost::bind(&LLPanelDisplay::onVertexShaderEnable)); + mCtrlAvatarVP->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); //---------------------------------------------------------------------------- // Avatar Render Mode mCtrlAvatarCloth = getChild("AvatarCloth"); mCtrlAvatarImpostors = getChild("AvatarImpostors"); - mCtrlAvatarImpostors->setCommitCallback(boost::bind(&LLPanelDisplay::onVertexShaderEnable)); - mCtrlNonImpostors = getChild("AvatarMaxVisible"); - - //---------------------------------------------------------------------------- - // Checkbox for lighting detail - mCtrlLightingDetail2 = getChild("LightingDetailRadio"); + mCtrlAvatarImpostors->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); //---------------------------------------------------------------------------- // Checkbox for ambient occlusion @@ -266,73 +272,63 @@ BOOL LLPanelDisplay::postBuild() //---------------------------------------------------------------------------- // Global Shader Enable mCtrlShaderEnable = getChild("BasicShaders"); - mCtrlShaderEnable->setCommitCallback(boost::bind(&LLPanelDisplay::onVertexShaderEnable)); + mCtrlShaderEnable->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); //============================================================================ // Object detail slider - mCtrlDrawDistance = getChild("DrawDistance"); - mDrawDistanceMeterText1 = getChild("DrawDistanceMeterText1"); - mDrawDistanceMeterText2 = getChild("DrawDistanceMeterText2"); - mCtrlDrawDistance->setCommitCallback(boost::bind(&LLPanelDisplay::updateMeterText, this)); - - // Object detail slider - mCtrlLODFactor = getChild("ObjectMeshDetail"); - mLODFactorText = getChild("ObjectMeshDetailText"); - mCtrlLODFactor->setCommitCallback(boost::bind(&LLPanelDisplay::updateSliderText, _1,mLODFactorText)); + LLSliderCtrl* ctrl_slider = getChild("ObjectMeshDetail"); + LLTextBox* slider_text = getChild("ObjectMeshDetailText"); + ctrl_slider->setCommitCallback(boost::bind(updateSliderText, ctrl_slider, slider_text)); + updateSliderText(ctrl_slider, slider_text); // Flex object detail slider - mCtrlFlexFactor = getChild("FlexibleMeshDetail"); - mFlexFactorText = getChild("FlexibleMeshDetailText"); - mCtrlFlexFactor->setCommitCallback(boost::bind(&LLPanelDisplay::updateSliderText,_1, mFlexFactorText)); + ctrl_slider = getChild("FlexibleMeshDetail"); + slider_text = getChild("FlexibleMeshDetailText"); + ctrl_slider->setCommitCallback(boost::bind(updateSliderText, ctrl_slider, slider_text)); + updateSliderText(ctrl_slider, slider_text); // Tree detail slider - mCtrlTreeFactor = getChild("TreeMeshDetail"); - mTreeFactorText = getChild("TreeMeshDetailText"); - mCtrlTreeFactor->setCommitCallback(boost::bind(&LLPanelDisplay::updateSliderText, _1, mTreeFactorText)); + ctrl_slider = getChild("TreeMeshDetail"); + slider_text = getChild("TreeMeshDetailText"); + ctrl_slider->setCommitCallback(boost::bind(updateSliderText, ctrl_slider, slider_text)); + updateSliderText(ctrl_slider, slider_text); // Avatar detail slider - mCtrlAvatarFactor = getChild("AvatarMeshDetail"); - mAvatarFactorText = getChild("AvatarMeshDetailText"); - mCtrlAvatarFactor->setCommitCallback(boost::bind(&LLPanelDisplay::updateSliderText, _1, mAvatarFactorText)); + ctrl_slider = getChild("AvatarMeshDetail"); + slider_text = getChild("AvatarMeshDetailText"); + ctrl_slider->setCommitCallback(boost::bind(updateSliderText, ctrl_slider, slider_text)); + updateSliderText(ctrl_slider, slider_text); // Avatar physics detail slider - mCtrlAvatarPhysicsFactor = getChild("AvatarPhysicsDetail"); - mAvatarPhysicsFactorText = getChild("AvatarPhysicsDetailText"); - mCtrlAvatarPhysicsFactor->setCommitCallback(boost::bind(&LLPanelDisplay::updateSliderText, _1, mAvatarPhysicsFactorText)); + ctrl_slider = getChild("AvatarPhysicsDetail"); + slider_text = getChild("AvatarPhysicsDetailText"); + ctrl_slider->setCommitCallback(boost::bind(updateSliderText, ctrl_slider, slider_text)); + updateSliderText(ctrl_slider, slider_text); // Terrain detail slider - mCtrlTerrainFactor = getChild("TerrainMeshDetail"); - mTerrainFactorText = getChild("TerrainMeshDetailText"); - mCtrlTerrainFactor->setCommitCallback(boost::bind(&LLPanelDisplay::updateSliderText, _1, mTerrainFactorText)); + ctrl_slider = getChild("TerrainMeshDetail"); + slider_text = getChild("TerrainMeshDetailText"); + ctrl_slider->setCommitCallback(boost::bind(updateSliderText, ctrl_slider, slider_text)); + updateSliderText(ctrl_slider, slider_text); // Terrain detail slider - mCtrlSkyFactor = getChild("SkyMeshDetail"); - mSkyFactorText = getChild("SkyMeshDetailText"); - mCtrlSkyFactor->setCommitCallback(boost::bind(&LLPanelDisplay::updateSliderText, _1, mSkyFactorText)); - - // Particle detail slider - mCtrlMaxParticle = getChild("MaxParticleCount"); + ctrl_slider = getChild("SkyMeshDetail"); + slider_text = getChild("SkyMeshDetailText"); + ctrl_slider->setCommitCallback(boost::bind(updateSliderText, ctrl_slider, slider_text)); + updateSliderText(ctrl_slider, slider_text); // Glow detail slider - mCtrlPostProcess = getChild("RenderPostProcess"); - mPostProcessText = getChild("PostProcessText"); - mCtrlPostProcess->setCommitCallback(boost::bind(&LLPanelDisplay::updateSliderText, _1, mPostProcessText)); + ctrl_slider = getChild("RenderPostProcess"); + slider_text = getChild("PostProcessText"); + ctrl_slider->setCommitCallback(boost::bind(updateSliderText, ctrl_slider, slider_text)); + updateSliderText(ctrl_slider, slider_text); // Text boxes (for enabling/disabling) - mShaderText = getChild("ShadersText"); - mReflectionText = getChild("ReflectionDetailText"); - mAvatarText = getChild("AvatarRenderingText"); - mTerrainText = getChild("TerrainDetailText"); - mMeshDetailText = getChild("MeshDetailText"); - mShadowDetailText = getChild("ShadowDetailText"); - mTerrainScaleText = getChild("TerrainScaleText"); // Hardware tab mVBO = getChild("vbo"); - mVBO->setCommitCallback(boost::bind(&LLPanelDisplay::onVertexShaderEnable)); - - mVBOStream = getChild("vbo_stream"); + mVBO->setCommitCallback(boost::bind(&LLPanelDisplay::refreshEnabledState, this)); if(gGLManager.mIsATI) //AMD gpus don't go beyond 8x fsaa. { @@ -439,16 +435,6 @@ void LLPanelDisplay::refresh() mLocalLights = gSavedSettings.getBOOL("RenderLocalLights"); mTerrainDetail = gSavedSettings.getS32("RenderTerrainDetail"); - // slider text boxes - updateSliderText(mCtrlLODFactor, mLODFactorText); - updateSliderText(mCtrlFlexFactor, mFlexFactorText); - updateSliderText(mCtrlTreeFactor, mTreeFactorText); - updateSliderText(mCtrlAvatarFactor, mAvatarFactorText); - updateSliderText(mCtrlAvatarPhysicsFactor, mAvatarPhysicsFactorText); - updateSliderText(mCtrlTerrainFactor, mTerrainFactorText); - updateSliderText(mCtrlPostProcess, mPostProcessText); - updateSliderText(mCtrlSkyFactor, mSkyFactorText); - // Hardware tab mUseVBO = gSavedSettings.getBOOL("RenderVBOEnable"); mUseFBO = gSavedSettings.getBOOL("RenderUseFBO"); @@ -462,6 +448,13 @@ void LLPanelDisplay::refresh() childSetValue("fsaa", (LLSD::Integer) mFSAASamples); childSetValue("vsync", (LLSD::Integer) mVsyncMode); + // Depth of Field tab + mFNumber = gSavedSettings.getF32("CameraFNumber"); + mFocalLength = gSavedSettings.getF32("CameraFocalLength"); + mMaxCoF = gSavedSettings.getF32("CameraMaxCoF"); + mFocusTrans = gSavedSettings.getF32("CameraFocusTransitionTime"); + mDoFRes = gSavedSettings.getF32("CameraDoFResScale"); + refreshEnabledState(); } @@ -478,18 +471,25 @@ void LLPanelDisplay::refreshEnabledState() mWindowSizeLabel->setVisible(!isFullScreen); mCtrlWindowSize->setVisible(!isFullScreen); - // disable graphics settings and exit if it's not set to custom - if(!gSavedSettings.getBOOL("RenderCustomSettings")) + // Hardware tab + getChild("GrapicsCardTextureMemory")->setMinValue(LLViewerTextureList::getMinVideoRamSetting()); + getChild("GrapicsCardTextureMemory")->setMaxValue(LLViewerTextureList::getMaxVideoRamSetting()); + + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || + !gGLManager.mHasVertexBufferObject) { - setHiddenGraphicsState(true); - return; + mVBO->setEnabled(false); + mVBO->setValue(false); } - // otherwise turn them all on and selectively turn off others - else - { - setHiddenGraphicsState(false); - } + static LLCachedControl wlatmos("WindLightUseAtmosShaders",false); + // if no windlight shaders, enable gamma, and fog distance + getChildView("gamma")->setEnabled(!wlatmos); + getChildView("fog")->setEnabled(!wlatmos); + getChildView("note")->setVisible(wlatmos); + + // disable graphics settings and exit if it's not set to custom + if (!gSavedSettings.getBOOL("RenderCustomSettings")) return; // Reflections BOOL reflections = gSavedSettings.getBOOL("VertexShaderEnable") @@ -499,19 +499,10 @@ void LLPanelDisplay::refreshEnabledState() // Bump & Shiny bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump"); - mCtrlBumpShiny->setEnabled(bumpshiny ? TRUE : FALSE); + mCtrlBumpShiny->setEnabled(bumpshiny); - if (gSavedSettings.getBOOL("VertexShaderEnable") == FALSE || - gSavedSettings.getBOOL("RenderAvatarVP") == FALSE) - { - mCtrlAvatarCloth->setEnabled(false); - } - else - { - mCtrlAvatarCloth->setEnabled(true); - } + mCtrlAvatarCloth->setEnabled(gSavedSettings.getBOOL("VertexShaderEnable") && gSavedSettings.getBOOL("RenderAvatarVP")); - static LLCachedControl wlatmos("WindLightUseAtmosShaders",false); //I actually recommend RenderUseFBO:FALSE for ati users when not using deferred, so RenderUseFBO shouldn't control visibility of the element. // Instead, gGLManager.mHasFramebufferObject seems better as it is determined by hardware and not current user settings. -Shyotl //Enabling deferred will force RenderUseFBO to TRUE. @@ -528,9 +519,6 @@ void LLPanelDisplay::refreshEnabledState() mCtrlAmbientOcc->setEnabled(can_defer && render_deferred); mCtrlDeferredDoF->setEnabled(can_defer && render_deferred); - // Disable max non-impostors slider if avatar impostors are off - mCtrlNonImpostors->setEnabled(gSavedSettings.getBOOL("RenderUseImpostors")); - // Vertex Shaders // mCtrlShaderEnable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")); // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0a @@ -559,61 +547,43 @@ void LLPanelDisplay::refreshEnabledState() mCtrlWindLight->setEnabled(fCtrlWindLightEnable && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV) || !mWindLight)); // [/RLVa:KB] - // turn off sky detail if atmospherics isn't on - mCtrlSkyFactor->setEnabled(wlatmos); - mSkyFactorText->setEnabled(wlatmos); - // Avatar Mode and FBO if (render_deferred && wlatmos && shaders) { - childSetEnabled("fbo", false); - childSetValue("fbo", true); + getChildView("fbo")->setEnabled(false); + getChildView("fbo")->setValue(true); mCtrlAvatarVP->setEnabled(false); gSavedSettings.setBOOL("RenderAvatarVP", true); } - else if (!shaders) - { - childSetEnabled("fbo", gGLManager.mHasFramebufferObject); - mCtrlAvatarVP->setEnabled(false); - gSavedSettings.setBOOL("RenderAvatarVP", false); - } else { - childSetEnabled("fbo", gGLManager.mHasFramebufferObject); - mCtrlAvatarVP->setEnabled(true); + getChildView("fbo")->setEnabled(gGLManager.mHasFramebufferObject); + mCtrlAvatarVP->setEnabled(shaders); + if (!shaders) gSavedSettings.setBOOL("RenderAvatarVP", false); } - // Hardware tab - S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); - S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(); - childSetMinValue("GrapicsCardTextureMemory", min_tex_mem); - childSetMaxValue("GrapicsCardTextureMemory", max_tex_mem); - - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || - !gGLManager.mHasVertexBufferObject) - { - mVBO->setEnabled(false); - //Streaming VBOs -Shyotl - mVBOStream->setEnabled(false); - } - else - { - mVBOStream->setEnabled(gSavedSettings.getBOOL("RenderVBOEnable")); - } - - // if no windlight shaders, enable gamma, and fog distance - childSetEnabled("gamma",!wlatmos); - childSetEnabled("fog", !wlatmos); - childSetVisible("note", wlatmos); - // now turn off any features that are unavailable disableUnavailableSettings(); } void LLPanelDisplay::disableUnavailableSettings() { + // disabled terrain scale + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderTerrainScale")) + { + mCtrlTerrainScale->setEnabled(false); + mCtrlTerrainScale->setValue(false); + } + // disabled impostors + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseImpostors")) + { + mCtrlAvatarImpostors->setEnabled(false); + mCtrlAvatarImpostors->setValue(false); + } + // if vertex shaders off, disable all shader related products - if(!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")) + // Singu Note: Returns early this, place all unrelated checks above now. + if (!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")) { mCtrlShaderEnable->setEnabled(FALSE); mCtrlShaderEnable->setValue(FALSE); @@ -638,6 +608,7 @@ void LLPanelDisplay::disableUnavailableSettings() mCtrlDeferredDoF->setValue(FALSE); mCtrlShadowDetail->setEnabled(FALSE); mCtrlShadowDetail->setValue(FALSE); + return; } // disabled windlight @@ -654,13 +625,6 @@ void LLPanelDisplay::disableUnavailableSettings() mCtrlReflectionDetail->setValue(FALSE); } - // disabled terrain scale - if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderTerrainScale")) - { - mCtrlTerrainScale->setEnabled(false); - mCtrlTerrainScale->setValue(false); - } - // disabled av if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP")) { @@ -671,18 +635,11 @@ void LLPanelDisplay::disableUnavailableSettings() mCtrlAvatarCloth->setValue(FALSE); } // disabled cloth - if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth")) + else if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth")) { mCtrlAvatarCloth->setEnabled(FALSE); mCtrlAvatarCloth->setValue(FALSE); } - // disabled impostors - if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseImpostors")) - { - mCtrlAvatarImpostors->setEnabled(FALSE); - mCtrlAvatarImpostors->setValue(FALSE); - mCtrlNonImpostors->setEnabled(FALSE); - } // disabled deferred if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) { @@ -698,119 +655,6 @@ void LLPanelDisplay::disableUnavailableSettings() } -void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) -{ - // quick check - //llassert(mGraphicsBorder != NULL); - - llassert(mCtrlDrawDistance != NULL); - llassert(mCtrlLODFactor != NULL); - llassert(mCtrlFlexFactor != NULL); - llassert(mCtrlTreeFactor != NULL); - llassert(mCtrlAvatarFactor != NULL); - llassert(mCtrlTerrainFactor != NULL); - llassert(mCtrlSkyFactor != NULL); - llassert(mCtrlMaxParticle != NULL); - llassert(mCtrlPostProcess != NULL); - - llassert(mLODFactorText != NULL); - llassert(mFlexFactorText != NULL); - llassert(mTreeFactorText != NULL); - llassert(mAvatarFactorText != NULL); - llassert(mTerrainFactorText != NULL); - llassert(mSkyFactorText != NULL); - llassert(mPostProcessText != NULL); - - llassert(mCtrlTransparentWater != NULL); - llassert(mCtrlBumpShiny != NULL); - llassert(mCtrlWindLight != NULL); - llassert(mCtrlAvatarVP != NULL); - llassert(mCtrlShaderEnable != NULL); - llassert(mCtrlAvatarImpostors != NULL); - llassert(mCtrlNonImpostors != NULL); - llassert(mCtrlAvatarCloth != NULL); - llassert(mCtrlLightingDetail2 != NULL); - llassert(mCtrlAmbientOcc != NULL); - - llassert(mRadioTerrainDetail != NULL); - llassert(mCtrlReflectionDetail != NULL); - llassert(mCtrlTerrainScale != NULL); - - llassert(mMeshDetailText != NULL); - llassert(mShaderText != NULL); - llassert(mReflectionText != NULL); - llassert(mTerrainScaleText != NULL); - llassert(mAvatarText != NULL); - llassert(mTerrainText != NULL); - llassert(mDrawDistanceMeterText1 != NULL); - llassert(mDrawDistanceMeterText2 != NULL); - - // enable/disable the states - //mGraphicsBorder->setVisible(!isHidden); - /* - LLColor4 light(.45098f, .51765f, .6078f, 1.0f); - LLColor4 dark(.10196f, .10196f, .10196f, 1.0f); - b ? mGraphicsBorder->setColors(dark, light) : mGraphicsBorder->setColors(dark, dark); - */ - - mCtrlDrawDistance->setVisible(!isHidden); - mCtrlLODFactor->setVisible(!isHidden); - mCtrlFlexFactor->setVisible(!isHidden); - mCtrlTreeFactor->setVisible(!isHidden); - mCtrlAvatarFactor->setVisible(!isHidden); - mCtrlAvatarPhysicsFactor->setVisible(!isHidden); - mCtrlTerrainFactor->setVisible(!isHidden); - mCtrlSkyFactor->setVisible(!isHidden); - mCtrlMaxParticle->setVisible(!isHidden); - mCtrlPostProcess->setVisible(!isHidden); - - mLODFactorText->setVisible(!isHidden); - mFlexFactorText->setVisible(!isHidden); - mTreeFactorText->setVisible(!isHidden); - mAvatarFactorText->setVisible(!isHidden); - mAvatarPhysicsFactorText->setVisible(!isHidden); - mTerrainFactorText->setVisible(!isHidden); - mSkyFactorText->setVisible(!isHidden); - mPostProcessText->setVisible(!isHidden); - - mCtrlTransparentWater->setVisible(!isHidden); - mCtrlBumpShiny->setVisible(!isHidden); - mCtrlWindLight->setVisible(!isHidden); - mCtrlAvatarVP->setVisible(!isHidden); - mCtrlShaderEnable->setVisible(!isHidden); - mCtrlAvatarImpostors->setVisible(!isHidden); - mCtrlNonImpostors->setVisible(!isHidden); - mCtrlAvatarCloth->setVisible(!isHidden); - mCtrlLightingDetail2->setVisible(!isHidden); - mCtrlAmbientOcc->setVisible(!isHidden); - - mRadioTerrainDetail->setVisible(!isHidden); - mCtrlReflectionDetail->setVisible(!isHidden); - mCtrlTerrainScale->setVisible(!isHidden); - - mCtrlDeferred->setVisible(!isHidden); - mCtrlDeferredDoF->setVisible(!isHidden); - mCtrlShadowDetail->setVisible(!isHidden); - - // text boxes - mShaderText->setVisible(!isHidden); - mReflectionText->setVisible(!isHidden); - mAvatarText->setVisible(!isHidden); - mTerrainText->setVisible(!isHidden); - mDrawDistanceMeterText1->setVisible(!isHidden); - mDrawDistanceMeterText2->setVisible(!isHidden); - mShadowDetailText->setVisible(!isHidden); - mTerrainScaleText->setVisible(!isHidden); - - // hide one meter text if we're making things visible - if(!isHidden) - { - updateMeterText(); - } - - mMeshDetailText->setVisible(!isHidden); -} - void LLPanelDisplay::cancel() { gSavedSettings.setBOOL("FullScreenAutoDetectAspectRatio", mFSAutoDetectAspect); @@ -859,6 +703,13 @@ void LLPanelDisplay::cancel() gSavedSettings.setS32("TextureMemory", mVideoCardMem); gSavedSettings.setF32("RenderFogRatio", mFogRatio); gSavedSettings.setS32("SHRenderVsyncMode", mVsyncMode); + + // Depth of Field tab + gSavedSettings.setF32("CameraFNumber", mFNumber); + gSavedSettings.setF32("CameraFocalLength", mFocalLength); + gSavedSettings.setF32("CameraMaxCoF", mMaxCoF); + gSavedSettings.setF32("CameraFocusTransitionTime", mFocusTrans); + gSavedSettings.setF32("CameraDoFResScale", mDoFRes); } void LLPanelDisplay::apply() @@ -885,7 +736,7 @@ void LLPanelDisplay::apply() gSavedSettings.setS32("SHRenderVsyncMode", vsync_value); applyResolution(); - + // Only set window size if we're not in fullscreen mode if (mCtrlWindowed->get()) { @@ -911,30 +762,15 @@ void LLPanelDisplay::apply() } } -void LLPanelDisplay::onChangeQuality(LLUICtrl* caller) +void LLPanelDisplay::onChangeQuality(LLUICtrl* ctrl) { - LLSlider* sldr = dynamic_cast(caller); - - if(sldr == NULL) - { - return; - } - - U32 set = (U32)sldr->getValueF32(); - LLFeatureManager::getInstance()->setGraphicsLevel(set, true); - - LLFloaterPreference::refreshEnabledGraphics(); + LLFeatureManager::getInstance()->setGraphicsLevel(ctrl->getValue(), true); + refreshEnabledState(); refresh(); } -void LLPanelDisplay::onChangeCustom() -{ - LLFloaterPreference::refreshEnabledGraphics(); -} - void LLPanelDisplay::applyResolution() { - gGL.flush(); char aspect_ratio_text[ASPECT_RATIO_STR_LEN]; /*Flawfinder: ignore*/ if (mCtrlAspectRatio->getCurrentIndex() == -1) @@ -1059,16 +895,6 @@ void LLPanelDisplay::onCommitAutoDetectAspect(const LLSD& value) } } -void LLPanelDisplay::onKeystrokeAspectRatio() -{ - mCtrlAutoDetectAspect->set(FALSE); -} - -void LLPanelDisplay::onSelectAspectRatio() -{ - mCtrlAutoDetectAspect->set(FALSE); -} - //static void LLPanelDisplay::fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator) { @@ -1085,56 +911,38 @@ void LLPanelDisplay::fractionFromDecimal(F32 decimal_val, S32& numerator, S32& d } } -void LLPanelDisplay::onVertexShaderEnable() -{ - LLFloaterPreference::refreshEnabledGraphics(); -} - -//static void LLPanelDisplay::setHardwareDefaults() { LLFeatureManager::getInstance()->applyRecommendedSettings(); - LLControlVariable* controlp = gSavedSettings.getControl("RenderAvatarMaxVisible"); - if (controlp) + if (LLControlVariable* controlp = gSavedSettings.getControl("RenderAvatarMaxVisible")) { controlp->resetToDefault(true); } - LLFloaterPreference::refreshEnabledGraphics(); + refreshEnabledState(); } -//static -void LLPanelDisplay::updateSliderText(LLUICtrl* ctrl, LLTextBox* text_box) +void updateSliderText(LLSliderCtrl* slider, LLTextBox* text_box) { - // get our UI widgets - LLSliderCtrl* slider = dynamic_cast(ctrl); - if(text_box == NULL || slider == NULL) - { - return; - } - - //Hack to display 'Off' for avatar physics slider. - if(slider->getName() == "AvatarPhysicsDetail" && !slider->getValueF32()) - { - text_box->setText(std::string("Off")); - return; - } - // get range and points when text should change - F32 range = slider->getMaxValue() - slider->getMinValue(); - llassert(range > 0); - F32 midPoint = slider->getMinValue() + range / 3.0f; - F32 highPoint = slider->getMinValue() + (2.0f * range / 3.0f); + const F32 value = slider->getValue().asFloat(); + const F32 min_val = slider->getMinValue(); + const F32 max_val = slider->getMaxValue(); + const F32 range = (max_val - min_val)/3.f; // choose the right text - if(slider->getValueF32() < midPoint) + if (value < min_val + range) { - text_box->setText(std::string("Low")); + //Hack to display 'Off' for avatar physics slider. + if (!value && slider->getName() == "AvatarPhysicsDetail") + text_box->setText(std::string("Off")); + else + text_box->setText(std::string("Low")); } - else if (slider->getValueF32() < highPoint) + else if (value < min_val + 2.0f * range) { text_box->setText(std::string("Mid")); } - else if(slider->getValueF32() < slider->getMaxValue()) + else if (value < max_val) { text_box->setText(std::string("High")); } @@ -1144,14 +952,3 @@ void LLPanelDisplay::updateSliderText(LLUICtrl* ctrl, LLTextBox* text_box) } } -void LLPanelDisplay::updateMeterText() -{ - // toggle the two text boxes based on whether we have 2 or 3 digits - F32 val = mCtrlDrawDistance->getValueF32(); - bool two_digits = val < 100; - mDrawDistanceMeterText1->setVisible(two_digits); - mDrawDistanceMeterText2->setVisible(!two_digits); -} - - - diff --git a/indra/newview/llpaneldisplay.h b/indra/newview/llpaneldisplay.h index 1652b497b..688757f9a 100644 --- a/indra/newview/llpaneldisplay.h +++ b/indra/newview/llpaneldisplay.h @@ -70,7 +70,6 @@ public: void refresh(); // Refresh enable/disable void refreshEnabledState(); void disableUnavailableSettings(); - void setHiddenGraphicsState(bool isHidden); void apply(); // Apply the changed values. void applyResolution(); void applyWindowSize(); @@ -92,22 +91,6 @@ protected: LLSliderCtrl *mCtrlSliderQuality; LLCheckBoxCtrl *mCtrlCustomSettings; - // performance sliders and boxes - //LLViewBorder *mGraphicsBorder; - - LLSliderCtrl *mCtrlDrawDistance; // the draw distance slider - LLSliderCtrl *mCtrlLODFactor; // LOD for volume objects - LLSliderCtrl *mCtrlFlexFactor; // Timeslice for flexible objects - LLSliderCtrl *mCtrlTreeFactor; // Control tree cutoff distance - LLSliderCtrl *mCtrlAvatarFactor; // LOD for avatars - LLSliderCtrl *mCtrlAvatarPhysicsFactor; // Physics LOD for avatars - LLSliderCtrl *mCtrlTerrainFactor; // LOD for terrain - LLSliderCtrl *mCtrlSkyFactor; // LOD for terrain - LLSliderCtrl *mCtrlMaxParticle; // Max Particle - LLSliderCtrl *mCtrlPostProcess; // Max Particle - LLSliderCtrl *mCtrlNonImpostors; // Max non-impostors - - LLCheckBoxCtrl *mCtrlTransparentWater; LLCheckBoxCtrl *mCtrlBumpShiny; LLCheckBoxCtrl *mCtrlWindLight; LLCheckBoxCtrl *mCtrlAvatarVP; @@ -119,7 +102,6 @@ protected: LLComboBox *mCtrlTerrainScale; LLCheckBoxCtrl *mCtrlAvatarImpostors; LLCheckBoxCtrl *mCtrlAvatarCloth; - LLCheckBoxCtrl *mCtrlLightingDetail2; LLCheckBoxCtrl *mCtrlAmbientOcc; LLRadioGroup *mRadioTerrainDetail; @@ -127,27 +109,7 @@ protected: LLTextBox *mDisplayResLabel; LLTextBox *mWindowSizeLabel; - LLTextBox *mShaderText; - LLTextBox *mReflectionText; - LLTextBox *mAvatarText; - LLTextBox *mTerrainText; - LLTextBox *mDrawDistanceMeterText1; - LLTextBox *mDrawDistanceMeterText2; - - LLTextBox *mMeshDetailText; - LLTextBox *mLODFactorText; - LLTextBox *mFlexFactorText; - LLTextBox *mTreeFactorText; - LLTextBox *mAvatarFactorText; - LLTextBox *mAvatarPhysicsFactorText; - LLTextBox *mTerrainFactorText; - LLTextBox *mSkyFactorText; - LLTextBox *mPostProcessText; - LLTextBox *mShadowDetailText; - LLTextBox *mTerrainScaleText; - LLCheckBoxCtrl *mVBO; - LLCheckBoxCtrl *mVBOStream; BOOL mFSAutoDetectAspect; F32 mAspectRatio; @@ -196,24 +158,22 @@ protected: F32 mFogRatio; S32 mVsyncMode; + // Depth of Field tab + F32 mFNumber; + F32 mFocalLength; + F32 mMaxCoF; + F32 mFocusTrans; + F32 mDoFRes; + // if the quality radio buttons are changed void onChangeQuality(LLUICtrl* caller); - // if the custom settings box is clicked - static void onChangeCustom(); - void onCommitAutoDetectAspect(const LLSD& value); - void onKeystrokeAspectRatio(); - void onSelectAspectRatio(); void onCommitWindowedMode(); - static void updateSliderText(LLUICtrl* ctrl, LLTextBox* text_box); void updateMeterText(); /// callback for defaults - static void setHardwareDefaults(); - - // callback for when client turns on shaders - static void onVertexShaderEnable(); + void setHardwareDefaults(); // helper function static void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 8e4f890ff..400baa869 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -67,45 +67,46 @@ #include // subparts of the UI for focus, camera position, etc. -enum ESubpart { - SUBPART_SHAPE_HEAD = 1, // avoid 0 - SUBPART_SHAPE_EYES, - SUBPART_SHAPE_EARS, - SUBPART_SHAPE_NOSE, - SUBPART_SHAPE_MOUTH, - SUBPART_SHAPE_CHIN, - SUBPART_SHAPE_TORSO, - SUBPART_SHAPE_LEGS, - SUBPART_SHAPE_WHOLE, - SUBPART_SHAPE_DETAIL, - SUBPART_SKIN_COLOR, - SUBPART_SKIN_FACEDETAIL, - SUBPART_SKIN_MAKEUP, - SUBPART_SKIN_BODYDETAIL, - SUBPART_HAIR_COLOR, - SUBPART_HAIR_STYLE, - SUBPART_HAIR_EYEBROWS, - SUBPART_HAIR_FACIAL, - SUBPART_EYES, - SUBPART_SHIRT, - SUBPART_PANTS, - SUBPART_SHOES, - SUBPART_SOCKS, - SUBPART_JACKET, - SUBPART_GLOVES, - SUBPART_UNDERSHIRT, - SUBPART_UNDERPANTS, - SUBPART_SKIRT, - SUBPART_ALPHA, - SUBPART_TATTOO, - SUBPART_PHYSICS_BREASTS_UPDOWN, - SUBPART_PHYSICS_BREASTS_INOUT, - SUBPART_PHYSICS_BREASTS_LEFTRIGHT, - SUBPART_PHYSICS_BELLY_UPDOWN, - SUBPART_PHYSICS_BUTT_UPDOWN, - SUBPART_PHYSICS_BUTT_LEFTRIGHT, - SUBPART_PHYSICS_ADVANCED, - }; +enum ESubpart +{ + SUBPART_SHAPE_HEAD = 1, // avoid 0 + SUBPART_SHAPE_EYES, + SUBPART_SHAPE_EARS, + SUBPART_SHAPE_NOSE, + SUBPART_SHAPE_MOUTH, + SUBPART_SHAPE_CHIN, + SUBPART_SHAPE_TORSO, + SUBPART_SHAPE_LEGS, + SUBPART_SHAPE_WHOLE, + SUBPART_SHAPE_DETAIL, + SUBPART_SKIN_COLOR, + SUBPART_SKIN_FACEDETAIL, + SUBPART_SKIN_MAKEUP, + SUBPART_SKIN_BODYDETAIL, + SUBPART_HAIR_COLOR, + SUBPART_HAIR_STYLE, + SUBPART_HAIR_EYEBROWS, + SUBPART_HAIR_FACIAL, + SUBPART_EYES, + SUBPART_SHIRT, + SUBPART_PANTS, + SUBPART_SHOES, + SUBPART_SOCKS, + SUBPART_JACKET, + SUBPART_GLOVES, + SUBPART_UNDERSHIRT, + SUBPART_UNDERPANTS, + SUBPART_SKIRT, + SUBPART_ALPHA, + SUBPART_TATTOO, + SUBPART_PHYSICS_BREASTS_UPDOWN, + SUBPART_PHYSICS_BREASTS_INOUT, + SUBPART_PHYSICS_BREASTS_LEFTRIGHT, + SUBPART_PHYSICS_BELLY_UPDOWN, + SUBPART_PHYSICS_BUTT_UPDOWN, + SUBPART_PHYSICS_BUTT_LEFTRIGHT, + SUBPART_PHYSICS_ADVANCED, +}; using namespace LLAvatarAppearanceDefines; @@ -115,99 +116,99 @@ typedef std::vector subpart_vec_t; class LLEditWearableDictionary : public LLSingleton { - //-------------------------------------------------------------------- - // Constructors and Destructors - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Constructors and Destructors + //-------------------------------------------------------------------- public: - LLEditWearableDictionary(); - virtual ~LLEditWearableDictionary(); - - //-------------------------------------------------------------------- - // Wearable Types - //-------------------------------------------------------------------- + LLEditWearableDictionary(); + virtual ~LLEditWearableDictionary(); + + //-------------------------------------------------------------------- + // Wearable Types + //-------------------------------------------------------------------- public: - struct WearableEntry : public LLDictionaryEntry - { - WearableEntry(LLWearableType::EType type, - const std::string &title, - U8 num_color_swatches, // number of 'color_swatches' - U8 num_texture_pickers, // number of 'texture_pickers' - U8 num_subparts, ... ); // number of subparts followed by a list of ETextureIndex and ESubparts + struct WearableEntry : public LLDictionaryEntry + { + WearableEntry(LLWearableType::EType type, + const std::string &title, + U8 num_color_swatches, // number of 'color_swatches' + U8 num_texture_pickers, // number of 'texture_pickers' + U8 num_subparts, ... ); // number of subparts followed by a list of ETextureIndex and ESubparts - const LLWearableType::EType mWearableType; - subpart_vec_t mSubparts; - texture_vec_t mColorSwatchCtrls; - texture_vec_t mTextureCtrls; - }; + const LLWearableType::EType mWearableType; + subpart_vec_t mSubparts; + texture_vec_t mColorSwatchCtrls; + texture_vec_t mTextureCtrls; + }; - struct Wearables : public LLDictionary - { - Wearables(); - } mWearables; + struct Wearables : public LLDictionary + { + Wearables(); + } mWearables; - const WearableEntry* getWearable(LLWearableType::EType type) const { return mWearables.lookup(type); } + const WearableEntry* getWearable(LLWearableType::EType type) const { return mWearables.lookup(type); } - //-------------------------------------------------------------------- - // Subparts - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Subparts + //-------------------------------------------------------------------- public: - struct SubpartEntry : public LLDictionaryEntry - { - SubpartEntry(ESubpart part, - const std::string &joint, - const std::string &edit_group, - const std::string &button_name, - const LLVector3d &target_offset, - const LLVector3d &camera_offset, - const ESex &sex); + struct SubpartEntry : public LLDictionaryEntry + { + SubpartEntry(ESubpart part, + const std::string &joint, + const std::string &edit_group, + const std::string &button_name, + const LLVector3d &target_offset, + const LLVector3d &camera_offset, + const ESex &sex); - - ESubpart mSubpart; - std::string mTargetJoint; - std::string mEditGroup; - std::string mButtonName; - LLVector3d mTargetOffset; - LLVector3d mCameraOffset; - ESex mSex; - }; - struct Subparts : public LLDictionary - { - Subparts(); - } mSubparts; + ESubpart mSubpart; + std::string mTargetJoint; + std::string mEditGroup; + std::string mButtonName; + LLVector3d mTargetOffset; + LLVector3d mCameraOffset; + ESex mSex; + }; - const SubpartEntry* getSubpart(ESubpart subpart) const { return mSubparts.lookup(subpart); } + struct Subparts : public LLDictionary + { + Subparts(); + } mSubparts; - //-------------------------------------------------------------------- - // Picker Control Entries - //-------------------------------------------------------------------- + const SubpartEntry* getSubpart(ESubpart subpart) const { return mSubparts.lookup(subpart); } + + //-------------------------------------------------------------------- + // Picker Control Entries + //-------------------------------------------------------------------- public: - struct PickerControlEntry : public LLDictionaryEntry - { - PickerControlEntry(ETextureIndex tex_index, - const std::string name, - const LLUUID default_image_id = LLUUID::null, - const bool allow_no_texture = false - ); - ETextureIndex mTextureIndex; - const std::string mControlName; - const LLUUID mDefaultImageId; - const bool mAllowNoTexture; - }; + struct PickerControlEntry : public LLDictionaryEntry + { + PickerControlEntry(ETextureIndex tex_index, + const std::string name, + const LLUUID default_image_id = LLUUID::null, + const bool allow_no_texture = false + ); + ETextureIndex mTextureIndex; + const std::string mControlName; + const LLUUID mDefaultImageId; + const bool mAllowNoTexture; + }; - struct ColorSwatchCtrls : public LLDictionary - { - ColorSwatchCtrls(); - } mColorSwatchCtrls; + struct ColorSwatchCtrls : public LLDictionary + { + ColorSwatchCtrls(); + } mColorSwatchCtrls; - struct TextureCtrls : public LLDictionary - { - TextureCtrls(); - } mTextureCtrls; + struct TextureCtrls : public LLDictionary + { + TextureCtrls(); + } mTextureCtrls; - const PickerControlEntry* getTexturePicker(ETextureIndex index) const { return mTextureCtrls.lookup(index); } - const PickerControlEntry* getColorSwatch(ETextureIndex index) const { return mColorSwatchCtrls.lookup(index); } + const PickerControlEntry* getTexturePicker(ETextureIndex index) const { return mTextureCtrls.lookup(index); } + const PickerControlEntry* getColorSwatch(ETextureIndex index) const { return mColorSwatchCtrls.lookup(index); } }; LLEditWearableDictionary::LLEditWearableDictionary() @@ -222,55 +223,55 @@ LLEditWearableDictionary::~LLEditWearableDictionary() LLEditWearableDictionary::Wearables::Wearables() { - // note the subpart that is listed first is treated as "default", regardless of what order is in enum. - // Please match the order presented in XUI. -Nyx - // this will affect what camera angle is shown when first editing a wearable - addEntry(LLWearableType::WT_SHAPE, new WearableEntry(LLWearableType::WT_SHAPE,"edit_shape_title",0,0,9, SUBPART_SHAPE_WHOLE, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS)); - addEntry(LLWearableType::WT_SKIN, new WearableEntry(LLWearableType::WT_SKIN,"edit_skin_title",0,3,4, TEX_HEAD_BODYPAINT, TEX_UPPER_BODYPAINT, TEX_LOWER_BODYPAINT, SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL)); - addEntry(LLWearableType::WT_HAIR, new WearableEntry(LLWearableType::WT_HAIR,"edit_hair_title",0,1,4, TEX_HAIR, SUBPART_HAIR_COLOR, SUBPART_HAIR_STYLE, SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL)); - addEntry(LLWearableType::WT_EYES, new WearableEntry(LLWearableType::WT_EYES,"edit_eyes_title",0,1,1, TEX_EYES_IRIS, SUBPART_EYES)); - addEntry(LLWearableType::WT_SHIRT, new WearableEntry(LLWearableType::WT_SHIRT,"edit_shirt_title",1,1,1, TEX_UPPER_SHIRT, TEX_UPPER_SHIRT, SUBPART_SHIRT)); - addEntry(LLWearableType::WT_PANTS, new WearableEntry(LLWearableType::WT_PANTS,"edit_pants_title",1,1,1, TEX_LOWER_PANTS, TEX_LOWER_PANTS, SUBPART_PANTS)); - addEntry(LLWearableType::WT_SHOES, new WearableEntry(LLWearableType::WT_SHOES,"edit_shoes_title",1,1,1, TEX_LOWER_SHOES, TEX_LOWER_SHOES, SUBPART_SHOES)); - addEntry(LLWearableType::WT_SOCKS, new WearableEntry(LLWearableType::WT_SOCKS,"edit_socks_title",1,1,1, TEX_LOWER_SOCKS, TEX_LOWER_SOCKS, SUBPART_SOCKS)); - addEntry(LLWearableType::WT_JACKET, new WearableEntry(LLWearableType::WT_JACKET,"edit_jacket_title",1,2,1, TEX_UPPER_JACKET, TEX_UPPER_JACKET, TEX_LOWER_JACKET, SUBPART_JACKET)); - addEntry(LLWearableType::WT_GLOVES, new WearableEntry(LLWearableType::WT_GLOVES,"edit_gloves_title",1,1,1, TEX_UPPER_GLOVES, TEX_UPPER_GLOVES, SUBPART_GLOVES)); - addEntry(LLWearableType::WT_UNDERSHIRT, new WearableEntry(LLWearableType::WT_UNDERSHIRT,"edit_undershirt_title",1,1,1, TEX_UPPER_UNDERSHIRT, TEX_UPPER_UNDERSHIRT, SUBPART_UNDERSHIRT)); - addEntry(LLWearableType::WT_UNDERPANTS, new WearableEntry(LLWearableType::WT_UNDERPANTS,"edit_underpants_title",1,1,1, TEX_LOWER_UNDERPANTS, TEX_LOWER_UNDERPANTS, SUBPART_UNDERPANTS)); - addEntry(LLWearableType::WT_SKIRT, new WearableEntry(LLWearableType::WT_SKIRT,"edit_skirt_title",1,1,1, TEX_SKIRT, TEX_SKIRT, SUBPART_SKIRT)); - addEntry(LLWearableType::WT_ALPHA, new WearableEntry(LLWearableType::WT_ALPHA,"edit_alpha_title",0,5,1, TEX_LOWER_ALPHA, TEX_UPPER_ALPHA, TEX_HEAD_ALPHA, TEX_EYES_ALPHA, TEX_HAIR_ALPHA, SUBPART_ALPHA)); - addEntry(LLWearableType::WT_TATTOO, new WearableEntry(LLWearableType::WT_TATTOO,"edit_tattoo_title",1,3,1, TEX_HEAD_TATTOO, TEX_LOWER_TATTOO, TEX_UPPER_TATTOO, TEX_HEAD_TATTOO, SUBPART_TATTOO)); - addEntry(LLWearableType::WT_PHYSICS, new WearableEntry(LLWearableType::WT_PHYSICS,"edit_physics_title",0,0,7, SUBPART_PHYSICS_BREASTS_UPDOWN, SUBPART_PHYSICS_BREASTS_INOUT, SUBPART_PHYSICS_BREASTS_LEFTRIGHT, SUBPART_PHYSICS_BELLY_UPDOWN, SUBPART_PHYSICS_BUTT_UPDOWN, SUBPART_PHYSICS_BUTT_LEFTRIGHT, SUBPART_PHYSICS_ADVANCED)); + // note the subpart that is listed first is treated as "default", regardless of what order is in enum. + // Please match the order presented in XUI. -Nyx + // this will affect what camera angle is shown when first editing a wearable + addEntry(LLWearableType::WT_SHAPE, new WearableEntry(LLWearableType::WT_SHAPE,"edit_shape_title",0,0,9, SUBPART_SHAPE_WHOLE, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS)); + addEntry(LLWearableType::WT_SKIN, new WearableEntry(LLWearableType::WT_SKIN,"edit_skin_title",0,3,4, TEX_HEAD_BODYPAINT, TEX_UPPER_BODYPAINT, TEX_LOWER_BODYPAINT, SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL)); + addEntry(LLWearableType::WT_HAIR, new WearableEntry(LLWearableType::WT_HAIR,"edit_hair_title",0,1,4, TEX_HAIR, SUBPART_HAIR_COLOR, SUBPART_HAIR_STYLE, SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL)); + addEntry(LLWearableType::WT_EYES, new WearableEntry(LLWearableType::WT_EYES,"edit_eyes_title",0,1,1, TEX_EYES_IRIS, SUBPART_EYES)); + addEntry(LLWearableType::WT_SHIRT, new WearableEntry(LLWearableType::WT_SHIRT,"edit_shirt_title",1,1,1, TEX_UPPER_SHIRT, TEX_UPPER_SHIRT, SUBPART_SHIRT)); + addEntry(LLWearableType::WT_PANTS, new WearableEntry(LLWearableType::WT_PANTS,"edit_pants_title",1,1,1, TEX_LOWER_PANTS, TEX_LOWER_PANTS, SUBPART_PANTS)); + addEntry(LLWearableType::WT_SHOES, new WearableEntry(LLWearableType::WT_SHOES,"edit_shoes_title",1,1,1, TEX_LOWER_SHOES, TEX_LOWER_SHOES, SUBPART_SHOES)); + addEntry(LLWearableType::WT_SOCKS, new WearableEntry(LLWearableType::WT_SOCKS,"edit_socks_title",1,1,1, TEX_LOWER_SOCKS, TEX_LOWER_SOCKS, SUBPART_SOCKS)); + addEntry(LLWearableType::WT_JACKET, new WearableEntry(LLWearableType::WT_JACKET,"edit_jacket_title",1,2,1, TEX_UPPER_JACKET, TEX_UPPER_JACKET, TEX_LOWER_JACKET, SUBPART_JACKET)); + addEntry(LLWearableType::WT_GLOVES, new WearableEntry(LLWearableType::WT_GLOVES,"edit_gloves_title",1,1,1, TEX_UPPER_GLOVES, TEX_UPPER_GLOVES, SUBPART_GLOVES)); + addEntry(LLWearableType::WT_UNDERSHIRT, new WearableEntry(LLWearableType::WT_UNDERSHIRT,"edit_undershirt_title",1,1,1, TEX_UPPER_UNDERSHIRT, TEX_UPPER_UNDERSHIRT, SUBPART_UNDERSHIRT)); + addEntry(LLWearableType::WT_UNDERPANTS, new WearableEntry(LLWearableType::WT_UNDERPANTS,"edit_underpants_title",1,1,1, TEX_LOWER_UNDERPANTS, TEX_LOWER_UNDERPANTS, SUBPART_UNDERPANTS)); + addEntry(LLWearableType::WT_SKIRT, new WearableEntry(LLWearableType::WT_SKIRT,"edit_skirt_title",1,1,1, TEX_SKIRT, TEX_SKIRT, SUBPART_SKIRT)); + addEntry(LLWearableType::WT_ALPHA, new WearableEntry(LLWearableType::WT_ALPHA,"edit_alpha_title",0,5,1, TEX_LOWER_ALPHA, TEX_UPPER_ALPHA, TEX_HEAD_ALPHA, TEX_EYES_ALPHA, TEX_HAIR_ALPHA, SUBPART_ALPHA)); + addEntry(LLWearableType::WT_TATTOO, new WearableEntry(LLWearableType::WT_TATTOO,"edit_tattoo_title",1,3,1, TEX_HEAD_TATTOO, TEX_LOWER_TATTOO, TEX_UPPER_TATTOO, TEX_HEAD_TATTOO, SUBPART_TATTOO)); + addEntry(LLWearableType::WT_PHYSICS, new WearableEntry(LLWearableType::WT_PHYSICS,"edit_physics_title",0,0,7, SUBPART_PHYSICS_BREASTS_UPDOWN, SUBPART_PHYSICS_BREASTS_INOUT, SUBPART_PHYSICS_BREASTS_LEFTRIGHT, SUBPART_PHYSICS_BELLY_UPDOWN, SUBPART_PHYSICS_BUTT_UPDOWN, SUBPART_PHYSICS_BUTT_LEFTRIGHT, SUBPART_PHYSICS_ADVANCED)); } LLEditWearableDictionary::WearableEntry::WearableEntry(LLWearableType::EType type, - const std::string &title, - U8 num_color_swatches, - U8 num_texture_pickers, - U8 num_subparts, ... ) : - LLDictionaryEntry(title), - mWearableType(type) + const std::string &title, + U8 num_color_swatches, + U8 num_texture_pickers, + U8 num_subparts, ... ) : + LLDictionaryEntry(title), + mWearableType(type) { - va_list argp; - va_start(argp, num_subparts); + va_list argp; + va_start(argp, num_subparts); - for (U8 i = 0; i < num_color_swatches; ++i) - { - ETextureIndex index = (ETextureIndex)va_arg(argp,int); - mColorSwatchCtrls.push_back(index); - } + for (U8 i = 0; i < num_color_swatches; ++i) + { + ETextureIndex index = (ETextureIndex)va_arg(argp,int); + mColorSwatchCtrls.push_back(index); + } - for (U8 i = 0; i < num_texture_pickers; ++i) - { - ETextureIndex index = (ETextureIndex)va_arg(argp,int); - mTextureCtrls.push_back(index); - } + for (U8 i = 0; i < num_texture_pickers; ++i) + { + ETextureIndex index = (ETextureIndex)va_arg(argp,int); + mTextureCtrls.push_back(index); + } - for (U8 i = 0; i < num_subparts; ++i) - { - ESubpart part = (ESubpart)va_arg(argp,int); - mSubparts.push_back(part); - } + for (U8 i = 0; i < num_subparts; ++i) + { + ESubpart part = (ESubpart)va_arg(argp,int); + mSubparts.push_back(part); + } } LLEditWearableDictionary::Subparts::Subparts() @@ -320,73 +321,73 @@ LLEditWearableDictionary::Subparts::Subparts() } LLEditWearableDictionary::SubpartEntry::SubpartEntry(ESubpart part, - const std::string &joint, - const std::string &edit_group, - const std::string &button_name, - const LLVector3d &target_offset, - const LLVector3d &camera_offset, - const ESex &sex) : - LLDictionaryEntry(edit_group), - mSubpart(part), - mTargetJoint(joint), - mEditGroup(edit_group), - mButtonName(button_name), - mTargetOffset(target_offset), - mCameraOffset(camera_offset), - mSex(sex) + const std::string &joint, + const std::string &edit_group, + const std::string &button_name, + const LLVector3d &target_offset, + const LLVector3d &camera_offset, + const ESex &sex) : + LLDictionaryEntry(edit_group), + mSubpart(part), + mTargetJoint(joint), + mEditGroup(edit_group), + mButtonName(button_name), + mTargetOffset(target_offset), + mCameraOffset(camera_offset), + mSex(sex) { } LLEditWearableDictionary::ColorSwatchCtrls::ColorSwatchCtrls() { - addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Color/Tint" )); - addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Color/Tint" )); - addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Color/Tint" )); - addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Color/Tint" )); - addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Color/Tint" )); - addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Color/Tint" )); - addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Color/Tint" )); - addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Color/Tint" )); - addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Color/Tint" )); - addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry(TEX_HEAD_TATTOO, "Color/Tint" )); + addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Color/Tint" )); + addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Color/Tint" )); + addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Color/Tint" )); + addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Color/Tint" )); + addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Color/Tint" )); + addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Color/Tint" )); + addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Color/Tint" )); + addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Color/Tint" )); + addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Color/Tint" )); + addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry(TEX_HEAD_TATTOO, "Color/Tint" )); } LLEditWearableDictionary::TextureCtrls::TextureCtrls() { - addEntry ( TEX_HEAD_BODYPAINT, new PickerControlEntry (TEX_HEAD_BODYPAINT, "Head Tattoos", LLUUID::null, TRUE )); - addEntry ( TEX_UPPER_BODYPAINT, new PickerControlEntry (TEX_UPPER_BODYPAINT, "Upper Tattoos", LLUUID::null, TRUE )); - addEntry ( TEX_LOWER_BODYPAINT, new PickerControlEntry (TEX_LOWER_BODYPAINT, "Lower Tattoos", LLUUID::null, TRUE )); - addEntry ( TEX_HAIR, new PickerControlEntry (TEX_HAIR, "Texture", LLUUID( gSavedSettings.getString( "UIImgDefaultHairUUID" ) ), FALSE )); - addEntry ( TEX_EYES_IRIS, new PickerControlEntry (TEX_EYES_IRIS, "Iris", LLUUID( gSavedSettings.getString( "UIImgDefaultEyesUUID" ) ), FALSE )); - addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShirtUUID" ) ), FALSE )); - addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultPantsUUID" ) ), FALSE )); - addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShoesUUID" ) ), FALSE )); - addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSocksUUID" ) ), FALSE )); - addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Upper Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE )); - addEntry ( TEX_LOWER_JACKET, new PickerControlEntry (TEX_LOWER_JACKET, "Lower Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE )); - addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSkirtUUID" ) ), FALSE )); - addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultGlovesUUID" ) ), FALSE )); - addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE )); - addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE )); - addEntry ( TEX_LOWER_ALPHA, new PickerControlEntry (TEX_LOWER_ALPHA, "Lower Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); - addEntry ( TEX_UPPER_ALPHA, new PickerControlEntry (TEX_UPPER_ALPHA, "Upper Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); - addEntry ( TEX_HEAD_ALPHA, new PickerControlEntry (TEX_HEAD_ALPHA, "Head Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); - addEntry ( TEX_EYES_ALPHA, new PickerControlEntry (TEX_EYES_ALPHA, "Eye Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); - addEntry ( TEX_HAIR_ALPHA, new PickerControlEntry (TEX_HAIR_ALPHA, "Hair Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); - addEntry ( TEX_LOWER_TATTOO, new PickerControlEntry (TEX_LOWER_TATTOO, "Lower Tattoo", LLUUID::null, TRUE )); - addEntry ( TEX_UPPER_TATTOO, new PickerControlEntry (TEX_UPPER_TATTOO, "Upper Tattoo", LLUUID::null, TRUE )); - addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry (TEX_HEAD_TATTOO, "Head Tattoo", LLUUID::null, TRUE )); + addEntry ( TEX_HEAD_BODYPAINT, new PickerControlEntry (TEX_HEAD_BODYPAINT, "Head Tattoos", LLUUID::null, TRUE )); + addEntry ( TEX_UPPER_BODYPAINT, new PickerControlEntry (TEX_UPPER_BODYPAINT, "Upper Tattoos", LLUUID::null, TRUE )); + addEntry ( TEX_LOWER_BODYPAINT, new PickerControlEntry (TEX_LOWER_BODYPAINT, "Lower Tattoos", LLUUID::null, TRUE )); + addEntry ( TEX_HAIR, new PickerControlEntry (TEX_HAIR, "Texture", LLUUID( gSavedSettings.getString( "UIImgDefaultHairUUID" ) ), FALSE )); + addEntry ( TEX_EYES_IRIS, new PickerControlEntry (TEX_EYES_IRIS, "Iris", LLUUID( gSavedSettings.getString( "UIImgDefaultEyesUUID" ) ), FALSE )); + addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShirtUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultPantsUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShoesUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSocksUUID" ) ), FALSE )); + addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Upper Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_JACKET, new PickerControlEntry (TEX_LOWER_JACKET, "Lower Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE )); + addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSkirtUUID" ) ), FALSE )); + addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultGlovesUUID" ) ), FALSE )); + addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_ALPHA, new PickerControlEntry (TEX_LOWER_ALPHA, "Lower Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_UPPER_ALPHA, new PickerControlEntry (TEX_UPPER_ALPHA, "Upper Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_HEAD_ALPHA, new PickerControlEntry (TEX_HEAD_ALPHA, "Head Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_EYES_ALPHA, new PickerControlEntry (TEX_EYES_ALPHA, "Eye Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_HAIR_ALPHA, new PickerControlEntry (TEX_HAIR_ALPHA, "Hair Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_LOWER_TATTOO, new PickerControlEntry (TEX_LOWER_TATTOO, "Lower Tattoo", LLUUID::null, TRUE )); + addEntry ( TEX_UPPER_TATTOO, new PickerControlEntry (TEX_UPPER_TATTOO, "Upper Tattoo", LLUUID::null, TRUE )); + addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry (TEX_HEAD_TATTOO, "Head Tattoo", LLUUID::null, TRUE )); } LLEditWearableDictionary::PickerControlEntry::PickerControlEntry(ETextureIndex tex_index, - const std::string name, - const LLUUID default_image_id, - const bool allow_no_texture) : - LLDictionaryEntry(name), - mTextureIndex(tex_index), - mControlName(name), - mDefaultImageId(default_image_id), - mAllowNoTexture(allow_no_texture) + const std::string name, + const LLUUID default_image_id, + const bool allow_no_texture) : + LLDictionaryEntry(name), + mTextureIndex(tex_index), + mControlName(name), + mDefaultImageId(default_image_id), + mAllowNoTexture(allow_no_texture) { } @@ -408,13 +409,13 @@ typedef boost::functionmName == mName); - } -private: - const std::string mName; + PickerControlEntryNamePredicate(const std::string name) : mName (name) {}; + bool operator()(const LLEditWearableDictionary::PickerControlEntry* entry) const + { + return (entry && entry->mName == mName); + } + private: + const std::string mName; } PickerControlEntryNamePredicate; // A full specialization of get_pickers_indexes for LLColorSwatchCtrl @@ -422,12 +423,12 @@ template <> const texture_vec_t& get_pickers_indexes (const LLEditWearableDictionary::WearableEntry *wearable_entry) { - if (!wearable_entry) - { - llwarns << "could not get LLColorSwatchCtrl indexes for null wearable entry." << llendl; - return null_texture_vec; - } - return wearable_entry->mColorSwatchCtrls; + if (!wearable_entry) + { + llwarns << "could not get LLColorSwatchCtrl indexes for null wearable entry." << llendl; + return null_texture_vec; + } + return wearable_entry->mColorSwatchCtrls; } // A full specialization of get_pickers_indexes for LLTextureCtrl @@ -435,12 +436,12 @@ template <> const texture_vec_t& get_pickers_indexes (const LLEditWearableDictionary::WearableEntry *wearable_entry) { - if (!wearable_entry) - { - llwarns << "could not get LLTextureCtrl indexes for null wearable entry." << llendl; - return null_texture_vec; - } - return wearable_entry->mTextureCtrls; + if (!wearable_entry) + { + llwarns << "could not get LLTextureCtrl indexes for null wearable entry." << llendl; + return null_texture_vec; + } + return wearable_entry->mTextureCtrls; } // A full specialization of get_picker_entry for LLColorSwatchCtrl @@ -448,7 +449,7 @@ template <> const LLEditWearableDictionary::PickerControlEntry* get_picker_entry (const ETextureIndex index) { - return LLEditWearableDictionary::getInstance()->getColorSwatch(index); + return LLEditWearableDictionary::getInstance()->getColorSwatch(index); } // A full specialization of get_picker_entry for LLTextureCtrl @@ -456,154 +457,150 @@ template <> const LLEditWearableDictionary::PickerControlEntry* get_picker_entry (const ETextureIndex index) { - return LLEditWearableDictionary::getInstance()->getTexturePicker(index); + return LLEditWearableDictionary::getInstance()->getTexturePicker(index); } template const LLEditWearableDictionary::PickerControlEntry* find_picker_ctrl_entry_if(LLWearableType::EType type, const Predicate pred) { - const LLEditWearableDictionary::WearableEntry *wearable_entry - = LLEditWearableDictionary::getInstance()->getWearable(type); - if (!wearable_entry) - { - llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl; - return NULL; - } - const texture_vec_t& indexes = get_pickers_indexes(wearable_entry); - for (texture_vec_t::const_iterator - iter = indexes.begin(), - iter_end = indexes.end(); - iter != iter_end; ++iter) - { - const ETextureIndex te = *iter; - const LLEditWearableDictionary::PickerControlEntry* entry - = get_picker_entry(te); - if (!entry) - { - llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl; - continue; - } - if (pred(entry)) - { - return entry; - } - } - return NULL; + const LLEditWearableDictionary::WearableEntry *wearable_entry + = LLEditWearableDictionary::getInstance()->getWearable(type); + if (!wearable_entry) + { + llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl; + return NULL; + } + const texture_vec_t& indexes = get_pickers_indexes(wearable_entry); + for (texture_vec_t::const_iterator + iter = indexes.begin(), + iter_end = indexes.end(); + iter != iter_end; ++iter) + { + const ETextureIndex te = *iter; + const LLEditWearableDictionary::PickerControlEntry* entry = get_picker_entry(te); + if (!entry) + { + llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl; + continue; + } + if (pred(entry)) + { + return entry; + } + } + return NULL; } template -void -for_each_picker_ctrl_entry(LLPanel* panel, LLWearableType::EType type, function_t fun) +void for_each_picker_ctrl_entry(LLPanel* panel, LLWearableType::EType type, function_t fun) { - if (!panel) - { - llwarns << "the panel wasn't passed for wearable of type: " << type << llendl; - return; - } - const LLEditWearableDictionary::WearableEntry *wearable_entry - = LLEditWearableDictionary::getInstance()->getWearable(type); - if (!wearable_entry) - { - llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl; - return; - } - const texture_vec_t& indexes = get_pickers_indexes(wearable_entry); - for (texture_vec_t::const_iterator - iter = indexes.begin(), - iter_end = indexes.end(); - iter != iter_end; ++iter) - { - const ETextureIndex te = *iter; - const LLEditWearableDictionary::PickerControlEntry* entry - = get_picker_entry(te); - if (!entry) - { - llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl; - continue; - } - fun (panel, entry); - } + if (!panel) + { + llwarns << "the panel wasn't passed for wearable of type: " << type << llendl; + return; + } + const LLEditWearableDictionary::WearableEntry* wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type); + if (!wearable_entry) + { + llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl; + return; + } + const texture_vec_t& indexes = get_pickers_indexes(wearable_entry); + for (texture_vec_t::const_iterator + iter = indexes.begin(), + iter_end = indexes.end(); + iter != iter_end; ++iter) + { + const ETextureIndex te = *iter; + const LLEditWearableDictionary::PickerControlEntry* entry = get_picker_entry(te); + if (!entry) + { + llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl; + continue; + } + fun (panel, entry); + } } // The helper functions for pickers management static void init_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) { - LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild(entry->mControlName); - if (color_swatch_ctrl) - { - color_swatch_ctrl->setCommitCallback(boost::bind(&LLPanelEditWearable::onColorSwatchCommit, self, _1)); - // Can't get the color from the wearable here, since the wearable may not be set when this is called. - color_swatch_ctrl->setOriginal(LLColor4::white); - } + LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild(entry->mControlName); + if (color_swatch_ctrl) + { + color_swatch_ctrl->setCommitCallback(boost::bind(&LLPanelEditWearable::onColorSwatchCommit, self, _1)); + // Can't get the color from the wearable here, since the wearable may not be set when this is called. + color_swatch_ctrl->setOriginal(LLColor4::white); + } } static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) { - LLTextureCtrl* texture_ctrl = panel->getChild(entry->mControlName); - if (texture_ctrl) - { - texture_ctrl->setCommitCallback(boost::bind(&LLPanelEditWearable::onTexturePickerCommit, self, _1)); - texture_ctrl->setDefaultImageAssetID(entry->mDefaultImageId); - texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture); - // Don't allow (no copy) or (notransfer) textures to be selected. - texture_ctrl->setImmediateFilterPermMask(PERM_NONE);//PERM_COPY | PERM_TRANSFER); - texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);//PERM_COPY | PERM_TRANSFER); - } + LLTextureCtrl* texture_ctrl = panel->getChild(entry->mControlName); + if (texture_ctrl) + { + texture_ctrl->setCommitCallback(boost::bind(&LLPanelEditWearable::onTexturePickerCommit, self, _1)); + texture_ctrl->setDefaultImageAssetID(entry->mDefaultImageId); + texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture); + // Don't allow (no copy) or (notransfer) textures to be selected. + texture_ctrl->setImmediateFilterPermMask(PERM_NONE);//PERM_COPY | PERM_TRANSFER); + texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);//PERM_COPY | PERM_TRANSFER); + } } static void update_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) { - LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild(entry->mControlName); - if (color_swatch_ctrl) - { - color_swatch_ctrl->set(self->getWearable()->getClothesColor(entry->mTextureIndex)); - } + LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild(entry->mControlName); + if (color_swatch_ctrl) + { + color_swatch_ctrl->set(self->getWearable()->getClothesColor(entry->mTextureIndex)); + } } static void update_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) { - LLTextureCtrl* texture_ctrl = panel->getChild(entry->mControlName); - if (texture_ctrl) - { - LLUUID new_id; - LLLocalTextureObject *lto = self->getWearable()->getLocalTextureObject(entry->mTextureIndex); - if( lto && (lto->getID() != IMG_DEFAULT_AVATAR) ) - { - new_id = lto->getID(); - } - else - { - new_id = LLUUID::null; - } - LLUUID old_id = texture_ctrl->getImageAssetID(); - if (old_id != new_id) - { - // texture has changed, close the floater to avoid DEV-22461 - texture_ctrl->closeFloater(); - } - texture_ctrl->setImageAssetID(new_id); - } + LLTextureCtrl* texture_ctrl = panel->getChild(entry->mControlName); + if (texture_ctrl) + { + LLUUID new_id; + LLLocalTextureObject *lto = self->getWearable()->getLocalTextureObject(entry->mTextureIndex); + if (lto && (lto->getID() != IMG_DEFAULT_AVATAR)) + { + new_id = lto->getID(); + } + else + { + new_id = LLUUID::null; + } + LLUUID old_id = texture_ctrl->getImageAssetID(); + if (old_id != new_id) + { + // texture has changed, close the floater to avoid DEV-22461 + texture_ctrl->closeFloater(); + } + texture_ctrl->setImageAssetID(new_id); + } } static void set_enabled_color_swatch_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) { - LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild(entry->mControlName); - if (color_swatch_ctrl) - { - color_swatch_ctrl->setEnabled(enabled); - color_swatch_ctrl->setVisible(enabled); - } + LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild(entry->mControlName); + if (color_swatch_ctrl) + { + color_swatch_ctrl->setEnabled(enabled); + color_swatch_ctrl->setVisible(enabled); + } } static void set_enabled_texture_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) { - LLTextureCtrl* texture_ctrl = panel->getChild(entry->mControlName); - if (texture_ctrl) - { - texture_ctrl->setEnabled(enabled); - texture_ctrl->setVisible(enabled); - } + LLTextureCtrl* texture_ctrl = panel->getChild(entry->mControlName); + if (texture_ctrl) + { + texture_ctrl->setEnabled(enabled); + texture_ctrl->setVisible(enabled); + } } class LLWearableSaveAsDialog : public LLModalDialog @@ -620,11 +617,11 @@ public: mParent( parent ) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_wearable_save_as.xml"); - - childSetAction("Save", boost::bind(&LLWearableSaveAsDialog::onSave, this) ); - childSetAction("Cancel", boost::bind(&LLWearableSaveAsDialog::onCancel, this) ); - childSetTextArg("name ed", "[DESC]", desc); + getChild("Save")->setCommitCallback(boost::bind(&LLWearableSaveAsDialog::onSave, this) ); + getChild("Cancel")->setCommitCallback(boost::bind(&LLWearableSaveAsDialog::onCancel, this) ); + + getChild("name ed")->setTextArg("[DESC]", desc); } ~LLWearableSaveAsDialog() { @@ -644,7 +641,7 @@ public: void onSave() { - mItemName = childGetValue("name ed").asString(); + mItemName = getChildView("name ed")->getValue().asString(); LLStringUtil::trim(mItemName); if( !mItemName.empty() ) { @@ -671,7 +668,8 @@ LLPanelEditWearable::LLPanelEditWearable( LLWearableType::EType type, LLFloaterC mCurrentWearable( NULL ), mPendingWearable( NULL ), mPendingRefresh( false ), - mCustomizeFloater( parent ) + mCustomizeFloater( parent ), + mSubpartBtns() { } LLPanelEditWearable::~LLPanelEditWearable() @@ -686,28 +684,43 @@ BOOL LLPanelEditWearable::postBuild() { std::string icon_name = LLInventoryIcon::getIconName(LLWearableType::getAssetType( mType ),LLInventoryType::IT_WEARABLE,mType,FALSE); - childSetValue("icon", icon_name); + getChildView("icon")->setValue(icon_name); - childSetAction("Create New", boost::bind(&LLPanelEditWearable::onBtnCreateNew, this) ); + mCreateNew = getChild("Create New"); + mCreateNew->setCommitCallback(boost::bind(&LLPanelEditWearable::onBtnCreateNew, this) ); + mTakeOff = getChild("Take Off"); // If PG, can't take off underclothing or shirt mCanTakeOff = LLWearableType::getAssetType( mType ) == LLAssetType::AT_CLOTHING && !( gAgent.isTeen() && (mType == LLWearableType::WT_UNDERSHIRT || mType == LLWearableType::WT_UNDERPANTS) ); - childSetVisible("Take Off", mCanTakeOff); - childSetAction("Take Off", boost::bind(&LLPanelEditWearable::onBtnTakeOff, this) ); + mTakeOff->setVisible(mCanTakeOff); + mTakeOff->setCommitCallback(boost::bind(&LLPanelEditWearable::onBtnTakeOff, this) ); - LLUICtrl* sex_radio = getChild("sex radio", true, false); - if(sex_radio) + if (mSexRadio = findChild("sex radio")) { - sex_radio->setCommitCallback(boost::bind(&LLPanelEditWearable::onCommitSexChange,this) ); + mSexRadio->setCommitCallback(boost::bind(&LLPanelEditWearable::onCommitSexChange, this)); } - childSetAction("Save", boost::bind(&LLPanelEditWearable::saveChanges, this, false, std::string()) ); + mSave = getChild("Save"); + mSave->setCommitCallback(boost::bind(&LLPanelEditWearable::saveChanges, this, false, std::string()) ); - childSetAction("Save As", boost::bind(&LLPanelEditWearable::onBtnSaveAs, this) ); + mSaveAs = getChild("Save As"); + mSaveAs->setCommitCallback(boost::bind(&LLPanelEditWearable::onBtnSaveAs, this) ); - childSetAction("Revert", boost::bind(&LLPanelEditWearable::revertChanges, this) ); + mRevert = getChild("Revert"); + mRevert->setCommitCallback(boost::bind(&LLPanelEditWearable::revertChanges, this) ); + + // Cache other UI for later + mNotWornI = getChildView("not worn instructions"); + mNoModI = getChildView("no modify instructions"); + mNotWornT = getChild("title_not_worn"); + mNoModT = getChild("title_no_modify"); + mTitle = getChild("title"); + mTitleLoading = getChild("title_loading"); + mPath = getChild("path"); + mSquare = getChildView("square"); + mAvHeight = getChild("avheight", false, false); configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible"); configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible"); @@ -719,10 +732,10 @@ BOOL LLPanelEditWearable::postBuild() const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(mType); if (!wearable_entry) { - llwarns << "could not get wearable dictionary entry for wearable of type: " << mType << llendl; + llwarns << "could not get wearable dictionary entry for wearable of type: " << mType << llendl; } U8 num_subparts = wearable_entry->mSubparts.size(); - + for (U8 index = 0; index < num_subparts; ++index) { // dive into data structures to get the panel we need @@ -731,38 +744,45 @@ BOOL LLPanelEditWearable::postBuild() if (!subpart_entry) { - llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; - continue; + llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; + mSubpartBtns.push_back(NULL); + continue; } - if(!subpart_entry->mButtonName.empty()) + if (!subpart_entry->mButtonName.empty()) { llinfos << "Finding button " << subpart_entry->mButtonName << llendl; - llassert_always(getChild(subpart_entry->mButtonName,true,false)); - childSetAction(subpart_entry->mButtonName, boost::bind(&LLPanelEditWearable::changeCamera, this, index)); + LLButton* btn(findChild(subpart_entry->mButtonName)); + llassert_always(btn); + mSubpartBtns.push_back(btn); + btn->setCommitCallback(boost::bind(&LLPanelEditWearable::changeCamera, this, index)); } - } + else + { + mSubpartBtns.push_back(NULL); + llwarns << "could not get wearable subpart button for subpart num: " << subpart_e << llendl; + } + } // initialize texture and color picker controls for_each_picker_ctrl_entry (this, mType, boost::bind(init_color_swatch_ctrl, this, _1, _2)); for_each_picker_ctrl_entry (this, mType, boost::bind(init_texture_ctrl, this, _1, _2)); } - LLTabContainer* tab = getChild("layer_tabs", true, false); - if(tab) + if (mTab = findChild("layer_tabs")) { for(U32 i = 1; i <= LLAgentWearables::MAX_CLOTHING_PER_TYPE; ++i) { LLPanel* new_panel = new LLPanel(llformat("%i",i)); - tab->addTabPanel(new_panel, llformat("Layer %i",i)); + mTab->addTabPanel(new_panel, llformat("Layer %i",i)); } - tab->setCommitCallback(boost::bind(&LLPanelEditWearable::onTabChanged, this, _1)); - tab->setValidateCallback(boost::bind(&LLPanelEditWearable::onTabPrecommit, this)); + mTab->setCommitCallback(boost::bind(&LLPanelEditWearable::onTabChanged, this, _1)); + mTab->setValidateCallback(boost::bind(&LLPanelEditWearable::onTabPrecommit, this)); } - childSetTextArg("title_not_worn", "[DESC]", LLWearableType::getTypeLabel( mType )); - childSetTextArg("title_loading", "[DESC]", LLWearableType::getTypeLabel( mType )); - childSetTextArg("title_no_modify", "[DESC]", LLWearableType::getTypeLabel( mType )); - childSetTextArg("title", "[DESC]", LLWearableType::getTypeLabel( mType )); + mNotWornT->setTextArg("[DESC]", LLWearableType::getTypeLabel(mType)); + mTitleLoading->setTextArg("[DESC]", LLWearableType::getTypeLabel(mType)); + mNoModT->setTextArg("[DESC]", LLWearableType::getTypeLabel(mType)); + mTitle->setTextArg("[DESC]", LLWearableType::getTypeLabel(mType)); return TRUE; } @@ -774,7 +794,7 @@ BOOL LLPanelEditWearable::isDirty() const void LLPanelEditWearable::draw() { - if( mCustomizeFloater->isMinimized() || !isAgentAvatarValid()) + if (mCustomizeFloater->isMinimized() || !isAgentAvatarValid()) return; refreshWearables(false); @@ -787,7 +807,7 @@ void LLPanelEditWearable::draw() BOOL is_copyable = FALSE; BOOL is_complete = FALSE; LLInventoryItem* item = NULL; - if(wearable && (item = gInventory.getItem(wearable->getItemID()))) + if (wearable && (item = gInventory.getItem(wearable->getItemID()))) { const LLPermissions& perm = item->getPermissions(); is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID()); @@ -795,40 +815,32 @@ void LLPanelEditWearable::draw() is_complete = ((LLViewerInventoryItem*)item)->isComplete(); } - childSetEnabled("Save", has_wearable && is_modifiable && is_complete && is_dirty); - childSetEnabled("Save As", has_wearable && is_copyable && is_complete); - childSetEnabled("Revert", has_wearable && is_dirty ); - childSetEnabled("Take Off", has_wearable); - childSetVisible("Take Off", has_wearable && mCanTakeOff); - childSetVisible("Create New", !has_any_wearable); - childSetVisible("not worn instructions", !has_any_wearable); - childSetVisible("title_not_worn", !has_any_wearable); - childSetVisible("no modify instructions",has_wearable && !is_modifiable); - childSetVisible("title_no_modify", has_wearable && !is_modifiable); - childSetVisible("title", has_wearable && is_modifiable && is_complete); - childSetVisible("title_loading", (!has_wearable && has_any_wearable) || (has_wearable && is_modifiable && !is_complete)); - childSetVisible("path", has_wearable); - childSetVisible("square", has_wearable && !is_modifiable); //lock icon + mSave->setEnabled(has_wearable && is_modifiable && is_complete && is_dirty); + mSaveAs->setEnabled(has_wearable && is_copyable && is_complete); + mRevert->setEnabled(has_wearable && is_dirty ); + mTakeOff->setEnabled(has_wearable); + if (mCanTakeOff) mTakeOff->setVisible(has_wearable); + mCreateNew->setVisible(!has_any_wearable); + mNotWornI->setVisible(!has_any_wearable); + mNotWornT->setVisible(!has_any_wearable); + mNoModI->setVisible(has_wearable && !is_modifiable); + mNoModT->setVisible(has_wearable && !is_modifiable); + mTitle->setVisible(has_wearable && is_modifiable && is_complete); + mTitleLoading->setVisible(has_wearable ? is_modifiable && !is_complete : has_any_wearable); + mPath->setVisible(has_wearable); + mSquare->setVisible(has_wearable && !is_modifiable); //lock icon - /*LLTabContainer* tab = getChild("layer_tabs", true, false); - if(tab) - { - tab->setEnabled(has_any_wearable); - tab->setVisible(has_any_wearable); - }*/ - - if(has_wearable && is_modifiable) + if (has_wearable && is_modifiable) { for_each_picker_ctrl_entry (this, mType, boost::bind(update_color_swatch_ctrl, this, _1, _2)); for_each_picker_ctrl_entry (this, mType, boost::bind(update_texture_ctrl, this, _1, _2)); for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_color_swatch_ctrl, is_complete, _1, _2)); - for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_texture_ctrl, is_complete, _1, _2)); - for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); - iter != mAlphaCheckbox2Index.end(); ++iter ) - { - LLCheckBoxCtrl* ctrl = getChild(iter->first, true, false); - if (ctrl) - { + for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_texture_ctrl, is_complete, _1, _2)); + for(ctrl_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); + iter != mAlphaCheckbox2Index.end(); ++iter) + { + if (LLUICtrl* ctrl = iter->first) + { ctrl->setEnabled(is_copyable && is_complete); ctrl->setVisible(is_copyable && is_complete); } @@ -845,31 +857,34 @@ void LLPanelEditWearable::draw() U8 num_subparts = wearable_entry->mSubparts.size(); for (U8 index = 0; index < num_subparts; ++index) - { + { // dive into data structures to get the panel we need ESubpart subpart_e = wearable_entry->mSubparts[index]; const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); - - if (!subpart_entry) - { - llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; - continue; - } - childSetVisible(subpart_entry->mButtonName,has_wearable); - if( has_wearable && is_complete && is_modifiable ) + if (!subpart_entry) { - childSetEnabled(subpart_entry->mButtonName, subpart_entry->mSex & gAgentAvatarp->getSex() ); + llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; + continue; + } + + if (index >= mSubpartBtns.size()) continue; + LLButton* child = mSubpartBtns[index]; + if (!child) continue; + + child->setVisible(has_wearable); + if (has_wearable && is_complete && is_modifiable) + { + child->setEnabled(subpart_entry->mSex & gAgentAvatarp->getSex()); } else { - childSetEnabled(subpart_entry->mButtonName, FALSE ); + child->setEnabled(false); } } } - LLTextBox *av_height = getChild("avheight",FALSE,FALSE); - if(av_height) //Only display this if the element exists + if (mAvHeight) //Only display this if the element exists { // Display the shape's nominal height. // @@ -883,8 +898,8 @@ void LLPanelEditWearable::draw() std::ostringstream avheight(std::ostringstream::trunc); avheight << std::fixed << std::setprecision(2) << avsize << " m (" << feet << "' " << inches << "\")"; - av_height->setVisible(TRUE); - av_height->setTextArg("[AVHEIGHT]",avheight.str()); + mAvHeight->setVisible(TRUE); + mAvHeight->setTextArg("[AVHEIGHT]",avheight.str()); } LLPanel::draw(); @@ -893,7 +908,7 @@ void LLPanelEditWearable::draw() void LLPanelEditWearable::setVisible(BOOL visible) { LLPanel::setVisible( visible ); - if( !visible ) + if (!visible) { for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_color_swatch_ctrl, FALSE, _1, _2)); } @@ -901,11 +916,11 @@ void LLPanelEditWearable::setVisible(BOOL visible) void LLPanelEditWearable::onTabChanged(LLUICtrl* ctrl) { - if(mPendingWearable) + if (mPendingWearable) return; U32 tab_index = ((LLTabContainer*)ctrl)->getCurrentPanelIndex(); U32 wearable_index = gAgentWearables.getWearableCount(mType) - tab_index - 1; - if(wearable_index != mCurrentIndex ) + if (wearable_index != mCurrentIndex ) { setWearableIndex(wearable_index); } @@ -918,35 +933,34 @@ bool LLPanelEditWearable::onTabPrecommit() void LLPanelEditWearable::setWearableIndex(S32 index) { - if(mPendingWearable) + if (mPendingWearable) return; mCurrentIndex = index; - LLTabContainer* tab = getChild("layer_tabs", true, false); - if(tab) + if (mTab) { U32 tab_index = gAgentWearables.getWearableCount(mType) - index - 1; - if(tab->getCurrentPanelIndex() != tab_index) - tab->selectTab(tab_index); - } + if (mTab->getCurrentPanelIndex() != tab_index) + mTab->selectTab(tab_index); + } LLViewerWearable* wearable = gAgentWearables.getViewerWearable(mType,mCurrentIndex); // Singu note: Set title even if the wearable didn't change: the name might have changed (when renamed). - if(wearable) + if (wearable) { - childSetTextArg("title", "[DESC]", wearable->getName() ); - childSetTextArg("title_no_modify", "[DESC]", wearable->getName()); + mTitle->setTextArg("[DESC]", wearable->getName()); + mNoModT->setTextArg("[DESC]", wearable->getName()); } else { - childSetTextArg("title", "[DESC]", std::string(LLWearableType::getTypeLabel( mType )) ); - childSetTextArg("title_no_modify", "[DESC]", std::string(LLWearableType::getTypeLabel( mType ))); + mTitle->setTextArg("[DESC]", std::string(LLWearableType::getTypeLabel(mType))); + mNoModT->setTextArg("[DESC]", std::string(LLWearableType::getTypeLabel(mType))); } - if(wearable == getWearable()) + if (wearable == getWearable()) return; mCurrentWearable = wearable; @@ -964,19 +978,19 @@ void LLPanelEditWearable::setWearableIndex(S32 index) } const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart((ESubpart)mCurrentSubpart); - if(subpart_entry) + if (subpart_entry) { value_map_t sorted_params; getSortedParams(sorted_params, subpart_entry->mEditGroup, editable); buildParamList(mCustomizeFloater->getScrollingPanelList(), sorted_params); } - if(wearable) + if (wearable) { std::string path; const LLUUID& item_id = wearable->getItemID(); append_path(item_id, path); - childSetTextArg("path", "[PATH]", path); + mPath->setTextArg("[PATH]", path); } updateScrollingPanelList(); @@ -985,38 +999,35 @@ void LLPanelEditWearable::setWearableIndex(S32 index) void LLPanelEditWearable::refreshWearables(bool force_immediate) { - if(!force_immediate && !mPendingRefresh) + if (!force_immediate && !mPendingRefresh) return; mPendingRefresh = false; U32 index; - if(mPendingWearable) + if (mPendingWearable) { index = gAgentWearables.getWearableIndex(mPendingWearable); - if(index == LLAgentWearables::MAX_CLOTHING_PER_TYPE) + if (index == LLAgentWearables::MAX_CLOTHING_PER_TYPE) return; mPendingWearable = NULL; } else { index = gAgentWearables.getWearableIndex(getWearable()); - if(index == LLAgentWearables::MAX_CLOTHING_PER_TYPE) + if (index == LLAgentWearables::MAX_CLOTHING_PER_TYPE) { index = gAgentWearables.getWearableCount(mType); - if(index) + if (index) --index; } } - - - LLTabContainer* tab = getChild("layer_tabs", true, false); - if(tab) + if (mTab) { for(U32 i = 0; i < LLAgentWearables::MAX_CLOTHING_PER_TYPE; ++i) { - tab->enableTabButton(i, i < gAgentWearables.getWearableCount(mType)); + mTab->enableTabButton(i, i < gAgentWearables.getWearableCount(mType)); } } setWearableIndex(index); @@ -1029,10 +1040,10 @@ void LLPanelEditWearable::wearablesChanged() void LLPanelEditWearable::onBtnSaveAs() { - if(mActiveModal) + if (mActiveModal) return; LLViewerWearable* wearable = getWearable(); - if( wearable ) + if (wearable) { mActiveModal = new LLWearableSaveAsDialog( wearable->getName(), this, boost::bind(&LLPanelEditWearable::onSaveAsCommit, this, _1)); mActiveModal->startModal(); @@ -1050,48 +1061,32 @@ void LLPanelEditWearable::onCommitSexChange() if (!isAgentAvatarValid()) return; LLWearableType::EType type = mType; // TODO: MULTI-WEARABLE - U32 index = mCurrentIndex; // TODO: MULTI-WEARABLE + U32 index = mCurrentIndex; // TODO: MULTI-WEARABLE - if( !gAgentWearables.isWearableModifiable(type, index)) - { + if (!gAgentWearables.isWearableModifiable(type, index)) + { return; - } + } LLViewerVisualParam* param = static_cast(gAgentAvatarp->getVisualParam( "male" )); - if( !param ) + if (!param) { return; } bool is_new_sex_male = (gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE) == SEX_MALE; - LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, index); + LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, index); if (wearable) { wearable->setVisualParamWeight(param->getID(), is_new_sex_male, FALSE); } - param->setWeight( is_new_sex_male, FALSE ); - + param->setWeight( is_new_sex_male, FALSE ); + gAgentAvatarp->updateSexDependentLayerSets( FALSE ); gAgentAvatarp->updateVisualParams(); updateScrollingPanelUI(); - - //if(!wearable) - //{ - // return; - //} - - - - //wearable->setVisualParamWeight(param->getID(), (new_sex == SEX_MALE), TRUE); - //wearable->writeToAvatar(); - //avatar->updateVisualParams(); - -// gFloaterCustomize->clearScrollingPanelList(); - - // Assumes that we're in the "Shape" Panel. - //self->setSubpart( SUBPART_SHAPE_WHOLE ); } void LLPanelEditWearable::onBtnCreateNew() @@ -1105,7 +1100,7 @@ bool LLPanelEditWearable::onSelectAutoWearOption(const LLSD& notification, const { S32 option = LLNotification::getSelectedOption(notification, response); LLVOAvatar* avatar = gAgentAvatarp; - if(avatar) + if (avatar) { // Create a new wearable in the default folder for the wearable's asset type. LLViewerWearable* wearable = LLWearableList::instance().createNewWearable( (LLWearableType::EType)notification["payload"]["wearable_type"].asInteger(), avatar ); @@ -1165,22 +1160,22 @@ void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl) void LLPanelEditWearable::setNewImageID(ETextureIndex te_index, LLUUID const& uuid) { - LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid); - if( image->getID() == IMG_DEFAULT ) - { - image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); - } - if (getWearable()) - { - U32 index = gAgentWearables.getWearableIndex(getWearable()); - gAgentAvatarp->setLocalTexture(te_index, image, FALSE, index); - LLVisualParamHint::requestHintUpdates(); - gAgentAvatarp->wearableUpdated(mType, FALSE); - } - if (mType == LLWearableType::WT_ALPHA && image->getID() != IMG_INVISIBLE) - { - mPreviousAlphaTexture[te_index] = image->getID(); - } + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid); + if (image->getID() == IMG_DEFAULT) + { + image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); + } + if (getWearable()) + { + U32 index = gAgentWearables.getWearableIndex(getWearable()); + gAgentAvatarp->setLocalTexture(te_index, image, FALSE, index); + LLVisualParamHint::requestHintUpdates(); + gAgentAvatarp->wearableUpdated(mType, FALSE); + } + if (mType == LLWearableType::WT_ALPHA && image->getID() != IMG_INVISIBLE) + { + mPreviousAlphaTexture[te_index] = image->getID(); + } } void LLPanelEditWearable::onColorSwatchCommit(const LLUICtrl* base_ctrl ) @@ -1191,22 +1186,21 @@ void LLPanelEditWearable::onColorSwatchCommit(const LLUICtrl* base_ctrl ) { LLWearableType::EType type = getWearable()->getType(); const PickerControlEntryNamePredicate name_pred(ctrl->getName()); - const LLEditWearableDictionary::PickerControlEntry* entry - = find_picker_ctrl_entry_if(type, name_pred); + const LLEditWearableDictionary::PickerControlEntry* entry = find_picker_ctrl_entry_if(type, name_pred); if (entry) { - const LLColor4& old_color = getWearable()->getClothesColor(entry->mTextureIndex); - const LLColor4& new_color = LLColor4(ctrl->getValue()); - if( old_color != new_color ) - { - getWearable()->setClothesColor(entry->mTextureIndex, new_color, TRUE); - LLVisualParamHint::requestHintUpdates(); - gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE); - } + const LLColor4& old_color = getWearable()->getClothesColor(entry->mTextureIndex); + const LLColor4& new_color = LLColor4(ctrl->getValue()); + if (old_color != new_color) + { + getWearable()->setClothesColor(entry->mTextureIndex, new_color, TRUE); + LLVisualParamHint::requestHintUpdates(); + gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE); + } } else { - llwarns << "could not get color swatch dictionary entry for wearable of type: " << type << llendl; + llwarns << "could not get color swatch dictionary entry for wearable of type: " << type << llendl; } } } @@ -1216,12 +1210,11 @@ void LLPanelEditWearable::hideTextureControls() { for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_texture_ctrl, FALSE, _1, _2)); for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_color_swatch_ctrl, FALSE, _1, _2)); - for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); + for(ctrl_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); iter != mAlphaCheckbox2Index.end(); ++iter ) { - LLCheckBoxCtrl* ctrl = getChild(iter->first, true, false); - if (ctrl) - { + if (LLUICtrl* ctrl = iter->first) + { ctrl->setEnabled(FALSE); ctrl->setVisible(FALSE); } @@ -1232,18 +1225,17 @@ void LLPanelEditWearable::saveChanges(bool force_save_as, std::string new_name) { if (!getWearable() || (!force_save_as && !isDirty())) { - // do nothing if no unsaved changes - return; + // do nothing if no unsaved changes + return; } U32 index = gAgentWearables.getWearableIndex(getWearable()); - // Find an existing link to this wearable's inventory item, if any, and its description field. LLInventoryItem *link_item = NULL; std::string description; - if(gAgentAvatarp->isUsingServerBakes()) + if (gAgentAvatarp->isUsingServerBakes()) { LLInventoryModel::item_array_t links = LLAppearanceMgr::instance().findCOFItemLinks(getWearable()->getItemID()); @@ -1266,10 +1258,10 @@ void LLPanelEditWearable::saveChanges(bool force_save_as, std::string new_name) { mPendingWearable = new_wearable; mCurrentWearable = new_wearable; - childSetTextArg("title", "[DESC]", new_wearable->getName()); - childSetTextArg("title_no_modify", "[DESC]", new_wearable->getName()); + mTitle->setTextArg("[DESC]", new_wearable->getName()); + mNoModT->setTextArg("[DESC]", new_wearable->getName()); } - } + } else { // Make another copy of this link, with the same @@ -1300,9 +1292,9 @@ void LLPanelEditWearable::revertChanges() // no unsaved changes to revert return; } - + wearable->revertValues(); - childSetTextArg("title", "[DESC]", wearable->getName() ); + mTitle->setTextArg("[DESC]", wearable->getName()); gAgentAvatarp->wearableUpdated(mType, FALSE); if (mType == LLWearableType::WT_ALPHA) @@ -1322,18 +1314,17 @@ void LLPanelEditWearable::setUIPermissions(U32 perm_mask, BOOL is_complete) BOOL is_copyable = (perm_mask & PERM_COPY) ? TRUE : FALSE; BOOL is_modifiable = (perm_mask & PERM_MODIFY) ? TRUE : FALSE; - childSetEnabled("Save", is_modifiable && is_complete); - childSetEnabled("Save As", is_copyable && is_complete); - if (LLView* view = findChild("sex radio")) - view->setEnabled(is_modifiable && is_complete); + mSave->setEnabled(is_modifiable && is_complete); + mSaveAs->setEnabled(is_copyable && is_complete); + if (mSexRadio) + mSexRadio->setEnabled(is_modifiable && is_complete); for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_texture_ctrl, is_copyable && is_modifiable && is_complete, _1, _2)); for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_color_swatch_ctrl, is_modifiable && is_complete, _1, _2)); - for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); + for(ctrl_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); iter != mAlphaCheckbox2Index.end(); ++iter ) - { - LLCheckBoxCtrl* ctrl = getChild(iter->first, true, false); - if (ctrl) - { + { + if (LLUICtrl* ctrl = iter->first) + { ctrl->setEnabled(is_copyable && is_modifiable && is_complete); ctrl->setVisible(is_copyable && is_modifiable && is_complete); } @@ -1348,22 +1339,22 @@ void LLPanelEditWearable::changeCamera(U8 subpart) llinfos << "could not get wearable dictionary entry for wearable type: " << mType << llendl; return; } - + if (subpart >= wearable_entry->mSubparts.size()) { llinfos << "accordion tab expanded for invalid subpart. Wearable type: " << mType << " subpart num: " << subpart << llendl; return; } - + ESubpart subpart_e = wearable_entry->mSubparts[subpart]; const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); - + if (!subpart_entry) { llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; return; } - + mCurrentSubpart = subpart_e; //Update the buttons to reflect the current selected subpart. for (U8 index = 0; index < wearable_entry->mSubparts.size(); ++index) @@ -1371,12 +1362,13 @@ void LLPanelEditWearable::changeCamera(U8 subpart) // dive into data structures to get the panel we need ESubpart subpart_e = wearable_entry->mSubparts[index]; const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); - + if (subpart_entry) - { - LLButton* btn = getChild(subpart_entry->mButtonName); + { + if (index < mSubpartBtns.size()) + if (LLButton* btn = mSubpartBtns[index]) { - btn->setToggleState( subpart == subpart_e ); + btn->setToggleState(subpart == subpart_e); } } } @@ -1389,7 +1381,7 @@ void LLPanelEditWearable::changeCamera(U8 subpart) updateScrollingPanelUI(); // Update the camera - if(gMorphView) + if (gMorphView) { gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) ); gMorphView->setCameraTargetOffset( subpart_entry->mTargetOffset ); @@ -1445,7 +1437,7 @@ void LLPanelEditWearable::updateScrollingPanelUI() { LLViewerWearable* wearable = getWearable(); // do nothing if we don't have a valid wearable we're editing - if(!wearable) + if (!wearable) { return; } @@ -1454,7 +1446,7 @@ void LLPanelEditWearable::updateScrollingPanelUI() llinfos << "cur_wearable->isDirty()=" << wearable->isDirty() << llendl; LLViewerInventoryItem* item = gInventory.getItem(wearable->getItemID()); - if(item) + if (item) { U32 perm_mask = item->getPermissions().getMaskOwner(); BOOL is_complete = item->isComplete(); @@ -1466,7 +1458,7 @@ void LLPanelEditWearable::updateScrollingPanelUI() void LLPanelEditWearable::onBtnTakeOff() { LLViewerWearable* wearable = getWearable(); - if( !wearable ) + if (!wearable) { return; } @@ -1478,7 +1470,7 @@ void LLPanelEditWearable::onBtnTakeOff() // static void LLPanelEditWearable::getSortedParams(value_map_t &sorted_params, const std::string &edit_group, bool editable) { - if(!getWearable())return; + if (!getWearable()) return; LLViewerWearable::visual_param_vec_t param_list; ESex avatar_sex = gAgentAvatarp->getSex(); @@ -1496,7 +1488,7 @@ void LLPanelEditWearable::getSortedParams(value_map_t &sorted_params, const std: || param->getEditGroup() != edit_group || !(param->getSex() & avatar_sex)) { - continue; + continue; } // negative getDisplayOrder() to make lowest order the highest priority @@ -1511,7 +1503,7 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value // sorted_params is sorted according to magnitude of effect from // least to greatest. Adding to the front of the child list // reverses that order. - if( panel_list ) + if (panel_list) { panel_list->clearPanels(); value_map_t::iterator end = sorted_params.end(); @@ -1526,25 +1518,24 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value void LLPanelEditWearable::configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name) { - LLCheckBoxCtrl* checkbox = getChild(name, true, false); - if(checkbox) - { - checkbox->setCommitCallback(boost::bind(&LLPanelEditWearable::onInvisibilityCommit, this, checkbox, te)); - initPreviousAlphaTextureEntry(te); - mAlphaCheckbox2Index[name] = te; - } + if (LLUICtrl* checkbox = findChild(name)) + { + checkbox->setCommitCallback(boost::bind(&LLPanelEditWearable::onInvisibilityCommit, this, checkbox, te)); + initPreviousAlphaTextureEntry(te); + mAlphaCheckbox2Index[checkbox] = te; + } } -void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te) +void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, LLAvatarAppearanceDefines::ETextureIndex te) { - if (!checkbox_ctrl) + if (!ctrl) return; if (!getWearable()) return; - llinfos << "onInvisibilityCommit, self " << this << " checkbox_ctrl " << checkbox_ctrl << llendl; + llinfos << "onInvisibilityCommit, self " << this << " ctrl " << ctrl << llendl; - bool new_invis_state = checkbox_ctrl->get(); + bool new_invis_state = ctrl->getValue(); if (new_invis_state) { LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te); @@ -1561,7 +1552,7 @@ void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LL LLUUID prev_id = mPreviousAlphaTexture[te]; if (prev_id.isNull() || (prev_id == IMG_INVISIBLE)) { - prev_id = LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ); + prev_id = LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ); } if (prev_id.isNull()) return; @@ -1579,32 +1570,31 @@ void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LL void LLPanelEditWearable::updateAlphaCheckboxes() { - if(!getWearable()) + if (!getWearable()) return; - for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); + for(ctrl_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); iter != mAlphaCheckbox2Index.end(); ++iter ) { LLAvatarAppearanceDefines::ETextureIndex te = (LLAvatarAppearanceDefines::ETextureIndex)iter->second; - LLCheckBoxCtrl* ctrl = getChild(iter->first, true, false); - if (ctrl) + if (LLUICtrl* ctrl = iter->first) { - ctrl->set(!gAgentAvatarp->isTextureVisible(te, getWearable())); + ctrl->setValue(!gAgentAvatarp->isTextureVisible(te, getWearable())); } } } void LLPanelEditWearable::initPreviousAlphaTextures() { - initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA); - initPreviousAlphaTextureEntry(TEX_UPPER_ALPHA); - initPreviousAlphaTextureEntry(TEX_HEAD_ALPHA); - initPreviousAlphaTextureEntry(TEX_EYES_ALPHA); - initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA); + initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA); + initPreviousAlphaTextureEntry(TEX_UPPER_ALPHA); + initPreviousAlphaTextureEntry(TEX_HEAD_ALPHA); + initPreviousAlphaTextureEntry(TEX_EYES_ALPHA); + initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA); } void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te) { - if(!getWearable()) + if (!getWearable()) return; LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te); if (lto) diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index a57a4b9d2..4bf1cc75e 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -34,7 +34,7 @@ #include "llwearabletype.h" class LLAccordionCtrl; -class LLCheckBoxCtrl; +class LLButton; class LLViewerWearable; class LLTextBox; class LLViewerInventoryItem; @@ -114,7 +114,7 @@ public: //alpha mask checkboxes void configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name); - void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te); + void onInvisibilityCommit(LLUICtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te); void updateAlphaCheckboxes(); void initPreviousAlphaTextures(); void initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te); @@ -123,8 +123,8 @@ private: LLFloaterCustomize* mCustomizeFloater; LLWearableType::EType mType; BOOL mCanTakeOff; - typedef std::map string_texture_index_map_t; - string_texture_index_map_t mAlphaCheckbox2Index; + typedef std::map ctrl_texture_index_map_t; + ctrl_texture_index_map_t mAlphaCheckbox2Index; typedef std::map s32_uuid_map_t; s32_uuid_map_t mPreviousAlphaTexture; @@ -135,6 +135,12 @@ private: //so this is needed to retain focus on this wearables tab over the messy transition. bool mPendingRefresh; //LLAgentWearables::setWearableOutfit fires a buttload of remove/wear calls which spams wearablesChanged //a bazillion pointless (and not particularly valid) times. Deferring to draw effectively sorts it all out. + + // Cached UI + LLUICtrl *mCreateNew, *mTakeOff, *mSexRadio, *mSave, *mSaveAs, *mRevert, *mNotWornT, *mNoModT, *mTitle, *mTitleLoading, *mPath, *mAvHeight; + LLView *mNotWornI, *mNoModI, *mSquare; + LLTabContainer* mTab; + std::vector mSubpartBtns; public: LLModalDialog* mActiveModal; }; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index db44b78d8..fe39b0afa 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -128,7 +128,7 @@ BOOL LLPanelFace::postBuild() mMediaDelete = getChildView("delete_media"); // Label caching - mLabelGlossy = getChildView("label glossy"); + mLabelGlossy = getChildView("label glossiness"); mLabelEnvironment = getChildView("label environment"); mLabelShinyColor = getChildView("label shinycolor"); mLabelAlphaMode = getChildView("label alphamode"); @@ -170,8 +170,8 @@ BOOL LLPanelFace::postBuild() mCtrlCopy = getChild("copytextures"); mCtrlPaste = getChild("pastetextures"); - mComboShiny->setCommitCallback(boost::bind(&LLPanelFace::sendShiny, this, boost::bind(&LLSD::asInteger, _2))); - mComboBumpy->setCommitCallback(boost::bind(&LLPanelFace::sendBump, this, boost::bind(&LLSD::asInteger, _2))); + mComboShiny->setCommitCallback(boost::bind(&LLPanelFace::sendShiny, this, boost::bind(&LLComboBox::getCurrentIndex, mComboShiny))); + mComboBumpy->setCommitCallback(boost::bind(&LLPanelFace::sendBump, this, boost::bind(&LLComboBox::getCurrentIndex, mComboBumpy))); mComboAlpha->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlphaMode, this)); mCtrlTexScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this)); mCtrlFlipTexScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitFlip, this, true)); @@ -1282,7 +1282,7 @@ void LLPanelFace::updateUI() LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright); - mCheckFullbright->setValue((S32)(fullbright_flag != 0)); + mCheckFullbright->setValue(fullbright_flag != 0); mCheckFullbright->setEnabled(editable); mCheckFullbright->setTentative(!identical_fullbright); } @@ -1800,7 +1800,7 @@ void LLPanelFace::onSelectTexture(const LLSD& data) LLSelectMgr::getInstance()->saveSelectedObjectTextures(); sendTexture(); - LLGLenum image_format; + LLGLenum image_format(0); bool identical_image_format = false; LLSelectedTE::getImageFormat(image_format, identical_image_format); @@ -2143,7 +2143,7 @@ void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face) { - LLGLenum image_format; + LLGLenum image_format(0); struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor { LLGLenum get(LLViewerObject* object, S32 te_index) diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 0ad383b14..5bbcf5868 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -304,7 +304,7 @@ private: ReturnType (LLMaterial::* const MaterialGetFunc)() const > static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value) { - DataType data_value; + DataType data_value = DataType(); struct GetTEMaterialVal : public LLSelectedTEGetFunctor { GetTEMaterialVal(DataType default_value) : _default(default_value) {} @@ -337,7 +337,7 @@ private: ReturnType (LLTextureEntry::* const TEGetFunc)() const > static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value) { - DataType data_value; + DataType data_value = DataType(); struct GetTEVal : public LLSelectedTEGetFunctor { GetTEVal(DataType default_value) : _default(default_value) {} diff --git a/indra/newview/llpanelgeneral.cpp b/indra/newview/llpanelgeneral.cpp index cf339762a..d794e43da 100644 --- a/indra/newview/llpanelgeneral.cpp +++ b/indra/newview/llpanelgeneral.cpp @@ -142,19 +142,8 @@ void LLPanelGeneral::apply() LLComboBox* fade_out_combobox = getChild("fade_out_combobox"); gSavedSettings.setS32("RenderName", fade_out_combobox->getCurrentIndex()); - S32 namesystem_combobox_index = getChild("namesystem_combobox")->getCurrentIndex(); - BOOL show_resident = getChild("show_resident_checkbox")->getValue(); - if(gSavedSettings.getS32("PhoenixNameSystem")!=namesystem_combobox_index || gSavedSettings.getBOOL("LiruShowLastNameResident")!=show_resident){ - gSavedSettings.setS32("PhoenixNameSystem", namesystem_combobox_index); - gSavedSettings.setBOOL("LiruShowLastNameResident", show_resident); - if(gAgent.getRegion()){ - if(namesystem_combobox_index<=0 || namesystem_combobox_index>2) LLAvatarNameCache::setUseDisplayNames(false); - else LLAvatarNameCache::setUseDisplayNames(true); - LLVOAvatar::invalidateNameTags(); // Remove all clienttags to get them updated - - LLAvatarTracker::instance().updateFriends(); - } - } + gSavedSettings.setS32("PhoenixNameSystem", getChild("namesystem_combobox")->getCurrentIndex()); + gSavedSettings.setBOOL("LiruShowLastNameResident", getChild("show_resident_checkbox")->getValue()); gSavedSettings.setString("LoginLocation", childGetValue("default_start_location").asString()); gSavedSettings.setBOOL("ShowStartLocation", childGetValue("show_location_checkbox")); diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 92ce2545f..4e65628bb 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -157,6 +157,7 @@ LLPanelGroup::LLPanelGroup(const LLUUID& group_id) mFactoryMap["members_sub_tab"] = LLCallbackMap(LLPanelGroupMembersSubTab::createTab, &mID); mFactoryMap["roles_sub_tab"] = LLCallbackMap(LLPanelGroupRolesSubTab::createTab, &mID); mFactoryMap["actions_sub_tab"] = LLCallbackMap(LLPanelGroupActionsSubTab::createTab, &mID); + mFactoryMap["banlist_sub_tab"] = LLCallbackMap(LLPanelGroupBanListSubTab::createTab, &mID); LLGroupMgr::getInstance()->addObserver(this); diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index f9ea38136..1367c8760 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -168,12 +168,16 @@ public: virtual BOOL isVisibleByAgent(LLAgent* agentp); + virtual void setGroupID(const LLUUID& id) { mGroupID = id; } + void setAllowEdit(BOOL v) { mAllowEdit = v; } void addObserver(LLPanelGroupTabObserver *obs); void removeObserver(LLPanelGroupTabObserver *obs); void notifyObservers(); + const LLUUID& getGroupID() const { return mGroupID; } + protected: LLUUID mGroupID; LLTabContainer* mTabContainer; diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp new file mode 100644 index 000000000..c6e290963 --- /dev/null +++ b/indra/newview/llpanelgroupbulk.cpp @@ -0,0 +1,424 @@ +/** +* @file llpanelgroupbulk.cpp +* @brief Implementation of llpanelgroupbulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, 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$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelgroupbulk.h" +#include "llpanelgroupbulkimpl.h" + +#include "llagent.h" +#include "llavatarnamecache.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcallingcard.h" +#include "llcombobox.h" +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llnamelistctrl.h" +#include "llnotificationsutil.h" +#include "llscrolllistitem.h" +#include "llspinctrl.h" +#include "lltextbox.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" + + +////////////////////////////////////////////////////////////////////////// +// Implementation of llpanelgroupbulkimpl.h functions +////////////////////////////////////////////////////////////////////////// +LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) : + mGroupID(group_id), + mBulkAgentList(NULL), + mOKButton(NULL), + mRemoveButton(NULL), + mGroupName(NULL), + mLoadingText(), + mTooManySelected(), + mCloseCallback(NULL), + mCloseCallbackUserData(NULL), + mRoleNames(NULL), + mOwnerWarning(), + mAlreadyInGroup(), + mConfirmedOwnerInvite(false), + mListFullNotificationSent(false) +{} + +LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl() +{ + for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + } + mAvatarNameCacheConnections.clear(); +} + +void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata) +{ + LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata; + + if(panelp) + { + //Right now this is hard coded with some knowledge that it is part + //of a floater since the avatar picker needs to be added as a dependent + //floater to the parent floater. + //Soon the avatar picker will be embedded into this panel + //instead of being it's own separate floater. But that is next week. + //This will do for now. -jwolk May 10, 2006 + /* Singu Note: We're different, we don't do this.. + LLView* button = panelp->findChild("add_button"); + */ + LLFloater* root_floater = gFloaterView->getParentFloater(panelp); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + // boost::bind(callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button); + boost::bind(&LLPanelGroupBulkImpl::callbackAddUsers, panelp->mImplementation, _1), TRUE); + if(picker) + { + root_floater->addDependentFloater(picker); + } + } +} + +void LLPanelGroupBulkImpl::callbackClickRemove(void* userdata) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; + if (selfp) + selfp->handleRemove(); +} + +void LLPanelGroupBulkImpl::callbackClickCancel(void* userdata) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; + if(selfp) + (*(selfp->mCloseCallback))(selfp->mCloseCallbackUserData); +} + +void LLPanelGroupBulkImpl::callbackSelect(LLUICtrl* ctrl, void* userdata) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; + if (selfp) + selfp->handleSelection(); +} + +void LLPanelGroupBulkImpl::callbackAddUsers(const uuid_vec_t& agent_ids) +{ + std::vector names; + for (S32 i = 0; i < (S32)agent_ids.size(); i++) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(agent_ids[i], &av_name)) + { + onAvatarNameCache(agent_ids[i], av_name); + } + else + { + if (mAvatarNameCacheConnections[agent_ids[i]].connected()) + { + mAvatarNameCacheConnections[agent_ids[i]].disconnect(); + } + // *TODO : Add a callback per avatar name being fetched. + mAvatarNameCacheConnections[agent_ids[i]] = LLAvatarNameCache::get(agent_ids[i],boost::bind(&LLPanelGroupBulkImpl::onAvatarNameCache, this, _1, _2)); + } + } +} + +void LLPanelGroupBulkImpl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + if (mAvatarNameCacheConnections[agent_id].connected()) + { + mAvatarNameCacheConnections[agent_id].disconnect(); + } + std::vector names; + uuid_vec_t agent_ids; + agent_ids.push_back(agent_id); + std::string name; + LLAvatarNameCache::getPNSName(av_name, name); + names.push_back(name); + + addUsers(names, agent_ids); +} + +void LLPanelGroupBulkImpl::handleRemove() +{ + std::vector selection = mBulkAgentList->getAllSelected(); + if (selection.empty()) + return; + + std::vector::iterator iter; + for(iter = selection.begin(); iter != selection.end(); ++iter) + { + mInviteeIDs.erase((*iter)->getUUID()); + } + + mBulkAgentList->deleteSelectedItems(); + mRemoveButton->setEnabled(FALSE); + + if( mOKButton && mOKButton->getEnabled() && + mBulkAgentList->isEmpty()) + { + mOKButton->setEnabled(FALSE); + } +} + +void LLPanelGroupBulkImpl::handleSelection() +{ + std::vector selection = mBulkAgentList->getAllSelected(); + if (selection.empty()) + mRemoveButton->setEnabled(FALSE); + else + mRemoveButton->setEnabled(TRUE); +} + +void LLPanelGroupBulkImpl::addUsers(const std::vector& names, const uuid_vec_t& agent_ids) +{ + std::string name; + LLUUID id; + + if(mListFullNotificationSent) + { + return; + } + + if( !mListFullNotificationSent && + (names.size() + mInviteeIDs.size() > MAX_GROUP_INVITES)) + { + mListFullNotificationSent = true; + + // Fail! Show a warning and don't add any names. + LLSD msg; + msg["MESSAGE"] = mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + return; + } + + for (S32 i = 0; i < (S32)names.size(); ++i) + { + name = names[i]; + id = agent_ids[i]; + + if(mInviteeIDs.find(id) != mInviteeIDs.end()) + { + continue; + } + + //add the name to the names list + LLSD row; + row["id"] = id; + row["columns"][0]["value"] = name; + + mBulkAgentList->addElement(row); + mInviteeIDs.insert(id); + + // We've successfully added someone to the list. + if(mOKButton && !mOKButton->getEnabled()) + mOKButton->setEnabled(TRUE); + } +} + +void LLPanelGroupBulkImpl::setGroupName(std::string name) +{ + if(mGroupName) + mGroupName->setText(name); +} + + +LLPanelGroupBulk::LLPanelGroupBulk(const LLUUID& group_id) : + LLPanel(), + mImplementation(new LLPanelGroupBulkImpl(group_id)), + mPendingGroupPropertiesUpdate(false), + mPendingRoleDataUpdate(false), + mPendingMemberDataUpdate(false) +{} + +LLPanelGroupBulk::~LLPanelGroupBulk() +{ + delete mImplementation; +} + +void LLPanelGroupBulk::clear() +{ + mImplementation->mInviteeIDs.clear(); + + if(mImplementation->mBulkAgentList) + mImplementation->mBulkAgentList->deleteAllItems(); + + if(mImplementation->mOKButton) + mImplementation->mOKButton->setEnabled(FALSE); +} + +void LLPanelGroupBulk::update() +{ + updateGroupName(); + updateGroupData(); +} + +void LLPanelGroupBulk::draw() +{ + LLPanel::draw(); + update(); +} + +void LLPanelGroupBulk::updateGroupName() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); + + if( gdatap && + gdatap->isGroupPropertiesDataComplete()) + { + // Only do work if the current group name differs + if(mImplementation->mGroupName->getText().compare(gdatap->mName) != 0) + mImplementation->setGroupName(gdatap->mName); + } + else + { + mImplementation->setGroupName(mImplementation->mLoadingText); + } +} + +void LLPanelGroupBulk::updateGroupData() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); + if(gdatap && gdatap->isGroupPropertiesDataComplete()) + { + mPendingGroupPropertiesUpdate = false; + } + else + { + if(!mPendingGroupPropertiesUpdate) + { + mPendingGroupPropertiesUpdate = true; + LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); + } + } + + if(gdatap && gdatap->isRoleDataComplete()) + { + mPendingRoleDataUpdate = false; + } + else + { + if(!mPendingRoleDataUpdate) + { + mPendingRoleDataUpdate = true; + LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + } + } + + if(gdatap && gdatap->isMemberDataComplete()) + { + mPendingMemberDataUpdate = false; + } + else + { + if(!mPendingMemberDataUpdate) + { + mPendingMemberDataUpdate = true; + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); + } + } +} + +void LLPanelGroupBulk::addUserCallback(const LLUUID& id, const LLAvatarName& av_name) +{ + std::vector names; + uuid_vec_t agent_ids; + agent_ids.push_back(id); + std::string name; + LLAvatarNameCache::getPNSName(av_name, name); + names.push_back(name); + + mImplementation->addUsers(names, agent_ids); +} + +void LLPanelGroupBulk::setCloseCallback(void (*close_callback)(void*), void* data) +{ + mImplementation->mCloseCallback = close_callback; + mImplementation->mCloseCallbackUserData = data; +} + +void LLPanelGroupBulk::addUsers(uuid_vec_t& agent_ids) +{ + std::vector names; + for (S32 i = 0; i < (S32)agent_ids.size(); i++) + { + std::string fullname; + LLUUID agent_id = agent_ids[i]; + LLViewerObject* dest = gObjectList.findObject(agent_id); + if(dest && dest->isAvatar()) + { + LLNameValue* nvfirst = dest->getNVPair("FirstName"); + LLNameValue* nvlast = dest->getNVPair("LastName"); + if(nvfirst && nvlast) + { + fullname = LLCacheName::buildFullName( + nvfirst->getString(), nvlast->getString()); + + } + if (!fullname.empty()) + { + names.push_back(fullname); + } + else + { + llwarns << "llPanelGroupBulk: Selected avatar has no name: " << dest->getID() << llendl; + names.push_back("(Unknown)"); + } + } + else + { + //looks like user try to invite offline friend + //for offline avatar_id gObjectList.findObject() will return null + //so we need to do this additional search in avatar tracker, see EXT-4732 + //if (LLAvatarTracker::instance().isBuddy(agent_id)) // Singu Note: We may be using this from another avatar list like group profile, disregard friendship status. + { + LLAvatarName av_name; + if (!LLAvatarNameCache::get(agent_id, &av_name)) + { + // actually it should happen, just in case + LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupBulk::addUserCallback, this, _1, _2)); + // for this special case! + //when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence + // removed id will be added in callback + agent_ids.erase(agent_ids.begin() + i); + } + else + { + std::string name; + LLAvatarNameCache::getPNSName(av_name, name); + names.push_back(name); + } + } + } + } + mImplementation->mListFullNotificationSent = false; + mImplementation->addUsers(names, agent_ids); +} + diff --git a/indra/newview/llpanelgroupbulk.h b/indra/newview/llpanelgroupbulk.h new file mode 100644 index 000000000..d03e4fca2 --- /dev/null +++ b/indra/newview/llpanelgroupbulk.h @@ -0,0 +1,73 @@ +/** +* @file llpanelgroupbulk.h +* @brief Header file for llpanelgroupbulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, 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$ +*/ +#ifndef LL_LLPANELGROUPBULK_H +#define LL_LLPANELGROUPBULK_H + +#include "llpanel.h" +#include "lluuid.h" + +class LLAvatarName; +class LLGroupMgrGroupData; +class LLPanelGroupBulkImpl; + +// Base panel class for bulk group invite / ban floaters +class LLPanelGroupBulk : public LLPanel +{ +public: + LLPanelGroupBulk(const LLUUID& group_id); + /*virtual*/ ~LLPanelGroupBulk(); + +public: + static void callbackClickSubmit(void* userdata) {} + virtual void submit() = 0; + +public: + virtual void clear(); + virtual void update(); + virtual void draw(); + +protected: + virtual void updateGroupName(); + virtual void updateGroupData(); + +public: + // this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers(). + virtual void addUserCallback(const LLUUID& id, const LLAvatarName& av_name); + virtual void setCloseCallback(void (*close_callback)(void*), void* data); + + virtual void addUsers(uuid_vec_t& agent_ids); + +public: + LLPanelGroupBulkImpl* mImplementation; + +protected: + bool mPendingGroupPropertiesUpdate; + bool mPendingRoleDataUpdate; + bool mPendingMemberDataUpdate; +}; + +#endif // LL_LLPANELGROUPBULK_H diff --git a/indra/newview/llpanelgroupbulkban.cpp b/indra/newview/llpanelgroupbulkban.cpp new file mode 100644 index 000000000..1899689d7 --- /dev/null +++ b/indra/newview/llpanelgroupbulkban.cpp @@ -0,0 +1,160 @@ +/** +* @file llpanelgroupbulkban.cpp +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, 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$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelgroupbulkban.h" +#include "llpanelgroupbulk.h" +#include "llpanelgroupbulkimpl.h" + +#include "llagent.h" +#include "llavatarnamecache.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcallingcard.h" +#include "llcombobox.h" +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llnamelistctrl.h" +#include "llnotificationsutil.h" +#include "llscrolllistitem.h" +#include "llslurl.h" +#include "llspinctrl.h" +#include "lltextbox.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" + +#include + +LLPanelGroupBulkBan::LLPanelGroupBulkBan(const LLUUID& group_id) : LLPanelGroupBulk(group_id) +{ + // Pass on construction of this panel to the control factory. + //buildFromFile( "panel_group_bulk_ban.xml"); + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_bulk_ban.xml"); +} + +BOOL LLPanelGroupBulkBan::postBuild() +{ + BOOL recurse = TRUE; + + mImplementation->mLoadingText = getString("loading"); + mImplementation->mGroupName = getChild("group_name_text", recurse); + mImplementation->mBulkAgentList = getChild("banned_agent_list", recurse); + if ( mImplementation->mBulkAgentList ) + { + mImplementation->mBulkAgentList->setCommitOnSelectionChange(TRUE); + mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation); + } + + LLButton* button = getChild("add_button", recurse); + if ( button ) + { + // default to opening avatarpicker automatically + // (*impl::callbackClickAdd)((void*)this); + button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this); + } + + mImplementation->mRemoveButton = + getChild("remove_button", recurse); + if ( mImplementation->mRemoveButton ) + { + mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); + mImplementation->mRemoveButton->setEnabled(FALSE); + } + + mImplementation->mOKButton = + getChild("ban_button", recurse); + if ( mImplementation->mOKButton ) + { + mImplementation->mOKButton->setCommitCallback(boost::bind(&LLPanelGroupBulkBan::submit, this)); + mImplementation->mOKButton->setEnabled(FALSE); + } + + button = getChild("cancel_button", recurse); + if ( button ) + { + button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); + } + + mImplementation->mTooManySelected = getString("ban_selection_too_large"); + + update(); + return TRUE; +} + +void LLPanelGroupBulkBan::submit() +{ + std::vector banned_agent_list; + std::vector agents = mImplementation->mBulkAgentList->getAllData(); + std::vector::iterator iter = agents.begin(); + for(;iter != agents.end(); ++iter) + { + LLScrollListItem* agent = *iter; + banned_agent_list.push_back(agent->getUUID()); + } + + const S32 MAX_GROUP_BANS = 100; // Max invites per request. 100 to match server cap. + if (banned_agent_list.size() > MAX_GROUP_BANS) + { + // Fail! + LLSD msg; + msg["MESSAGE"] = mImplementation->mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); + return; + } + + LLGroupMgrGroupData * group_datap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); + if (group_datap) + { + BOOST_FOREACH(const LLGroupMgrGroupData::ban_list_t::value_type& group_ban_pair, group_datap->mBanList) + { + const LLUUID& group_ban_agent_id = group_ban_pair.first; + if (std::find(banned_agent_list.begin(), banned_agent_list.end(), group_ban_agent_id) != banned_agent_list.end()) + { + // Fail! + std::string av_name; + LLAvatarNameCache::getPNSName(group_ban_agent_id, av_name); + + LLStringUtil::format_map_t string_args; + string_args["[RESIDENT]"] = av_name; + + LLSD msg; + msg["MESSAGE"] = getString("already_banned", string_args); + LLNotificationsUtil::add("GenericAlert", msg); + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); + return; + } + } + } + + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mImplementation->mGroupID, LLGroupMgr::BAN_CREATE | LLGroupMgr::BAN_UPDATE, banned_agent_list); + LLGroupMgr::getInstance()->sendGroupMemberEjects(mImplementation->mGroupID, banned_agent_list); + + //then close + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); +} diff --git a/indra/newview/llpanelgroupbulkban.h b/indra/newview/llpanelgroupbulkban.h new file mode 100644 index 000000000..a4c071230 --- /dev/null +++ b/indra/newview/llpanelgroupbulkban.h @@ -0,0 +1,46 @@ +/** +* @file llpanelgroupbulkban.h +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, 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$ +*/ + +#ifndef LL_LLPANELGROUPBULKBAN_H +#define LL_LLPANELGROUPBULKBAN_H + +#include "llpanel.h" +#include "lluuid.h" +#include "llpanelgroupbulk.h" + +class LLAvatarName; + +class LLPanelGroupBulkBan : public LLPanelGroupBulk +{ +public: + LLPanelGroupBulkBan(const LLUUID& group_id); + ~LLPanelGroupBulkBan() {} + + virtual BOOL postBuild(); + + virtual void submit(); +}; + +#endif // LL_LLPANELGROUPBULKBAN_H diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h new file mode 100644 index 000000000..154b4cecf --- /dev/null +++ b/indra/newview/llpanelgroupbulkimpl.h @@ -0,0 +1,96 @@ + /** +* @file llpanelgroupbulkimpl.h +* @brief Class definition for implementation class of LLPanelGroupBulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, 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$ +*/ +#ifndef LL_LLPANELGROUPBULKIMPL_H +#define LL_LLPANELGROUPBULKIMPL_H + +#include "llpanel.h" +#include "lluuid.h" + +class LLAvatarName; +class LLNameListCtrl; +class LLTextBox; +class LLComboBox; + +////////////////////////////////////////////////////////////////////////// +// Implementation found in llpanelgroupbulk.cpp +////////////////////////////////////////////////////////////////////////// +class LLPanelGroupBulkImpl +{ +public: + LLPanelGroupBulkImpl(const LLUUID& group_id); + ~LLPanelGroupBulkImpl(); + + static void callbackClickAdd(void* userdata); + static void callbackClickRemove(void* userdata); + + static void callbackClickCancel(void* userdata); + + static void callbackSelect(LLUICtrl* ctrl, void* userdata); + void callbackAddUsers(const uuid_vec_t& agent_ids); + + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + + void handleRemove(); + void handleSelection(); + + void addUsers(const std::vector& names, const uuid_vec_t& agent_ids); + void setGroupName(std::string name); + + +public: + static const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap. + + + LLUUID mGroupID; + + LLNameListCtrl* mBulkAgentList; + LLButton* mOKButton; + LLButton* mRemoveButton; + LLTextBox* mGroupName; + + std::string mLoadingText; + std::string mTooManySelected; + + std::set mInviteeIDs; + + void (*mCloseCallback)(void* data); + void* mCloseCallbackUserData; + typedef std::map avatar_name_cache_connection_map_t; + avatar_name_cache_connection_map_t mAvatarNameCacheConnections; + + // The following are for the LLPanelGroupInvite subclass only. + // These aren't needed for LLPanelGroupBulkBan, but if we have to add another + // group bulk floater for some reason, we'll have these objects too. +public: + LLComboBox* mRoleNames; + std::string mOwnerWarning; + std::string mAlreadyInGroup; + bool mConfirmedOwnerInvite; + bool mListFullNotificationSent; +}; + +#endif // LL_LLPANELGROUPBULKIMPL_H diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 5b58e6b76..48d74eacd 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -103,6 +103,14 @@ LLPanelGroupGeneral::LLPanelGroupGeneral(const std::string& name, LLPanelGroupGeneral::~LLPanelGroupGeneral() { + for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + } + mAvatarNameCacheConnections.clear(); } BOOL LLPanelGroupGeneral::postBuild() @@ -810,9 +818,16 @@ void LLPanelGroupGeneral::updateMembers() else { // If name is not cached, onNameCache() should be called when it is cached and add this member to list. - LLAvatarNameCache::get(mMemberProgress->first, - boost::bind(&LLPanelGroupGeneral::onNameCache, - this, gdatap->getMemberVersion(), member, _2)); + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(mMemberProgress->first); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); + } + mAvatarNameCacheConnections[mMemberProgress->first] = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupGeneral::onNameCache, this, gdatap->getMemberVersion(), member, _2, _1)); } } @@ -854,8 +869,18 @@ void LLPanelGroupGeneral::addMember(LLGroupMemberData* member) /*LLScrollListItem* member_row =*/ mListVisibleMembers->addNameItemRow(item_params); } -void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name) +void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id) { + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(av_id); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); + } + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); if (!gdatap diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 84058ac84..a0a1fd5fb 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -68,7 +68,7 @@ public: virtual void draw(); - void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name); + void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id); private: void onFocusEdit(); void onCommitAny(); @@ -113,6 +113,8 @@ private: LLComboBox *mComboMature; LLGroupMgrGroupData::member_list_t::iterator mMemberProgress; + typedef std::map avatar_name_cache_connection_map_t; + avatar_name_cache_connection_map_t mAvatarNameCacheConnections; }; #endif diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index f16d4985c..5ae135380 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -258,7 +258,7 @@ void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap) //else if they have the limited add to roles power //we add every role the user is in //else we just add to everyone - bool is_owner = member_data->isInRole(gdatap->mOwnerRole); + bool is_owner = member_data->isOwner(); bool can_assign_any = gAgent.hasPowerInGroup(mGroupID, GP_ROLE_ASSIGN_MEMBER); bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID, @@ -461,7 +461,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) //looks like user try to invite offline friend //for offline avatar_id gObjectList.findObject() will return null //so we need to do this additional search in avatar tracker, see EXT-4732 - if (LLAvatarTracker::instance().isBuddy(agent_id)) + //if (LLAvatarTracker::instance().isBuddy(agent_id)) // Singu Note: We may be using this from another avatar list like group profile, disregard friendship status. { LLAvatarName av_name; if (!LLAvatarNameCache::get(agent_id, &av_name)) @@ -476,7 +476,9 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) } else { - names.push_back(av_name.getLegacyName()); + std::string name; + LLAvatarNameCache::getPNSName(av_name, name); + names.push_back(name); } } } @@ -489,7 +491,9 @@ void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& a std::vector names; uuid_vec_t agent_ids; agent_ids.push_back(id); - names.push_back(av_name.getLegacyName()); + std::string name; + LLAvatarNameCache::getPNSName(av_name, name); + names.push_back(name); mImplementation->addUsers(names, agent_ids); } @@ -540,7 +544,7 @@ void LLPanelGroupInvite::updateLists() { waiting = true; } - if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete()) + if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() && gdatap->isRoleMemberDataComplete()) { if ( mImplementation->mRoleNames ) { @@ -568,6 +572,7 @@ void LLPanelGroupInvite::updateLists() { LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); } mPendingUpdate = TRUE; @@ -615,7 +620,7 @@ BOOL LLPanelGroupInvite::postBuild() } mImplementation->mOKButton = - getChild("ok_button", recurse); + getChild("invite_button", recurse); if ( mImplementation->mOKButton ) { mImplementation->mOKButton->setClickedCallback(impl::callbackClickOK, mImplementation); diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index dec32551a..8a66eef09 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -410,27 +410,14 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) msg->getUUID("QueryData", "OwnerID", owner_id, 0); msg->getUUID("TransactionData", "TransactionID", trans_id); + S32 total_contribution = 0; if(owner_id.isNull()) { // special block which has total contribution ++first_block; - - S32 total_contribution; + msg->getS32("QueryData", "ActualArea", total_contribution, 0); mPanel.getChild("total_contributed_land_value")->setTextArg("[AREA]", llformat("%d", total_contribution)); - - S32 committed; - msg->getS32("QueryData", "BillableArea", committed, 0); - mPanel.getChild("total_land_in_use_value")->setTextArg("[AREA]", llformat("%d", committed)); - - S32 available = total_contribution - committed; - mPanel.getChild("land_available_value")->setTextArg("[AREA]", llformat("%d", available)); - - if ( mGroupOverLimitTextp && mGroupOverLimitIconp ) - { - mGroupOverLimitIconp->setVisible(available < 0); - mGroupOverLimitTextp->setVisible(available < 0); - } } if ( trans_id != mTransID ) return; @@ -449,7 +436,8 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) std::string sim_name; std::string land_sku; std::string land_type; - + S32 committed = 0; + for(S32 i = first_block; i < count; ++i) { msg->getUUID("QueryData", "OwnerID", owner_id, i); @@ -478,6 +466,9 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) S32 region_y = llround(global_y) % REGION_WIDTH_UNITS; std::string location = sim_name + llformat(" (%d, %d)", region_x, region_y); std::string area; + committed+=billable_area; + + if(billable_area == actual_area) { area = llformat("%d", billable_area); @@ -514,6 +505,17 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) mGroupParcelsp->addElement(row, ADD_SORTED); } + + mPanel.getChild("total_land_in_use_value")->setTextArg("[AREA]", llformat("%d", committed)); + + S32 available = total_contribution - committed; + mPanel.getChild("land_available_value")->setTextArg("[AREA]", llformat("%d", available)); + + if ( mGroupOverLimitTextp && mGroupOverLimitIconp ) + { + mGroupOverLimitIconp->setVisible(available < 0); + mGroupOverLimitTextp->setVisible(available < 0); + } } } diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 74c591f1e..40e450dd7 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -53,6 +53,7 @@ #include "llscrolllistctrl.h" #include "llscrolllistitem.h" #include "lltextbox.h" +#include "lltrans.h" #include "roles_constants.h" #include "llviewerwindow.h" @@ -511,6 +512,7 @@ void LLPanelGroupNotices::onSelectNotice() lldebugs << "Item " << item->getUUID() << " selected." << llendl; } +bool is_openable(LLAssetType::EType type); void LLPanelGroupNotices::showNotice(const std::string& subject, const std::string& message, const bool& has_inventory, @@ -549,6 +551,7 @@ void LLPanelGroupNotices::showNotice(const std::string& subject, mViewInventoryName->setText(ss.str()); mBtnOpenAttachment->setEnabled(TRUE); + mBtnOpenAttachment->setLabel(LLTrans::getString(is_openable(inventory_offer->mType) ? "GroupNotifyOpenAttachment" : "GroupNotifySaveAttachment")); } else { diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index e38bda37b..d9afd5b04 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llpanelgrouproles.cpp * @brief Panel for roles information about a particular group. * @@ -38,6 +38,7 @@ #include "llavatarnamecache.h" #include "llbutton.h" #include "llfiltereditor.h" +#include "llfloatergroupbulkban.h" #include "llfloatergroupinvite.h" #include "lliconctrl.h" #include "lllineeditor.h" @@ -109,6 +110,9 @@ bool agentCanAddToRole(const LLUUID& group_id, return false; } + +// LLPanelGroupRoles ///////////////////////////////////////////////////// + // static void* LLPanelGroupRoles::createTab(void* data) { @@ -308,7 +312,6 @@ bool LLPanelGroupRoles::onModalClose(const LLSD& notification, const LLSD& respo return false; } - bool LLPanelGroupRoles::apply(std::string& mesg) { // Pass this along to the currently visible sub tab. @@ -374,39 +377,33 @@ void LLPanelGroupRoles::activate() { // Start requesting member and role data if needed. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); - //if (!gdatap || mFirstUse) + if (!gdatap || !gdatap->isMemberDataComplete()) { - // Check member data. - - if (!gdatap || !gdatap->isMemberDataComplete() ) - { - LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); - } - - // Check role data. - if (!gdatap || !gdatap->isRoleDataComplete() ) - { - // Mildly hackish - clear all pending changes - cancel(); - - LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); - } - - // Check role-member mapping data. - if (!gdatap || !gdatap->isRoleMemberDataComplete() ) - { - LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); - } - - // Need this to get base group member powers - if (!gdatap || !gdatap->isGroupPropertiesDataComplete() ) - { - LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); - } - - mFirstUse = FALSE; + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } + if (!gdatap || !gdatap->isRoleDataComplete() ) + { + // Mildly hackish - clear all pending changes + cancel(); + + LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); + } + + // Check role-member mapping data. + if (!gdatap || !gdatap->isRoleMemberDataComplete() ) + { + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); + } + + // Need this to get base group member powers + if (!gdatap || !gdatap->isGroupPropertiesDataComplete() ) + { + LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); + } + + mFirstUse = FALSE; + LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel(); if (panelp) panelp->activate(); } @@ -441,14 +438,38 @@ void LLPanelGroupRoles::tabChanged() notifyObservers(); } -//////////////////////////// -// LLPanelGroupSubTab -//////////////////////////// +void LLPanelGroupRoles::setGroupID(const LLUUID& id) +{ + LLPanelGroupTab::setGroupID(id); + + LLPanelGroupMembersSubTab* group_members_tab = findChild("members_sub_tab"); + LLPanelGroupRolesSubTab* group_roles_tab = findChild("roles_sub_tab"); + LLPanelGroupActionsSubTab* group_actions_tab = findChild("actions_sub_tab"); + LLPanelGroupBanListSubTab* group_ban_tab = findChild("banlist_sub_tab"); + + if (group_members_tab) group_members_tab->setGroupID(id); + if (group_roles_tab) group_roles_tab->setGroupID(id); + if (group_actions_tab) group_actions_tab->setGroupID(id); + if (group_ban_tab) group_ban_tab->setGroupID(id); + + LLButton* button = getChild("member_invite"); + if (button) + button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE)); + + if (mSubTabContainer) + mSubTabContainer->selectTab(1); + group_roles_tab->mFirstOpen = TRUE; + activate(); +} + + +// LLPanelGroupSubTab //////////////////////////////////////////////////// LLPanelGroupSubTab::LLPanelGroupSubTab(const std::string& name, const LLUUID& group_id) : LLPanelGroupTab(name, group_id), mHeader(NULL), mFooter(NULL), mActivated(false), + mHasGroupBanPower(false), mSearchEditor(NULL) { } @@ -493,6 +514,17 @@ BOOL LLPanelGroupSubTab::postBuild() return LLPanelGroupTab::postBuild(); } +void LLPanelGroupSubTab::setGroupID(const LLUUID& id) +{ + LLPanelGroupTab::setGroupID(id); + if(mSearchEditor) + { + mSearchEditor->clear(); + setSearchFilter(""); + } + + mActivated = false; +} void LLPanelGroupSubTab::setSearchFilter(const std::string& filter) { @@ -559,9 +591,10 @@ void LLPanelGroupSubTab::buildActionsList(LLScrollListCtrl* ctrl, return; } + mHasGroupBanPower = false; + std::vector::iterator ras_it = LLGroupMgr::getInstance()->mRoleActionSets.begin(); std::vector::iterator ras_end = LLGroupMgr::getInstance()->mRoleActionSets.end(); - for ( ; ras_it != ras_end; ++ras_it) { buildActionCategory(ctrl, @@ -685,6 +718,33 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, row["columns"][column_index]["value"] = (*ra_it)->mDescription; row["columns"][column_index]["font"] = "SANSSERIF_SMALL"; + if (mHasGroupBanPower) + { + // The ban ability is being set. Prevent these abilities from being manipulated + if ((*ra_it)->mPowerBit == GP_MEMBER_EJECT) + { + row["enabled"] = false; + } + else if ((*ra_it)->mPowerBit == GP_ROLE_REMOVE_MEMBER) + { + row["enabled"] = false; + } + } + else + { + /* Singu Note: enabled should not be set on here if it was turned off above for another reason... right? Oh well, we'll find out. + */ + // The ban ability is not set. Allow these abilities to be manipulated + if ((*ra_it)->mPowerBit == GP_MEMBER_EJECT) + { + row["enabled"] = true; + } + else if ((*ra_it)->mPowerBit == GP_ROLE_REMOVE_MEMBER) + { + row["enabled"] = true; + } + } + LLScrollListItem* item = ctrl->addElement(row, ADD_BOTTOM, (*ra_it)); if (-1 != check_box_index) @@ -720,6 +780,15 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, check->setTentative(TRUE); } } + + // Regardless of whether or not this ability is allowed by all or some, we want to prevent + // the group managers from accidentally disabling either of the two additional abilities + // tied with GP_GROUP_BAN_ACCESS + if ( (allowed_by_all & GP_GROUP_BAN_ACCESS) == GP_GROUP_BAN_ACCESS || + (allowed_by_some & GP_GROUP_BAN_ACCESS) == GP_GROUP_BAN_ACCESS) + { + mHasGroupBanPower = true; + } } } @@ -739,10 +808,7 @@ void LLPanelGroupSubTab::setFooterEnabled(BOOL enable) } } -//////////////////////////// -// LLPanelGroupMembersSubTab -//////////////////////////// - +// LLPanelGroupMembersSubTab ///////////////////////////////////////////// // static void* LLPanelGroupMembersSubTab::createTab(void* data) { @@ -764,6 +830,14 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab(const std::string& name, co LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab() { + for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + } + mAvatarNameCacheConnections.clear(); } BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) @@ -804,9 +878,27 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) mEjectBtn->setEnabled(FALSE); } + mBanBtn = parent->getChild("member_ban", recurse); + if (mBanBtn) + { + mBanBtn->setClickedCallback(boost::bind(&LLPanelGroupMembersSubTab::handleBanMember,this)); + mBanBtn->setEnabled(FALSE); + } + return TRUE; } +void LLPanelGroupMembersSubTab::setGroupID(const LLUUID& id) +{ + //clear members list + if(mMembersList) mMembersList->deleteAllItems(); + if(mAssignedRolesList) mAssignedRolesList->deleteAllItems(); + if(mAllowedActionsList) mAllowedActionsList->deleteAllItems(); + + LLPanelGroupSubTab::setGroupID(id); +} + + // static void LLPanelGroupMembersSubTab::onMemberSelect(LLUICtrl* ctrl, void* user_data) @@ -836,7 +928,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() // Build a vector of all selected members, and gather allowed actions. uuid_vec_t selected_members; - U64 allowed_by_all = 0xffffffffffffLL; + U64 allowed_by_all = GP_ALL_POWERS; //0xffffffffffffLL; U64 allowed_by_some = 0; std::vector::iterator itor; @@ -873,8 +965,8 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() LLGroupMgrGroupData::role_list_t::iterator iter = gdatap->mRoles.begin(); LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end(); - BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID, - GP_MEMBER_EJECT); + BOOL can_ban_members = gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS); + BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_EJECT); BOOL member_is_owner = FALSE; for( ; iter != end; ++iter) @@ -921,6 +1013,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() { // Can't remove other owners. cb_enable = FALSE; + can_ban_members = FALSE; break; } } @@ -1004,7 +1097,10 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() mAssignedRolesList->setEnabled(TRUE); if (gAgent.isGodlike()) + { can_eject_members = TRUE; + can_ban_members = TRUE; + } if (!can_eject_members && !member_is_owner) { @@ -1017,10 +1113,41 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() if ( member_data && member_data->isInRole(gdatap->mOwnerRole) ) { can_eject_members = TRUE; + can_ban_members = TRUE; } } + + } + + // ... or we can eject them because we have all the requisite powers... + if ( gAgent.hasPowerInGroup(mGroupID, GP_ROLE_REMOVE_MEMBER) && + !member_is_owner) + { + if (gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_EJECT)) + { + can_eject_members = TRUE; + } + + if (gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) + { + can_ban_members = TRUE; + } } + + uuid_vec_t::const_iterator member_iter = selected_members.begin(); + uuid_vec_t::const_iterator member_end = selected_members.end(); + for ( ; member_iter != member_end; ++member_iter) + { + // Don't count the agent. + if ((*member_iter) == gAgent.getID()) + { + can_eject_members = FALSE; + can_ban_members = FALSE; + } + } + + mBanBtn->setEnabled(can_ban_members); mEjectBtn->setEnabled(can_eject_members); } @@ -1075,10 +1202,31 @@ void LLPanelGroupMembersSubTab::handleEjectMembers() mMembersList->deleteSelectedItems(); + sendEjectNotifications(mGroupID, selected_members); + LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members); } +void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members) +{ + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id); + + if (group_data) + { + for (uuid_vec_t::const_iterator i = selected_members.begin(); i != selected_members.end(); ++i) + { + LLSD args; + std::string av_name; + LLAvatarNameCache::getPNSName(*i, av_name); + args["AVATAR_NAME"] = av_name; + args["GROUP_NAME"] = group_data->mName; + + LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args)); + } + } +} + void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, LLRoleMemberChangeType type) { @@ -1087,12 +1235,11 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, //add that the user is requesting to change the roles for selected //members - U64 powers_all_have = 0xffffffffffffLL; + U64 powers_all_have = GP_ALL_POWERS; U64 powers_some_have = 0; BOOL is_owner_role = ( gdatap->mOwnerRole == role_id ); LLUUID member_id; - std::vector selection = mMembersList->getAllSelected(); if (selection.empty()) @@ -1103,7 +1250,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, for (std::vector::iterator itor = selection.begin() ; itor != selection.end(); ++itor) { - member_id = (*itor)->getUUID(); //see if we requested a change for this member before @@ -1169,7 +1315,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, FALSE); } - // static void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data) { @@ -1540,22 +1685,32 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data) LLNameListCtrl::NameItem item_params; item_params.value = data->getID(); - item_params.columns.add().column("name").font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/; + item_params.columns.add().column("name").font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL"); item_params.columns.add().column("donated").value(donated.getString()) - .font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/; + .font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL"); static const LLCachedControl format(gSavedSettings, "ShortDateFormat"); item_params.columns.add().column("online").value(data->getOnlineStatus()) .format(format).type(is_online_status_string(data->getOnlineStatus()) ? "text" : "date") - .font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/; + .font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL"); mMembersList->addNameItemRow(item_params); mHasMatch = TRUE; } -void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name) +void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id) { + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(av_id); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); + } + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); if (!gdatap || gdatap->getMemberVersion() != update_id @@ -1605,7 +1760,6 @@ void LLPanelGroupMembersSubTab::updateMembers() mMembersList->deleteAllItems(); } - LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); LLTimer update_time; @@ -1629,8 +1783,16 @@ void LLPanelGroupMembersSubTab::updateMembers() else { // If name is not cached, onNameCache() should be called when it is cached and add this member to list. - LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, - this, gdatap->getMemberVersion(), mMemberProgress->second, _2)); + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(mMemberProgress->first); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); + } + mAvatarNameCacheConnections[mMemberProgress->first] = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, this, gdatap->getMemberVersion(), mMemberProgress->second, _2, _1)); } } @@ -1655,12 +1817,35 @@ void LLPanelGroupMembersSubTab::updateMembers() handleMemberSelect(); } +void LLPanelGroupMembersSubTab::handleBanMember() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if (!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL; + return; + } + + // Singu Note: We have this function, so there's less code here. + uuid_vec_t ban_ids = mMembersList->getSelectedIDs(); + if (ban_ids.empty()) + { + return; + } + + uuid_vec_t::iterator itor; + for(itor = ban_ids.begin(); itor != ban_ids.end(); ++itor) + { + LLGroupBanData ban_data; + gdatap->createBanEntry(*itor, ban_data); + } + + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mGroupID, LLGroupMgr::BAN_CREATE, ban_ids); + handleEjectMembers(); +} -//////////////////////////// -// LLPanelGroupRolesSubTab -//////////////////////////// - +// LLPanelGroupRolesSubTab /////////////////////////////////////////////// // static void* LLPanelGroupRolesSubTab::createTab(void* data) { @@ -1679,7 +1864,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab(const std::string& name, const mMemberVisibleCheck(NULL), mDeleteRoleButton(NULL), mCreateRoleButton(NULL), - + mFirstOpen(TRUE), mHasRoleChange(FALSE) { } @@ -1779,6 +1964,7 @@ void LLPanelGroupRolesSubTab::deactivate() lldebugs << "LLPanelGroupRolesSubTab::deactivate()" << llendl; LLPanelGroupSubTab::deactivate(); + mFirstOpen = FALSE; } bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg) @@ -1786,6 +1972,12 @@ bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg) lldebugs << "LLPanelGroupRolesSubTab::needsApply()" << llendl; LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if (!gdatap) + { + llwarns << "Unable to get group data for group " << mGroupID << llendl; + return false; + } + return (mHasRoleChange // Text changed in current role || (gdatap && gdatap->pendingRoleChanges())); // Pending role changes in the group @@ -1796,7 +1988,7 @@ bool LLPanelGroupRolesSubTab::apply(std::string& mesg) lldebugs << "LLPanelGroupRolesSubTab::apply()" << llendl; saveRoleChanges(true); - + mFirstOpen = FALSE; LLGroupMgr::getInstance()->sendGroupRoleChanges(mGroupID); notifyObservers(); @@ -1933,14 +2125,17 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) } } - if (!gdatap || !gdatap->isMemberDataComplete()) + if (!mFirstOpen) { - LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); - } - - if (!gdatap || !gdatap->isRoleMemberDataComplete()) - { - LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); + if (!gdatap || !gdatap->isMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); + } + + if (!gdatap || !gdatap->isRoleMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); + } } if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc) @@ -1956,6 +2151,9 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) void LLPanelGroupRolesSubTab::onRoleSelect(LLUICtrl* ctrl, void* user_data) { LLPanelGroupRolesSubTab* self = static_cast(user_data); + if (!self) + return; + self->handleRoleSelect(); } @@ -2135,41 +2333,116 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force) LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata(); U64 power = rap->mPowerBit; - if (check->get()) + bool isEnablingAbility = check->get(); + LLRoleData rd; + LLSD args; + + if (isEnablingAbility && + !force && + ((GP_ROLE_ASSIGN_MEMBER == power) || (GP_ROLE_CHANGE_ACTIONS == power) )) { - if (!force && ( (GP_ROLE_ASSIGN_MEMBER == power) - || (GP_ROLE_CHANGE_ACTIONS == power) )) + // Uncheck the item, for now. It will be + // checked if they click 'Yes', below. + check->set(FALSE); + + LLRoleData rd; + LLSD args; + + if ( gdatap->getRoleData(role_id, rd) ) { - // Uncheck the item, for now. It will be - // checked if they click 'Yes', below. - check->set(FALSE); - - LLRoleData rd; - LLSD args; - - if ( gdatap->getRoleData(role_id, rd) ) + args["ACTION_NAME"] = rap->mDescription; + args["ROLE_NAME"] = rd.mRoleName; + mHasModal = TRUE; + std::string warning = "AssignDangerousActionWarning"; + if (GP_ROLE_CHANGE_ACTIONS == power) { - args["ACTION_NAME"] = rap->mDescription; - args["ROLE_NAME"] = rd.mRoleName; - mHasModal = TRUE; - std::string warning = "AssignDangerousActionWarning"; - if (GP_ROLE_CHANGE_ACTIONS == power) - { - warning = "AssignDangerousAbilityWarning"; - } - LLNotificationsUtil::add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check)); - } - else - { - llwarns << "Unable to look up role information for role id: " - << role_id << llendl; + warning = "AssignDangerousAbilityWarning"; } + LLNotificationsUtil::add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check)); } else { - gdatap->addRolePower(role_id,power); + llwarns << "Unable to look up role information for role id: " + << role_id << llendl; } } + + if (GP_GROUP_BAN_ACCESS == power) + { + std::string warning = isEnablingAbility ? "AssignBanAbilityWarning" : "RemoveBanAbilityWarning"; + + ////////////////////////////////////////////////////////////////////////// + // Get role data for both GP_ROLE_REMOVE_MEMBER and GP_MEMBER_EJECT + // Add description and role name to LLSD + // Pop up dialog saying "Yo, you also granted these other abilities when you did this!" + if (gdatap->getRoleData(role_id, rd)) + { + args["ACTION_NAME"] = rap->mDescription; + args["ROLE_NAME"] = rd.mRoleName; + mHasModal = TRUE; + + std::vector all_data = mAllowedActionsList->getAllData(); + std::vector::iterator ad_it = all_data.begin(); + std::vector::iterator ad_end = all_data.end(); + LLRoleAction* adp; + for( ; ad_it != ad_end; ++ad_it) + { + adp = (LLRoleAction*)(*ad_it)->getUserdata(); + if (adp->mPowerBit == GP_MEMBER_EJECT) + { + args["ACTION_NAME_2"] = adp->mDescription; + } + else if (adp->mPowerBit == GP_ROLE_REMOVE_MEMBER) + { + args["ACTION_NAME_3"] = adp->mDescription; + } + } + + LLNotificationsUtil::add(warning, args); + } + else + { + llwarns << "Unable to look up role information for role id: " + << role_id << llendl; + } + + ////////////////////////////////////////////////////////////////////////// + + LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.find(role_id); + U64 current_role_powers = GP_NO_POWERS; + if (rit != gdatap->mRoles.end()) + { + current_role_powers = ((*rit).second->getRoleData().mRolePowers); + } + + if (isEnablingAbility) + { + power |= (GP_ROLE_REMOVE_MEMBER | GP_MEMBER_EJECT); + current_role_powers |= power; + } + else + { + current_role_powers &= ~GP_GROUP_BAN_ACCESS; + } + + mAllowedActionsList->deleteAllItems(); + buildActionsList( mAllowedActionsList, + current_role_powers, + current_role_powers, + boost::bind(&LLPanelGroupRolesSubTab::handleActionCheck, this, _1, false), + TRUE, + FALSE, + FALSE); + + } + + ////////////////////////////////////////////////////////////////////////// + // Adding non-specific ability to role + ////////////////////////////////////////////////////////////////////////// + if (isEnablingAbility) + { + gdatap->addRolePower(role_id, power); + } else { gdatap->removeRolePower(role_id,power); @@ -2177,6 +2450,7 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force) mHasRoleChange = TRUE; notifyObservers(); + } bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check) @@ -2196,7 +2470,6 @@ bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& return false; } - // static void LLPanelGroupRolesSubTab::onPropertiesKey(LLLineEditor* ctrl, void* user_data) { @@ -2374,10 +2647,26 @@ void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role) mHasRoleChange = FALSE; } } -//////////////////////////// -// LLPanelGroupActionsSubTab -//////////////////////////// +void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id) +{ + if (mRolesList) mRolesList->deleteAllItems(); + if (mAssignedMembersList) mAssignedMembersList->deleteAllItems(); + if (mAllowedActionsList) mAllowedActionsList->deleteAllItems(); + + if (mRoleName) mRoleName->clear(); + if (mRoleDescription) mRoleDescription->clear(); + if (mRoleTitle) mRoleTitle->clear(); + + mHasRoleChange = FALSE; + + setFooterEnabled(FALSE); + + LLPanelGroupSubTab::setGroupID(id); +} + + +// LLPanelGroupActionsSubTab ///////////////////////////////////////////// // static void* LLPanelGroupActionsSubTab::createTab(void* data) { @@ -2555,3 +2844,223 @@ void LLPanelGroupActionsSubTab::handleActionSelect() LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); } } + +void LLPanelGroupActionsSubTab::setGroupID(const LLUUID& id) +{ + if (mActionList) mActionList->deleteAllItems(); + if (mActionRoles) mActionRoles->deleteAllItems(); + if (mActionMembers) mActionMembers->deleteAllItems(); + + if (mActionDescription) mActionDescription->clear(); + + LLPanelGroupSubTab::setGroupID(id); +} + +// LLPanelGroupBanListSubTab ///////////////////////////////////////////// +// static +void* LLPanelGroupBanListSubTab::createTab(void* data) +{ + LLUUID* group_id = static_cast(data); + return new LLPanelGroupBanListSubTab("panel group ban list sub tab", *group_id); +} + +LLPanelGroupBanListSubTab::LLPanelGroupBanListSubTab(const std::string& name, const LLUUID& group_id) + : LLPanelGroupSubTab(name, group_id), + mBanList(NULL), + mCreateBanButton(NULL), + mDeleteBanButton(NULL) +{} + +BOOL LLPanelGroupBanListSubTab::postBuildSubTab(LLView* root) +{ + LLPanelGroupSubTab::postBuildSubTab(root); + + // Upcast parent so we can ask it for sibling controls. + LLPanelGroupRoles* parent = (LLPanelGroupRoles*)root; + + // Look recursively from the parent to find all our widgets. + bool recurse = true; + + mHeader = parent->getChild("banlist_header", recurse); + mFooter = parent->getChild("banlist_footer", recurse); + + mBanList = parent->getChild("ban_list", recurse); + + mCreateBanButton = parent->getChild("ban_create", recurse); + mDeleteBanButton = parent->getChild("ban_delete", recurse); + mRefreshBanListButton = parent->getChild("ban_refresh", recurse); + + if (!mBanList || !mCreateBanButton || !mDeleteBanButton || !mRefreshBanListButton) + return FALSE; + + mBanList->setCommitOnSelectionChange(TRUE); + mBanList->setCommitCallback(boost::bind(&LLPanelGroupBanListSubTab::handleBanEntrySelect, this)); + + mCreateBanButton->setCommitCallback(boost::bind(&LLPanelGroupBanListSubTab::handleCreateBanEntry, this)); + mCreateBanButton->setEnabled(FALSE); + + mDeleteBanButton->setCommitCallback(boost::bind(&LLPanelGroupBanListSubTab::handleDeleteBanEntry, this)); + mDeleteBanButton->setEnabled(FALSE); + + mRefreshBanListButton->setCommitCallback(boost::bind(&LLPanelGroupBanListSubTab::handleRefreshBanList, this)); + mRefreshBanListButton->setEnabled(FALSE); + + mBanList->setOnNameListCompleteCallback(boost::bind(&LLPanelGroupBanListSubTab::onBanListCompleted, this, _1)); + + populateBanList(); + + //setFooterEnabled(FALSE); // Singu Note: This probably serves no purpose upstream, but for us, we need the footer enabled because we use it to make use of this entire panel. + return TRUE; +} + +void LLPanelGroupBanListSubTab::activate() +{ + LLPanelGroupSubTab::activate(); + + mBanList->deselectAllItems(); + mDeleteBanButton->setEnabled(FALSE); + + mCreateBanButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)); + + // BAKER: Should I really request everytime activate() is called? + // Perhaps I should only do it on a force refresh, or if an action on the list happens... + // Because it's not going to live-update the list anyway... You'd have to refresh if you + // wanted to see someone else's additions anyway... + // + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); + + //setFooterEnabled(FALSE); // Singu Note: This probably serves no purpose upstream, but for us, we need the footer enabled because we use it to make use of this entire panel. + update(GC_ALL); +} + +void LLPanelGroupBanListSubTab::update(LLGroupChange gc) +{ + populateBanList(); +} + +void LLPanelGroupBanListSubTab::draw() +{ + LLPanelGroupSubTab::draw(); + + // BAKER: Might be good to put it here instead of update, maybe.. See how often draw gets hit. + //if( + // populateBanList(); +} + +void LLPanelGroupBanListSubTab::handleBanEntrySelect() +{ + if (gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) + { + mDeleteBanButton->setEnabled(!!mBanList->getFirstSelected()); // Singu Note: Avoid empty selection. + } +} + +void LLPanelGroupBanListSubTab::handleCreateBanEntry() +{ + LLFloaterGroupBulkBan::showForGroup(mGroupID); + //populateBanList(); +} + +void LLPanelGroupBanListSubTab::handleDeleteBanEntry() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if (!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL; + return; + } + + // Singu Note: We have this function, so there's less code here. + uuid_vec_t ban_ids = mBanList->getSelectedIDs(); + if (ban_ids.empty()) + { + return; + } + + bool can_ban_members = false; + if (gAgent.isGodlike() || + gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) + { + can_ban_members = true; + } + + // Owners can ban anyone in the group. + LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find(gAgent.getID()); + if (mi != gdatap->mMembers.end()) + { + LLGroupMemberData* member_data = (*mi).second; + if (member_data && member_data->isInRole(gdatap->mOwnerRole)) + { + can_ban_members = true; + } + } + + if (!can_ban_members) + return; + + uuid_vec_t::iterator itor; + for(itor = ban_ids.begin(); itor != ban_ids.end(); ++itor) + { + LLUUID ban_id = (*itor); + + gdatap->removeBanEntry(ban_id); + mBanList->removeNameItem(ban_id); + + } + // Removing an item removes the selection, we shouldn't be able to click the button anymore until we reselect another entry. + mDeleteBanButton->setEnabled(FALSE); + + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mGroupID, LLGroupMgr::BAN_DELETE, ban_ids); +} + +void LLPanelGroupBanListSubTab::handleRefreshBanList() +{ + mRefreshBanListButton->setEnabled(FALSE); + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); +} + +void LLPanelGroupBanListSubTab::onBanListCompleted(bool isComplete) +{ + if (isComplete) + { + mRefreshBanListButton->setEnabled(TRUE); + populateBanList(); + } +} + +void LLPanelGroupBanListSubTab::populateBanList() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if (!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL; + return; + } + + mBanList->deleteAllItems(); + std::map::const_iterator entry = gdatap->mBanList.begin(); + for(; entry != gdatap->mBanList.end(); entry++) + { + LLNameListCtrl::NameItem ban_entry; + ban_entry.value = entry->first; + LLGroupBanData bd = entry->second; + + ban_entry.columns.add().column("name").font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL"); + + // Singu Note: We have special date columns, so our code is unique here + ban_entry.columns.add().column("ban_date").value(bd.mBanDate).type("date").format("%Y/%m%d").font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL"); + + mBanList->addNameItemRow(ban_entry); + } + + mRefreshBanListButton->setEnabled(TRUE); +} + +void LLPanelGroupBanListSubTab::setGroupID(const LLUUID& id) +{ + if (mBanList) + mBanList->deleteAllItems(); + + //setFooterEnabled(FALSE); + LLPanelGroupSubTab::setGroupID(id); +} diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index fe1103f2f..aaf60c7a6 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -46,11 +46,9 @@ class LLScrollListItem; class LLTextEditor; class LLGroupMemberData; -// Forward declare for friend usage. -//virtual BOOL LLPanelGroupSubTab::postBuildSubTab(LLView*); - typedef std::map icon_map_t; + class LLPanelGroupRoles : public LLPanelGroupTab, public LLPanelGroupTabObserver { @@ -89,6 +87,8 @@ public: virtual void cancel(); virtual void update(LLGroupChange gc); + virtual void setGroupID(const LLUUID& id); + // PanelGroupTab observer trigger virtual void tabChanged(); @@ -103,6 +103,7 @@ protected: std::string mWantApplyMesg; }; + class LLPanelGroupSubTab : public LLPanelGroupTab { public: @@ -123,6 +124,8 @@ public: bool matchesActionSearchFilter(std::string action); void setFooterEnabled(BOOL enable); + + virtual void setGroupID(const LLUUID& id); protected: void buildActionsList(LLScrollListCtrl* ctrl, U64 allowed_by_some, @@ -152,9 +155,13 @@ protected: bool mActivated; + bool mHasGroupBanPower; // Used to communicate between action sets due to the dependency between + // GP_GROUP_BAN_ACCESS and GP_EJECT_MEMBER and GP_ROLE_REMOVE_MEMBER + void setOthersVisible(BOOL b); }; + class LLPanelGroupMembersSubTab : public LLPanelGroupSubTab { public: @@ -176,11 +183,15 @@ public: static void onEjectMembers(void*); void handleEjectMembers(); + void sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members); static void onRoleCheck(LLUICtrl* check, void* user_data); void handleRoleCheck(const LLUUID& role_id, LLRoleMemberChangeType type); + void handleBanMember(); + + void applyMemberChanges(); bool addOwnerCB(const LLSD& notification, const LLSD& response); @@ -194,8 +205,10 @@ public: virtual void draw(); + virtual void setGroupID(const LLUUID& id); + void addMemberToList(LLGroupMemberData* data); - void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name); + void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id); protected: typedef std::map role_change_data_map_t; @@ -212,6 +225,7 @@ protected: LLScrollListCtrl* mAssignedRolesList; LLScrollListCtrl* mAllowedActionsList; LLButton* mEjectBtn; + LLButton* mBanBtn; BOOL mChanged; BOOL mPendingMemberUpdate; @@ -221,8 +235,11 @@ protected: U32 mNumOwnerAdditions; LLGroupMgrGroupData::member_list_t::iterator mMemberProgress; + typedef std::map avatar_name_cache_connection_map_t; + avatar_name_cache_connection_map_t mAvatarNameCacheConnections; }; + class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab { public: @@ -263,6 +280,11 @@ public: void handleDeleteRole(); void saveRoleChanges(bool select_saved_role); + + virtual void setGroupID(const LLUUID& id); + + BOOL mFirstOpen; + protected: void handleActionCheck(LLUICtrl* ctrl, bool force); LLSD createRoleItem(const LLUUID& role_id, std::string name, std::string title, S32 members); @@ -284,6 +306,7 @@ protected: std::string mRemoveEveryoneTxt; }; + class LLPanelGroupActionsSubTab : public LLPanelGroupSubTab { public: @@ -301,6 +324,8 @@ public: virtual void update(LLGroupChange gc); void handleActionSelect(); + + virtual void setGroupID(const LLUUID& id); protected: LLScrollListCtrl* mActionList; LLScrollListCtrl* mActionRoles; @@ -310,4 +335,42 @@ protected: }; +class LLPanelGroupBanListSubTab : public LLPanelGroupSubTab +{ +public: + LLPanelGroupBanListSubTab(const std::string& name, const LLUUID& group_id); + virtual ~LLPanelGroupBanListSubTab() {} + + virtual BOOL postBuildSubTab(LLView* root); + + static void* createTab(void* data); + + virtual void activate(); + virtual void update(LLGroupChange gc); + virtual void draw(); + + void handleBanEntrySelect(); + + void handleCreateBanEntry(); + + void handleDeleteBanEntry(); + + void handleRefreshBanList(); + + void onBanListCompleted(bool isComplete); + +protected: + void populateBanList(); + +public: + virtual void setGroupID(const LLUUID& id); + +protected: + LLNameListCtrl* mBanList; + LLButton* mCreateBanButton; + LLButton* mDeleteBanButton; + LLButton* mRefreshBanListButton; + +}; + #endif // LL_LLPANELGROUPROLES_H diff --git a/indra/newview/llpanelgroupvoting.cpp b/indra/newview/llpanelgroupvoting.cpp index f45cd2818..7ea149966 100644 --- a/indra/newview/llpanelgroupvoting.cpp +++ b/indra/newview/llpanelgroupvoting.cpp @@ -688,7 +688,7 @@ public: } //If we get back a normal response, handle it here - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { //Ack'd the proposal initialization, now let's finish up. LLPanelGroupVoting::handleResponse( @@ -697,10 +697,10 @@ public: } //If we get back an error (not found, etc...), handle it here - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { llinfos << "LLPanelGroupVotingResponder::error " - << status << ": " << reason << llendl; + << mStatus << ": " << mReason << llendl; LLPanelGroupVoting::handleFailure(mGroupID); } @@ -721,20 +721,20 @@ public: } //If we get back a normal response, handle it here - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { //Ack'd the proposal initialization, now let's finish up. LLPanelGroupVoting::handleResponse( mGroupID, LLPanelGroupVoting::BALLOT, - content["voted"].asBoolean()); + mContent["voted"].asBoolean()); } //If we get back an error (not found, etc...), handle it here - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { llinfos << "LLPanelGroupVotingResponder::error " - << status << ": " << reason << llendl; + << mStatus << ": " << mReason << llendl; LLPanelGroupVoting::handleFailure(mGroupID); } diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp index 526ade3e9..4b4755c25 100644 --- a/indra/newview/llpanelland.cpp +++ b/indra/newview/llpanelland.cpp @@ -155,13 +155,13 @@ void LLPanelLandInfo::refresh() && ((gAgent.getID() == auth_buyer_id) || (auth_buyer_id.isNull()))); - if (is_public) + if (is_public && !LLViewerParcelMgr::getInstance()->getParcelSelection()->getMultipleOwners()) { - childSetEnabled("button buy land",TRUE); + getChildView("button buy land")->setEnabled(TRUE); } else { - childSetEnabled("button buy land",can_buy); + getChildView("button buy land")->setEnabled(can_buy); } BOOL owner_release = LLViewerParcelMgr::isParcelOwnedByAgent(parcel, GP_LAND_RELEASE); diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index e96e4d368..74712a649 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -154,7 +154,6 @@ public: LLLoginRefreshHandler gLoginRefreshHandler; - //--------------------------------------------------------------------------- // Public methods //--------------------------------------------------------------------------- @@ -191,6 +190,8 @@ LLPanelLogin::LLPanelLogin(const LLRect& rect) password_edit->setCommitCallback(mungePassword, this); password_edit->setDrawAsterixes(TRUE); + getChild("remove_login")->setCommitCallback(boost::bind(&LLPanelLogin::confirmDelete, this)); + // change z sort of clickable text to be behind buttons sendChildToBack(getChildView("channel_text")); sendChildToBack(getChildView("forgot_password_text")); @@ -354,6 +355,8 @@ void LLPanelLogin::reshapeBrowser() LLPanelLogin::~LLPanelLogin() { + std::string login_hist_filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "saved_logins_sg2.xml"); + LLSavedLogins::saveFile(mLoginHistoryData, login_hist_filepath); LLPanelLogin::sInstance = NULL; if ( gFocusMgr.getDefaultKeyboardFocus() == this ) @@ -738,21 +741,24 @@ void LLPanelLogin::updateGridCombo() const HippoGridInfo *curGrid = gHippoGridManager->getCurrentGrid(); const HippoGridInfo *defGrid = gHippoGridManager->getGrid(defaultGrid); + S32 idx(-1); HippoGridManager::GridIterator it, end = gHippoGridManager->endGrid(); for (it = gHippoGridManager->beginGrid(); it != end; ++it) { std::string grid = it->second->getGridName(); - if(grid.empty() || it->second == defGrid || it->second == curGrid) + if (grid.empty() || it->second == defGrid) continue; + if (it->second == curGrid) idx = grids->getItemCount(); grids->add(grid); } - if(curGrid || defGrid) + if (curGrid || defGrid) { - if(defGrid) + if (defGrid) + { grids->add(defGrid->getGridName(),ADD_TOP); - if(curGrid && defGrid != curGrid) - grids->add(curGrid->getGridName(),ADD_TOP); - grids->setCurrentByIndex(0); + ++idx; + } + grids->setCurrentByIndex(idx); } else { @@ -1127,3 +1133,23 @@ void LLPanelLogin::clearPassword() sInstance->mIncomingPassword = blank; sInstance->mMungedPassword = blank; } + +void LLPanelLogin::confirmDelete() +{ + LLNotificationsUtil::add("ConfirmDeleteUser", LLSD(), LLSD(), boost::bind(&LLPanelLogin::removeLogin, this, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); +} + +void LLPanelLogin::removeLogin(bool knot) +{ + if (knot) return; + LLComboBox* combo(getChild("username_combo")); + const std::string label(combo->getTextEntry()); + if (combo->isTextDirty() || !combo->itemExists(label)) return; // Text entries aren't in the list + const LLSD& selected = combo->getSelectedValue(); + if (!selected.isUndefined()) + { + mLoginHistoryData.deleteEntry(selected.get("firstname").asString(), selected.get("lastname").asString(), selected.get("grid").asString()); + combo->remove(label); + combo->selectFirstItem(); + } +} diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 05c4c3b18..35c3f5890 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -118,6 +118,8 @@ private: void onLoginComboLostFocus(LLComboBox* combo_box); static void onNameCheckChanged(LLUICtrl* ctrl, void* data); static void clearPassword(); + void confirmDelete(); + void removeLogin(bool knot); public: diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 3ebc38710..5fa463a34 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -70,10 +70,10 @@ #include "lllayoutstack.h" // Functions pulled from pipeline.cpp -glh::matrix4f glh_get_current_modelview(); -glh::matrix4f glh_get_current_projection(); +const LLMatrix4a& glh_get_current_modelview(); +const LLMatrix4a& glh_get_current_projection(); // Functions pulled from llviewerdisplay.cpp -bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model); +bool get_hud_matrices(LLMatrix4a &proj, LLMatrix4a &model); // Warning: make sure these two match! const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels[] = { ZOOM_NONE, ZOOM_MEDIUM }; @@ -609,37 +609,45 @@ void LLPanelPrimMediaControls::updateShape() vert_it = vect_face.begin(); vert_end = vect_face.end(); - glh::matrix4f mat; + LLMatrix4a mat; if (!is_hud) { - mat = glh_get_current_projection() * glh_get_current_modelview(); + mat.setMul(glh_get_current_projection(),glh_get_current_modelview()); } else { - glh::matrix4f proj, modelview; + LLMatrix4a proj, modelview; if (get_hud_matrices(proj, modelview)) - mat = proj * modelview; + { + //mat = proj * modelview; + mat.setMul(proj,modelview); + } } - LLVector3 min = LLVector3(1,1,1); - LLVector3 max = LLVector3(-1,-1,-1); + LLVector4a min; + min.splat(1.f); + LLVector4a max; + max.splat(-1.f); for(; vert_it != vert_end; ++vert_it) { // project silhouette vertices into screen space - glh::vec3f screen_vert = glh::vec3f(vert_it->mV); - mat.mult_matrix_vec(screen_vert); - + LLVector4a screen_vert; + screen_vert.load3(vert_it->mV,1.f); + + mat.perspectiveTransform(screen_vert,screen_vert); + // add to screenspace bounding box - update_min_max(min, max, LLVector3(screen_vert.v)); + min.setMin(screen_vert,min); + max.setMax(screen_vert,max); } // convert screenspace bbox to pixels (in screen coords) LLRect window_rect = gViewerWindow->getWorldViewRectScaled(); LLCoordGL screen_min; - screen_min.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (min.mV[VX] + 1.f) * 0.5f); - screen_min.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (min.mV[VY] + 1.f) * 0.5f); + screen_min.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (min.getF32ptr()[VX] + 1.f) * 0.5f); + screen_min.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (min.getF32ptr()[VY] + 1.f) * 0.5f); LLCoordGL screen_max; - screen_max.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (max.mV[VX] + 1.f) * 0.5f); - screen_max.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (max.mV[VY] + 1.f) * 0.5f); + screen_max.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (max.getF32ptr()[VX] + 1.f) * 0.5f); + screen_max.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (max.getF32ptr()[VY] + 1.f) * 0.5f); // grow panel so that screenspace bounding box fits inside "media_region" element of panel LLRect media_panel_rect; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 8237555ca..5fddee427 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -96,7 +96,14 @@ public: return false; } - const std::string verb = params[1].asString(); + std::string verb = params[1].asString(); +#if LL_WINDOWS // C++11 + while (!verb.empty() && std::ispunct(verb.back())) + verb.pop_back(); +#else + for (size_t i = verb.size()-1; i >= 0 && std::ispunct(verb[i]); --i) + verb.erase(i); +#endif if (verb == "about") { LLAvatarActions::showProfile(avatar_id); diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 86db29ccb..96a9940a4 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -140,7 +140,7 @@ void LLParticipantList::handleSpeakerSelect() { const LLUUID& speaker_id = mAvatarList->getValue().asUUID(); LLPointer selected_speakerp = mSpeakerMgr->findSpeaker(speaker_id); - if (speaker_id.isNull() || selected_speakerp.isNull()) + if (speaker_id.isNull() || selected_speakerp.isNull() || mAvatarList->getNumSelected() != 1) { // Disable normal controls if (LLView* view = findChild("mute_btn")) diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index 783c728c0..79147655b 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -116,8 +116,8 @@ public: NavMeshStatusResponder(const std::string &pCapabilityURL, LLViewerRegion *pRegion, bool pIsGetStatusOnly); virtual ~NavMeshStatusResponder(); - /*virtual*/ void result(const LLSD &pContent); - /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return navMeshStatusResponder_timeout; } /*virtual*/ char const* getName(void) const { return "NavMeshStatusResponder"; } @@ -140,8 +140,8 @@ public: NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr); virtual ~NavMeshResponder(); - /*virtual*/ void result(const LLSD &pContent); - /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return navMeshResponder_timeout; } /*virtual*/ char const* getName(void) const { return "NavMeshResponder"; } @@ -163,8 +163,8 @@ public: AgentStateResponder(const std::string &pCapabilityURL); virtual ~AgentStateResponder(); - /*virtual*/ void result(const LLSD &pContent); - /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return agentStateResponder_timeout; } /*virtual*/ char const* getName(void) const { return "AgentStateResponder"; } @@ -184,8 +184,8 @@ public: NavMeshRebakeResponder(const std::string &pCapabilityURL, LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback); virtual ~NavMeshRebakeResponder(); - /*virtual*/ void result(const LLSD &pContent); - /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return navMeshRebakeResponder_timeout; } /*virtual*/ char const* getName(void) const { return "NavMeshRebakeResponder"; } @@ -245,8 +245,8 @@ public: ObjectLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr); virtual ~ObjectLinksetsResponder(); - /*virtual*/ void result(const LLSD &pContent); - /*virtual*/ void error(U32 pStatus, const std::string &pReason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return objectLinksetsResponder_timeout; } /*virtual*/ char const* getName(void) const { return "ObjectLinksetsResponder"; } @@ -266,8 +266,8 @@ public: TerrainLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr); virtual ~TerrainLinksetsResponder(); - /*virtual*/ void result(const LLSD &pContent); - /*virtual*/ void error(U32 pStatus, const std::string &pReason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return terrainLinksetsResponder_timeout; } /*virtual*/ char const* getName(void) const { return "TerrainLinksetsResponder"; } @@ -287,8 +287,8 @@ public: CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback); virtual ~CharactersResponder(); - /*virtual*/ void result(const LLSD &pContent); - /*virtual*/ void error(U32 pStatus, const std::string &pReason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return charactersResponder_timeout; } /*virtual*/ char const* getName(void) const { return "CharactersResponder"; } @@ -813,15 +813,15 @@ NavMeshStatusResponder::~NavMeshStatusResponder() { } -void NavMeshStatusResponder::result(const LLSD &pContent) +void NavMeshStatusResponder::httpSuccess(void) { - LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID, pContent); + LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID, mContent); LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly); } -void NavMeshStatusResponder::error(U32 pStatus, const std::string& pReason) +void NavMeshStatusResponder::httpFailure(void) { - llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + llwarns << "error with request to URL '" << mCapabilityURL << "' because " << mReason << " (statusCode:" << mStatus << ")" << llendl; LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID); LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly); } @@ -841,14 +841,14 @@ NavMeshResponder::~NavMeshResponder() { } -void NavMeshResponder::result(const LLSD &pContent) +void NavMeshResponder::httpSuccess(void) { - mNavMeshPtr->handleNavMeshResult(pContent, mNavMeshVersion); + mNavMeshPtr->handleNavMeshResult(mContent, mNavMeshVersion); } -void NavMeshResponder::error(U32 pStatus, const std::string& pReason) +void NavMeshResponder::httpFailure(void) { - mNavMeshPtr->handleNavMeshError(pStatus, pReason, mCapabilityURL, mNavMeshVersion); + mNavMeshPtr->handleNavMeshError(mStatus, mReason, mCapabilityURL, mNavMeshVersion); } //--------------------------------------------------------------------------- @@ -863,17 +863,17 @@ AgentStateResponder::~AgentStateResponder() { } -void AgentStateResponder::result(const LLSD &pContent) +void AgentStateResponder::httpSuccess(void) { - llassert(pContent.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD)); - llassert(pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean()); - BOOL canRebakeRegion = pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean(); + llassert(mContent.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD)); + llassert(mContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean()); + BOOL canRebakeRegion = mContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean(); LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion); } -void AgentStateResponder::error(U32 pStatus, const std::string &pReason) +void AgentStateResponder::httpFailure(void) { - llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + llwarns << "error with request to URL '" << mCapabilityURL << "' because " << mReason << " (statusCode:" << mStatus << ")" << llendl; LLPathfindingManager::getInstance()->handleAgentState(FALSE); } @@ -891,14 +891,14 @@ NavMeshRebakeResponder::~NavMeshRebakeResponder() { } -void NavMeshRebakeResponder::result(const LLSD &pContent) +void NavMeshRebakeResponder::httpSuccess(void) { mRebakeNavMeshCallback(true); } -void NavMeshRebakeResponder::error(U32 pStatus, const std::string &pReason) +void NavMeshRebakeResponder::httpFailure(void) { - llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + llwarns << "error with request to URL '" << mCapabilityURL << "' because " << mReason << " (statusCode:" << mStatus << ")" << llendl; mRebakeNavMeshCallback(false); } @@ -997,14 +997,14 @@ ObjectLinksetsResponder::~ObjectLinksetsResponder() { } -void ObjectLinksetsResponder::result(const LLSD &pContent) +void ObjectLinksetsResponder::httpSuccess(void) { - mLinksetsResponsderPtr->handleObjectLinksetsResult(pContent); + mLinksetsResponsderPtr->handleObjectLinksetsResult(mContent); } -void ObjectLinksetsResponder::error(U32 pStatus, const std::string &pReason) +void ObjectLinksetsResponder::httpFailure(void) { - mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, mCapabilityURL); + mLinksetsResponsderPtr->handleObjectLinksetsError(mStatus, mReason, mCapabilityURL); } //--------------------------------------------------------------------------- @@ -1021,14 +1021,14 @@ TerrainLinksetsResponder::~TerrainLinksetsResponder() { } -void TerrainLinksetsResponder::result(const LLSD &pContent) +void TerrainLinksetsResponder::httpSuccess(void) { - mLinksetsResponsderPtr->handleTerrainLinksetsResult(pContent); + mLinksetsResponsderPtr->handleTerrainLinksetsResult(mContent); } -void TerrainLinksetsResponder::error(U32 pStatus, const std::string &pReason) +void TerrainLinksetsResponder::httpFailure(void) { - mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, mCapabilityURL); + mLinksetsResponsderPtr->handleTerrainLinksetsError(mStatus, mReason, mCapabilityURL); } //--------------------------------------------------------------------------- @@ -1046,15 +1046,15 @@ CharactersResponder::~CharactersResponder() { } -void CharactersResponder::result(const LLSD &pContent) +void CharactersResponder::httpSuccess(void) { - LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(pContent)); + LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(mContent)); mCharactersCallback(mRequestId, LLPathfindingManager::kRequestCompleted, characterListPtr); } -void CharactersResponder::error(U32 pStatus, const std::string &pReason) +void CharactersResponder::httpFailure(void) { - llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + llwarns << "error with request to URL '" << mCapabilityURL << "' because " << mReason << " (statusCode:" << mStatus << ")" << llendl; LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList()); mCharactersCallback(mRequestId, LLPathfindingManager::kRequestError, characterListPtr); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index ca82b2c3b..1ef801423 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -64,23 +64,14 @@ #include "llagent.h" #include "llmenugl.h" #include "roles_constants.h" +#include "llfloatersearchreplace.h" +#include "llfloaterperms.h" #include "llselectmgr.h" #include "llviewerinventory.h" #include "llviewermenu.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" -#include "llkeyboard.h" -#include "llscrollcontainer.h" -#include "llcheckboxctrl.h" -#include "llselectmgr.h" -#include "lltooldraganddrop.h" -#include "llscrolllistctrl.h" -#include "lltextbox.h" -#include "llslider.h" -#include "lldir.h" -#include "llcombobox.h" -#include "llfloatersearchreplace.h" #include "llviewerstats.h" #include "llviewertexteditor.h" #include "llviewerwindow.h" @@ -88,7 +79,6 @@ #include "llmediactrl.h" #include "lluictrlfactory.h" #include "lltrans.h" -#include "llviewercontrol.h" #include "llappviewer.h" #include "llsdserialize.h" @@ -1207,18 +1197,6 @@ bool LLScriptEdContainer::onExternalChange(const std::string& filename) return true; } -// virtual -void LLScriptEdContainer::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLPreview::reshape(width, height, called_from_parent); - - if (!isMinimized()) - { - // So that next time you open a script it will have the same height and width (although not the same position). - gSavedSettings.setRect("PreviewScriptRect", getRect()); - } -} - // // virtual BOOL LLScriptEdContainer::canSaveAs() const @@ -1891,7 +1869,7 @@ void LLLiveLSLEditor::loadAsset() mIsModifiable = item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE); - + refreshFromItem(item); // This is commented out, because we don't completely // handle script exports yet. /* @@ -1914,7 +1892,7 @@ void LLLiveLSLEditor::loadAsset() mScriptEd->enableSave(FALSE); LLPermissions perm; perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, gAgent.getGroupID()); - perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER); + perm.initMasks(PERM_ALL, PERM_ALL, LLFloaterPerms::getEveryonePerms("Scripts"), LLFloaterPerms::getGroupPerms("Scripts"), LLFloaterPerms::getNextOwnerPerms("Scripts")); mItem = new LLViewerInventoryItem(mItemUUID, mObjectUUID, perm, diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 906708333..ac95da40c 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -197,7 +197,6 @@ protected: LLTextEditor* getEditor() { return mScriptEd->mEditor; } /*virtual*/ const char *getTitleName() const { return "Script"; } - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); // /*virtual*/ BOOL canSaveAs() const; /*virtual*/ void saveAs(); diff --git a/indra/newview/llproductinforequest.cpp b/indra/newview/llproductinforequest.cpp index 27aeea77e..e0d9cdc4b 100644 --- a/indra/newview/llproductinforequest.cpp +++ b/indra/newview/llproductinforequest.cpp @@ -46,16 +46,15 @@ class LLProductInfoRequestResponder : public LLHTTPClient::ResponderWithResult { public: //If we get back a normal response, handle it here - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { - LLProductInfoRequestManager::instance().setSkuDescriptions(content); + LLProductInfoRequestManager::instance().setSkuDescriptions(mContent); } //If we get back an error (not found, etc...), handle it here - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { - llwarns << "LLProductInfoRequest::error(" - << status << ": " << reason << ")" << llendl; + llwarns << "httpFailure: " << dumpResponse() << llendl; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return productInfoRequestResponder_timeout; } diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index f8fbe5740..1f7bf144d 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -53,9 +53,9 @@ LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandlesetErrorStatus(status, reason); + observer->setErrorStatus(mStatus, mReason); } } diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h index 922a77a5b..ffc4adc11 100644 --- a/indra/newview/llremoteparcelrequest.h +++ b/indra/newview/llremoteparcelrequest.h @@ -49,10 +49,10 @@ public: LLRemoteParcelRequestResponder(LLHandle observer_handle); //If we get back a normal response, handle it here - /*virtual*/ void result(const LLSD& content); + /*virtual*/ void httpSuccess(void); //If we get back an error (not found, etc...), handle it here - /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return remoteParcelRequestResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLRemoteParcelRequestResponder"; } diff --git a/indra/newview/llsavedlogins.h b/indra/newview/llsavedlogins.h index 5461bae8e..1ca24c132 100644 --- a/indra/newview/llsavedlogins.h +++ b/indra/newview/llsavedlogins.h @@ -158,7 +158,7 @@ public: * @brief Deletes a login history entry by looking up its name and grid. * @param firstname First name to find and delete. * @param lastname Last name to find and delete. - * @param grid grif nickname to find and delete. + * @param grid grid nickname to find and delete. */ void deleteEntry(const std::string& firstname, const std::string& lastname, const std::string& grid); /** diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp index 1e208f64d..edf3ee170 100644 --- a/indra/newview/llscrollingpanelparam.cpp +++ b/indra/newview/llscrollingpanelparam.cpp @@ -77,10 +77,6 @@ LLScrollingPanelParam::LLScrollingPanelParam( const std::string& name, mHintMin->setAllowsUpdates( FALSE ); mHintMax->setAllowsUpdates( FALSE ); - std::string min_name = LLTrans::getString(param->getMinDisplayName()); - std::string max_name = LLTrans::getString(param->getMaxDisplayName()); - childSetValue("min param text", min_name); - childSetValue("max param text", max_name); mLess = getChild("less"); mLess->setMouseDownCallback( boost::bind(&LLScrollingPanelParam::onHintMouseDown, this, false) ); mLess->setMouseUpCallback( boost::bind(&LLScrollingPanelParam::onHintMouseUp, this, false) ); @@ -93,6 +89,10 @@ LLScrollingPanelParam::LLScrollingPanelParam( const std::string& name, mMore->setHeldDownCallback( boost::bind(&LLScrollingPanelParam::onHintHeldDown, this, true) ); mMore->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD ); } + mMinText = getChildView("min param text"); + mMinText->setValue(LLTrans::getString(param->getMinDisplayName())); + mMaxText = getChildView("max param text"); + mMaxText->setValue(LLTrans::getString(param->getMaxDisplayName())); setVisible(FALSE); setBorderVisible( FALSE ); @@ -157,9 +157,6 @@ void LLScrollingPanelParam::draw() if(mMore) mMore->setVisible(mHintMax && mHintMax->getVisible()); - // Draw all the children except for the labels - childSetVisible( "min param text", FALSE ); - childSetVisible( "max param text", FALSE ); LLPanel::draw(); // Draw the hints over the "less" and "more" buttons. @@ -191,23 +188,8 @@ void LLScrollingPanelParam::draw() // Draw labels on top of the buttons - childSetVisible( "min param text", TRUE ); - drawChild(getChild("min param text"), BTN_BORDER, BTN_BORDER); - - childSetVisible( "max param text", TRUE ); - drawChild(getChild("max param text"), BTN_BORDER, BTN_BORDER); -} - -// static -void LLScrollingPanelParam::onSliderMouseDown(LLUICtrl* ctrl, void* userdata) -{ -} - -// static -void LLScrollingPanelParam::onSliderMouseUp(LLUICtrl* ctrl, void* userdata) -{ - LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata; - LLVisualParamHint::requestHintUpdates( self->mHintMin, self->mHintMax ); + drawChild(mMinText, BTN_BORDER, BTN_BORDER, true); + drawChild(mMaxText, BTN_BORDER, BTN_BORDER, true); } void LLScrollingPanelParam::onHintMouseDown( bool max ) @@ -262,17 +244,16 @@ void LLScrollingPanelParam::onHintHeldDown( bool max ) // Make sure we're not taking the slider out of bounds // (this is where some simple UI limits are stored) F32 new_percent = weightToPercent(new_weight); - LLSliderCtrl* slider = getChild("param slider"); - if (slider) + if (mSlider) { - if (slider->getMinValue() < new_percent - && new_percent < slider->getMaxValue()) + if (mSlider->getMinValue() < new_percent + && new_percent < mSlider->getMaxValue()) { mWearable->setVisualParamWeight(param->getID(), new_weight, FALSE); mWearable->writeToAvatar(gAgentAvatarp); gAgentAvatarp->updateVisualParams(); - slider->setValue( weightToPercent( new_weight ) ); + mSlider->setValue( weightToPercent( new_weight ) ); } } } @@ -301,15 +282,14 @@ void LLScrollingPanelParam::onHintMouseUp( bool max ) // step a fraction in the negative direction F32 new_weight = current_weight + (range / 10.f); F32 new_percent = weightToPercent(new_weight); - LLSliderCtrl* slider = getChild("param slider"); - if (slider) + if (mSlider) { - if (slider->getMinValue() < new_percent - && new_percent < slider->getMaxValue()) + if (mSlider->getMinValue() < new_percent + && new_percent < mSlider->getMaxValue()) { mWearable->setVisualParamWeight(param->getID(), new_weight, FALSE); mWearable->writeToAvatar(gAgentAvatarp); - slider->setValue( weightToPercent( new_weight ) ); + mSlider->setValue( weightToPercent( new_weight ) ); } } } diff --git a/indra/newview/llscrollingpanelparam.h b/indra/newview/llscrollingpanelparam.h index 8c02e5fa6..bc7d9543e 100644 --- a/indra/newview/llscrollingpanelparam.h +++ b/indra/newview/llscrollingpanelparam.h @@ -47,9 +47,6 @@ public: virtual void setVisible( BOOL visible ); virtual void updatePanel(BOOL allow_modify); - static void onSliderMouseDown(LLUICtrl* ctrl, void* userdata); - static void onSliderMouseUp(LLUICtrl* ctrl, void* userdata); - void onHintMouseUp( bool max ); void onHintMouseDown( bool max ); void onHintHeldDown( bool max ); @@ -69,6 +66,8 @@ public: protected: LLTimer mMouseDownTimer; // timer for how long mouse has been held down on a hint. F32 mLastHeldTime; +private: + LLView *mMinText, *mMaxText; }; diff --git a/indra/newview/llscrollingpanelparambase.cpp b/indra/newview/llscrollingpanelparambase.cpp index 672153d04..8c34e0b6e 100644 --- a/indra/newview/llscrollingpanelparambase.cpp +++ b/indra/newview/llscrollingpanelparambase.cpp @@ -49,7 +49,7 @@ LLScrollingPanelParamBase::LLScrollingPanelParamBase( const std::string& name, { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_scrolling_param.xml"); //Set up the slider - LLSliderCtrl *slider = getChild("param slider"); + mSlider = getChild("param slider"); //Kill everything that isn't the slider... if(!bVisualHint) @@ -58,7 +58,7 @@ LLScrollingPanelParamBase::LLScrollingPanelParamBase( const std::string& name, child_list_t::const_iterator it; for (it = getChildList()->begin(); it != getChildList()->end(); it++) { - if ((*it) != slider && (*it)->getName() != "panel border") + if ((*it) != mSlider && (*it)->getName() != "panel border") { to_remove.push_back(*it); } @@ -68,14 +68,14 @@ LLScrollingPanelParamBase::LLScrollingPanelParamBase( const std::string& name, removeChild(*it); delete (*it); } - slider->translate(0,/*PARAM_HINT_HEIGHT*/128); + mSlider->translate(0,/*PARAM_HINT_HEIGHT*/128); reshape(getRect().getWidth(),getRect().getHeight()-128); } - slider->setValue(weightToPercent(param->getWeight())); - slider->setLabelArg("[DESC]", param->getDisplayName()); - slider->setEnabled(mAllowModify); - slider->setCommitCallback(boost::bind(&LLScrollingPanelParamBase::onSliderMoved, this, _1)); + mSlider->setValue(weightToPercent(param->getWeight())); + mSlider->setLabelArg("[DESC]", param->getDisplayName()); + mSlider->setEnabled(mAllowModify); + mSlider->setCommitCallback(boost::bind(&LLScrollingPanelParamBase::onSliderMoved, this, _1)); setVisible(FALSE); setBorderVisible( FALSE ); @@ -87,37 +87,25 @@ LLScrollingPanelParamBase::~LLScrollingPanelParamBase() void LLScrollingPanelParamBase::updatePanel(BOOL allow_modify) { - LLViewerVisualParam* param = mParam; - - if(!mWearable) + if (!mWearable) { // not editing a wearable just now, no update necessary return; } - F32 current_weight = mWearable->getVisualParamWeight( param->getID() ); - childSetValue("param slider", weightToPercent( current_weight ) ); + F32 current_weight = mWearable->getVisualParamWeight(mParam->getID()); + mSlider->setValue(weightToPercent(current_weight)); mAllowModify = allow_modify; - childSetEnabled("param slider", mAllowModify); + mSlider->setEnabled(mAllowModify); } void LLScrollingPanelParamBase::onSliderMoved(LLUICtrl* ctrl) { - if(!mParam) - { - return; - } - - if(!mWearable) - { - return; - } - - LLSliderCtrl* slider = (LLSliderCtrl*) ctrl; + if (!mParam || !mWearable) return; F32 current_weight = mWearable->getVisualParamWeight(mParam->getID()); - F32 new_weight = percentToWeight( (F32)slider->getValue().asReal() ); - if (current_weight != new_weight ) + F32 new_weight = percentToWeight(ctrl->getValue().asFloat()); + if (current_weight != new_weight) { mWearable->setVisualParamWeight( mParam->getID(), new_weight, FALSE); mWearable->writeToAvatar(gAgentAvatarp); @@ -127,12 +115,10 @@ void LLScrollingPanelParamBase::onSliderMoved(LLUICtrl* ctrl) F32 LLScrollingPanelParamBase::weightToPercent( F32 weight ) { - LLViewerVisualParam* param = mParam; - return (weight - param->getMinWeight()) / (param->getMaxWeight() - param->getMinWeight()) * 100.f; + return (weight - mParam->getMinWeight()) / (mParam->getMaxWeight() - mParam->getMinWeight()) * 100.f; } F32 LLScrollingPanelParamBase::percentToWeight( F32 percent ) { - LLViewerVisualParam* param = mParam; - return percent / 100.f * (param->getMaxWeight() - param->getMinWeight()) + param->getMinWeight(); + return percent / 100.f * (mParam->getMaxWeight() - mParam->getMinWeight()) + mParam->getMinWeight(); } diff --git a/indra/newview/llscrollingpanelparambase.h b/indra/newview/llscrollingpanelparambase.h index d114f622d..5ffab3053 100644 --- a/indra/newview/llscrollingpanelparambase.h +++ b/indra/newview/llscrollingpanelparambase.h @@ -57,6 +57,7 @@ public: protected: BOOL mAllowModify; LLWearable *mWearable; + class LLSliderCtrl* mSlider; }; #endif diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 976397931..c10570d7d 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1262,12 +1262,12 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & size.setSub(max_extents, min_extents); size.mul(0.5f); - mGridOrigin.set(center.getF32ptr()); LLDrawable* drawable = first_grid_object->mDrawable; if (drawable && drawable->isActive()) { - mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix(); + first_grid_object->getRenderMatrix().affineTransform(center,center); } + mGridOrigin.set(center.getF32ptr()); mGridScale.set(size.getF32ptr()); } } @@ -5709,7 +5709,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) if (mSelectedObjects->getNumNodes()) { LLUUID inspect_item_id= LLUUID::null; - LLFloaterInspect* inspect_instance = LLFloaterInspect::instanceExists() ? LLFloaterInspect::getInstance() : NULL; + LLFloaterInspect* inspect_instance = LLFloaterInspect::findInstance(); if(inspect_instance && inspect_instance->getVisible()) { inspect_item_id = inspect_instance->getSelectedUUID(); @@ -6119,7 +6119,7 @@ void pushWireframe(LLDrawable* drawable) { LLVertexBuffer::unbind(); gGL.pushMatrix(); - gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); + gGL.multMatrix(vobj->getRelativeXform()); LLVolume* volume = NULL; @@ -6176,7 +6176,7 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color) if (drawable->isActive()) { gGL.loadMatrix(gGLModelView); - gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix); + gGL.multMatrix(objectp->getRenderMatrix()); } else if (!is_hud_object) { @@ -6297,7 +6297,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) if (drawable->isActive()) { - gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix); + gGL.multMatrix(objectp->getRenderMatrix()); } LLVolume *volume = objectp->getVolume(); @@ -6447,7 +6447,7 @@ void dialog_refresh_all() LLFloaterProperties::dirtyAll(); - LLFloaterInspect* inspect_instance = LLFloaterInspect::instanceExists() ? LLFloaterInspect::getInstance() : NULL; + LLFloaterInspect* inspect_instance = LLFloaterInspect::findInstance(); if(inspect_instance) { inspect_instance->dirty(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 41890cdaa..9c8182cef 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2917,7 +2917,7 @@ void renderNormals(LLDrawable* drawablep) { LLVolume* volume = vol->getVolume(); gGL.pushMatrix(); - gGL.multMatrix((F32*) vol->getRelativeXform().mMatrix); + gGL.multMatrix(vol->getRelativeXform()); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -3071,7 +3071,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) LLVector3 size(0.25f,0.25f,0.25f); gGL.pushMatrix(); - gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); + gGL.multMatrix(volume->getRelativeXform()); if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH) { @@ -3369,7 +3369,7 @@ void renderPhysicsShapes(LLSpatialGroup* group) if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) { gGL.pushMatrix(); - gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix); + gGL.multMatrix(object->getRegion()->mRenderMatrix); //push face vertices for terrain for (S32 i = 0; i < drawable->getNumFaces(); ++i) { @@ -3576,6 +3576,7 @@ void renderLights(LLDrawable* drawablep) } } +LL_ALIGN_PREFIX(16) class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect { public: @@ -3648,7 +3649,7 @@ public: } } } -}; +} LL_ALIGN_POSTFIX(16); void renderRaycast(LLDrawable* drawablep) { @@ -3683,7 +3684,7 @@ void renderRaycast(LLDrawable* drawablep) gGL.pushMatrix(); gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); - gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); + gGL.multMatrix(vobj->getRelativeXform()); LLVector4a start, end; if (transform) @@ -3760,10 +3761,13 @@ void renderRaycast(LLDrawable* drawablep) LLVector3 normal(gDebugRaycastNormal.getF32ptr()); LLVector3 binormal(debug_binormal.getF32ptr()); + //LLCoordFrame isn't vectorized, for now. orient.lookDir(normal, binormal); LLMatrix4 rotation; orient.getRotMatrixToParent(rotation); - gGL.multMatrix((float*)rotation.mMatrix); + LLMatrix4a rotationa; + rotationa.loadu((F32*)rotation.mMatrix); + gGL.multMatrix(rotationa); gGL.diffuseColor4f(1,0,0,0.5f); drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f)); @@ -4330,14 +4334,11 @@ public: if (group->mSpatialPartition->isBridge()) { - LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix(); + LLMatrix4a local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix(); local_matrix.invert(); - LLMatrix4a local_matrix4a; - local_matrix4a.loadu(local_matrix); - - local_matrix4a.affineTransform(mStart, local_start); - local_matrix4a.affineTransform(mEnd, local_end); + local_matrix.affineTransform(mStart, local_start); + local_matrix.affineTransform(mEnd, local_end); } if (LLLineSegmentBoxIntersect(local_start, local_end, center, size)) @@ -4376,7 +4377,7 @@ public: if (vobj->isAvatar()) { LLVOAvatar* avatar = (LLVOAvatar*) vobj; - if (gFloaterTools->getVisible() || LLFloaterInspect::instanceExists()) + if (gFloaterTools->getVisible() || LLFloaterInspect::findInstance()) { 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 8d2b5a47b..29f86656a 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -102,15 +102,15 @@ public: void validate(); - LLVector4a mExtents[2]; + LL_ALIGN_16(LLVector4a mExtents[2]); LLPointer mVertexBuffer; LLPointer mTexture; std::vector > mTextureList; S32 mDebugColor; - const LLMatrix4* mTextureMatrix; - const LLMatrix4* mModelMatrix; + const LLMatrix4a* mTextureMatrix; + const LLMatrix4a* mModelMatrix; U16 mStart; U16 mEnd; U32 mCount; diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 215e9f242..2d0501ff5 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -32,6 +32,7 @@ #include "llavatarnamecache.h" #include "llimpanel.h" // For LLFloaterIMPanel #include "llimview.h" +#include "llgroupmgr.h" #include "llsdutil.h" #include "llui.h" #include "llviewerobjectlist.h" @@ -61,8 +62,7 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy mModeratorMutedVoice(FALSE), mModeratorMutedText(FALSE) { - // Make sure we also get the display name if SLIM or some other external voice client is used and not whatever is provided. - if ((name.empty() && type == SPEAKER_AGENT) || type == SPEAKER_EXTERNAL) + if (name.empty() && type == SPEAKER_AGENT) { lookupName(); } @@ -100,6 +100,19 @@ bool LLSpeaker::isInVoiceChannel() return mStatus <= LLSpeaker::STATUS_VOICE_ACTIVE || mStatus == LLSpeaker::STATUS_MUTED; } +LLSpeakerUpdateSpeakerEvent::LLSpeakerUpdateSpeakerEvent(LLSpeaker* source) +: LLEvent(source, "Speaker update speaker event"), + mSpeakerID (source->mID) +{ +} + +LLSD LLSpeakerUpdateSpeakerEvent::getValue() +{ + LLSD ret; + ret["id"] = mSpeakerID; + return ret; +} + LLSpeakerUpdateModeratorEvent::LLSpeakerUpdateModeratorEvent(LLSpeaker* source) : LLEvent(source, "Speaker add moderator event"), mSpeakerID (source->mID), @@ -257,6 +270,11 @@ bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_ return true; } +bool LLSpeakersDelayActionsStorage::isTimerStarted(const LLUUID& speaker_id) +{ + return (mActionTimersMap.size() > 0) && (mActionTimersMap.find(speaker_id) != mActionTimersMap.end()); +} + // // ModerationResponder // @@ -269,9 +287,9 @@ public: mSessionID = session_id; } - /*virtual*/ void error(U32 status, const std::string& reason) + virtual void httpFailure(void) { - llwarns << "ModerationResponder error [status:" << status << "]: " << reason << llendl; + llwarns << mStatus << ": " << mReason << llendl; if ( gIMMgr ) { @@ -280,7 +298,7 @@ public: //403 == you're not a mod //should be disabled if you're not a moderator - if ( 403 == status ) + if ( 403 == mStatus ) { floaterp->showSessionEventError( "mute", @@ -308,8 +326,10 @@ private: LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) : mVoiceChannel(channelp), mVoiceModerated(false), - mModerateModeHandledFirstTime(false) + mModerateModeHandledFirstTime(false), + mSpeakerListUpdated(false) { + mGetListTime.reset(); static LLUICachedControl remove_delay ("SpeakerParticipantRemoveDelay", 10.0); mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay); @@ -322,7 +342,8 @@ LLSpeakerMgr::~LLSpeakerMgr() LLPointer LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type) { - if (id.isNull()) + LLUUID session_id = getSessionID(); + if (id.isNull() || (id == session_id)) { return NULL; } @@ -434,6 +455,7 @@ void LLSpeakerMgr::update(BOOL resort_ok) { speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32(); speakerp->mHasSpoken = TRUE; + fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker"); } speakerp->mStatus = LLSpeaker::STATUS_SPEAKING; // interpolate between active color and full speaking color based on power of speech output @@ -522,6 +544,81 @@ void LLSpeakerMgr::updateSpeakerList() (LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL)); } } + else + { + // If not, check if the list is empty, except if it's Nearby Chat (session_id NULL). + LLUUID session_id = getSessionID(); + if (!session_id.isNull() && !mSpeakerListUpdated) + { + // If the list is empty, we update it with whatever we have locally so that it doesn't stay empty too long. + // *TODO: Fix the server side code that sometimes forgets to send back the list of participants after a chat started. + // (IOW, fix why we get no ChatterBoxSessionAgentListUpdates message after the initial ChatterBoxSessionStartReply) + /* Singu TODO: LLIMModel::LLIMSession + LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id); + if (session->isGroupSessionType() && (mSpeakers.size() <= 1)) + */ + LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(session_id); + if (floater && floater->getSessionType() == LLFloaterIMPanel::GROUP_SESSION && (mSpeakers.size() <= 1)) + { + const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout"); + // For groups, we need to hit the group manager. + // Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail. + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id); + if (!gdatap && (mGetListTime.getElapsedTimeF32() >= load_group_timeout)) + { + // Request the data the first time around + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(session_id); + } + else if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty()) + { + // Add group members when we get the complete list (note: can take a while before we get that list) + LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin(); + const S32 load_group_max_members = gSavedSettings.getS32("ChatLoadGroupMaxMembers"); + S32 updated = 0; + while (member_it != gdatap->mMembers.end()) + { + LLGroupMemberData* member = member_it->second; + LLUUID id = member_it->first; + // Add only members who are online and not already in the list + if ((member->getOnlineStatus() == "Online") && (mSpeakers.find(id) == mSpeakers.end())) + { + LLPointer speakerp = setSpeaker(id, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT); + speakerp->mIsModerator = ((member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR); + updated++; + } + ++member_it; + // Limit the number of "manually updated" participants to a reasonable number to avoid severe fps drop + // *TODO : solve the perf issue of having several hundreds of widgets in the conversation list + if (updated >= load_group_max_members) + break; + } + mSpeakerListUpdated = true; + } + } + /* Singu TODO: LLIMModel::LLIMSession + else if (mSpeakers.size() == 0) + { + // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list + for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it) + { + // Add buddies if they are on line, add any other avatar. + if (!LLAvatarTracker::instance().isBuddy(*it) || LLAvatarTracker::instance().isBuddyOnline(*it)) + { + setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT); + } + } + mSpeakerListUpdated = true; + } + */ + else + { + // The list has been updated the normal way (i.e. by a ChatterBoxSessionAgentListUpdates received from the server) + mSpeakerListUpdated = true; + } + } + } + // Always add the current agent (it has to be there...). Will do nothing if already there. + setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT); } void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp) @@ -586,6 +683,10 @@ const LLUUID LLSpeakerMgr::getSessionID() return mVoiceChannel->getSessionID(); } +bool LLSpeakerMgr::isSpeakerToBeRemoved(const LLUUID& speaker_id) +{ + return mSpeakerDelayRemover && mSpeakerDelayRemover->isTimerStarted(speaker_id); +} void LLSpeakerMgr::setSpeakerTyping(const LLUUID& speaker_id, BOOL typing) { @@ -604,6 +705,7 @@ void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id) { speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32(); speakerp->mHasSpoken = TRUE; + fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker"); } } @@ -773,10 +875,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update) } } } -/*prep# - virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content) - llwarns << "ModerationResponder error [status:" << status << "]: " << content << llendl; - */ + void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id) { LLPointer speakerp = findSpeaker(speaker_id); @@ -956,7 +1055,7 @@ void LLLocalSpeakerMgr::updateSpeakerList() if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY) { LLVOAvatar* avatarp = gObjectList.findAvatar(speaker_id); - if (!avatarp || dist_vec_squared(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS_SQUARED) + if (!avatarp || dist_vec_squared(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS * CHAT_NORMAL_RADIUS) { setSpeakerNotInChannel(speakerp); } diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 1d58d1b1d..107749224 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -81,6 +81,15 @@ public: BOOL mModeratorMutedText; }; +class LLSpeakerUpdateSpeakerEvent : public LLOldEvents::LLEvent +{ +public: + LLSpeakerUpdateSpeakerEvent(LLSpeaker* source); + /*virtual*/ LLSD getValue(); +private: + const LLUUID& mSpeakerID; +}; + class LLSpeakerUpdateModeratorEvent : public LLOldEvents::LLEvent { public: @@ -186,6 +195,8 @@ public: void unsetActionTimer(const LLUUID& speaker_id); void removeAllTimers(); + + bool isTimerStarted(const LLUUID& speaker_id); private: /** * Callback of the each instance of LLSpeakerActionTimer. @@ -230,6 +241,7 @@ public: void getSpeakerList(speaker_list_t* speaker_list, BOOL include_text); LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; } const LLUUID getSessionID(); + bool isSpeakerToBeRemoved(const LLUUID& speaker_id); /** * Removes avaline speaker. @@ -253,6 +265,8 @@ protected: typedef std::map > speaker_map_t; speaker_map_t mSpeakers; + bool mSpeakerListUpdated; + LLTimer mGetListTime; speaker_list_t mSpeakersSorted; LLFrameTimer mSpeechTimer; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index cc2cc300c..3621179de 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -60,6 +60,7 @@ #include "hippolimits.h" #include "floaterao.h" #include "statemachine/aifilepicker.h" +#include "lfsimfeaturehandler.h" #include "llares.h" #include "llavatarnamecache.h" @@ -115,9 +116,11 @@ #include "llfeaturemanager.h" #include "llfirstuse.h" #include "llfloateractivespeakers.h" +#include "llfloateravatar.h" #include "llfloaterbeacons.h" #include "llfloatercamera.h" #include "llfloaterchat.h" +#include "llfloaterdestinations.h" #include "llfloatergesture.h" #include "llfloaterhud.h" #include "llfloaterinventory.h" @@ -140,6 +143,7 @@ #include "llkeyboard.h" #include "llloginhandler.h" // gLoginHandler, SLURL support #include "llpanellogin.h" +#include "llmediafilter.h" #include "llmutelist.h" #include "llnotify.h" #include "llpanelavatar.h" @@ -222,6 +226,7 @@ #include "wlfPanel_AdvSettings.h" //Lower right Windlight and Rendering options #include "lldaycyclemanager.h" #include "llfloaterblacklist.h" +#include "scriptcounter.h" #include "shfloatermediaticker.h" #include "llpacketring.h" // @@ -324,6 +329,12 @@ void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is dialog_refresh_all(); } +void simfeature_debug_update(const std::string& val, const std::string& setting) +{ + //if (!val.empty()) // Singu Note: Should we only update the setting if not empty? + gSavedSettings.setString(setting, val); +} + // // exported functionality // @@ -374,6 +385,30 @@ void hooked_process_sound_trigger(LLMessageSystem *msg, void **) LLFloaterAvatarList::sound_trigger_hook(msg,NULL); } +void convert_legacy_settings() +{ + // Convert legacy settings to new ones here. + if (!gSavedPerAccountSettings.getBOOL("DefaultUploadPermissionsConverted")) + { + gSavedSettings.setBOOL("UploadsEveryoneCopy", gSavedSettings.getBOOL("EveryoneCopy")); + bool val = gSavedPerAccountSettings.getBOOL("EveryoneExport"); + gSavedPerAccountSettings.setBOOL("UploadsEveryoneExport", val); + gSavedPerAccountSettings.setBOOL("ObjectsEveryoneExport", val); + val = gSavedSettings.getBOOL("NextOwnerCopy"); + gSavedSettings.setBOOL("UploadsNextOwnerCopy", val); + gSavedSettings.setBOOL("ObjectsNextOwnerCopy", val); + val = gSavedSettings.getBOOL("NextOwnerModify"); + gSavedSettings.setBOOL("UploadsNextOwnerModify", val); + gSavedSettings.setBOOL("ObjectsNextOwnerModify", val); + val = gSavedSettings.getBOOL("NextOwnerTransfer"); + gSavedSettings.setBOOL("UploadsNextOwnerTransfer", val); + gSavedSettings.setBOOL("ObjectsNextOwnerTransfer", val); + val = gSavedSettings.getBOOL("NextOwnerTransfer"); + gSavedSettings.setBOOL("UploadsShareWithGroup", gSavedSettings.getBOOL("ShareWithGroup")); + gSavedPerAccountSettings.setBOOL("DefaultUploadPermissionsConverted", true); + } +} + void init_audio() { if (FALSE == gSavedSettings.getBOOL("NoAudio")) @@ -1039,6 +1074,8 @@ bool idle_startup() gSavedPerAccountSettings.setU32("LastLogoff", time_corrected()); } + convert_legacy_settings(); + //Default the path if one isn't set. if (gSavedPerAccountSettings.getString("InstantMessageLogPath").empty()) { @@ -1229,6 +1266,10 @@ bool idle_startup() requested_options.push_back("tutorial_setting"); requested_options.push_back("login-flags"); requested_options.push_back("global-textures"); + // Opensim requested options + requested_options.push_back("avatar_picker_url"); + requested_options.push_back("destination_guide_url"); + // if(gSavedSettings.getBOOL("ConnectAsGod")) { gSavedSettings.setBOOL("UseDebugMenus", TRUE); @@ -1547,13 +1588,22 @@ bool idle_startup() if (process_login_success_response(password, first_sim_size_x, first_sim_size_y)) { std::string name = firstname; - if (!gHippoGridManager->getCurrentGrid()->isSecondLife() || + bool secondlife(gHippoGridManager->getCurrentGrid()->isSecondLife()); + if (!secondlife || !boost::algorithm::iequals(lastname, "Resident")) { name += " " + lastname; } if (gSavedSettings.getBOOL("LiruGridInTitle")) gWindowTitle += "- " + gHippoGridManager->getCurrentGrid()->getGridName() + " "; gViewerWindow->getWindow()->setTitle(gWindowTitle += "- " + name); + + if (!secondlife) + { + LFSimFeatureHandler& inst(LFSimFeatureHandler::instance()); + inst.setDestinationGuideURLCallback(boost::bind(simfeature_debug_update, _1, "DestinationGuideURL")); + inst.setSearchURLCallback(boost::bind(simfeature_debug_update, _1, "SearchURL")); + } + // Pass the user information to the voice chat server interface. LLVoiceClient::getInstance()->userAuthorized(name, gAgentID); // create the default proximal channel @@ -1695,6 +1745,7 @@ bool idle_startup() if (STATE_MULTIMEDIA_INIT == LLStartUp::getStartupState()) { LLStartUp::multimediaInit(); + LLMediaFilter::getInstance(); LLStartUp::setStartupState( STATE_FONT_INIT ); display_startup(); return FALSE; @@ -1758,45 +1809,6 @@ bool idle_startup() LLRect window(0, gViewerWindow->getWindowHeight(), gViewerWindow->getWindowWidth(), 0); gViewerWindow->adjustControlRectanglesForFirstUse(window); - if (gSavedSettings.getBOOL("ShowMiniMap")) - { - LLFloaterMap::showInstance(); - } - if (gSavedSettings.getBOOL("ShowRadar")) - { - LLFloaterAvatarList::showInstance(); - } - // - else if (gSavedSettings.getBOOL("RadarKeepOpen")) - { - LLFloaterAvatarList::getInstance()->close(); - } - if (gSavedSettings.getBOOL("SHShowMediaTicker")) - { - SHFloaterMediaTicker::showInstance(); - } - // - if (gSavedSettings.getBOOL("ShowCameraControls")) - { - LLFloaterCamera::showInstance(); - } - if (gSavedSettings.getBOOL("ShowMovementControls")) - { - LLFloaterMove::showInstance(); - } - - if (gSavedSettings.getBOOL("ShowActiveSpeakers")) - { - LLFloaterActiveSpeakers::showInstance(); - } - - if (gSavedSettings.getBOOL("ShowBeaconsFloater")) - { - LLFloaterBeacons::showInstance(); - } - - - if (!gNoRender) { //Set up cloud rendertypes. Passed argument is unused. @@ -2394,6 +2406,51 @@ bool idle_startup() gDisplaySwapBuffers = TRUE; display_startup(); + if (gSavedSettings.getBOOL("ShowMiniMap")) + { + LLFloaterMap::showInstance(); + } + if (gSavedSettings.getBOOL("ShowRadar")) + { + LLFloaterAvatarList::showInstance(); + } + // + else if (gSavedSettings.getBOOL("RadarKeepOpen")) + { + LLFloaterAvatarList::getInstance()->close(); + } + if (gSavedSettings.getBOOL("SHShowMediaTicker")) + { + SHFloaterMediaTicker::showInstance(); + } + // + if (gSavedSettings.getBOOL("ShowCameraControls")) + { + LLFloaterCamera::showInstance(); + } + if (gSavedSettings.getBOOL("ShowMovementControls")) + { + LLFloaterMove::showInstance(); + } + + if (gSavedSettings.getBOOL("ShowActiveSpeakers")) + { + LLFloaterActiveSpeakers::showInstance(); + } + + if (gSavedSettings.getBOOL("ShowBeaconsFloater")) + { + LLFloaterBeacons::showInstance(); + } + if (gSavedSettings.getBOOL("ShowAvatarFloater")) + { + LLFloaterAvatar::showInstance(); + } + if (gSavedSettings.getBOOL("DestinationGuideShown")) + { + LLFloaterDestinations::showInstance(); + } + LLMessageSystem* msg = gMessageSystem; msg->setHandlerFuncFast(_PREHASH_SoundTrigger, hooked_process_sound_trigger); msg->setHandlerFuncFast(_PREHASH_PreloadSound, process_preload_sound); @@ -2607,7 +2664,6 @@ bool idle_startup() { set_startup_status(1.0, "", ""); display_startup(); - LLViewerParcelMedia::loadDomainFilterList(); // Let the map know about the inventory. LLFloaterWorldMap* floater_world_map = gFloaterWorldMap; @@ -2936,6 +2992,22 @@ void pass_processObjectPropertiesFamily(LLMessageSystem *msg, void**) JCFloaterAreaSearch::processObjectPropertiesFamily(msg, NULL); } +void process_script_running_reply(LLMessageSystem* msg, void** v) +{ + LLLiveLSLEditor::processScriptRunningReply(msg, v); + if (ScriptCounter::sCheckMap.size()) + { + LLUUID item_id; + msg->getUUIDFast(_PREHASH_Script, _PREHASH_ItemID, item_id); + std::map::iterator it = ScriptCounter::sCheckMap.find(item_id); + if (it != ScriptCounter::sCheckMap.end()) + { + it->second->processRunningReply(msg); + ScriptCounter::sCheckMap.erase(it); + } + } +} + void register_viewer_callbacks(LLMessageSystem* msg) { msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data ); @@ -2986,8 +3058,7 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFuncFast(_PREHASH_CoarseLocationUpdate, LLWorld::processCoarseUpdate, NULL); msg->setHandlerFuncFast(_PREHASH_ReplyTaskInventory, LLViewerObject::processTaskInv, NULL); msg->setHandlerFuncFast(_PREHASH_DerezContainer, process_derez_container, NULL); - msg->setHandlerFuncFast(_PREHASH_ScriptRunningReply, - &LLLiveLSLEditor::processScriptRunningReply); + msg->setHandlerFuncFast(_PREHASH_ScriptRunningReply, process_script_running_reply); msg->setHandlerFuncFast(_PREHASH_DeRezAck, process_derez_ack); @@ -4041,7 +4112,8 @@ bool process_login_success_response(std::string& password, U32& first_sim_size_x LLWorldMap::gotMapServerURL(true); } - if(gHippoGridManager->getConnectedGrid()->isOpenSimulator()) + bool opensim = gHippoGridManager->getConnectedGrid()->isOpenSimulator(); + if (opensim) { std::string web_profile_url = response["web_profile_url"]; //if(!web_profile_url.empty()) // Singu Note: We're using this to check if this grid supports web profiles at all, so set empty if empty. @@ -4134,7 +4206,15 @@ bool process_login_success_response(std::string& password, U32& first_sim_size_x if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setPasswordUrl(tmp); tmp = response["search"].asString(); if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setSearchUrl(tmp); - if (gHippoGridManager->getConnectedGrid()->isOpenSimulator()) gSavedSettings.setString("SearchURL", tmp); // Singu Note: For web search purposes, always set this setting + else if (opensim) tmp = gHippoGridManager->getConnectedGrid()->getSearchUrl(); // Fallback from grid info response for setting + if (opensim) + { + gSavedSettings.setString("SearchURL", tmp); // Singu Note: For web search purposes, always set this setting + tmp = response["avatar_picker_url"].asString(); + gSavedSettings.setString("AvatarPickerURL", tmp); + gMenuBarView->getChildView("Avatar Picker")->setVisible(!tmp.empty()); + gSavedSettings.setString("DestinationGuideURL", response["destination_guide_url"].asString()); + } tmp = response["currency"].asString(); if (!tmp.empty()) { diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index ff99580e6..182a829a2 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -47,8 +47,8 @@ extern bool gShiftFrame; extern U64 gFrameTime; extern LLPipeline gPipeline; -LLSurfacePatch::LLSurfacePatch() : - mHasReceivedData(FALSE), +LLSurfacePatch::LLSurfacePatch() +: mHasReceivedData(FALSE), mSTexUpdate(FALSE), mDirty(FALSE), mDirtyZStats(TRUE), diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index d17c6316d..7a0955c4f 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -291,7 +291,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id) LLUUID item_id = findItemID(mImageAssetID, FALSE); if (item_id.isNull()) { - mInventoryPanel->clearSelection(); + mInventoryPanel->getRootFolder()->clearSelection(); } else { diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 2079180fd..ae023d71f 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -345,11 +345,11 @@ public: /*virtual*/ bool needsHeaders(void) const { return true; } - /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { + /*virtual*/ void completedHeaders(void) { LL_DEBUGS("Texture") << "HTTP HEADERS COMPLETE: " << mID << LL_ENDL; std::string rangehdr; - if (headers.getFirstValue("content-range", rangehdr)) + if (mReceivedHeaders.getFirstValue("content-range", rangehdr)) { std::vector tokens; boost::split(tokens,rangehdr,boost::is_any_of(" -/")); @@ -387,9 +387,8 @@ public: } } - /*virtual*/ void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const buffer_ptr_t& buffer) + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, + buffer_ptr_t const& buffer) { static LLCachedControl log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog"); static LLCachedControl log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator"); @@ -413,18 +412,18 @@ public: worker->lockWorkMutex(); bool success = false; bool partial = false; - if (HTTP_OK <= status && status < HTTP_MULTIPLE_CHOICES) + if (HTTP_OK <= mStatus && mStatus < HTTP_MULTIPLE_CHOICES) { success = true; - if (HTTP_PARTIAL_CONTENT == status) // partial information + if (HTTP_PARTIAL_CONTENT == mStatus) // partial information { partial = true; } } if (!success) { - worker->setGetStatus(status, reason); - llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl; + worker->setGetStatus(mStatus, mReason); + llwarns << "CURL GET FAILED, status:" << mStatus << " reason:" << mReason << llendl; } S32 data_size = worker->callbackHttpGet(mReplyOffset, mReplyLength, channels, buffer, partial, success); @@ -1416,7 +1415,9 @@ bool LLTextureFetchWorker::doWork(S32 param) // Call LLHTTPClient::request directly instead of LLHTTPClient::getByteRange, because we want to pass a NULL AIEngine. if (mRequestedOffset > 0 || mRequestedSize > 0) { - headers.addHeader("Range", llformat("bytes=%d-%d", mRequestedOffset, mRequestedOffset + mRequestedSize - 1)); + int const range_end = mRequestedOffset + mRequestedSize - 1; + char const* const range_format = (range_end >= HTTP_REQUESTS_RANGE_END_MAX) ? "bytes=%d-" : "bytes=%d-%d"; + headers.addHeader("Range", llformat(range_format, mRequestedOffset, range_end)); } LLHTTPClient::request(mUrl, LLHTTPClient::HTTP_GET, NULL, new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, mRequestedOffset), @@ -3331,9 +3332,9 @@ class AssetReportHandler : public LLHTTPClient::ResponderWithCompleted public: // Threads: Ttf - /*virtual*/ virtual void completed(U32 status, std::string const& reason, LLSD const& content) + /*virtual*/ virtual void httpCompleted(void) { - if (status) + if (mStatus) { LL_DEBUGS("Texture") << "Successfully delivered asset metrics to grid." << LL_ENDL; @@ -3341,7 +3342,7 @@ public: else { LL_WARNS("Texture") << "Error delivering asset metrics to grid. Reason: " - << status << LL_ENDL; + << mStatus << LL_ENDL; } } diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 2c442069e..44c8c4a0e 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -783,6 +783,7 @@ BOOL LLToolCompGun::handleRightMouseUp(S32 x, S32 y, MASK mask) mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV(); mTargetFOV = mOriginalFOV; + gSavedSettings.getBOOL("LiruMouselookInstantZoom") ? LLViewerCamera::getInstance()->setDefaultFOV(mTargetFOV) : mTimerFOV.start(); } @@ -814,6 +815,7 @@ BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask) else mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV(); mTargetFOV = gSavedSettings.getF32("ExodusAlternativeFOV"); + gSavedSettings.getBOOL("LiruMouselookInstantZoom") ? LLViewerCamera::getInstance()->setDefaultFOV(mTargetFOV) : mTimerFOV.start(); return TRUE; @@ -832,6 +834,7 @@ BOOL LLToolCompGun::handleScrollWheel(S32 x, S32 y, S32 clicks) llclamp(mTargetFOV -= (0.05f * -clicks), 0.1f, 3.0f) ); + gSavedSettings.getBOOL("LiruMouselookInstantZoom") ? LLViewerCamera::getInstance()->setDefaultFOV(mTargetFOV) : mTimerFOV.start(); } else if (clicks > 0) gAgentCamera.changeCameraToDefault(); diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 3b44f27a3..dfcee38e7 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1591,7 +1591,7 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL case LLAssetType::AT_CALLINGCARD: // Calling Cards in object are disabled for now // because of incomplete LSL support. See STORM-1117. - return ACCEPT_NO; + //return ACCEPT_NO; default: break; } @@ -1604,7 +1604,7 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL transfer = TRUE; } BOOL volume = (LL_PCODE_VOLUME == obj->getPCode()); - BOOL attached = obj->isAttachment(); + BOOL attached = false; // No longer necessary. BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE; // [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c) | Modified: RLVa-1.0.0c diff --git a/indra/newview/lltoolmorph.h b/indra/newview/lltoolmorph.h index 950a3ab11..a3f557a46 100644 --- a/indra/newview/lltoolmorph.h +++ b/indra/newview/lltoolmorph.h @@ -65,6 +65,16 @@ public: LLWearable *wearable, F32 param_weight); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + /*virtual*/ S8 getType() const ; BOOL needsRender(); @@ -110,6 +120,17 @@ protected: /*virtual */ ~LLVisualParamReset(){} public: LLVisualParamReset(); + + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + /*virtual */ BOOL render(); /*virtual*/ S8 getType() const ; diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 39cd470f3..4a9b6b0b7 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -215,7 +215,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom); } - if (!gAgentCamera.getFocusOnAvatar() && // if camera not glued to avatar + if (gSavedSettings.getBOOL("RightClickTurnsAvatar") && !gAgentCamera.getFocusOnAvatar() && // if camera not glued to avatar LLVOAvatar::findAvatarFromAttachment(object) != gAgentAvatarp && // and it's not one of your attachments object != gAgentAvatarp) // and it's not you { diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index 769afc378..f5638b6e2 100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -60,17 +60,15 @@ public : { } - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { LL_WARNS("Translate") << "URL Request error: " << reason << LL_ENDL; handleFailure(); } /*virtual*/ void completedRaw( - U32 status, - const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) + LLChannelDescriptors const& channels, + LLIOPipe::buffer_ptr_t const& buffer) { LLBufferStream istr(channels, buffer.get()); diff --git a/indra/newview/lluploadfloaterobservers.cpp b/indra/newview/lluploadfloaterobservers.cpp index c8aef6585..dd3d523d2 100644 --- a/indra/newview/lluploadfloaterobservers.cpp +++ b/indra/newview/lluploadfloaterobservers.cpp @@ -39,25 +39,24 @@ LLUploadModelPremissionsResponder::LLUploadModelPremissionsResponder(const LLHan { } -void LLUploadModelPremissionsResponder::error(U32 status, const std::string& reason) +void LLUploadModelPremissionsResponder::httpFailure(void) { - llwarns << "LLUploadModelPremissionsResponder::error(" - << status << ": " << reason << ")" << llendl; + llwarns << "httpFailure: " << dumpResponse() << llendl; LLUploadPermissionsObserver* observer = mObserverHandle.get(); if (observer) { - observer->setPermissonsErrorStatus(status, reason); + observer->setPermissonsErrorStatus(mStatus, mReason); } } -void LLUploadModelPremissionsResponder::result(const LLSD& content) +void LLUploadModelPremissionsResponder::httpSuccess(void) { LLUploadPermissionsObserver* observer = mObserverHandle.get(); if (observer) { - observer->onPermissionsReceived(content); + observer->onPermissionsReceived(mContent); } } diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h index 0ddba6735..a417b9a98 100644 --- a/indra/newview/lluploadfloaterobservers.h +++ b/indra/newview/lluploadfloaterobservers.h @@ -104,8 +104,8 @@ public: LLUploadModelPremissionsResponder(const LLHandle& observer); - /*virtual*/ void error(U32 status, const std::string& reason); - /*virtual*/ void result(const LLSD& content); + /*virtual*/ void httpFailure(void); + /*virtual*/ void httpSuccess(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return uploadModelPremissionsResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLUploadModelPremissionsResponder"; } diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index dcf955cef..1bb73493d 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -51,6 +51,7 @@ #include "hippogridmanager.h" // library includes +#include "llnotifications.h" #include "llnotificationsutil.h" #include "llsd.h" @@ -269,7 +270,7 @@ public: // Teleport requests *must* come from a trusted browser // inside the app, otherwise a malicious web page could // cause a constant teleport loop. JC - LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_BLOCK) { } + LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_THROTTLE) { } bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) @@ -285,19 +286,52 @@ public: tokens[2].asReal(), tokens[3].asReal()); } - + + LLSD args; + args["LOCATION"] = tokens[0]; + // Region names may be %20 escaped. - std::string region_name = LLURI::unescape(tokens[0]); + + LLSD payload; + payload["region_name"] = region_name; + payload["callback_url"] = LLSLURL(region_name, coords).getSLURLString(); + + LLNotificationsUtil::add("TeleportViaSLAPP", args, payload); + return true; + } + + static void teleport_via_slapp(std::string region_name, std::string callback_url) + { + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, LLURLDispatcherImpl::regionHandleCallback, - LLSLURL(region_name, coords).getSLURLString(), + callback_url, true); // teleport - return true; } + + static bool teleport_via_slapp_callback(const LLSD& notification, const LLSD& response) + { + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + std::string region_name = notification["payload"]["region_name"].asString(); + std::string callback_url = notification["payload"]["callback_url"].asString(); + + if (option == 0) + { + teleport_via_slapp(region_name, callback_url); + return true; + } + + return false; + } + }; LLTeleportHandler gTeleportHandler; +static LLNotificationFunctorRegistration open_landmark_callback_reg("TeleportViaSLAPP", LLTeleportHandler::teleport_via_slapp_callback); + + //--------------------------------------------------------------------------- diff --git a/indra/newview/lluserauth.cpp b/indra/newview/lluserauth.cpp index 21e9835ea..4c5645e12 100644 --- a/indra/newview/lluserauth.cpp +++ b/indra/newview/lluserauth.cpp @@ -293,11 +293,11 @@ LLUserAuth::UserAuthcode LLUserAuth::authResponse() } mLastTransferRateBPS = mResponder->transferRate(); - mErrorMessage = mResponder->reason(); + mErrorMessage = mResponder->getReason(); // if curl was ok, parse the download area. CURLcode result = mResponder->result_code(); - if (is_internal_http_error(mResponder->http_status())) + if (is_internal_http_error(mResponder->getStatus())) { // result can be a meaningless CURLE_OK in the case of an internal error. result = CURLE_FAILED_INIT; // Just some random error to get the default case below. @@ -342,7 +342,7 @@ LLUserAuth::UserAuthcode LLUserAuth::parseResponse() XMLRPC_REQUEST response = mResponder->response(); if(!response) { - U32 status = mResponder->http_status(); + U32 status = mResponder->getStatus(); // Is it an HTTP error? if (!(200 <= status && status < 400)) { diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index b70183fd4..ba35d78d8 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -27,10 +27,9 @@ #include "llviewerprecompiledheaders.h" #include "llviewercamera.h" - #include "llagent.h" #include "llagentcamera.h" -#include "llmatrix4a.h" + #include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" @@ -56,53 +55,6 @@ U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; -//glu pick matrix implementation borrowed from Mesa3D -glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport) -{ - GLfloat m[16]; - GLfloat sx, sy; - GLfloat tx, ty; - - sx = viewport[2] / width; - sy = viewport[3] / height; - tx = (viewport[2] + 2.f * (viewport[0] - x)) / width; - ty = (viewport[3] + 2.f * (viewport[1] - y)) / height; - - #define M(row,col) m[col*4+row] - M(0,0) = sx; M(0,1) = 0.f; M(0,2) = 0.f; M(0,3) = tx; - M(1,0) = 0.f; M(1,1) = sy; M(1,2) = 0.f; M(1,3) = ty; - M(2,0) = 0.f; M(2,1) = 0.f; M(2,2) = 1.f; M(2,3) = 0.f; - M(3,0) = 0.f; M(3,1) = 0.f; M(3,2) = 0.f; M(3,3) = 1.f; - #undef M - - return glh::matrix4f(m); -} - -glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) -{ - GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f); - - return glh::matrix4f(f/aspect, 0, 0, 0, - 0, f, 0, 0, - 0, 0, (zFar+zNear)/(zNear-zFar), (2.f*zFar*zNear)/(zNear-zFar), - 0, 0, -1.f, 0); -} - -glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up) -{ - LLVector3 f = center-eye; - f.normVec(); - up.normVec(); - LLVector3 s = f % up; - LLVector3 u = s % f; - - return glh::matrix4f(s[0], s[1], s[2], 0, - u[0], u[1], u[2], 0, - -f[0], -f[1], -f[2], 0, - 0, 0, 0, 1); - -} - LLViewerCamera::LLViewerCamera() : LLCamera() { calcProjection(getFar()); @@ -172,37 +124,26 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect())); } -const LLMatrix4 &LLViewerCamera::getProjection() const +const LLMatrix4a &LLViewerCamera::getProjection() const { calcProjection(getFar()); return mProjectionMatrix; } -const LLMatrix4 &LLViewerCamera::getModelview() const +const LLMatrix4a &LLViewerCamera::getModelview() const { - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); - getMatrixToLocal(mModelviewMatrix); - mModelviewMatrix *= cfr; + LLMatrix4 modelview; + getMatrixToLocal(modelview); + LLMatrix4a modelviewa; + modelviewa.loadu((F32*)modelview.mMatrix); + mModelviewMatrix.setMul(OGL_TO_CFR_ROTATION,modelviewa); return mModelviewMatrix; } void LLViewerCamera::calcProjection(const F32 far_distance) const { - F32 fov_y, z_far, z_near, aspect, f; - fov_y = getView(); - z_far = far_distance; - z_near = getNear(); - aspect = getAspect(); - - f = 1/tan(fov_y*0.5f); - - mProjectionMatrix.setZero(); - mProjectionMatrix.mMatrix[0][0] = f/aspect; - mProjectionMatrix.mMatrix[1][1] = f; - mProjectionMatrix.mMatrix[2][2] = (z_far + z_near)/(z_near - z_far); - mProjectionMatrix.mMatrix[3][2] = (2*z_far*z_near)/(z_near - z_far); - mProjectionMatrix.mMatrix[2][3] = -1; + mProjectionMatrix = gGL.genPersp( getView()*RAD_TO_DEG, getAspect(), getNear(), far_distance ); } // Sets up opengl state for 3D drawing. If for selection, also @@ -213,59 +154,33 @@ void LLViewerCamera::calcProjection(const F32 far_distance) const //static void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip, BOOL no_hacks) { - GLint* viewport = (GLint*) gGLViewport; - F64 model[16]; - F64 proj[16]; - - for (U32 i = 0; i < 16; i++) - { - model[i] = (F64) gGLModelView[i]; - proj[i] = (F64) gGLProjection[i]; - } - - GLdouble objX,objY,objZ; - LLVector3 frust[8]; + LLRect view_port(gGLViewport[0],gGLViewport[1]+gGLViewport[3],gGLViewport[0]+gGLViewport[2],gGLViewport[1]); + if (no_hacks) { - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[0]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[1]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[2]); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[3]); - gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,1.f),gGLModelView,gGLProjection,view_port,frust[4]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,1.f),gGLModelView,gGLProjection,view_port,frust[5]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,1.f),gGLModelView,gGLProjection,view_port,frust[6]); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,1.f),gGLModelView,gGLProjection,view_port,frust[7]); } else if (zflip) { - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[0]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[1]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[2]); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[3]); - gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,1.f),gGLModelView,gGLProjection,view_port,frust[4]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,1.f),gGLModelView,gGLProjection,view_port,frust[5]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,1.f),gGLModelView,gGLProjection,view_port,frust[6]); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,1.f),gGLModelView,gGLProjection,view_port,frust[7]); for (U32 i = 0; i < 4; i++) { @@ -276,14 +191,10 @@ void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zfli } else { - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[0]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[1]); + gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[2]); + gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[3]); if (ortho) { @@ -330,20 +241,24 @@ void LLViewerCamera::setPerspective(BOOL for_selection, gGL.matrixMode( LLRender::MM_PROJECTION ); gGL.loadIdentity(); - glh::matrix4f proj_mat; + LLMatrix4a proj_mat; + proj_mat.setIdentity(); if (for_selection) { // make a tiny little viewport // anything drawn into this viewport will be "selected" - GLint viewport[4]; - viewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - viewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - viewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - viewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + const LLRect& rect = gViewerWindow->getWorldViewRectRaw(); - proj_mat = gl_pick_matrix(x+width/2.f, y_from_bot+height/2.f, (GLfloat) width, (GLfloat) height, viewport); + const F32 scale_x = rect.getWidth() / F32(width); + const F32 scale_y = rect.getHeight() / F32(height); + const F32 trans_x = scale_x + (2.f * (rect.mLeft - x)) / F32(width) - 1.f; + const F32 trans_y = scale_y + (2.f * (rect.mBottom - y_from_bot)) / F32(height) - 1.f; + + //Generate a pick matrix + proj_mat.applyScale_affine(scale_x, scale_y, 1.f); + proj_mat.setTranslate_affine(LLVector3(trans_x, trans_y, 0.f)); if (limit_select_distance) { @@ -377,37 +292,28 @@ void LLViewerCamera::setPerspective(BOOL for_selection, float offset = mZoomFactor - 1.f; int pos_y = mZoomSubregion / llceil(mZoomFactor); int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor)); - glh::matrix4f translate; - translate.set_translate(glh::vec3f(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f)); - glh::matrix4f scale; - scale.set_scale(glh::vec3f(mZoomFactor, mZoomFactor, 1.f)); - proj_mat = scale*proj_mat; - proj_mat = translate*proj_mat; + proj_mat.applyScale_affine(mZoomFactor,mZoomFactor,1.f); + proj_mat.applyTranslation_affine(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f); } calcProjection(z_far); // Update the projection matrix cache - proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far); - - gGL.loadMatrix(proj_mat.m); - - for (U32 i = 0; i < 16; i++) - { - gGLProjection[i] = proj_mat.m[i]; - } + proj_mat.mul(gGL.genPersp(fov_y,aspect,z_near,z_far)); + + gGL.loadMatrix(proj_mat); + + gGLProjection = proj_mat; gGL.matrixMode(LLRender::MM_MODELVIEW ); - glh::matrix4f modelview((GLfloat*) OGL_TO_CFR_ROTATION); + LLMatrix4a ogl_matrix; + getOpenGLTransform(ogl_matrix.getF32ptr()); - GLfloat ogl_matrix[16]; - - getOpenGLTransform(ogl_matrix); - - modelview *= glh::matrix4f(ogl_matrix); + LLMatrix4a modelview; + modelview.setMul(OGL_TO_CFR_ROTATION, ogl_matrix); - gGL.loadMatrix(modelview.m); + gGL.loadMatrix(modelview); if (for_selection && (width > 1 || height > 1)) { @@ -426,10 +332,7 @@ void LLViewerCamera::setPerspective(BOOL for_selection, { // Save GL matrices for access elsewhere in code, especially project_world_to_screen //glGetDoublev(GL_MODELVIEW_MATRIX, gGLModelView); - for (U32 i = 0; i < 16; i++) - { - gGLModelView[i] = modelview.m[i]; - } + glh_set_current_modelview(modelview); } updateFrustumPlanes(*this); @@ -443,89 +346,14 @@ void LLViewerCamera::setPerspective(BOOL for_selection, }*/ } - // Uses the last GL matrices set in set_perspective to project a point from // screen coordinates to the agent's region. void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 screen_y, LLVector3* pos_agent) const { - GLdouble x, y, z; - - F64 mdlv[16]; - F64 proj[16]; - - for (U32 i = 0; i < 16; i++) - { - mdlv[i] = (F64) gGLModelView[i]; - proj[i] = (F64) gGLProjection[i]; - } - - gluUnProject( - GLdouble(screen_x), GLdouble(screen_y), 0.0, - mdlv, proj, (GLint*)gGLViewport, - &x, - &y, - &z ); - pos_agent->setVec( (F32)x, (F32)y, (F32)z ); -} - -//Based off of http://www.opengl.org/wiki/GluProject_and_gluUnProject_code -int glProjectf(const LLVector3& object, const F32* modelview, const F32* projection, const LLRect& viewport, LLVector3& windowCoordinate) -{ - const LLVector4a obj_vector(object.mV[VX],object.mV[VY],object.mV[VZ]); - LLVector4a temp_matrix; - - const LLMatrix4a &view_matrix=*(LLMatrix4a*)modelview; - const LLMatrix4a &proj_matrix=*(LLMatrix4a*)projection; - - view_matrix.affineTransform(obj_vector, temp_matrix); - - //Passing temp_matrix as v and res is safe. res not altered until after all other calculations - proj_matrix.rotate4(temp_matrix, temp_matrix); - - if(temp_matrix[VW]==0.0) - return 0; - - temp_matrix.div(temp_matrix[VW]); - - //Map x, y to range 0-1 - temp_matrix.mul(.5f); - temp_matrix.add(.5f); - - //Window coordinates - windowCoordinate[0]=temp_matrix[VX]*viewport.getWidth()+viewport.mLeft; - windowCoordinate[1]=temp_matrix[VY]*viewport.getHeight()+viewport.mBottom; - //This is only correct when glDepthRange(0.0, 1.0) - windowCoordinate[2]=temp_matrix[VZ]; - - return 1; -} - -void MultiplyMatrices4by4OpenGL_FLOAT(LLMatrix4a& dest_matrix, const LLMatrix4a& input_matrix1, const LLMatrix4a& input_matrix2) -{ - input_matrix1.rotate4(input_matrix2.mMatrix[VX],dest_matrix.mMatrix[VX]); - input_matrix1.rotate4(input_matrix2.mMatrix[VY],dest_matrix.mMatrix[VY]); - input_matrix1.rotate4(input_matrix2.mMatrix[VZ],dest_matrix.mMatrix[VZ]); - input_matrix1.rotate4(input_matrix2.mMatrix[VW],dest_matrix.mMatrix[VW]); - - //Those four lines do this: - /* - result[0]=matrix1[0]*matrix2[0]+matrix1[4]*matrix2[1]+matrix1[8]*matrix2[2]+matrix1[12]*matrix2[3]; - result[1]=matrix1[1]*matrix2[0]+matrix1[5]*matrix2[1]+matrix1[9]*matrix2[2]+matrix1[13]*matrix2[3]; - result[2]=matrix1[2]*matrix2[0]+matrix1[6]*matrix2[1]+matrix1[10]*matrix2[2]+matrix1[14]*matrix2[3]; - result[3]=matrix1[3]*matrix2[0]+matrix1[7]*matrix2[1]+matrix1[11]*matrix2[2]+matrix1[15]*matrix2[3]; - result[4]=matrix1[0]*matrix2[4]+matrix1[4]*matrix2[5]+matrix1[8]*matrix2[6]+matrix1[12]*matrix2[7]; - result[5]=matrix1[1]*matrix2[4]+matrix1[5]*matrix2[5]+matrix1[9]*matrix2[6]+matrix1[13]*matrix2[7]; - result[6]=matrix1[2]*matrix2[4]+matrix1[6]*matrix2[5]+matrix1[10]*matrix2[6]+matrix1[14]*matrix2[7]; - result[7]=matrix1[3]*matrix2[4]+matrix1[7]*matrix2[5]+matrix1[11]*matrix2[6]+matrix1[15]*matrix2[7]; - result[8]=matrix1[0]*matrix2[8]+matrix1[4]*matrix2[9]+matrix1[8]*matrix2[10]+matrix1[12]*matrix2[11]; - result[9]=matrix1[1]*matrix2[8]+matrix1[5]*matrix2[9]+matrix1[9]*matrix2[10]+matrix1[13]*matrix2[11]; - result[10]=matrix1[2]*matrix2[8]+matrix1[6]*matrix2[9]+matrix1[10]*matrix2[10]+matrix1[14]*matrix2[11]; - result[11]=matrix1[3]*matrix2[8]+matrix1[7]*matrix2[9]+matrix1[11]*matrix2[10]+matrix1[15]*matrix2[11]; - result[12]=matrix1[0]*matrix2[12]+matrix1[4]*matrix2[13]+matrix1[8]*matrix2[14]+matrix1[12]*matrix2[15]; - result[13]=matrix1[1]*matrix2[12]+matrix1[5]*matrix2[13]+matrix1[9]*matrix2[14]+matrix1[13]*matrix2[15]; - result[14]=matrix1[2]*matrix2[12]+matrix1[6]*matrix2[13]+matrix1[10]*matrix2[14]+matrix1[14]*matrix2[15]; - result[15]=matrix1[3]*matrix2[12]+ matrix1[7]*matrix2[13]+matrix1[11]*matrix2[14]+matrix1[15]*matrix2[15]; - */ + gGL.unprojectf( + LLVector3(screen_x,screen_y,0.f), + gGLModelView, gGLProjection, LLRect(gGLViewport[0],gGLViewport[1]+gGLViewport[3],gGLViewport[0]+gGLViewport[2],gGLViewport[1]), + *pos_agent ); } // Uses the last GL matrices set in set_perspective to project a point from @@ -553,7 +381,7 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord const LLRect& world_view_rect = gViewerWindow->getWorldViewRectRaw(); - if (GL_TRUE == glProjectf(pos_agent, gGLModelView, gGLProjection, world_view_rect, window_coordinates)) + if (gGL.projectf(pos_agent, gGLModelView, gGLProjection, world_view_rect, window_coordinates)) { F32 &x = window_coordinates.mV[VX]; F32 &y = window_coordinates.mV[VY]; @@ -653,7 +481,7 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent, const LLRect& world_view_rect = gViewerWindow->getWorldViewRectRaw(); LLVector3 window_coordinates; - if (GL_TRUE == glProjectf(pos_agent, gGLModelView, gGLProjection, world_view_rect, window_coordinates)) + if (gGL.projectf(pos_agent, gGLModelView, gGLProjection, world_view_rect, window_coordinates)) { F32 &x = window_coordinates.mV[VX]; F32 &y = window_coordinates.mV[VY]; @@ -848,14 +676,12 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) LLVOVolume* vo_volume = (LLVOVolume*) volumep; vo_volume->updateRelativeXform(); - LLMatrix4 mat = vo_volume->getRelativeXform(); LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition())); LLMatrix4a render_mata; render_mata.loadu(render_mat); - LLMatrix4a mata; - mata.loadu(mat); + const LLMatrix4a& mata = vo_volume->getRelativeXform();; num_faces = volume->getNumVolumeFaces(); for (i = 0; i < num_faces; i++) diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index d9ac2af30..0c465592b 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -32,16 +32,17 @@ #include "llstat.h" #include "lltimer.h" #include "m4math.h" +#include "llmatrix4a.h" #include "llcoord.h" class LLViewerObject; // This rotation matrix moves the default OpenGL reference frame // (-Z at, Y up) to Cory's favorite reference frame (X at, Z up) -const F32 OGL_TO_CFR_ROTATION[16] = { 0.f, 0.f, -1.f, 0.f, // -Z becomes X - -1.f, 0.f, 0.f, 0.f, // -X becomes Y - 0.f, 1.f, 0.f, 0.f, // Y becomes Z - 0.f, 0.f, 0.f, 1.f }; +static LL_ALIGN_16(const LLMatrix4a) OGL_TO_CFR_ROTATION(LLVector4a( 0.f, 0.f, -1.f, 0.f), // -Z becomes X + LLVector4a(-1.f, 0.f, 0.f, 0.f), // -X becomes Y + LLVector4a( 0.f, 1.f, 0.f, 0.f), // Y becomes Z + LLVector4a( 0.f, 0.f, 0.f, 1.f) ); const BOOL FOR_SELECTION = TRUE; const BOOL NOT_FOR_SELECTION = FALSE; @@ -88,8 +89,8 @@ public: static void updateCameraAngle(void* user_data, const LLSD& value); void setPerspective(BOOL for_selection, S32 x, S32 y_from_bot, S32 width, S32 height, BOOL limit_select_distance, F32 z_near = 0, F32 z_far = 0); - const LLMatrix4 &getProjection() const; - const LLMatrix4 &getModelview() const; + const LLMatrix4a &getProjection() const; + const LLMatrix4a &getModelview() const; // Warning! These assume the current global matrices are correct void projectScreenToPosAgent(const S32 screen_x, const S32 screen_y, LLVector3* pos_agent ) const; @@ -137,8 +138,8 @@ protected: F32 mAverageSpeed ; F32 mAverageAngularSpeed ; - mutable LLMatrix4 mProjectionMatrix; // Cache of perspective matrix - mutable LLMatrix4 mModelviewMatrix; + mutable LLMatrix4a mProjectionMatrix; // Cache of perspective matrix + mutable LLMatrix4a mModelviewMatrix; F32 mCameraFOVDefault; F32 mSavedFOVDefault; // F32 mCosHalfCameraFOV; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index d87d82ad5..ef609c4a9 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -84,6 +84,8 @@ #include "aicurl.h" #include "aihttptimeoutpolicy.h" +void load_default_bindings(bool zqsd); + #ifdef TOGGLE_HACKED_GODLIKE_VIEWER BOOL gHackGodmode = FALSE; #endif @@ -627,6 +629,8 @@ static bool handlePhoenixNameSystemChanged(const LLSD& newvalue) } // [/Ansariel: Display name support] +bool handleUpdateFriends() { LLAvatarTracker::instance().updateFriends(); return true; } + static bool handleAllowLargeSounds(const LLSD& newvalue) { if(gAudiop) @@ -824,8 +828,11 @@ void settings_setup_listeners() // [Ansariel: Display name support] gSavedSettings.getControl("PhoenixNameSystem")->getSignal()->connect(boost::bind(&handlePhoenixNameSystemChanged, _2)); // [/Ansariel: Display name support] + gSavedSettings.getControl("LiruShowLastNameResident")->getSignal()->connect(boost::bind(handlePhoenixNameSystemChanged, _2)); + gSavedSettings.getControl("FriendNameSystem")->getSignal()->connect(boost::bind(handleUpdateFriends)); gSavedSettings.getControl("AllowLargeSounds")->getSignal()->connect(boost::bind(&handleAllowLargeSounds, _2)); + gSavedSettings.getControl("LiruUseZQSDKeys")->getSignal()->connect(boost::bind(load_default_bindings, _2)); } void onCommitControlSetting_gSavedSettings(LLUICtrl* ctrl, void* name) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 093f61d4f..4994869ce 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -767,8 +767,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); - glh::matrix4f proj = glh_get_current_projection(); - glh::matrix4f mod = glh_get_current_modelview(); + const LLMatrix4a saved_proj = glh_get_current_projection(); + const LLMatrix4a saved_mod = glh_get_current_modelview(); glViewport(0,0,512,512); LLVOAvatar::updateFreezeCounter() ; @@ -777,12 +777,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo LLVOAvatar::updateImpostors(); } - glh_set_current_projection(proj); - glh_set_current_modelview(mod); + glh_set_current_projection(saved_proj); + glh_set_current_modelview(saved_mod); gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadMatrix(proj.m); + gGL.loadMatrix(saved_proj); gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(mod.m); + gGL.loadMatrix(saved_mod); gViewerWindow->setup3DViewport(); LLGLState::checkStates(); @@ -1049,12 +1049,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo //store this frame's modelview matrix for use //when rendering next frame's occlusion queries - for (U32 i = 0; i < 16; i++) - { - gGLPreviousModelView[i] = gGLLastModelView[i]; - gGLLastModelView[i] = gGLModelView[i]; - gGLLastProjection[i] = gGLProjection[i]; - } + gGLPreviousModelView = gGLLastModelView; + gGLLastModelView = gGLModelView; + gGLLastProjection = gGLProjection; stop_glerror(); } @@ -1146,8 +1143,8 @@ void render_hud_attachments() gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); - glh::matrix4f current_proj = glh_get_current_projection(); - glh::matrix4f current_mod = glh_get_current_modelview(); + const LLMatrix4a saved_proj = glh_get_current_projection(); + const LLMatrix4a saved_mod = glh_get_current_modelview(); // clamp target zoom level to reasonable values // gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f); @@ -1243,8 +1240,8 @@ void render_hud_attachments() gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.popMatrix(); - glh_set_current_projection(current_proj); - glh_set_current_modelview(current_mod); + glh_set_current_projection(saved_proj); + glh_set_current_modelview(saved_mod); } LLRect get_whole_screen_region() @@ -1267,7 +1264,7 @@ LLRect get_whole_screen_region() return whole_screen; } -bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::matrix4f &model) +bool get_hud_matrices(const LLRect& screen_region, LLMatrix4a &proj, LLMatrix4a &model) { if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment()) { @@ -1275,28 +1272,24 @@ bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::mat LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); - proj = gl_ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth); - proj.element(2,2) = -0.01f; - + proj = gGL.genOrtho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth); + proj.getRow<2>().copyComponent<2>(LLVector4a(-0.01f)); + F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect(); - glh::matrix4f mat; F32 scale_x = (F32)gViewerWindow->getWorldViewWidthScaled() / (F32)screen_region.getWidth(); F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight(); - mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f)); - mat.set_translate( - glh::vec3f(clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), - clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), - 0.f)); - proj *= mat; - - glh::matrix4f tmp_model((GLfloat*) OGL_TO_CFR_ROTATION); - - mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level)); - mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f)); - - tmp_model *= mat; - model = tmp_model; + + proj.applyTranslation_affine( + clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), + clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), + 0.f); + proj.applyScale_affine(scale_x, scale_y, 1.f); + + model = OGL_TO_CFR_ROTATION; + model.applyTranslation_affine(LLVector3(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f)); + model.applyScale_affine(zoom_level); + return TRUE; } else @@ -1305,7 +1298,7 @@ bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::mat } } -bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model) +bool get_hud_matrices(LLMatrix4a &proj, LLMatrix4a &model) { LLRect whole_screen = get_whole_screen_region(); return get_hud_matrices(whole_screen, proj, model); @@ -1319,17 +1312,17 @@ BOOL setup_hud_matrices() BOOL setup_hud_matrices(const LLRect& screen_region) { - glh::matrix4f proj, model; + LLMatrix4a proj, model; bool result = get_hud_matrices(screen_region, proj, model); if (!result) return result; - + // set up transform to keep HUD objects in front of camera gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadMatrix(proj.m); + gGL.loadMatrix(proj); glh_set_current_projection(proj); gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(model.m); + gGL.loadMatrix(model); glh_set_current_modelview(model); return TRUE; } @@ -1340,13 +1333,13 @@ void render_ui(F32 zoom_factor, int subfield, bool tiling) { LLGLState::checkStates(); - glh::matrix4f saved_view = glh_get_current_modelview(); + const LLMatrix4a saved_view = glh_get_current_modelview(); if (!gSnapshot) { gGL.pushMatrix(); gGL.loadMatrix(gGLLastModelView); - glh_set_current_modelview(glh_copy_matrix(gGLLastModelView)); + glh_set_current_modelview(gGLLastModelView); } { diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp index 54ac54fd2..26ef02e77 100644 --- a/indra/newview/llviewerdisplayname.cpp +++ b/indra/newview/llviewerdisplayname.cpp @@ -62,7 +62,7 @@ class LLSetDisplayNameResponder : public LLHTTPClient::ResponderIgnoreBody { public: // only care about errors - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD()); LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots(); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index a779b617b..02b5c9c58 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -132,8 +132,8 @@ LLViewerFolderDictionary::LLViewerFolderDictionary() addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "inv_folder_outfit.tga", "inv_folder_outfit.tga", TRUE, false)); addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "inv_folder_mesh.tga", "inv_folder_mesh.tga", FALSE, false)); - addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "inv_folder_inbox.tga", "inv_folder_inbox.tga", FALSE, false)); - addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "inv_folder_outbox.tga", "inv_folder_outbox.tga", FALSE, false)); + addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Received Items", "inv_folder_inbox.tga", "inv_folder_inbox.tga", FALSE, false)); + addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Merchant Outbox", "inv_folder_outbox.tga", "inv_folder_outbox.tga", FALSE, false)); addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false)); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 7194711a6..4455b4d11 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -47,6 +47,7 @@ #include "llinventorybridge.h" #include "llinventorypanel.h" #include "llfloaterinventory.h" +#include "llfloaterperms.h" #include "lllandmark.h" #include "llviewerassettype.h" @@ -950,23 +951,72 @@ void activate_gesture_cb(const LLUUID& inv_item) LLGestureMgr::instance().activateGesture(inv_item); } +void create_script_cb(const LLUUID& inv_item) +{ + if (!inv_item.isNull()) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item); + if (item) + { + LLPermissions perm = item->getPermissions(); + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Scripts")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Scripts")); + + item->setPermissions(perm); + + item->updateServer(FALSE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + } + } +} + void create_gesture_cb(const LLUUID& inv_item) { - if (inv_item.isNull()) - return; - - LLGestureMgr::instance().activateGesture(inv_item); - - LLViewerInventoryItem* item = gInventory.getItem(inv_item); - if (!item) return; - gInventory.updateItem(item); - gInventory.notifyObservers(); - - if(!LLPreview::show(inv_item,FALSE)) + if (!inv_item.isNull()) { - LLPreviewGesture* preview = LLPreviewGesture::show(std::string("Gesture: ") + item->getName(), inv_item, LLUUID::null); - // Force to be entirely onscreen. - gFloaterView->adjustToFitScreen(preview, FALSE); + LLGestureMgr::instance().activateGesture(inv_item); + + LLViewerInventoryItem* item = gInventory.getItem(inv_item); + if (item) + { + LLPermissions perm = item->getPermissions(); + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures")); + + item->setPermissions(perm); + + item->updateServer(FALSE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + + if (!LLPreview::show(inv_item,FALSE)) + { + LLPreviewGesture* preview = LLPreviewGesture::show(std::string("Gesture: ") + item->getName(), inv_item, LLUUID::null); + // Force to be entirely onscreen. + gFloaterView->adjustToFitScreen(preview, FALSE); + } + } + } +} + +void create_notecard_cb(const LLUUID& inv_item) +{ + if (!inv_item.isNull()) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item); + if (item) + { + LLPermissions perm = item->getPermissions(); + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Notecards")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Notecards")); + + item->setPermissions(perm); + + item->updateServer(FALSE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + } } } @@ -1225,22 +1275,45 @@ void create_new_item(const std::string& name, LLViewerAssetType::generateDescriptionFor(asset_type, desc); next_owner_perm = (next_owner_perm) ? next_owner_perm : PERM_MOVE | PERM_TRANSFER; - - if (inv_type == LLInventoryType::IT_GESTURE) + LLPointer cb = NULL; + + switch(inv_type) { - LLPointer cb = new LLBoostFuncInventoryCallback(create_gesture_cb); - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type, - NOT_WEARABLE, next_owner_perm, cb); + case LLInventoryType::IT_LSL: + { + cb = new LLBoostFuncInventoryCallback(create_script_cb); + next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Scripts"); + break; + } + + case LLInventoryType::IT_GESTURE: + { + cb = new LLBoostFuncInventoryCallback(create_gesture_cb); + next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Gestures"); + break; + } + + case LLInventoryType::IT_NOTECARD: + { + cb = new LLBoostFuncInventoryCallback(create_notecard_cb); + next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Notecards"); + break; + } + default: + break; } - else - { - LLPointer cb = NULL; - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type, - NOT_WEARABLE, next_owner_perm, cb); - } - + + create_inventory_item(gAgent.getID(), + gAgent.getSessionID(), + parent_id, + LLTransactionID::tnull, + name, + desc, + asset_type, + inv_type, + NOT_WEARABLE, + next_owner_perm, + cb); } const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not) @@ -1281,7 +1354,7 @@ const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probabl parent_id, LLAssetType::AT_LSL_TEXT, LLInventoryType::IT_LSL, - PERM_MOVE | PERM_TRANSFER); + PERM_MOVE | PERM_TRANSFER); // overridden in create_new_item } else if ("notecard" == type_name) { @@ -1290,7 +1363,7 @@ const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probabl parent_id, LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, - PERM_ALL); + PERM_ALL); // overridden in create_new_item } else if ("gesture" == type_name) { @@ -1299,7 +1372,7 @@ const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probabl parent_id, LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, - PERM_ALL); + PERM_ALL); // overridden in create_new_item } else { diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index c3bdfe5f8..208e0643f 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -118,14 +118,15 @@ void LLViewerJointMesh::uploadJointMatrices() //calculate joint matrices for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.count(); joint_num++) { - LLMatrix4 joint_mat = *reference_mesh->mJointRenderData[joint_num]->mWorldMatrix; + LLMatrix4a joint_mat = *reference_mesh->mJointRenderData[joint_num]->mWorldMatrix; if (hardware_skinning) { - joint_mat *= LLDrawPoolAvatar::getModelView(); + joint_mat.setMul(LLDrawPoolAvatar::getModelView(),joint_mat); + //joint_mat *= LLDrawPoolAvatar::getModelView(); } - gJointMatUnaligned[joint_num] = joint_mat; - gJointRotUnaligned[joint_num] = joint_mat.getMat3(); + gJointMatUnaligned[joint_num] = LLMatrix4(joint_mat.getF32ptr()); + gJointRotUnaligned[joint_num] = gJointMatUnaligned[joint_num].getMat3(); } BOOL last_pivot_uploaded = FALSE; @@ -334,8 +335,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) else { gGL.pushMatrix(); - LLMatrix4 jointToWorld = getWorldMatrix(); - gGL.multMatrix((GLfloat*)jointToWorld.mMatrix); + gGL.multMatrix(getWorldMatrix()); buff->setBuffer(mask); buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); gGL.popMatrix(); diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index 36099abe8..f5af5683a 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -2,31 +2,25 @@ * @file llviewerjoystick.cpp * @brief Joystick / NDOF device functionality. * - * $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$ */ @@ -42,10 +36,12 @@ #include "lltoolmgr.h" #include "llselectmgr.h" #include "llviewermenu.h" +#include "llvoavatarself.h" // Singu Note: For toggle sit. #include "llagent.h" #include "llagentcamera.h" #include "llfocusmgr.h" +#include // ---------------------------------------------------------------------------- // Constants @@ -57,15 +53,73 @@ #define RY_I 5 #define RZ_I 3 -// flycam translations in build mode should be reduced -const F32 BUILDMODE_FLYCAM_T_SCALE = 3.f; - // minimum time after setting away state before coming back const F32 MIN_AFK_TIME = 2.f; F32 LLViewerJoystick::sLastDelta[] = {0,0,0,0,0,0,0}; F32 LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0}; +// Note: Save the type of controller +enum EControllerType { NONE, SPACE_NAV, XBOX, DS3, UNKNOWN }; +static EControllerType sType = NONE; + +// Control cursor instead of avatar? +bool sControlCursor = false; + +enum XBoxKeys +{ + XBOX_A_KEY = 0, + XBOX_B_KEY, + XBOX_X_KEY, + XBOX_Y_KEY, + XBOX_L_BUMP_KEY, + XBOX_R_BUMP_KEY, + XBOX_BACK_KEY, + XBOX_START_KEY, + XBOX_L_STICK_CLICK, + XBOX_R_STICK_CLICK +}; + +bool isOUYA(const std::string& desc) { return desc.find("OUYA") != std::string::npos; } + +bool isXboxLike(const std::string& desc) +{ + return desc.find("Xbox") != std::string::npos + || isOUYA(desc); +} + +bool isDS3Like(const std::string& desc) +{ + return desc.find("MotioninJoy") != std::string::npos; +} + +enum DS3Keys +{ + DS3_TRIANGLE_KEY = 0, + DS3_CIRCLE_KEY, + DS3_X_KEY, + DS3_SQUARE_KEY, + DS3_L1_KEY, + DS3_R1_KEY, + DS3_L2_KEY, + DS3_R2_KEY, + DS3_SELECT_KEY, + DS3_L_STICK_CLICK, + DS3_R_STICK_CLICK, + DS3_START_KEY, + DS3_LOGO_KEY +}; + +S32 get_joystick_type() +{ + if (sType == SPACE_NAV) return 0; + if (sType == XBOX) return isOUYA(LLViewerJoystick::getInstance()->getDescription()) ? 1 : 2; + if (sType == DS3) return 3; + + return -1; // sType == NONE || sType == UNKNOWN +} +// + // These constants specify the maximum absolute value coming in from the device. // HACK ALERT! the value of MAX_JOYSTICK_INPUT_VALUE is not arbitrary as it // should be. It has to be equal to 3000 because the SpaceNavigator on Windows @@ -163,7 +217,7 @@ LLViewerJoystick::LLViewerJoystick() memset(mBtn, 0, sizeof(mBtn)); // factor in bandwidth? bandwidth = gViewerStats->mKBitStat - mPerfScale = 4000.f / gSysCPU.getMHz(); + mPerfScale = 4000.f / gSysCPU.getMHz(); // hmm. why? } // ----------------------------------------------------------------------------- @@ -247,11 +301,14 @@ void LLViewerJoystick::init(bool autoenable) } updateEnabled(autoenable); + const std::string desc(getDescription()); if (mDriverState == JDS_INITIALIZED) { + sControlCursor = false; // A Joystick device is plugged in if (isLikeSpaceNavigator()) { + sType = SPACE_NAV; // It's a space navigator, we have defaults for it. if (gSavedSettings.getString("JoystickInitialized") != "SpaceNavigator") { @@ -260,19 +317,52 @@ void LLViewerJoystick::init(bool autoenable) gSavedSettings.setString("JoystickInitialized", "SpaceNavigator"); } } + else if (isXboxLike(desc)) + { + sType = XBOX; + // It's an Xbox controller, we have defaults for it. + bool ouya(isOUYA(desc)); + std::string controller = ouya ? "OUYA" : "XboxController"; + if (gSavedSettings.getString("JoystickInitialized") != controller) + { + // Only set the defaults if we haven't already (in case they were overridden) + setSNDefaults(ouya ? 1 : 2); + gSavedSettings.setString("JoystickInitialized", controller); + } + } + else if (isDS3Like(desc)) + { + sType = DS3; + // It's a DS3 controller, we have defaults for it. + if (gSavedSettings.getString("JoystickInitialized") != "DualShock3") + { + // Only set the defaults if we haven't already (in case they were overridden) + setSNDefaults(3); + gSavedSettings.setString("JoystickInitialized", "DualShock3"); + } + } else { - // It's not a Space Navigator + // It's not a Space Navigator, 360 controller, or DualShock 3 + sType = UNKNOWN; gSavedSettings.setString("JoystickInitialized", "UnknownDevice"); } } else { // No device connected, don't change any settings + sType = NONE; } llinfos << "ndof: mDriverState=" << mDriverState << "; mNdofDev=" << mNdofDev << "; libinit=" << libinit << llendl; + + // + if (mDriverState == JDS_INITIALIZED) + { + llinfos << "Joystick = " << desc << llendl; + } + // #endif } @@ -283,7 +373,7 @@ void LLViewerJoystick::terminate() ndof_libcleanup(); llinfos << "Terminated connection with NDOF device." << llendl; - + mDriverState = JDS_UNINITIALIZED; #endif } @@ -421,14 +511,96 @@ void LLViewerJoystick::agentFly(F32 inc) } // ----------------------------------------------------------------------------- -void LLViewerJoystick::agentRotate(F32 pitch_inc, F32 yaw_inc) +void LLViewerJoystick::agentPitch(F32 pitch_inc) { - LLQuaternion new_rot; - pitch_inc = gAgent.clampPitchToLimits(-pitch_inc); - const LLQuaternion qx(pitch_inc, gAgent.getLeftAxis()); - const LLQuaternion qy(-yaw_inc, gAgent.getReferenceUpVector()); - new_rot.setQuat(qx * qy); - gAgent.rotate(new_rot); + if (pitch_inc < 0) + { + gAgent.setControlFlags(AGENT_CONTROL_PITCH_POS); + } + else if (pitch_inc > 0) + { + gAgent.setControlFlags(AGENT_CONTROL_PITCH_NEG); + } + + gAgent.pitch(-pitch_inc); +} + +// ----------------------------------------------------------------------------- +void LLViewerJoystick::agentYaw(F32 yaw_inc) +{ + // Cannot steer some vehicles in mouselook if the script grabs the controls + if (gAgentCamera.cameraMouselook() && !gSavedSettings.getBOOL("JoystickMouselookYaw")) + { + gAgent.rotate(-yaw_inc, gAgent.getReferenceUpVector()); + } + else + { + if (yaw_inc < 0) + { + gAgent.setControlFlags(AGENT_CONTROL_YAW_POS); + } + else if (yaw_inc > 0) + { + gAgent.setControlFlags(AGENT_CONTROL_YAW_NEG); + } + + gAgent.yaw(-yaw_inc); + } +} + +S32 linear_ramp(const F32& inc, const F32& prev_inc) +{ + // Start out linear for fine control but then ramp up more quickly for faster movement. + F32 nudge = inc > F_APPROXIMATELY_ZERO ? 1.f : -1.f; + F32 linear = inc + prev_inc; + F32 square = 0.f; + if (abs(linear) > 0.2f) + { + square = linear + (0.2f * -nudge); + square *= abs(square); + } + + return nudge + linear * 25.f + square * 300.f; +} + +void LLViewerJoystick::cursorSlide(F32 inc) +{ + static F32 prev_inc = 0.f; // Smooth a little. + if (!is_approx_zero(inc)) + { + S32 x, y; + LLUI::getMousePositionScreen(&x, &y); + x = llclamp(x + linear_ramp(inc, prev_inc), 0, gViewerWindow->getWindowWidthRaw()); + LLUI::setMousePositionScreen(x, y); + } + prev_inc = inc; +} + +void LLViewerJoystick::cursorPush(F32 inc) +{ + static F32 prev_inc = 0.f; // Smooth a little. + if (!is_approx_zero(0.001)) + { + S32 x, y; + LLUI::getMousePositionScreen(&x, &y); + y = llclamp(y + linear_ramp(inc, prev_inc), 0, gViewerWindow->getWindowHeightRaw()); + LLUI::setMousePositionScreen(x, y); + } + prev_inc = inc; +} + +void LLViewerJoystick::cursorZoom(F32 inc) +{ + if (!is_approx_zero(inc)) + { + static U8 count = 0; + ++count; + if (count == 3) // Slow down the zoom in/out. + { + gViewerWindow->handleScrollWheel(inc > F_APPROXIMATELY_ZERO ? 1 : -1); + count = 0; + } + } } // ----------------------------------------------------------------------------- @@ -589,25 +761,54 @@ void LLViewerJoystick::moveAvatar(bool reset) gSavedSettings.getS32("JoystickAxis5") }; - if (reset || mResetFlag) + if (!sControlCursor) { - resetDeltas(axis); - if (reset) + if (reset || mResetFlag) { - // Note: moving the agent triggers agent camera mode; - // don't do this every time we set mResetFlag (e.g. because we gained focus) - gAgent.moveAt(0, true); + resetDeltas(axis); + if (reset) + { + // Note: moving the agent triggers agent camera mode; + // don't do this every time we set mResetFlag (e.g. because we gained focus) + gAgent.moveAt(0, true); + } + return; } - return; } bool is_zero = true; + static bool button_held = false; - if (mBtn[1] == 1) + if (mBtn[sType == XBOX ? XBOX_L_STICK_CLICK : sType == DS3 ? DS3_L_STICK_CLICK : 1] == 1) { - agentJump(); + // If AutomaticFly is enabled, then button1 merely causes a + // jump (as the up/down axis already controls flying) if on the + // ground, or cease flight if already flying. + // If AutomaticFly is disabled, then button1 toggles flying. + if (gSavedSettings.getBOOL("AutomaticFly")) + { + if (!gAgent.getFlying()) + { + gAgent.moveUp(1); + } + else if (!button_held) + { + button_held = true; + gAgent.setFlying(FALSE); + } + } + else if (!button_held) + { + button_held = true; + gAgent.setFlying(!gAgent.getFlying()); + } + is_zero = false; } + else + { + button_held = false; + } F32 axis_scale[] = { @@ -719,7 +920,15 @@ void LLViewerJoystick::moveAvatar(bool reset) } sDelta[RX_I] += (cur_delta[RX_I] - sDelta[RX_I]) * time * feather; sDelta[RY_I] += (cur_delta[RY_I] - sDelta[RY_I]) * time * feather; - + + if (sControlCursor) + { + cursorSlide(sDelta[X_I]); // left / right + cursorPush(-sDelta[Z_I]); // up / down + cursorZoom(sDelta[RX_I]); // mousewheel + return; + } + handleRun((F32) sqrt(sDelta[Z_I]*sDelta[Z_I] + sDelta[X_I]*sDelta[X_I])); // Allow forward/backward movement some priority @@ -765,11 +974,13 @@ void LLViewerJoystick::moveAvatar(bool reset) { if (gAgent.getFlying()) { - agentRotate(eff_rx, eff_ry); + agentPitch(eff_rx); + agentYaw(eff_ry); } else { - agentRotate(eff_rx, 2.f * eff_ry); + agentPitch(eff_rx); + agentYaw(2.f * eff_ry); } } } @@ -778,7 +989,8 @@ void LLViewerJoystick::moveAvatar(bool reset) agentSlide(sDelta[X_I]); // move sideways agentFly(sDelta[Y_I]); // up/down & crouch agentPush(sDelta[Z_I]); // forward/back - agentRotate(sDelta[RX_I], sDelta[RY_I]); // pitch & turn + agentPitch(sDelta[RX_I]); // pitch + agentYaw(sDelta[RY_I]); // turn } } @@ -874,14 +1086,15 @@ void LLViewerJoystick::moveFlycam(bool reset) cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f); } - // we need smaller camera movements in build mode + // We may want to scale camera movements up or down in build mode. // NOTE: this needs to remain after the deadzone calculation, otherwise // we have issues with flycam "jumping" when the build dialog is opened/closed -Nyx if (in_build_mode) { if (i == X_I || i == Y_I || i == Z_I) { - cur_delta[i] /= BUILDMODE_FLYCAM_T_SCALE; + static LLCachedControl build_mode_scale(gSavedSettings,"FlycamBuildModeScale", 1.0); + cur_delta[i] *= build_mode_scale; } } @@ -976,15 +1189,16 @@ bool LLViewerJoystick::toggleFlycam() } else { - // we are in build mode, exiting from the flycam mode: since we are - // going to keep the flycam POV for the main camera until the avatar - // moves, we need to track this situation. + // Exiting from the flycam mode: since we are going to keep the flycam POV for + // the main camera until the avatar moves, we need to track this situation. setCameraNeedsUpdate(false); setNeedsReset(true); } return true; } +bool toggleCursor() { sControlCursor = !sControlCursor; return true; } + void LLViewerJoystick::scanJoystick() { if (mDriverState != JDS_INITIALIZED || !gSavedSettings.getBOOL("JoystickEnabled")) @@ -1000,20 +1214,131 @@ void LLViewerJoystick::scanJoystick() updateStatus(); static long toggle_flycam = 0; + static bool toggle_cursor = false; - if (mBtn[0] == 1) - { - if (mBtn[0] != toggle_flycam) + // Xbox 360 support + if (sType == XBOX || sType == DS3) + { + bool ds3 = sType == DS3; + // Special command keys ... + // - Back = toggle flycam + U8 key = ds3 ? (U8)DS3_SELECT_KEY : (U8)XBOX_BACK_KEY; + if (mBtn[key] == 1) { - toggle_flycam = toggleFlycam() ? 1 : 0; + if (!toggle_flycam) toggle_flycam = toggleFlycam(); + } + else + { + toggle_flycam = false; + } + + // - Start = toggle cursor/camera control + key = ds3 ? (U8)DS3_START_KEY : (U8)XBOX_START_KEY; + if (mBtn[key] == 1) + { + if (!toggle_cursor) toggle_cursor = toggleCursor(); + } + else + { + toggle_cursor = false; + } + + // Toggle mouselook ... + static bool right_stick_click_down = false; + key = ds3 ? (U8)DS3_R_STICK_CLICK : (U8)XBOX_R_STICK_CLICK; + if (!!mBtn[key] != right_stick_click_down) + { + if (right_stick_click_down = mBtn[key]) // Note: Setting, not comparing. + gAgentCamera.cameraMouselook() ? gAgentCamera.changeCameraToDefault() : gAgentCamera.changeCameraToMouselook(); + } + + MASK mask = gKeyboard->currentMask(TRUE); + // Esc + static bool esc_down = false; + key = ds3 ? (U8)DS3_TRIANGLE_KEY : (U8)XBOX_Y_KEY; + if (!!mBtn[key] != esc_down) + { + esc_down = mBtn[key]; + (gKeyboard->*(esc_down ? &LLKeyboard::handleTranslatedKeyDown : &LLKeyboard::handleTranslatedKeyDown))(KEY_ESCAPE, mask); + } + + // Alt + static bool alt_down = false; + key = ds3 ? (U8)DS3_X_KEY : (U8)XBOX_A_KEY; + if (!!mBtn[key] != alt_down) + { + gKeyboard->setControllerKey(KEY_ALT, alt_down = mBtn[key]); + } + + // Ctrl + static bool ctrl_down = false; + key = ds3 ? (U8)DS3_SQUARE_KEY : (U8)XBOX_X_KEY; + if (!!mBtn[key] != ctrl_down) + { + gKeyboard->setControllerKey(KEY_CONTROL, ctrl_down = mBtn[key]); + } + + // Shift + static bool shift_down = false; + key = ds3 ? (U8)DS3_CIRCLE_KEY : (U8)XBOX_B_KEY; + if (!!mBtn[key] != shift_down) + { + gKeyboard->setControllerKey(KEY_SHIFT, shift_down = mBtn[key]); + } + + // Mouse clicks ... + LLCoordGL coord; + LLUI::getMousePositionScreen(&coord.mX, &coord.mY); + static bool m1_down = false; + static F32 last_m1 = 0; + key = ds3 ? (U8)DS3_L1_KEY : (U8)XBOX_L_BUMP_KEY; + if (!!mBtn[key] != m1_down) + { + m1_down = mBtn[key]; + (gViewerWindow->*(m1_down ? &LLViewerWindow::handleMouseDown : &LLViewerWindow::handleMouseUp))(gViewerWindow->getWindow(), coord, mask); + if (m1_down && gFrameTimeSeconds-last_m1 == 0.5f) + gViewerWindow->handleDoubleClick(gViewerWindow->getWindow(), coord, mask); + last_m1 = gFrameTimeSeconds; + } + static bool m2_down = false; + key = ds3 ? (U8)DS3_R1_KEY : (U8)XBOX_R_BUMP_KEY; + if (!!mBtn[key] != m2_down) + { + m2_down = mBtn[key]; + (gViewerWindow->*(m2_down ? &LLViewerWindow::handleRightMouseDown : &LLViewerWindow::handleRightMouseUp))(gViewerWindow->getWindow(), coord, mask); + } + + if (ds3) // Yay bonus keys~ + { + static bool sit_down = false; + if (!!mBtn[DS3_LOGO_KEY] != sit_down) + { + if (sit_down = mBtn[DS3_LOGO_KEY]) + (gAgentAvatarp && gAgentAvatarp->isSitting()) ? gAgent.standUp() : gAgent.sitDown(); + } + /* Singu TODO: What should these be? + DS3_L2_KEY + DS3_R2_KEY + */ } } else + // { - toggle_flycam = 0; + if (mBtn[0] == 1) + { + if (mBtn[0] != toggle_flycam) + { + toggle_flycam = toggleFlycam() ? 1 : 0; + } + } + else + { + toggle_flycam = 0; + } } - if (!mOverrideCamera && !(LLToolMgr::getInstance()->inBuildMode() && gSavedSettings.getBOOL("JoystickBuildEnabled"))) + if (sControlCursor || (!mOverrideCamera && !(LLToolMgr::getInstance()->inBuildMode() && gSavedSettings.getBOOL("JoystickBuildEnabled")))) { moveAvatar(); } @@ -1028,6 +1353,11 @@ std::string LLViewerJoystick::getDescription() { res = ll_safe_string(mNdofDev->product); } + + // + // Tidy up description of Xbox controllers. + res = boost::regex_replace(res, boost::regex("^Controller \\((.*)\\)$", boost::regex::perl), "$1"); + // #endif return res; } @@ -1046,7 +1376,7 @@ bool LLViewerJoystick::isLikeSpaceNavigator() const } // ----------------------------------------------------------------------------- -void LLViewerJoystick::setSNDefaults() +void LLViewerJoystick::setSNDefaults(S32 type) { #if LL_DARWIN || LL_LINUX const float platformScale = 20.f; @@ -1060,61 +1390,75 @@ void LLViewerJoystick::setSNDefaults() #endif //gViewerWindow->alertXml("CacheWillClear"); - llinfos << "restoring SpaceNavigator defaults..." << llendl; + const bool ouya = type == 1; + const bool xbox = ouya || type == 2; + const bool ds3 = type == 3; + llinfos << "restoring " << (xbox ? ouya ? "OUYA Game Controller" : "Xbox Controller" : ds3 ? "Dual Shock 3" : "SpaceNavigator") << " defaults..." << llendl; + + /* + Axis 0: Left Thumbstick Horizontal + Axis 1: Left Thumbstick Vertical + Axis 2: Left and Right triggers (Analog) + Axis 3: Right Thumbstick Horizontal + Axis 4: Left Thumbstick Vertical + Axis 5: Unused + Syntax/Format: + Debug setting InternalMapping,Jostick Axis (see above) */ gSavedSettings.setS32("JoystickAxis0", 1); // z (at) - gSavedSettings.setS32("JoystickAxis1", 0); // x (slide) - gSavedSettings.setS32("JoystickAxis2", 2); // y (up) - gSavedSettings.setS32("JoystickAxis3", 4); // pitch - gSavedSettings.setS32("JoystickAxis4", 3); // roll - gSavedSettings.setS32("JoystickAxis5", 5); // yaw - gSavedSettings.setS32("JoystickAxis6", -1); + gSavedSettings.setS32("JoystickAxis1", ouya ? 3 : 0); // x (slide) + gSavedSettings.setS32("JoystickAxis2", ouya ? 4 : ds3 ? 3 : 2); // y (up) + gSavedSettings.setS32("JoystickAxis3", xbox ? ouya ? 3 : -1 : 4); // roll + gSavedSettings.setS32("JoystickAxis4", xbox ? 4 : ds3 ? 5 : 3); // pitch + gSavedSettings.setS32("JoystickAxis5", xbox ? ouya ? 0 : 3 : ds3 ? 2 : 5); // yaw + gSavedSettings.setS32("JoystickAxis6", ouya ? 5 : -1); - gSavedSettings.setBOOL("Cursor3D", is_3d_cursor); + const bool game = xbox || ds3; // All game controllers are relatively the same + gSavedSettings.setBOOL("Cursor3D", !game && is_3d_cursor); gSavedSettings.setBOOL("AutoLeveling", true); gSavedSettings.setBOOL("ZoomDirect", false); - gSavedSettings.setF32("AvatarAxisScale0", 1.f * platformScaleAvXZ); - gSavedSettings.setF32("AvatarAxisScale1", 1.f * platformScaleAvXZ); - gSavedSettings.setF32("AvatarAxisScale2", 1.f); - gSavedSettings.setF32("AvatarAxisScale4", .1f * platformScale); - gSavedSettings.setF32("AvatarAxisScale5", .1f * platformScale); - gSavedSettings.setF32("AvatarAxisScale3", 0.f * platformScale); - gSavedSettings.setF32("BuildAxisScale1", .3f * platformScale); - gSavedSettings.setF32("BuildAxisScale2", .3f * platformScale); - gSavedSettings.setF32("BuildAxisScale0", .3f * platformScale); - gSavedSettings.setF32("BuildAxisScale4", .3f * platformScale); - gSavedSettings.setF32("BuildAxisScale5", .3f * platformScale); - gSavedSettings.setF32("BuildAxisScale3", .3f * platformScale); - gSavedSettings.setF32("FlycamAxisScale1", 2.f * platformScale); - gSavedSettings.setF32("FlycamAxisScale2", 2.f * platformScale); - gSavedSettings.setF32("FlycamAxisScale0", 2.1f * platformScale); - gSavedSettings.setF32("FlycamAxisScale4", .1f * platformScale); - gSavedSettings.setF32("FlycamAxisScale5", .15f * platformScale); - gSavedSettings.setF32("FlycamAxisScale3", 0.f * platformScale); - gSavedSettings.setF32("FlycamAxisScale6", 0.f * platformScale); + gSavedSettings.setF32("AvatarAxisScale0", (xbox ? 0.43f : ds3 ? 0.215f : 1.f) * platformScaleAvXZ); + gSavedSettings.setF32("AvatarAxisScale1", (xbox ? 0.43f : ds3 ? 0.215f : 1.f) * platformScaleAvXZ); + gSavedSettings.setF32("AvatarAxisScale2", xbox ? 0.43f : ds3 ? -0.43f : 1.f); + gSavedSettings.setF32("AvatarAxisScale4", ds3 ? 0.215f * platformScaleAvXZ : ((xbox ? 4.f : .1f) * platformScale)); + gSavedSettings.setF32("AvatarAxisScale5", ds3 ? 0.215f * platformScaleAvXZ : ((xbox ? 4.f : .1f) * platformScale)); + gSavedSettings.setF32("AvatarAxisScale3", (game ? 4.f : 0.f) * platformScale); + gSavedSettings.setF32("BuildAxisScale1", (game ? ouya ? 20.f : 0.8f : .3f) * platformScale); + gSavedSettings.setF32("BuildAxisScale2", (xbox ? ouya ? 20.f : 0.8f : ds3 ? -0.8f : .3f) * platformScale); + gSavedSettings.setF32("BuildAxisScale0", (game ? ouya ? 50.f : 1.6f : .3f) * platformScale); + gSavedSettings.setF32("BuildAxisScale4", (game ? ouya ? 1.8f : 1.f : .3f) * platformScale); + gSavedSettings.setF32("BuildAxisScale5", (game ? 2.f : .3f) * platformScale); + gSavedSettings.setF32("BuildAxisScale3", (game ? ouya ? -6.f : 1.f : .3f) * platformScale); + gSavedSettings.setF32("FlycamAxisScale1", (game ? ouya ? 20.f : 16.f : 2.f) * platformScale); + gSavedSettings.setF32("FlycamAxisScale2", (game ? ouya ? 20.f : 16.f : ds3 ? -16.f : 2.f) * platformScale); + gSavedSettings.setF32("FlycamAxisScale0", (game ? ouya ? 50.f : 25.f : 2.1f) * platformScale); // Z Scale + gSavedSettings.setF32("FlycamAxisScale4", (game ? ouya ? 1.80 : -4.f : .1f) * platformScale); + gSavedSettings.setF32("FlycamAxisScale5", (game ? 4.f : .15f) * platformScale); + gSavedSettings.setF32("FlycamAxisScale3", (xbox ? 4.f : ds3 ? 6.f : 0.f) * platformScale); + gSavedSettings.setF32("FlycamAxisScale6", (game ? 4.f : 0.f) * platformScale); - gSavedSettings.setF32("AvatarAxisDeadZone0", .1f); - gSavedSettings.setF32("AvatarAxisDeadZone1", .1f); - gSavedSettings.setF32("AvatarAxisDeadZone2", .1f); - gSavedSettings.setF32("AvatarAxisDeadZone3", 1.f); - gSavedSettings.setF32("AvatarAxisDeadZone4", .02f); - gSavedSettings.setF32("AvatarAxisDeadZone5", .01f); - gSavedSettings.setF32("BuildAxisDeadZone0", .01f); - gSavedSettings.setF32("BuildAxisDeadZone1", .01f); - gSavedSettings.setF32("BuildAxisDeadZone2", .01f); - gSavedSettings.setF32("BuildAxisDeadZone3", .01f); - gSavedSettings.setF32("BuildAxisDeadZone4", .01f); - gSavedSettings.setF32("BuildAxisDeadZone5", .01f); - gSavedSettings.setF32("FlycamAxisDeadZone0", .01f); - gSavedSettings.setF32("FlycamAxisDeadZone1", .01f); - gSavedSettings.setF32("FlycamAxisDeadZone2", .01f); - gSavedSettings.setF32("FlycamAxisDeadZone3", .01f); - gSavedSettings.setF32("FlycamAxisDeadZone4", .01f); - gSavedSettings.setF32("FlycamAxisDeadZone5", .01f); - gSavedSettings.setF32("FlycamAxisDeadZone6", 1.f); + gSavedSettings.setF32("AvatarAxisDeadZone0", game ? .2f : .1f); + gSavedSettings.setF32("AvatarAxisDeadZone1", game ? .2f : .1f); + gSavedSettings.setF32("AvatarAxisDeadZone2", game ? .2f : .1f); + gSavedSettings.setF32("AvatarAxisDeadZone3", game ? .2f : 1.f); + gSavedSettings.setF32("AvatarAxisDeadZone4", game ? .2f : .02f); + gSavedSettings.setF32("AvatarAxisDeadZone5", game ? .2f : .01f); + gSavedSettings.setF32("BuildAxisDeadZone0", game ? .02f : .01f); + gSavedSettings.setF32("BuildAxisDeadZone1", game ? .02f : .01f); + gSavedSettings.setF32("BuildAxisDeadZone2", game ? .02f : .01f); + gSavedSettings.setF32("BuildAxisDeadZone3", game ? .02f : .01f); + gSavedSettings.setF32("BuildAxisDeadZone4", game ? .02f : .01f); + gSavedSettings.setF32("BuildAxisDeadZone5", game ? .02f : .01f); + gSavedSettings.setF32("FlycamAxisDeadZone0", game ? .2f : .01f); + gSavedSettings.setF32("FlycamAxisDeadZone1", game ? .2f : .01f); + gSavedSettings.setF32("FlycamAxisDeadZone2", game ? .2f : .01f); + gSavedSettings.setF32("FlycamAxisDeadZone3", game ? .1f : .01f); + gSavedSettings.setF32("FlycamAxisDeadZone4", game ? .25f : .01f); + gSavedSettings.setF32("FlycamAxisDeadZone5", game ? .25f : .01f); + gSavedSettings.setF32("FlycamAxisDeadZone6", game ? .2f : 1.f); - gSavedSettings.setF32("AvatarFeathering", 6.f); + gSavedSettings.setF32("AvatarFeathering", game ? 3.f : 6.f); gSavedSettings.setF32("BuildFeathering", 12.f); - gSavedSettings.setF32("FlycamFeathering", 5.f); + gSavedSettings.setF32("FlycamFeathering", game ? 1.f : 5.f); } diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h index 6be9db331..058821bcd 100644 --- a/indra/newview/llviewerjoystick.h +++ b/indra/newview/llviewerjoystick.h @@ -2,31 +2,25 @@ * @file llviewerjoystick.h * @brief Viewer joystick / NDOF device functionality. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&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$ */ @@ -56,6 +50,8 @@ public: virtual ~LLViewerJoystick(); void init(bool autoenable); + void terminate(); + void updateStatus(); void scanJoystick(); void moveObjects(bool reset = false); @@ -71,18 +67,23 @@ public: bool getOverrideCamera() { return mOverrideCamera; } void setOverrideCamera(bool val); bool toggleFlycam(); - void setSNDefaults(); + void setSNDefaults(S32 type = 0); std::string getDescription(); protected: void updateEnabled(bool autoenable); - void terminate(); void handleRun(F32 inc); void agentSlide(F32 inc); void agentPush(F32 inc); void agentFly(F32 inc); - void agentRotate(F32 pitch_inc, F32 turn_inc); + void agentPitch(F32 pitch_inc); + void agentYaw(F32 yaw_inc); void agentJump(); + // + void cursorSlide(F32 inc); + void cursorPush(F32 inc); + void cursorZoom(F32 inc); + // void resetDeltas(S32 axis[]); #if LIB_NDOF static NDOF_HotPlugResult HotPlugAddCallback(NDOF_Device *dev); diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 8c899a4ae..5104f7972 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -851,6 +851,14 @@ S32 LLViewerKeyboard::loadBindings(const std::string& filename) return binding_count; } +void LLViewerKeyboard::unloadBindings() +{ + for (S32 mode = 0; mode < MODE_COUNT; ++mode) + { + mRemapKeys[mode].clear(); + mBindingCount[mode] = 0; + } +} EKeyboardMode LLViewerKeyboard::getMode() { diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h index 2be702fee..56a31b18d 100644 --- a/indra/newview/llviewerkeyboard.h +++ b/indra/newview/llviewerkeyboard.h @@ -72,6 +72,7 @@ public: void bindNamedFunction(const std::string& name, LLKeyFunc func); S32 loadBindings(const std::string& filename); // returns number bound, 0 on error + void unloadBindings(); EKeyboardMode getMode(); BOOL modeFromString(const std::string& string, S32 *mode); // False on failure diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index e9211231f..2050c3983 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -194,25 +194,25 @@ public: disconnectOwner(); } - /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(void) { - if ((200 <= status && status < 300) || status == 405) // Using HEAD may result in a 405 METHOD NOT ALLOWED, but still have the right Content-Type header. + if ((200 <= mStatus && mStatus < 300) || mStatus == 405) // Using HEAD may result in a 405 METHOD NOT ALLOWED, but still have the right Content-Type header. { std::string media_type; - if (headers.getFirstValue("content-type", media_type)) + if (mReceivedHeaders.getFirstValue("content-type", media_type)) { std::string::size_type idx1 = media_type.find_first_of(";"); std::string mime_type = media_type.substr(0, idx1); - completeAny(status, mime_type); + completeAny(mStatus, mime_type); return; } - if (200 <= status && status < 300) + if (200 <= mStatus && mStatus < 300) { - llwarns << "LLMimeDiscoveryResponder::completedHeaders: OK HTTP status (" << status << ") but no Content-Type! Received headers: " << headers << llendl; + llwarns << "LLMimeDiscoveryResponder::completedHeaders: OK HTTP status (" << mStatus << ") but no Content-Type! Received headers: " << mReceivedHeaders << llendl; } } - llwarns << "LLMimeDiscoveryResponder::completedHeaders: Got status " << status << ". Using default mime-type: " << mDefaultMimeType << llendl; - completeAny(status, mDefaultMimeType); + llwarns << "LLMimeDiscoveryResponder::completedHeaders: Got status " << mStatus << ". Using default mime-type: " << mDefaultMimeType << llendl; + completeAny(mStatus, mDefaultMimeType); } void completeAny(U32 status, const std::string& mime_type) @@ -276,18 +276,14 @@ public: /*virtual*/ bool needsHeaders(void) const { return true; } - /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(void) { - LL_DEBUGS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL; - LL_DEBUGS("MediaAuth") << headers << LL_ENDL; + LL_DEBUGS("MediaAuth") << "status = " << mStatus << ", reason = " << mReason << LL_ENDL; + LL_DEBUGS("MediaAuth") << mReceivedHeaders << LL_ENDL; LLViewerMedia::openIDCookieResponse(get_cookie("agni_sl_session_id")); } - /*virtual*/ void completedRaw( - U32 status, - const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, LLIOPipe::buffer_ptr_t const& buffer) { // This is just here to disable the default behavior (attempting to parse the response as llsd). // We don't care about the content of the response, only the set-cookie header. @@ -306,14 +302,14 @@ public: /*virtual*/ bool needsHeaders(void) const { return true; } - /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(void) { - LL_INFOS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL; - LL_INFOS("MediaAuth") << headers << LL_ENDL; + LL_INFOS("MediaAuth") << "status = " << mStatus << ", reason = " << mReason << LL_ENDL; + LL_INFOS("MediaAuth") << mReceivedHeaders << LL_ENDL; bool found = false; AIHTTPReceivedHeaders::range_type cookies; - if (headers.getValues("set-cookie", cookies)) + if (mReceivedHeaders.getValues("set-cookie", cookies)) { for (AIHTTPReceivedHeaders::iterator_type cookie = cookies.first; cookie != cookies.second; ++cookie) { @@ -337,11 +333,7 @@ public: } } - /*virtual*/ void completedRaw( - U32 status, - const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, LLIOPipe::buffer_ptr_t const& buffer) { // This is just here to disable the default behavior (attempting to parse the response as llsd). // We don't care about the content of the response, only the set-cookie header. diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 52812a7ff..fd3346160 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2204,8 +2204,17 @@ void reload_objects(LLTextureReloader& texture_list, LLViewerObject::const_child for (U8 i = 0; i < object->getNumTEs(); i++) { texture_list.addTexture(object->getTEImage(i)); + const LLTextureEntry* te = object->getTE(i); + if (LLMaterial* mat = te ? te->getMaterialParams().get() : NULL) + { + if (mat->getSpecularID().notNull()) + texture_list.addTexture(LLViewerTextureManager::getFetchedTexture(mat->getSpecularID())); + if (mat->getNormalID().notNull()) + texture_list.addTexture(LLViewerTextureManager::getFetchedTexture(mat->getNormalID())); + } } + if(recurse) { reload_objects(texture_list,object->getChildren(), true); @@ -3008,6 +3017,7 @@ class LLScriptCount : public view_listener_t { if (LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()) { + if (ScriptCounter::getInstance(object->getID())) return true; ScriptCounter* sc = new ScriptCounter(false, object); sc->requestInventories(); // sc will destroy itself @@ -3022,6 +3032,7 @@ class LLScriptDelete : public view_listener_t { if (LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()) { + if (ScriptCounter::getInstance(object->getID())) return true; ScriptCounter* sc = new ScriptCounter(true, object); sc->requestInventories(); // sc will destroy itself @@ -6469,6 +6480,15 @@ BOOL enable_buy_land(void*) LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(), false); } +class LLWorldVisibleDestinations : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool visible(!LFSimFeatureHandler::instance().destinationGuideURL().empty()); + gMenuHolder->findControl(userdata["control"].asString())->setValue(visible); + return visible; + } +}; class LLObjectAttachToAvatar : public view_listener_t { @@ -8760,6 +8780,44 @@ class LLWorldEnvSettings : public view_listener_t } }; +class LLWorldEnableEnvSettings : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool result = false; + std::string tod = userdata.asString(); + + if (tod == "region") + { + return LLEnvManagerNew::instance().getUseRegionSettings(); + } + + if (LLEnvManagerNew::instance().getUseFixedSky()) + { + if (tod == "sunrise") + { + result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunrise"); + } + else if (tod == "noon") + { + result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midday"); + } + else if (tod == "sunset") + { + result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunset"); + } + else if (tod == "midnight") + { + result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midnight"); + } + else + { + llwarns << "Unknown item" << llendl; + } + } + return result; + } +}; class SinguCloseAllDialogs : public view_listener_t { @@ -8972,6 +9030,16 @@ class ListVisibleWebProfile : public view_listener_t } }; +void ban_from_group(const uuid_vec_t& ids); +class ListBanFromGroup : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + ban_from_group(get_focused_list_ids_selected()); + return true; + } +}; + class ListCopySLURL : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -9289,7 +9357,9 @@ void initialize_menus() addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation"); addMenu(new LLWorldEnableTeleportHome(), "World.EnableTeleportHome"); addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand"); + addMenu(new LLWorldVisibleDestinations(), "World.VisibleDestinations"); (new LLWorldEnvSettings())->registerListener(gMenuHolder, "World.EnvSettings"); + (new LLWorldEnableEnvSettings())->registerListener(gMenuHolder, "World.EnableEnvSettings"); // Tools menu @@ -9487,6 +9557,7 @@ void initialize_menus() addMenu(new ListEnableMute(), "List.EnableMute"); addMenu(new ListEnableOfferTeleport(), "List.EnableOfferTeleport"); addMenu(new ListVisibleWebProfile(), "List.VisibleWebProfile"); + addMenu(new ListBanFromGroup(), "List.BanFromGroup"); addMenu(new ListCopySLURL(), "List.CopySLURL"); addMenu(new ListCopyUUIDs(), "List.CopyUUIDs"); addMenu(new ListInviteToGroup(), "List.InviteToGroup"); @@ -9551,18 +9622,20 @@ void parse_simulator_features() { std::string insertMarker = "insert_" + i->first; - LLView* marker = gMenuBarView->getChildView(insertMarker, true, false); + LLMenuItemGL* marker = gMenuBarView->findChild(insertMarker); if (!marker) continue; LLMenuGL* menu = dynamic_cast(marker->getParent()); if (!menu) continue; + std::list::iterator it = menu->find(marker); + for (LLSD::map_iterator j = i->second.beginMap(); j != i->second.endMap(); ++j) { LLMenuItemCallGL* custom = new LLMenuItemCallGL(j->second.asString(), j->first, custom_selected); custom->setUserData(custom); gCustomMenuItems.push_back(custom); - menu->addChild(custom, marker); + menu->insert(it, custom); } } } diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 483b80ab9..301a461f7 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -440,9 +440,20 @@ class LLFileUploadBulk : public view_listener_t S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); void *userdata = NULL; gSavedSettings.setBOOL("TemporaryUpload", enabled); - upload_new_resource(filename, asset_name, asset_name, 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(), - display_name, callback, expected_upload_cost, userdata); + upload_new_resource( + filename, + asset_name, + asset_name, + 0, + LLFolderType::FT_NONE, + LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + display_name, + callback, + expected_upload_cost, + userdata); } } @@ -925,7 +936,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, if(exten == "lsl" || exten == "gesture" || exten == "notecard") // added notecard Oct 15 2009 { LLInventoryType::EType inv_type = LLInventoryType::IT_GESTURE; - if(exten == "lsl") inv_type = LLInventoryType::IT_LSL; + if (exten == "lsl") inv_type = LLInventoryType::IT_LSL; else if(exten == "gesture") inv_type = LLInventoryType::IT_GESTURE; else if(exten == "notecard") inv_type = LLInventoryType::IT_NOTECARD; create_inventory_item( gAgent.getID(), @@ -1374,6 +1385,19 @@ void NewResourceItemCallback::fire(const LLUUID& new_item_id) LLUUID vfile_id = LLUUID(new_item->getDescription()); if(vfile_id.isNull()) return; new_item->setDescription("(No Description)"); + std::string type("Uploads"); + switch(new_item->getInventoryType()) + { + case LLInventoryType::IT_LSL: type = "Scripts"; break; + case LLInventoryType::IT_GESTURE: type = "Gestures"; break; + case LLInventoryType::IT_NOTECARD: type = "Notecard"; break; + default: break; + } + LLPermissions perms = new_item->getPermissions(); + perms.setMaskNext(LLFloaterPerms::getNextOwnerPerms(type)); + perms.setMaskGroup(LLFloaterPerms::getGroupPerms(type)); + perms.setMaskEveryone(LLFloaterPerms::getEveryonePerms(type)); + new_item->setPermissions(perms); new_item->updateServer(FALSE); gInventory.updateItem(new_item); gInventory.notifyObservers(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index dbd630fb9..1c5ed208f 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -673,6 +673,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response) args["NAME"] = name; args["INVITE"] = message; LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification["payload"]); + return false; } } @@ -2523,7 +2524,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { if (!mute_im) RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM_REMOTE), session_id); - message = RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); + buffer = RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); } // [/RLVa:KB] @@ -3712,17 +3713,17 @@ void script_msg_api(const std::string& msg) class AuthHandler : public LLHTTPClient::ResponderWithCompleted { protected: - /*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { std::string content; - decode_raw_body(status, reason, channels, buffer, content); - if (status == HTTP_OK) + decode_raw_body(channels, buffer, content); + if (mStatus == HTTP_OK) { send_chat_from_viewer("AUTH:" + content, CHAT_TYPE_WHISPER, 427169570); } else { - llwarns << "Hippo AuthHandler: non-OK HTTP status " << status << " for URL " << mURL << " (" << reason << "). Error body: \"" << content << "\"." << llendl; + llwarns << "Hippo AuthHandler: non-OK HTTP status " << mStatus << " for URL " << mURL << " (" << mReason << "). Error body: \"" << content << "\"." << llendl; } } @@ -3800,6 +3801,12 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } else { + // make sure that we don't have an empty or all-whitespace name + LLStringUtil::trim(from_name); + if (from_name.empty()) + { + from_name = LLTrans::getString("Unnamed"); + } chat.mFromName = from_name; } @@ -4053,10 +4060,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) sdQuery["name"] = chat.mFromName; sdQuery["owner"] = owner_id; - /* Singu Note: We don't use this field, seems like part of llinspectremoteobject if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (!is_owned_by_me) ) sdQuery["rlv_shownames"] = true; - */ const LLViewerRegion* pRegion = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); if (pRegion) @@ -6310,6 +6315,8 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) return; } + if ((U32)amount < gSavedSettings.getU32("LiruShowTransactionThreshold")) return; // Don't show transactions of small amounts the user doesn't care about. + std::string reason = reason_from_transaction_type(transaction_type, item_description); @@ -7751,6 +7758,39 @@ void send_lures(const LLSD& notification, const LLSD& response) msg->nextBlockFast(_PREHASH_TargetData); msg->addUUIDFast(_PREHASH_TargetID, target_id); + // Record the offer. + if (notification["payload"]["ids"].size() < 10) // Singu Note: Do NOT spam chat! + { +// [RLVa:KB] - Checked: 2014-03-31 (Catznip-3.6) + bool fRlvHideName = notification["payload"]["rlv_shownames"].asBoolean(); +// [/RLVa:KB] + std::string target_name; + gCacheName->getFullName(target_id, target_name); // for im log filenames + + LLSD args; +// [RLVa:KB] - Checked: 2014-03-31 (Catznip-3.6) + if (fRlvHideName) + target_name = RlvStrings::getAnonym(target_name); + else +// [/RLVa:KB] + LLAvatarNameCache::getPNSName(target_id, target_name); + args["TO_NAME"] = target_name; + + LLSD payload; + + //*TODO please rewrite all keys to the same case, lower or upper + payload["from_id"] = target_id; + payload["SUPPRESS_TOAST"] = true; + LLNotificationsUtil::add("TeleportOfferSent", args, payload); + + /* Singu TODO? +// [RLVa:KB] - Checked: 2014-03-31 (Catznip-3.6) + if (!fRlvHideName) + LLRecentPeople::instance().add(target_id); +// [/RLVa:KB] +// LLRecentPeople::instance().add(target_id); + */ + } } gAgent.sendReliableMessage(); } @@ -7795,8 +7835,7 @@ void handle_lure(const uuid_vec_t& ids) LLSD edit_args; // [RLVa:KB] - Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.0.0a - edit_args["REGION"] = - (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? gAgent.getRegion()->getName() : RlvStrings::getString(RLV_STRING_HIDDEN); + edit_args["REGION"] = (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? gAgent.getRegion()->getName() : RlvStrings::getString(RLV_STRING_HIDDEN); // [/RLVa:KB] //edit_args["REGION"] = gAgent.getRegion()->getName(); @@ -7816,6 +7855,7 @@ void handle_lure(const uuid_vec_t& ids) return; } } + payload["rlv_shownames"] = !RlvActions::canShowName(RlvActions::SNC_TELEPORTOFFER); // [/RLVa:KB] payload["ids"].append(*it); } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6dac791b4..9ea0c19d5 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2622,6 +2622,7 @@ void LLViewerObject::saveScript( * interaction with doUpdateInventory() called below. */ lldebugs << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << llendl; + LLPointer task_item = new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), item->getAssetUUID(), item->getType(), @@ -2902,7 +2903,7 @@ BOOL LLViewerObject::loadTaskInvFile(const std::string& filename) while(ifs.good()) { ifs.getline(buffer, MAX_STRING); - sscanf(buffer, " %254s", keyword); /* Flawfinder: ignore */ + if (sscanf(buffer, " %254s", keyword) < 1) continue; if(0 == strcmp("inv_item", keyword)) { LLPointer inv = new LLViewerInventoryItem; @@ -3718,18 +3719,18 @@ const LLQuaternion LLViewerObject::getRenderRotation() const { if (!mDrawable->isRoot()) { - ret = getRotation() * LLQuaternion(mDrawable->getParent()->getWorldMatrix()); + ret = getRotation() * LLQuaternion(LLMatrix4(mDrawable->getParent()->getWorldMatrix().getF32ptr())); } else { - ret = LLQuaternion(mDrawable->getWorldMatrix()); + ret = LLQuaternion(LLMatrix4(mDrawable->getWorldMatrix().getF32ptr())); } } return ret; } -const LLMatrix4 LLViewerObject::getRenderMatrix() const +const LLMatrix4a& LLViewerObject::getRenderMatrix() const { return mDrawable->getWorldMatrix(); } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 21003bcb1..40564be40 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -288,7 +288,7 @@ public: const LLQuaternion getRotationRegion() const; const LLQuaternion getRotationEdit() const; const LLQuaternion getRenderRotation() const; - virtual const LLMatrix4 getRenderMatrix() const; + virtual const LLMatrix4a& getRenderMatrix() const; void setPosition(const LLVector3 &pos, BOOL damped = FALSE); void setPositionGlobal(const LLVector3d &position, BOOL damped = FALSE); @@ -298,7 +298,7 @@ public: void setPositionParent(const LLVector3 &pos_parent, BOOL damped = FALSE); void setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped = FALSE ); - virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const { return xform->getWorldMatrix(); } + virtual const LLMatrix4a& getWorldMatrix(LLXformMatrix* xform) const { return xform->getWorldMatrix(); } inline void setRotation(const F32 x, const F32 y, const F32 z, BOOL damped = FALSE); inline void setRotation(const LLQuaternion& quat, BOOL damped = FALSE); diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index e19e58afd..a24a8b231 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -967,8 +967,8 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) // User canceled save. return; } - - std::string file_name = filepicker->getFilename(); + + std::string file_name = filepicker->getFilename(); mFolder = gDirUtilp->getDirName(file_name); llifstream import_file(file_name); LLSDSerialize::fromXML(mLLSD, import_file); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 4ae625a52..2f9317090 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -738,28 +738,28 @@ public: } } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + /*virtual*/ void httpFailure(void) { llwarns << "Transport error requesting object cost " - << "HTTP status: " << statusNum << ", reason: " - << reason << "." << llendl; + << "HTTP status: " << mStatus << ", reason: " + << mReason << "." << llendl; // TODO*: Error message to user // For now just clear the request from the pending list clear_object_list_pending_requests(); } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { - if ( !content.isMap() || content.has("error") ) + if ( !mContent.isMap() || mContent.has("error") ) { // Improper response or the request had an error, // show an error to the user? llwarns << "Application level error when fetching object " - << "cost. Message: " << content["error"]["message"].asString() - << ", identifier: " << content["error"]["identifier"].asString() + << "cost. Message: " << mContent["error"]["message"].asString() + << ", identifier: " << mContent["error"]["identifier"].asString() << llendl; // TODO*: Adaptively adjust request size if the @@ -780,15 +780,15 @@ public: LLUUID object_id = iter->asUUID(); // Check to see if the request contains data for the object - if ( content.has(iter->asString()) ) + if ( mContent.has(iter->asString()) ) { F32 link_cost = - content[iter->asString()]["linked_set_resource_cost"].asReal(); + mContent[iter->asString()]["linked_set_resource_cost"].asReal(); F32 object_cost = - content[iter->asString()]["resource_cost"].asReal(); + mContent[iter->asString()]["resource_cost"].asReal(); - F32 physics_cost = content[iter->asString()]["physics_cost"].asReal(); - F32 link_physics_cost = content[iter->asString()]["linked_set_physics_cost"].asReal(); + F32 physics_cost = mContent[iter->asString()]["physics_cost"].asReal(); + F32 link_physics_cost = mContent[iter->asString()]["linked_set_physics_cost"].asReal(); gObjectList.updateObjectCost(object_id, object_cost, link_cost, physics_cost, link_physics_cost); } @@ -829,28 +829,28 @@ public: } } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + /*virtual*/ void httpFailure(void) { llwarns << "Transport error requesting object physics flags " - << "HTTP status: " << statusNum << ", reason: " - << reason << "." << llendl; + << "HTTP status: " << mStatus << ", reason: " + << mReason << "." << llendl; // TODO*: Error message to user // For now just clear the request from the pending list clear_object_list_pending_requests(); } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { - if ( !content.isMap() || content.has("error") ) + if ( !mContent.isMap() || mContent.has("error") ) { // Improper response or the request had an error, // show an error to the user? llwarns << "Application level error when fetching object " - << "physics flags. Message: " << content["error"]["message"].asString() - << ", identifier: " << content["error"]["identifier"].asString() + << "physics flags. Message: " << mContent["error"]["message"].asString() + << ", identifier: " << mContent["error"]["identifier"].asString() << llendl; // TODO*: Adaptively adjust request size if the @@ -871,9 +871,9 @@ public: LLUUID object_id = iter->asUUID(); // Check to see if the request contains data for the object - if ( content.has(iter->asString()) ) + if (mContent.has(iter->asString())) { - const LLSD& data = content[iter->asString()]; + const LLSD& data = mContent[iter->asString()]; S32 shape_type = data["PhysicsShapeType"].asInteger(); @@ -1459,15 +1459,10 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) objectp->setListIndex(-1); - S32 last_index = mActiveObjects.size()-1; + std::vector >::iterator iter = vector_replace_with_last(mActiveObjects, mActiveObjects.begin() + idx); + if(iter != mActiveObjects.end()) + (*iter)->setListIndex(idx); - if (idx != last_index) - { - mActiveObjects[idx] = mActiveObjects[last_index]; - mActiveObjects[idx]->setListIndex(idx); - } - - mActiveObjects.pop_back(); } } diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index dc62522cf..0df255f8d 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -49,11 +49,11 @@ #include "llviewerwindow.h" #include "llfirstuse.h" #include "llpluginclassmedia.h" +#include "llmediafilter.h" #include "llnotify.h" #include "llsdserialize.h" #include "llaudioengine.h" #include "lloverlaybar.h" -#include "slfloatermediafilter.h" #include "llstreamingaudio.h" // Static Variables @@ -61,12 +61,7 @@ S32 LLViewerParcelMedia::sMediaParcelLocalID = 0; LLUUID LLViewerParcelMedia::sMediaRegionID; viewer_media_t LLViewerParcelMedia::sMediaImpl; -bool LLViewerParcelMedia::sIsUserAction = false; -bool LLViewerParcelMedia::sMediaFilterListLoaded = false; -LLSD LLViewerParcelMedia::sMediaFilterList; -std::set LLViewerParcelMedia::sMediaQueries; -std::set LLViewerParcelMedia::sAllowedMedia; -std::set LLViewerParcelMedia::sDeniedMedia; +F32 LLViewerParcelMedia::sMediaCommandTime = 0; // Local functions bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel); @@ -151,7 +146,15 @@ void LLViewerParcelMedia::update(LLParcel* parcel) // Only play if the media types are the same. if(sMediaImpl->getMimeType() == parcel->getMediaType()) { - play(parcel); + if (gSavedSettings.getU32("MediaFilterEnable")) + { + LL_DEBUGS("MediaFilter") << "Filtering media URL: " << parcel->getMediaURL() << LL_ENDL; + LLMediaFilter::getInstance()->filterMediaUrl(parcel); + } + else + { + play(parcel); + } } else @@ -187,7 +190,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel) } // static -void LLViewerParcelMedia::play(LLParcel* parcel, bool filter) +void LLViewerParcelMedia::play(LLParcel* parcel) { lldebugs << "LLViewerParcelMedia::play" << llendl; @@ -197,17 +200,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel, bool filter) return; std::string media_url = parcel->getMediaURL(); - LLStringUtil::trim(media_url); - - if (!media_url.empty() && gSavedSettings.getBOOL("MediaEnableFilter") && (filter || !allowedMedia(media_url))) - { - // If filtering is needed or in case media_url just changed - // to something we did not yet approve. - LLViewerParcelMediaAutoPlay::playStarted(); - filterMedia(parcel, 0); - return; - } - + std::string media_current_url = parcel->getMediaCurrentURL(); std::string mime_type = parcel->getMediaType(); LLUUID placeholder_texture_id = parcel->getMediaID(); U8 media_auto_scale = parcel->getMediaAutoScale(); @@ -399,13 +392,27 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg // stop if( command == PARCEL_MEDIA_COMMAND_STOP ) { - stop(); + if (!LLMediaFilter::getInstance()->isAlertActive()) + { + stop(); + } + else + { + LLMediaFilter::getInstance()->setQueuedMediaCommand(PARCEL_MEDIA_COMMAND_STOP); + } } else // pause if( command == PARCEL_MEDIA_COMMAND_PAUSE ) { - pause(); + if (!LLMediaFilter::getInstance()->isAlertActive()) + { + pause(); + } + else + { + LLMediaFilter::getInstance()->setQueuedMediaCommand(PARCEL_MEDIA_COMMAND_PAUSE); + } } else // play @@ -419,14 +426,29 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg else { LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - play(parcel); + if (gSavedSettings.getU32("MediaFilterEnable")) + { + LL_DEBUGS("MediaFilter") << "PARCEL_MEDIA_COMMAND_PLAY: Filtering media URL: " << parcel->getMediaURL() << LL_ENDL; + LLMediaFilter::getInstance()->filterMediaUrl(parcel); + } + else + { + play(parcel); + } } } else // unload if( command == PARCEL_MEDIA_COMMAND_UNLOAD ) { - stop(); + if (!LLMediaFilter::getInstance()->isAlertActive()) + { + stop(); + } + else + { + LLMediaFilter::getInstance()->setQueuedMediaCommand(PARCEL_MEDIA_COMMAND_UNLOAD); + } } } @@ -435,10 +457,26 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg if(sMediaImpl.isNull()) { LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - play(parcel); + if (gSavedSettings.getU32("MediaFilterEnable")) + { + LL_DEBUGS("MediaFilter") << "PARCEL_MEDIA_COMMAND_TIME: Filtering media URL: " << parcel->getMediaURL() << LL_ENDL; + LLMediaFilter::getInstance()->filterMediaUrl(parcel); + } + else + { + play(parcel); + } } + } + if (!LLMediaFilter::getInstance()->isAlertActive()) + { seek(time); } + else + { + LLMediaFilter::getInstance()->setQueuedMediaCommand(PARCEL_MEDIA_COMMAND_TIME); + sMediaCommandTime = time; + } } ////////////////////////////////////////////////////////////////////////////////////////// @@ -492,7 +530,18 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void * parcel->setMediaAutoScale(media_auto_scale); parcel->setMediaLoop(media_loop); - play(parcel); + if (sMediaImpl.notNull()) + { + if (gSavedSettings.getU32("MediaFilterEnable")) + { + LL_DEBUGS("MediaFilter") << "Parcel media changed. Filtering media URL: " << parcel->getMediaURL() << LL_ENDL; + LLMediaFilter::getInstance()->filterMediaUrl(parcel); + } + else + { + play(parcel); + } + } } } } @@ -623,37 +672,37 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent case MEDIA_EVENT_CLOSE_REQUEST: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL; - }; + } break; case MEDIA_EVENT_PICK_FILE_REQUEST: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL; - }; + } break; case MEDIA_EVENT_GEOMETRY_CHANGE: { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE" << LL_ENDL; - }; + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL; + } break; case MEDIA_EVENT_AUTH_REQUEST: { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_AUTH_REQUEST" << LL_ENDL; - }; + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() << ", realm " << self->getAuthRealm() << LL_ENDL; + } break; case MEDIA_EVENT_LINK_HOVERED: { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED" << LL_ENDL; + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL; }; break; default: { LL_WARNS("Media") << "Media event: unknown event type" << LL_ENDL; - }; + } }; } @@ -663,7 +712,14 @@ bool callback_play_media(const LLSD& notification, const LLSD& response, LLParce if (option == 0) { gSavedSettings.setBOOL("AudioStreamingMedia", TRUE); - LLViewerParcelMedia::play(parcel); + if (gSavedSettings.getU32("MediaFilterEnable")) + { + LLMediaFilter::getInstance()->filterMediaUrl(parcel); + } + else + { + LLViewerParcelMedia::play(parcel); + } } else { @@ -694,11 +750,10 @@ void LLViewerParcelMedia::playStreamingMusic(LLParcel* parcel, bool filter) { std::string music_url = parcel->getMusicURL(); LLStringUtil::trim(music_url); - if (!music_url.empty() && gSavedSettings.getBOOL("MediaEnableFilter") && (filter || !allowedMedia(music_url))) + if (gSavedSettings.getU32("MediaFilterEnable")) { - // If filtering is needed or in case music_url just changed - // to something we did not yet approve. - filterMedia(parcel, 1); + LL_DEBUGS("MediaFilter") << "Filtering media URL: " << parcel->getMediaURL() << LL_ENDL; + LLMediaFilter::getInstance()->filterAudioUrl(music_url); } else if (gAudiop) { @@ -726,401 +781,3 @@ void LLViewerParcelMedia::stopStreamingMusic() LLOverlayBar::audioFilterStop(); } } - -bool LLViewerParcelMedia::allowedMedia(std::string media_url) -{ - LLStringUtil::trim(media_url); - std::string domain = extractDomain(media_url); - LLHost host; - host.setHostByName(domain); - std::string ip = host.getIPString(); - if (sAllowedMedia.count(domain) || sAllowedMedia.count(ip)) - { - return true; - } - std::string server; - for (S32 i = 0; i < (S32)sMediaFilterList.size(); i++) - { - server = sMediaFilterList[i]["domain"].asString(); - if (server == domain || server == ip) - { - if (sMediaFilterList[i]["action"].asString() == "allow") - { - return true; - } - else - { - return false; - } - } - } - return false; -} - -void LLViewerParcelMedia::filterMedia(LLParcel* parcel, U32 type) -{ - std::string media_action; - std::string media_url; - std::string domain; - std::string ip; - - if (parcel != LLViewerParcelMgr::getInstance()->getAgentParcel()) - { - // The parcel just changed (may occur right out after a TP) - sIsUserAction = false; - return; - } - - if (type == 0) - { - media_url = parcel->getMediaURL(); - } - else - { - media_url = parcel->getMusicURL(); - } - LLStringUtil::trim(media_url); - - domain = extractDomain(media_url); - - if (sMediaQueries.count(domain) > 0) - { - sIsUserAction = false; - return; - } - - LLHost host; - host.setHostByName(domain); - ip = host.getIPString(); - - if (sIsUserAction) - { - // This was a user manual request to play this media, so give - // it another chance... - sIsUserAction = false; - bool dirty = false; - if (sDeniedMedia.count(domain)) - { - sDeniedMedia.erase(domain); - dirty = true; - } - if (sDeniedMedia.count(ip)) - { - sDeniedMedia.erase(ip); - dirty = true; - } - if (dirty && SLFloaterMediaFilter::findInstance()) - { - SLFloaterMediaFilter::getInstance()->setDirty(); - } - } - - if (media_url.empty()) - { - media_action = "allow"; - } - else if (!sMediaFilterListLoaded || sDeniedMedia.count(domain) || sDeniedMedia.count(ip)) - { - media_action = "ignore"; - } - else if (sAllowedMedia.count(domain) || sAllowedMedia.count(ip)) - { - media_action = "allow"; - } - else - { - std::string server; - for (S32 i = 0; i < (S32)sMediaFilterList.size(); i++) - { - server = sMediaFilterList[i]["domain"].asString(); - if (server == domain || server == ip) - { - media_action = sMediaFilterList[i]["action"].asString(); - break; - } - } - } - - if (media_action == "allow") - { - if (type == 0) - { - play(parcel, false); - } - else - { - playStreamingMusic(parcel, false); - } - return; - } - if (media_action == "ignore") - { - if (type == 1) - { - LLViewerParcelMedia::stopStreamingMusic(); - } - return; - } - - LLSD args; - if (ip != domain && domain.find('/') == std::string::npos) - { - args["DOMAIN"] = domain + " (" + ip + ")"; - } - else - { - args["DOMAIN"] = domain; - } - - if (media_action == "deny") - { - LLNotificationsUtil::add("MediaBlocked", args); - if (type == 1) - { - LLViewerParcelMedia::stopStreamingMusic(); - } - // So to avoid other "blocked" messages later in the session - // for this url should it be requested again by a script. - // We don't add the IP, on purpose (want to show different - // blocks for different domains pointing to the same IP). - sDeniedMedia.insert(domain); - } - else - { - sMediaQueries.insert(domain); - args["URL"] = media_url; - if (type == 0) - { - args["TYPE"] = "media"; - } - else - { - args["TYPE"] = "audio"; - } - LLNotificationsUtil::add("MediaAlert", args, LLSD(), boost::bind(callback_media_alert, _1, _2, parcel, type, domain)); - } -} - -void callback_media_alert(const LLSD ¬ification, const LLSD &response, LLParcel* parcel, U32 type, std::string domain) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - - LLHost host; - host.setHostByName(domain); - std::string ip = host.getIPString(); - - LLSD args; - if (ip != domain && domain.find('/') == std::string::npos) - { - args["DOMAIN"] = domain + " (" + ip + ")"; - } - else - { - args["DOMAIN"] = domain; - } - - if (option == 0 || option == 3) // Allow or Whitelist - { - LLViewerParcelMedia::sAllowedMedia.insert(domain); - if (option == 3) // Whitelist - { - LLSD newmedia; - newmedia["domain"] = domain; - newmedia["action"] = "allow"; - LLViewerParcelMedia::sMediaFilterList.append(newmedia); - if (ip != domain && domain.find('/') == std::string::npos) - { - newmedia["domain"] = ip; - LLViewerParcelMedia::sMediaFilterList.append(newmedia); - } - LLViewerParcelMedia::saveDomainFilterList(); - args["LISTED"] = "whitelisted"; - LLNotificationsUtil::add("MediaListed", args); - } - if (type == 0) - { - LLViewerParcelMedia::play(parcel, false); - } - else - { - LLViewerParcelMedia::playStreamingMusic(parcel, false); - } - } - else - { - if (type == 1) - { - LLViewerParcelMedia::stopStreamingMusic(); - } - else - { - LLViewerParcelMedia::stopStreamingMusic(); - } - if (option == 1 || option == 2) // Deny or Blacklist - { - LLViewerParcelMedia::sDeniedMedia.insert(domain); - if (ip != domain && domain.find('/') == std::string::npos) - { - LLViewerParcelMedia::sDeniedMedia.insert(ip); - } - - if (option == 1) // Deny - { - LLNotificationsUtil::add("MediaBlocked", args); - } - else // Blacklist - { - LLSD newmedia; - newmedia["domain"] = domain; - newmedia["action"] = "deny"; - LLViewerParcelMedia::sMediaFilterList.append(newmedia); - if (ip != domain && domain.find('/') == std::string::npos) - { - newmedia["domain"] = ip; - LLViewerParcelMedia::sMediaFilterList.append(newmedia); - } - LLViewerParcelMedia::saveDomainFilterList(); - args["LISTED"] = "blacklisted"; - LLNotificationsUtil::add("MediaListed", args); - } - } - } - - LLViewerParcelMedia::sMediaQueries.erase(domain); - if (SLFloaterMediaFilter::findInstance()) SLFloaterMediaFilter::getInstance()->setDirty(); -} - -void LLViewerParcelMedia::saveDomainFilterList() -{ - std::string medialist_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "media_filter.xml"); - - llofstream medialistFile(medialist_filename); - LLSDSerialize::toPrettyXML(sMediaFilterList, medialistFile); - medialistFile.close(); -} - -bool LLViewerParcelMedia::loadDomainFilterList() -{ - sMediaFilterListLoaded = true; - - std::string medialist_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "media_filter.xml"); - - if (!LLFile::isfile(medialist_filename)) - { - LLSD emptyllsd; - llofstream medialistFile(medialist_filename); - LLSDSerialize::toPrettyXML(emptyllsd, medialistFile); - medialistFile.close(); - } - - if (LLFile::isfile(medialist_filename)) - { - llifstream medialistFile(medialist_filename); - LLSDSerialize::fromXML(sMediaFilterList, medialistFile); - medialistFile.close(); - if (SLFloaterMediaFilter::findInstance()) SLFloaterMediaFilter::getInstance()->setDirty(); - return true; - } - else - { - return false; - } -} - -void LLViewerParcelMedia::clearDomainFilterList() -{ - sMediaFilterList.clear(); - sAllowedMedia.clear(); - sDeniedMedia.clear(); - saveDomainFilterList(); - LLNotificationsUtil::add("MediaFiltersCleared"); - if (SLFloaterMediaFilter::findInstance()) SLFloaterMediaFilter::getInstance()->setDirty(); -} - -std::string LLViewerParcelMedia::extractDomain(std::string url) -{ - static std::string last_region = "@"; - - if (url.empty()) - { - return url; - } - - LLStringUtil::toLower(url); - - size_t pos = url.find("//"); - - if (pos != std::string::npos) - { - size_t count = url.size() - pos + 2; - url = url.substr(pos + 2, count); - } - - // Check that there is at least one slash in the URL and add a trailing - // one if not (for media/audio URLs such as http://mydomain.net) - if (url.find('/') == std::string::npos) - { - url += '/'; - } - - // If there's a user:password@ part, remove it - pos = url.find('@'); - if (pos != std::string::npos && pos < url.find('/')) // if '@' is not before the first '/', then it's not a user:password - { - size_t count = url.size() - pos + 1; - url = url.substr(pos + 1, count); - } - - //Singu note: The call to getHostName() freezes the viewer for a few seconds if the region has no reverse DNS... - // Avoid calling it three times therefore -- not to mention that if it fails, it returns an empty string which - // does NOT mean that it should match the current url as if the current url contains the current regions hostname! - std::string const hostname = gAgent.getRegion()->getHost().getHostName(); - if ((!hostname.empty() && url.find(hostname) == 0) || url.find(last_region) == 0) - { - // This must be a scripted object rezzed in the region: - // extend the concept of "domain" to encompass the - // scripted object server id and avoid blocking all other - // objects at once in this region... - - // Get rid of any port number - pos = url.find('/'); // We earlier made sure that there's one - url = hostname + url.substr(pos); - - pos = url.find('?'); - if (pos != std::string::npos) - { - // Get rid of any parameter - url = url.substr(0, pos); - } - - pos = url.rfind('/'); - if (pos != std::string::npos) - { - // Get rid of the filename, if any, keeping only the server + path - url = url.substr(0, pos); - } - } - else - { - pos = url.find(':'); - if (pos != std::string::npos && pos < url.find('/')) - { - // Keep anything before the port number and strip the rest off - url = url.substr(0, pos); - } - else - { - pos = url.find('/'); // We earlier made sure that there's one - url = url.substr(0, pos); - } - } - - // Remember this region, so to cope with requests occuring just after a - // TP out of it. - if (!hostname.empty()) // Singu note: also make sure that last_region doesn't become empty. - { - last_region = hostname; - } - - return url; -} diff --git a/indra/newview/llviewerparcelmedia.h b/indra/newview/llviewerparcelmedia.h index f6c85bf3b..ff954c37a 100644 --- a/indra/newview/llviewerparcelmedia.h +++ b/indra/newview/llviewerparcelmedia.h @@ -57,21 +57,13 @@ class LLViewerParcelMedia : public LLViewerMediaObserver // called when the agent's parcel has a new URL, or the agent has // walked on to a new parcel with media - static void play(LLParcel* parcel, bool filter = true); + static void play(LLParcel* parcel); // user clicked play button in media transport controls static void playStreamingMusic(LLParcel* parcel, bool filter = true); // play the parcel music stream static void stopStreamingMusic(); // stop the parcel music stream - static void filterMedia(LLParcel* parcel, U32 type); // type: 0 = media, 1 = streaming music - static bool allowedMedia(std::string media_url); - - static bool loadDomainFilterList(); - static void saveDomainFilterList(); - static void clearDomainFilterList(); - static std::string extractDomain(std::string url); - static void stop(); // user clicked stop button in media transport controls @@ -102,13 +94,9 @@ class LLViewerParcelMedia : public LLViewerMediaObserver static LLUUID sMediaRegionID; // HACK: this will change with Media on a Prim static viewer_media_t sMediaImpl; - - static bool sIsUserAction; - static bool sMediaFilterListLoaded; - static LLSD sMediaFilterList; - static std::set sMediaQueries; - static std::set sAllowedMedia; - static std::set sDeniedMedia; + + // Media Filter + static F32 sMediaCommandTime; }; diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 8f07858cf..3c0c37b3e 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -406,8 +406,7 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) // Kill dead particles (either flagged dead, or too old) if ((part->mLastUpdateTime > part->mMaxAge) || (LLViewerPart::LL_PART_DEAD_MASK == part->mFlags)) { - mParticles[i] = mParticles.back() ; - mParticles.pop_back() ; + vector_replace_with_last(mParticles, mParticles.begin() + i); delete part ; } else @@ -417,8 +416,7 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) { // Transfer particles between groups LLViewerPartSim::getInstance()->put(part) ; - mParticles[i] = mParticles.back() ; - mParticles.pop_back() ; + vector_replace_with_last(mParticles, mParticles.begin() + i); } else { @@ -675,11 +673,9 @@ void LLViewerPartSim::updateSimulation() S32 count = (S32) mViewerPartSources.size(); S32 start = (S32)ll_frand((F32)count); S32 dir = 1; - S32 deldir = 0; if (ll_frand() > 0.5f) { dir = -1; - deldir = -1; } S32 num_updates = 0; @@ -725,11 +721,9 @@ void LLViewerPartSim::updateSimulation() if (mViewerPartSources[i]->isDead()) { - mViewerPartSources[i] = mViewerPartSources.back(); - mViewerPartSources.pop_back(); - //mViewerPartSources.erase(mViewerPartSources.begin() + i); + vector_replace_with_last(mViewerPartSources, mViewerPartSources.begin() + i); + //mViewerPartSources.erase(it); count--; - i+=deldir; } else { @@ -764,9 +758,8 @@ void LLViewerPartSim::updateSimulation() if (!mViewerPartGroups[i]->getCount()) { delete mViewerPartGroups[i]; - mViewerPartGroups[i] = mViewerPartGroups.back(); - mViewerPartGroups.pop_back(); - //mViewerPartGroups.erase(mViewerPartGroups.begin() + i); + vector_replace_with_last(mViewerPartGroups, mViewerPartGroups.begin() + i); + //mViewerPartGroups.erase(it); i--; count--; } @@ -849,15 +842,15 @@ void LLViewerPartSim::removeLastCreatedSource() void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) { group_list_t& vec = mViewerPartGroups; - for (group_list_t::size_type i = 0;igetRegion() == regionp) + if ((*it)->getRegion() == regionp) { - delete vec[i]; - vec[i--] = vec.back(); - vec.pop_back(); + delete *it; + it = vector_replace_with_last(vec,it); //i = mViewerPartGroups.erase(iter); } + else ++it; } } diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index f98c6f10f..cce678081 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -187,7 +187,7 @@ //#include "lltextureentry.h" #include "lltreeparams.h" //#include "llvolume.h" -#include "llvolumemgr.h" +//#include "llvolumemgr.h" #include "material_codes.h" // Library includes from llxml diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 7103a7ede..cbc64d533 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -58,6 +58,7 @@ #include "lldir.h" #include "lleventpoll.h" #include "llfloatergodtools.h" +#include "llfloaterperms.h" #include "llfloaterreporter.h" #include "llfloaterregioninfo.h" #include "llhttpnode.h" @@ -223,9 +224,9 @@ public: virtual ~BaseCapabilitiesComplete() { } - void error(U32 statusNum, const std::string& reason) + void httpFailure(void) { - LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL; + LL_WARNS2("AppInit", "Capabilities") << mStatus << ": " << mReason << LL_ENDL; LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); if (regionp) { @@ -233,7 +234,7 @@ public: } } - void result(const LLSD& content) + void httpSuccess(void) { LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); if(!regionp) //region was removed @@ -248,7 +249,7 @@ public: } LLSD::map_const_iterator iter; - for(iter = content.beginMap(); iter != content.endMap(); ++iter) + for(iter = mContent.beginMap(); iter != mContent.endMap(); ++iter) { regionp->setCapability(iter->first, iter->second); LL_DEBUGS2("AppInit", "Capabilities") << "got capability for " @@ -320,6 +321,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, { // Moved this up... -> mWidth = region_width_meters; // + + mRenderMatrix.setIdentity(); + mImpl->mOriginGlobal = from_region_handle(handle); updateRenderMatrix(); @@ -546,7 +550,7 @@ void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global) void LLViewerRegion::updateRenderMatrix() { - mRenderMatrix.setTranslation(getOriginAgent()); + mRenderMatrix.setTranslate_affine(getOriginAgent()); } void LLViewerRegion::setTimeDilation(F32 time_dilation) @@ -1694,6 +1698,7 @@ void LLViewerRegion::unpackRegionHandshake() void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) { + capabilityNames.append("AgentPreferences"); capabilityNames.append("AgentState"); capabilityNames.append("AttachmentResources"); //capabilityNames.append("AvatarPickerSearch"); //Display name/SLID lookup (llfloateravatarpicker.cpp) @@ -1717,6 +1722,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("GetObjectCost"); capabilityNames.append("GetObjectPhysicsData"); capabilityNames.append("GetTexture"); + capabilityNames.append("GroupAPIv1"); capabilityNames.append("GroupMemberData"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("HomeLocation"); @@ -1737,7 +1743,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RenderMaterials"); capabilityNames.append("RequestTextureDownload"); - //capabilityNames.append("ResourceCostSelected"); //Object weights (llfloaterobjectweights.cpp) + capabilityNames.append("ResourceCostSelected"); capabilityNames.append("RetrieveNavMeshSrc"); capabilityNames.append("SearchStatRequest"); capabilityNames.append("SearchStatTracking"); @@ -1847,13 +1853,13 @@ public: { } - void error(U32 statusNum, const std::string& reason) + void httpFailure(void) { - LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL; + LL_WARNS2("AppInit", "SimulatorFeatures") << mStatus << ": " << mReason << LL_ENDL; retry(); } - void result(const LLSD& content) + void httpSuccess(void) { LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); if(!regionp) //region is removed or responder is not created. @@ -1862,7 +1868,7 @@ public: return ; } - regionp->setSimulatorFeatures(content); + regionp->setSimulatorFeatures(mContent); } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return simulatorFeaturesReceived_timeout; } @@ -1893,16 +1899,16 @@ public: : mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts) {} - /*virtual*/ void error(U32 statusNum, const std::string& reason) + /*virtual*/ void httpFailure(void) { - LL_WARNS2("AppInit", "GamingData") << statusNum << ": " << reason << LL_ENDL; + LL_WARNS2("AppInit", "GamingData") << mStatus << ": " << mReason << LL_ENDL; retry(); } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); - if(regionp) regionp->setGamingData(content); + if(regionp) regionp->setGamingData(mContent); } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return gamingDataReceived_timeout; } @@ -1998,6 +2004,8 @@ void LLViewerRegion::setCapabilitiesReceived(bool received) { mCapabilitiesReceivedSignal(getRegionID()); + LLFloaterPermsDefault::sendInitialPerms(); + // This is a single-shot signal. Forget callbacks to save resources. mCapabilitiesReceivedSignal.disconnect_all_slots(); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 1b6eee985..20c72de3f 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -114,6 +114,16 @@ public: const F32 region_width_meters); ~LLViewerRegion(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + // Call this after you have the region name and handle. void loadObjectCache(); void saveObjectCache(); @@ -130,7 +140,7 @@ public: void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); } void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); } void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); } - void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } + //void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } Never used void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); } @@ -400,7 +410,7 @@ public: LLStat mPacketsStat; LLStat mPacketsLostStat; - LLMatrix4 mRenderMatrix; + LL_ALIGN_16(LLMatrix4a mRenderMatrix); // These arrays are maintained in parallel. Ideally they'd be combined into a // single array of an aggrigate data type but for compatibility with the old diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 62dba3ca5..9f290579e 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -709,13 +709,13 @@ class ViewerStatsResponder : public LLHTTPClient::ResponderWithResult public: ViewerStatsResponder() { } - /*virtual*/ void error(U32 statusNum, const std::string& reason) + /*virtual*/ void httpFailure(void) { - llinfos << "ViewerStatsResponder::error " << statusNum << " " - << reason << llendl; + llinfos << "ViewerStatsResponder::error " << mStatus << " " + << mReason << llendl; } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { llinfos << "ViewerStatsResponder::result" << llendl; } diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h index 959c883da..d732a87bb 100644 --- a/indra/newview/llviewertexlayer.h +++ b/indra/newview/llviewertexlayer.h @@ -79,6 +79,16 @@ public: LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height); virtual ~LLViewerTexLayerSetBuffer(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + public: /*virtual*/ S8 getType() const; BOOL isInitialized(void) const; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 10c924225..c49be918a 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -914,6 +914,7 @@ LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, const LLHost& h { init(TRUE) ; generateGLTexture() ; + mGLTexturep->setNeedsAlphaAndPickMask(TRUE) ; } LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps) @@ -928,6 +929,7 @@ LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, const LLU { init(TRUE) ; generateGLTexture() ; + mGLTexturep->setNeedsAlphaAndPickMask(TRUE) ; } void LLViewerFetchedTexture::init(bool firstinit) @@ -3172,8 +3174,6 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL mGLTexturep->setAllowCompression(false); - mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ; - mIsPlaying = FALSE ; setMediaImpl() ; @@ -3204,7 +3204,6 @@ void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */) mUseMipMaps = usemipmaps ; getLastReferencedTimer()->reset() ; mGLTexturep->setUseMipMaps(mUseMipMaps) ; - mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ; } void LLViewerMediaTexture::setUseMipMaps(BOOL mipmap) diff --git a/indra/newview/llviewertextureanim.cpp b/indra/newview/llviewertextureanim.cpp index 2b364851a..1e6b7a343 100644 --- a/indra/newview/llviewertextureanim.cpp +++ b/indra/newview/llviewertextureanim.cpp @@ -49,15 +49,10 @@ LLViewerTextureAnim::LLViewerTextureAnim(LLVOVolume* vobj) : LLTextureAnim() LLViewerTextureAnim::~LLViewerTextureAnim() { - S32 end_idx = sInstanceList.size()-1; - - if (end_idx != mInstanceIndex) - { - sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; - sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; - } - - sInstanceList.pop_back(); + std::vector::iterator it(sInstanceList.begin() + mInstanceIndex); + std::vector::iterator iter = vector_replace_with_last(sInstanceList, it); + if(iter != sInstanceList.end()) + (*iter)->mInstanceIndex = mInstanceIndex; } void LLViewerTextureAnim::reset() diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1b9f340e8..099927c6d 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -696,32 +696,35 @@ public: static const LLCachedControl debug_show_render_matrices("DebugShowRenderMatrices"); if (debug_show_render_matrices) { - addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15])); + F32* m = gGLProjection.getF32ptr(); + + addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", m[12], m[13], m[14], m[15])); ypos += y_inc; - addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[8], gGLProjection[9], gGLProjection[10], gGLProjection[11])); + addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", m[8], m[9], m[10], m[11])); ypos += y_inc; - addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[4], gGLProjection[5], gGLProjection[6], gGLProjection[7])); + addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", m[4], m[5], m[6], m[7])); ypos += y_inc; - addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[0], gGLProjection[1], gGLProjection[2], gGLProjection[3])); + addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", m[0], m[1], m[2], m[3])); ypos += y_inc; addText(xpos, ypos, "Projection Matrix"); ypos += y_inc; + m = gGLModelView.getF32ptr(); - addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[12], gGLModelView[13], gGLModelView[14], gGLModelView[15])); + addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", m[12], m[13], m[14], m[15])); ypos += y_inc; - addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[8], gGLModelView[9], gGLModelView[10], gGLModelView[11])); + addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", m[8], m[9], m[10], m[11])); ypos += y_inc; - addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[4], gGLModelView[5], gGLModelView[6], gGLModelView[7])); + addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", m[4], m[5], m[6], m[7])); ypos += y_inc; - addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[0], gGLModelView[1], gGLModelView[2], gGLModelView[3])); + addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", m[0], m[1], m[2], m[3])); ypos += y_inc; addText(xpos, ypos, "View Matrix"); @@ -1030,7 +1033,7 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK // *HACK: this should be rolled into the composite tool logic, not // hardcoded at the top level. - if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance()) + if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized()) { // If the current tool didn't process the click, we should show // the pie menu. This can be done by passing the event to the pie @@ -2706,7 +2709,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) (MASK_CONTROL & mask) && ('D' == key || 'd' == key)) { - toggle_debug_menus(NULL); + if (gSavedSettings.getBOOL("LiruUseAdvancedMenuShortcut")) + toggle_debug_menus(NULL); } // handle shift-escape key (reset camera view) @@ -5481,7 +5485,7 @@ void LLViewerWindow::restartDisplay(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"); + BOOL was_maximized = mWindow->getMaximized(); mWantFullscreen = fullscreen; mShowFullscreenProgress = show_progress_bar; gSavedSettings.setBOOL("FullScreen", mWantFullscreen); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 26dae3313..802105235 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1158,7 +1158,7 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() << " Notification " << notification_name << " : " << comment - << llendl; + << LL_ENDL; if (gSavedSettings.getBOOL("DebugAvatarRezTime")) { @@ -1169,6 +1169,10 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c LLNotificationsUtil::add(notification_name,args); } } + +//------------------------------------------------------------------------ +// LLVOAvatar::~LLVOAvatar() +//------------------------------------------------------------------------ LLVOAvatar::~LLVOAvatar() { //App teardown is a mess. Avatar destruction can be unpredictable due to all potential refs to the smartptr. @@ -1226,7 +1230,6 @@ void LLVOAvatar::markDead() logPendingPhases(); LLViewerObject::markDead(); - } @@ -1248,7 +1251,7 @@ BOOL LLVOAvatar::isFullyBaked() BOOL LLVOAvatar::isFullyTextured() const { - for (U32 i = 0; i < (U32)mMeshLOD.size(); i++) + for (U32 i = 0; i < mMeshLOD.size(); i++) { LLAvatarJoint* joint = mMeshLOD[i]; if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT)) @@ -1581,10 +1584,9 @@ void LLVOAvatar::initInstance(void) 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_SIT_FEMALE, LLKeyframeMotion::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(); @@ -1649,7 +1651,10 @@ const LLVector3 LLVOAvatar::getRenderPosition() const } else { - return getPosition() * mDrawable->getParent()->getRenderMatrix(); + LLVector4a pos; + pos.load3(getPosition().mV); + mDrawable->getParent()->getRenderMatrix().affineTransform(pos,pos); + return LLVector3(pos.getF32ptr()); } } @@ -1707,9 +1712,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) LLPolyMesh* mesh = i->second; for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++) { - LLVector4a trans; - trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV); - update_min_max(newMin, newMax, trans); + update_min_max(newMin, newMax, mesh->mJointRenderData[joint_num]->mWorldMatrix->getRow()); } } @@ -1833,7 +1836,7 @@ void LLVOAvatar::renderJoints() jointp->updateWorldMatrix(); gGL.pushMatrix(); - gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] ); + gGL.multMatrix(jointp->getXform()->getWorldMatrix()); gGL.diffuseColor3f( 1.f, 0.f, 1.f ); @@ -1922,36 +1925,37 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { mCollisionVolumes[i].updateWorldMatrix(); - glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix); - glh::matrix4f inverse = mat.inverse(); - glh::matrix4f norm_mat = inverse.transpose(); + const LLMatrix4a& mat = mCollisionVolumes[i].getXform()->getWorldMatrix(); + LLMatrix4a inverse = mat; + inverse.invert(); + LLMatrix4a norm_mat = inverse; + norm_mat.transpose(); - glh::vec3f p1(start.getF32ptr()); - glh::vec3f p2(end.getF32ptr()); - inverse.mult_matrix_vec(p1); - inverse.mult_matrix_vec(p2); + LLVector4a p1, p2; + inverse.affineTransform(start,p1); //Might need to use perspectiveTransform here. + inverse.affineTransform(end,p2); LLVector3 position; LLVector3 norm; - if (linesegment_sphere(LLVector3(p1.v), LLVector3(p2.v), LLVector3(0,0,0), 1.f, position, norm)) + if (linesegment_sphere(LLVector3(p1.getF32ptr()), LLVector3(p2.getF32ptr()), LLVector3(0,0,0), 1.f, position, norm)) { - glh::vec3f res_pos(position.mV); - mat.mult_matrix_vec(res_pos); - - norm.normalize(); - glh::vec3f res_norm(norm.mV); - norm_mat.mult_matrix_dir(res_norm); - if (intersection) { - intersection->load3(res_pos.v); + LLVector4a res_pos; + res_pos.load3(position.mV); + mat.affineTransform(res_pos,res_pos); + *intersection = res_pos; } if (normal) { - normal->load3(res_norm.v); + LLVector4a res_norm; + res_norm.load3(norm.mV); + res_norm.normalize3fast(); + norm_mat.perspectiveTransform(res_norm,res_norm); + *normal = res_norm; } return TRUE; @@ -2140,7 +2144,7 @@ void LLVOAvatar::releaseMeshData() return; } - //llinfos << "Releasing" << llendl; + //LL_DEBUGS() << "Releasing mesh data" << LL_ENDL; // cleanup mesh data for (avatar_joint_list_t::iterator iter = mMeshLOD.begin(); @@ -2190,7 +2194,7 @@ void LLVOAvatar::restoreMeshData() { llassert(!isSelf()); - //llinfos << "Restoring" << llendl; + //LL_INFOS() << "Restoring" << LL_ENDL; mMeshValid = TRUE; updateJointLODs(); @@ -2367,6 +2371,9 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, } } + //LL_INFOS() << getRotation() << LL_ENDL; + //LL_INFOS() << getPosition() << LL_ENDL; + return retval; } @@ -2782,6 +2789,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) } } } + if(mDrawable) { mDrawable->movePartition(); @@ -3152,7 +3160,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last); - mNameText->setPositionAgent(name_position); + mNameText->setPositionAgent(name_position); idleCCSUpdateAttachmentText(render_name); idleUpdateNameTagText(new_name); idleUpdateNameTagAlpha(new_name, alpha); @@ -3648,7 +3656,6 @@ void LLVOAvatar::invalidateNameTags() if (avatar->isDead()) continue; avatar->clearNameTag(); - } } @@ -3703,11 +3710,9 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend) } /*else if (LLAvatarNameCache::useDisplayNames()) { - // ...color based on whether username "matches" a computed display - // name + // ...color based on whether username "matches" a computed display name LLAvatarName av_name; - if (LLAvatarNameCache::get(getID(), &av_name) - && av_name.mIsDisplayNameDefault) + if (LLAvatarNameCache::get(getID(), &av_name) && av_name.mIsDisplayNameDefault) { color_name = "NameTagMatch"; } @@ -3747,14 +3752,20 @@ void LLVOAvatar::slamPosition() bool LLVOAvatar::isVisuallyMuted() const { - if(isSelf())return false; - static LLCachedControl max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit"); - static LLCachedControl max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit"); - - return LLMuteList::getInstance()->isMuted(getID()) || + bool muted = false; + + if (!isSelf()) + { + static LLCachedControl max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit", 0); + static LLCachedControl max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 0.0); + static const LLCachedControl show_muted(gSavedSettings, "LiruLegacyDisplayMuteds", false); + + muted = (!show_muted && LLMuteList::getInstance()->isMuted(getID())) || (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) || (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f) || isLangolier(); + } + return muted; } void LLVOAvatar::resetFreezeTime() @@ -3767,6 +3778,7 @@ void LLVOAvatar::resetFreezeTime() } } + //------------------------------------------------------------------------ // updateCharacter() // called on both your avatar and other avatars @@ -3796,14 +3808,18 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) mUseServerBakes, central_bake_version); std::string origin_string = bakedTextureOriginInfo(); debug_line += " [" + origin_string + "]"; + S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion(); + S32 last_request_cof_version = LLAppearanceMgr::instance().getLastUpdateRequestCOFVersion(); + S32 last_received_cof_version = LLAppearanceMgr::instance().getLastAppearanceUpdateCOFVersion(); if (isSelf()) { - S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion(); - S32 last_request_cof_version = LLAppearanceMgr::instance().getLastUpdateRequestCOFVersion(); - S32 last_received_cof_version = LLAppearanceMgr::instance().getLastAppearanceUpdateCOFVersion(); debug_line += llformat(" - cof: %d req: %d rcv:%d", curr_cof_version, last_request_cof_version, last_received_cof_version); } + else + { + debug_line += llformat(" - cof rcv:%d", last_received_cof_version); + } addDebugText(debug_line); } if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) @@ -3874,12 +3890,12 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) mTimeVisible.reset(); } - //-------------------------------------------------------------------- // the rest should only be done occasionally for far away avatars //-------------------------------------------------------------------- - if (visible && (!isSelf() || isVisuallyMuted()) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) + bool visually_muted = isVisuallyMuted(); + if (visible && (!isSelf() || visually_muted) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) { const LLVector4a* ext = mDrawable->getSpatialExtents(); LLVector4a size; @@ -3888,8 +3904,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); - if (isVisuallyMuted()) - { // muted avatars update at 16 hz + if (visually_muted) + { // visually muted avatars update at 16 hz mUpdatePeriod = 16; } else if (mVisibilityRank <= LLVOAvatar::sMaxVisible || @@ -3947,7 +3963,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) removeAnimationData("Walk Speed"); } mMotionController.setTimeStep(time_step); -// llinfos << "Setting timestep to " << time_quantum * pixel_area_scale << llendl; +// LL_INFOS() << "Setting timestep to " << time_quantum * pixel_area_scale << LL_ENDL; } if (getParent() && !mIsSitting) @@ -4109,7 +4125,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } - LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion(); + LLQuaternion root_rotation = LLMatrix4(mRoot->getWorldMatrix().getF32ptr()).quaternion(); F32 root_roll, root_pitch, root_yaw; root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw); @@ -4126,14 +4142,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // and head turn. Once in motion, it must conform however. BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook(); - LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV ); + LLVector3 pelvisDir( mRoot->getWorldMatrix().getRow().getF32ptr() ); - static const LLCachedControl s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow"); - static const LLCachedControl s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast"); - - F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); + static const LLCachedControl s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0); + static const LLCachedControl s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0); + static const LLCachedControl useRealisticMouselook("UseRealisticMouselook"); + F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, useRealisticMouselook ? s_pelvis_rot_threshold_slow * 2 : s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); - if (self_in_mouselook) + if (self_in_mouselook && !useRealisticMouselook) { pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR; } @@ -4523,13 +4539,6 @@ void LLVOAvatar::updateVisibility() { releaseMeshData(); } - // this breaks off-screen chat bubbles - //if (mNameText) - //{ - // mNameText->markDead(); - // mNameText = NULL; - // sNumVisibleChatBubbles--; - //} } mVisible = visible; @@ -4772,12 +4781,8 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) num_indices += renderTransparent(first_pass); } } - - LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; - - //llinfos << "Avatar render: " << render_timer.getElapsedTimeF32() << llendl; - //render_stat.addValue(render_timer.getElapsedTimeF32()*1000.f); + LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; return num_indices; } @@ -5135,7 +5140,7 @@ void LLVOAvatar::releaseOldTextures() S32 new_total_mem = totalTextureMemForUUIDS(new_texture_ids); //S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs); - //LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << llendl; + //LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << LL_ENDL; if (!isSelf() && new_total_mem > new_baked_mem) { llwarns << "extra local textures stored for non-self av" << llendl; @@ -5256,7 +5261,7 @@ void LLVOAvatar::updateTextures() LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture " << imagep->getID() << " for avatar " << (isSelf() ? "" : getID().asString()) - << " on host " << getRegion()->getHost() << llendl; + << " on host " << getRegion()->getHost() << LL_ENDL; } addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); @@ -5278,7 +5283,7 @@ void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture } const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames. -const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = S32_MAX ; //frames +const S32 MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL = S32_MAX ; //frames void LLVOAvatar::checkTextureLoading() { static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds @@ -5341,7 +5346,7 @@ const F32 ADDITIONAL_PRI = 0.5f; void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level) { //Note: - //if this function is not called for the last MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL frames, + //if this function is not called for the last MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL frames, //the texture pipeline will stop fetching this texture. imagep->resetTextureStats(); @@ -5349,7 +5354,7 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel // Once server messaging is in place, we should call setCanUseHTTP(false) for old style // appearance requests imagep->setCanUseHTTP(true); - imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); + imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL); imagep->resetMaxVirtualSizeResetCounter() ; mMaxPixelArea = llmax(pixel_area, mMaxPixelArea); @@ -5396,7 +5401,8 @@ const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) std::string url = ""; if (isUsingServerBakes()) { - if (gSavedSettings.getString("AgentAppearanceServiceURL").empty()) + const std::string& appearance_service_url = gSavedSettings.getString("AgentAppearanceServiceURL"); + if (appearance_service_url.empty()) { // Probably a server-side issue if we get here: llwarns << "AgentAppearanceServiceURL not set - Baked texture requests will fail" << llendl; @@ -5406,8 +5412,8 @@ const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te); if (texture_entry != NULL) { - url = gSavedSettings.getString("AgentAppearanceServiceURL") + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString(); - //llinfos << "baked texture url: " << url << llendl; + url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString(); + //LL_INFOS() << "baked texture url: " << url << LL_ENDL; } } return url; @@ -5457,7 +5463,7 @@ void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos LLVector3 relativePos = gAgent.getPosAgentFromGlobal(outPos) - obj->getPositionAgent(); LLVector3 linearComponent = angularVelocity % relativePos; -// llinfos << "Linear Component of Rotation Velocity " << linearComponent << llendl; +// LL_INFOS() << "Linear Component of Rotation Velocity " << linearComponent << LL_ENDL; mStepObjectVelocity = obj->getVelocity() + linearComponent; } } @@ -5600,7 +5606,6 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL if ( start ) // start animation { static LLCachedControl play_typing_sound("PlayTypingSound"); - static LLCachedControl announce_snapshots("AnnounceSnapshots"); if (anim_id == ANIM_AGENT_TYPE && play_typing_sound) { if (gAudiop) @@ -5630,6 +5635,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL else if(anim_id == ANIM_AGENT_SNAPSHOT) { mIdleTimer.reset(); // Snapshot, not idle + static LLCachedControl announce_snapshots("AnnounceSnapshots"); if (announce_snapshots) { std::string name; @@ -5716,8 +5722,7 @@ std::string LLVOAvatar::getIdleTime(bool is_away, bool is_busy, bool is_appearan args["[MINUTES]"]=(LLSD::Integer)minutes; return LLTrans::getString("AvatarIdle", args); } - else - return std::string(); + return ""; } // Override selectively based on avatar sex and whether we're using new @@ -6584,30 +6589,24 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) if ( pVObj ) { const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj ); - if ( pSkinData ) + if ( pSkinData + && pSkinData->mJointNames.size() > 20 // full rig + && pSkinData->mAlternateBindMatrix.size() > 0 ) { - const int jointCnt = pSkinData->mJointNames.size(); - bool fullRig = ( jointCnt>=20 ) ? true : false; - if ( fullRig ) + LLVOAvatar::resetJointPositionsToDefault(); + //Need to handle the repositioning of the cam, updating rig data etc during outfit editing + //This handles the case where we detach a replacement rig. + if ( gAgentCamera.cameraCustomizeAvatar() ) { - const int bindCnt = pSkinData->mAlternateBindMatrix.size(); - if ( bindCnt > 0 ) - { - LLVOAvatar::resetJointPositionsToDefault(); - //Need to handle the repositioning of the cam, updating rig data etc during outfit editing - //This handles the case where we detach a replacement rig. - if ( gAgentCamera.cameraCustomizeAvatar() ) - { gAgent.unpauseAnimation(); //Still want to refocus on head bone gAgentCamera.changeCameraToCustomizeAvatar(); - } - } } - } + } } - } + } } + //----------------------------------------------------------------------------- // detachObject() //----------------------------------------------------------------------------- @@ -6621,12 +6620,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) if (attachment->isObjectAttached(viewer_object)) { - std::vector >::iterator it = std::find(mAttachedObjectsVector.begin(),mAttachedObjectsVector.end(),std::make_pair(viewer_object,attachment)); - if(it != mAttachedObjectsVector.end()) - { - (*it) = mAttachedObjectsVector.back(); - mAttachedObjectsVector.pop_back(); - } + vector_replace_with_last(mAttachedObjectsVector,std::make_pair(viewer_object,attachment)); cleanupAttachedMesh( viewer_object ); attachment->removeObject(viewer_object); @@ -6770,11 +6764,7 @@ void LLVOAvatar::getOffObject() at_axis.mV[VZ] = 0.f; at_axis.normalize(); gAgent.resetAxes(at_axis); - - //reset orientation -// mRoot.setRotation(avWorldRot); gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f)); - gAgentCamera.setSitCamera(LLUUID::null); if (sit_object && !sit_object->permYouOwner() && gSavedSettings.getBOOL("RevokePermsOnStandUp")) @@ -6957,7 +6947,7 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL } else if (global_color == mTexEyeColor) { -// llinfos << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << llendl; +// LL_INFOS() << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << LL_ENDL; invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet, upload_bake ); } updateMeshTextures(); @@ -7053,11 +7043,11 @@ void LLVOAvatar::startPhase(const std::string& phase_name) { if (!completed) { - LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << llendl; + LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << LL_ENDL; return; } } - LL_DEBUGS("Avatar") << "started phase " << phase_name << llendl; + LL_DEBUGS("Avatar") << "started phase " << phase_name << LL_ENDL; getPhases().startPhase(phase_name); } @@ -7072,13 +7062,13 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check) getPhases().stopPhase(phase_name); completed = true; logMetricsTimerRecord(phase_name, elapsed, completed); - LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << llendl; + LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << LL_ENDL; } else { if (err_check) { - LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << llendl; + LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << LL_ENDL; } } } @@ -7086,13 +7076,18 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check) { if (err_check) { - LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << llendl; + LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << LL_ENDL; } } } void LLVOAvatar::logPendingPhases() { + if (!isAgentAvatarValid()) + { + return; + } + for (LLViewerStats::phase_map_t::iterator it = getPhases().begin(); it != getPhases().end(); ++it) @@ -7127,6 +7122,11 @@ void LLVOAvatar::logPendingPhasesAllAvatars() void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed) { + if (!isAgentAvatarValid()) + { + return; + } + LLSD record; record["timer_name"] = phase_name; record["avatar_id"] = getID(); @@ -7258,6 +7258,8 @@ LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const return mMotionController.findMotion(id); } +// This is a semi-deprecated debugging tool - meshes will not show as +// colorized if using deferred rendering. void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color) { if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) @@ -7285,8 +7287,8 @@ void LLVOAvatar::updateMeshTextures() { static S32 update_counter = 0; mBakedTextureDebugText.clear(); - // llinfos << "updateMeshTextures" << llendl; if (gNoRender) return; + // if user has never specified a texture, assign the default for (U32 i=0; i < getNumTEs(); i++) { @@ -7835,14 +7837,14 @@ bool LLVOAvatar::visualParamWeightsAreDefault() // we have to not care whether skirt weights are default, if we're not actually wearing a skirt (is_wearing_skirt || !is_skirt_param)) { - //llinfos << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << llendl; + //LL_INFOS() << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << LL_ENDL; rtn = false; break; } } } - //llinfos << "params are default ? " << int(rtn) << llendl; + //LL_INFOS() << "params are default ? " << int(rtn) << LL_ENDL; return rtn; } @@ -7855,6 +7857,7 @@ void dump_visual_param(LLAPRFile& file, LLVisualParam const* viewer_param, F32 v viewer_param->getDumpWearableTypeName().c_str()); } + void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, const std::vector& params_for_dump, const LLTEContents& tec) @@ -7871,7 +7874,7 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, } else { - LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << llendl; + LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << LL_ENDL; } @@ -7923,7 +7926,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe U8 av_u8; mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0); contents.mAppearanceVersion = av_u8; - llinfos << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << llendl; + LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << LL_ENDL; mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0); // For future use: //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0); @@ -7970,7 +7973,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT if (num_blocks != expected_tweakable_count) { - llinfos << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << llendl; + LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL; } } else @@ -7981,7 +7984,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe } else { - llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl; + LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << LL_ENDL; } } @@ -7992,9 +7995,8 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe if (it != contents.mParams.end()) { S32 index = it - contents.mParams.begin(); - llinfos << "index: " << index << llendl; contents.mParamAppearanceVersion = llround(contents.mParamWeights[index]); - LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << llendl; + LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL; } } } @@ -8025,7 +8027,7 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32 } LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion << " param: " << contents.mParamAppearanceVersion - << " final: " << appearance_version << llendl; + << " final: " << appearance_version << LL_ENDL; return true; } @@ -8034,11 +8036,10 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32 //----------------------------------------------------------------------------- void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) { - LL_DEBUGS("Avatar") << "starts" << llendl; + LL_DEBUGS("Avatar") << "starts" << LL_ENDL; bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"); std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_"; - //if (enable_verbose_dumps) { dumpArchetypeXML(dump_prefix + "process_start"); } if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages")) { llwarns << "Blocking AvatarAppearance message" << llendl; @@ -8068,10 +8069,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) { LL_DEBUGS("Avatar") << "this_update_cof_version " << this_update_cof_version << " last_update_request_cof_version " << last_update_request_cof_version - << " my_cof_version " << LLAppearanceMgr::instance().getCOFVersion() << llendl; + << " my_cof_version " << LLAppearanceMgr::instance().getCOFVersion() << LL_ENDL; LLAppearanceMgr::instance().setLastAppearanceUpdateCOFVersion(this_update_cof_version); - + if (getRegion() && (getRegion()->getCentralBakeVersion()==0)) { llwarns << avString() << "Received AvatarAppearance message for self in non-server-bake region" << llendl; @@ -8083,7 +8084,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } else { - LL_DEBUGS("Avatar") << "appearance message received" << llendl; + LL_DEBUGS("Avatar") << "appearance message received" << LL_ENDL; } if (gNoRender) @@ -8103,7 +8104,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) if (isSelf() && isEditingAppearance()) { - llinfos << "ignoring appearance message while in appearance edit" << llendl; + LL_DEBUGS("Avatar") << "ignoring appearance message while in appearance edit" << LL_ENDL; return; } @@ -8114,7 +8115,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // appearance version, which may cause us to look for baked // textures in the wrong place and flag them as missing // assets. - llinfos << "ignoring appearance message due to lack of params" << llendl; + LL_DEBUGS("Avatar") << "ignoring appearance message due to lack of params" << LL_ENDL; return; } @@ -8124,8 +8125,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) SHClientTagMgr::instance().updateAvatarTag(this); -// dumpAvatarTEs( "POST processAvatarAppearance()" ); - // prevent the overwriting of valid baked textures with invalid baked textures for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++) { @@ -8144,7 +8143,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; mFirstAppearanceMessageReceived = TRUE; - LL_INFOS("Avatar") << avString() << "processAvatarAppearance start " << mID + LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; if (is_first_appearance_message ) @@ -8191,7 +8190,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT if (num_params != expected_tweakable_count) { - llinfos << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << llendl; + LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL; } if (params_changed) @@ -8279,7 +8278,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture { if (!userdata) return; - //llinfos << "onBakedTextureMasksLoaded: " << src_vi->getID() << llendl; + //LL_INFOS() << "onBakedTextureMasksLoaded: " << src_vi->getID() << LL_ENDL; const LLUUID id = src_vi->getID(); LLTextureMaskData* maskData = (LLTextureMaskData*) userdata; @@ -8293,7 +8292,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture { if (!aux_src->getData()) { - llwarns << "No auxiliary source data for onBakedTextureMasksLoaded" << llendl; + llwarns << "No auxiliary source (morph mask) data for image id " << id << llendl; return; } @@ -8314,7 +8313,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture /* if( id == head_baked->getID() ) if (self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet) - //llinfos << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << llendl; + //LL_INFOS() << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << LL_ENDL; self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); maskData->mLastDiscardLevel = discard_level; */ BOOL found_texture_id = false; @@ -8353,7 +8352,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture { // this can happen when someone uses an old baked texture possibly provided by // viewer-side baked texture caching - llwarns << "Masks loaded callback but NO aux source!" << llendl; + llwarns << "Masks loaded callback but NO aux source, id " << id << llendl; } } @@ -8589,6 +8588,7 @@ void LLVOAvatar::dumpArchetypeXML_cont(std::string const& fullpath, bool group_b } } + void LLVOAvatar::setVisibilityRank(U32 rank) { if (mDrawable.isNull() || mDrawable->isDead()) @@ -8840,7 +8840,6 @@ void LLVOAvatar::updateSoftwareSkinnedVertices(const LLMeshSkinInfo* skin, const //build matrix palette LLMatrix4a mp[JOINT_COUNT]; - LLMatrix4* mat = (LLMatrix4*) mp; U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT); @@ -8855,8 +8854,9 @@ void LLVOAvatar::updateSoftwareSkinnedVertices(const LLMeshSkinInfo* skin, const } if (joint) { - mat[j] = skin->mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); + LLMatrix4a mat; + mat.loadu((F32*)skin->mInvBindMatrix[j].mMatrix); + mp[j].setMul(joint->getWorldMatrix(),mat); } } @@ -8982,6 +8982,7 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d angle.mV[2] = da; } + void LLVOAvatar::idleUpdateRenderCost() { if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) @@ -9114,8 +9115,6 @@ void LLVOAvatar::idleUpdateRenderCost() } - - // Diagnostic output to identify all avatar-related textures. // Does not affect rendering cost calculation. // Could be wrapped in a debug option if output becomes problematic. @@ -9156,7 +9155,6 @@ void LLVOAvatar::idleUpdateRenderCost() } } - std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); setDebugText(llformat("%s %d", viz_string.c_str(), cost)); mVisualComplexity = cost; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index f8bd7fe13..b0bc08ab3 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -1076,6 +1076,6 @@ private: }; // LLVOAvatar extern const F32 SELF_ADDITIONAL_PRI; -extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL; +extern const S32 MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL; #endif // LL_VOAVATAR_H diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 14cbd4993..f5cf396c3 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -54,6 +54,7 @@ #include "llviewermedia.h" #include "llviewermenu.h" #include "llviewerobjectlist.h" +#include "llviewerparcelmgr.h" #include "llviewerstats.h" #include "llviewerregion.h" #include "llviewertexlayer.h" @@ -180,6 +181,8 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id, SHClientTagMgr::instance().updateAvatarTag(this); //No TE update messages for self. Force update here. + mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLVOAvatarSelf::handleTeleportFinished, this)); + lldebugs << "Marking avatar as self " << id << llendl; } @@ -2314,7 +2317,7 @@ public: { } - /*virtual*/ void result(LLSD const& content) + /*virtual*/ void httpSuccess(void) { LL_DEBUGS("Avatar") << "OK" << LL_ENDL; if (mLiveSequence == mExpectedSequence) @@ -2322,9 +2325,9 @@ public: mReportingStarted = true; } } - /*virtual*/ void error(U32 status, std::string const& reason) + /*virtual*/ void httpFailure(void) { - LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL; + LL_WARNS("Avatar") << "Failed " << mStatus << " reason " << mReason << LL_ENDL; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return appearanceChangeMetricsResponder_timeout; } /*virtual*/ char const* getName(void) const { return "AppearanceChangeMetricsResponder"; } @@ -2490,9 +2493,9 @@ public: { } - /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(void) { - if (isGoodStatus(status)) + if (isGoodStatus(mStatus)) { LL_DEBUGS("Avatar") << "status OK" << llendl; } @@ -2507,7 +2510,7 @@ public: } // Error - /*virtual*//* void error(U32 status, const std::string& reason) + /*virtual*//* void httpFailure(void) { if (isAgentAvatarValid()) { @@ -2662,7 +2665,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ; } imagep->resetTextureStats(); - imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); + imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL); imagep->addTextureStats( desired_pixels / texel_area_ratio ); imagep->forceUpdateBindStats() ; if (imagep->getDiscardLevel() < 0) @@ -3258,7 +3261,7 @@ LLVector3 LLVOAvatarSelf::getLegacyAvatarOffset() const if(on_pose_stand) offset.mV[VZ] += 7.5f; - return offset; + return mAvatarOffset + offset; } // static @@ -3289,3 +3292,23 @@ void LLVOAvatarSelf::setInvisible(bool invisible) gAgent.sendAgentSetAppearance(); } } + +void LLVOAvatarSelf::handleTeleportFinished() +{ + for (attachment_map_t::iterator it = mAttachmentPoints.begin(); it != mAttachmentPoints.end(); ++it) + { + LLViewerJointAttachment* attachment = it->second; + if (attachment && attachment->getIsHUDAttachment()) + { + typedef LLViewerJointAttachment::attachedobjs_vec_t object_vec_t; + const object_vec_t& obj_list = attachment->mAttachedObjects; + for (object_vec_t::const_iterator it2 = obj_list.begin(); it2 != obj_list.end(); ++it2) + { + if(*it2) + { + (*it2)->dirtySpatialGroup(true); + } + } + } + } +} diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 2c9d69b8b..fea466775 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -429,6 +429,11 @@ private: public: static void onChangeSelfInvisible(bool invisible); void setInvisible(bool invisible); +private: + void handleTeleportFinished(); +private: + boost::signals2::connection mTeleportFinishedSlot; + }; extern LLPointer gAgentAvatarp; diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index 0947e6025..24f64a70e 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -142,7 +142,6 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) group->setState(LLSpatialGroup::GEOM_DIRTY); } drawable->setNumFaces(0, NULL, getTEImage(0)); - LLPipeline::sCompiles++; return TRUE; } @@ -195,7 +194,6 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) } mDrawable->movePartition(); - LLPipeline::sCompiles++; return TRUE; } diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 9d802740f..5988ece29 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -492,7 +492,6 @@ void LLVOGrass::plantBlades() mDepth = (face->mCenterLocal - LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis(); mDrawable->setPosition(face->mCenterLocal); mDrawable->movePartition(); - LLPipeline::sCompiles++; } void LLVOGrass::getGeometry(S32 idx, @@ -620,7 +619,6 @@ void LLVOGrass::getGeometry(S32 idx, index_offset += 8; } - LLPipeline::sCompiles++; } U32 LLVOGrass::getPartitionType() const diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 97b7418b4..6ffb580cd 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -156,6 +156,5 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) *(texCoordsp++) = LLVector2(0.5f, 0.5f); face->getVertexBuffer()->flush(); - LLPipeline::sCompiles++; return TRUE; } diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 2fd7bb572..b42749d28 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -55,8 +55,9 @@ class LLVoiceCallCapResponder : public LLHTTPClient::ResponderWithResult public: LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {}; - /*virtual*/ void error(U32 status, const std::string& reason); // called with bad status codes - /*virtual*/ void result(const LLSD& content); + // called with bad status codes + virtual void httpFailure(void); + virtual void httpSuccess(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return voiceCallCapResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLVoiceCallCapResponder"; } @@ -65,14 +66,14 @@ private: }; -void LLVoiceCallCapResponder::error(U32 status, const std::string& reason) +void LLVoiceCallCapResponder::httpFailure(void) { LL_WARNS("Voice") << "LLVoiceCallCapResponder error [status:" - << status << "]: " << reason << LL_ENDL; + << mStatus << "]: " << mReason << LL_ENDL; LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); if ( channelp ) { - if ( 403 == status ) + if ( 403 == mStatus ) { //403 == no ability LLNotificationsUtil::add( @@ -89,22 +90,22 @@ void LLVoiceCallCapResponder::error(U32 status, const std::string& reason) } } -void LLVoiceCallCapResponder::result(const LLSD& content) +void LLVoiceCallCapResponder::httpSuccess(void) { LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); if (channelp) { // *TODO: DEBUG SPAM LLSD::map_const_iterator iter; - for(iter = content.beginMap(); iter != content.endMap(); ++iter) + for(iter = mContent.beginMap(); iter != mContent.endMap(); ++iter) { LL_DEBUGS("Voice") << "LLVoiceCallCapResponder::result got " << iter->first << LL_ENDL; } channelp->setChannelInfo( - content["voice_credentials"]["channel_uri"].asString(), - content["voice_credentials"]["channel_credentials"].asString()); + mContent["voice_credentials"]["channel_uri"].asString(), + mContent["voice_credentials"]["channel_credentials"].asString()); } } @@ -412,7 +413,7 @@ void LLVoiceChannel::doSetState(const EState& new_state) mState = new_state; if (!mStateChangedCallback.empty()) - mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent); + mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent, mSessionID); } //static diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index 55dcf0f07..cf389d971 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -49,7 +49,7 @@ public: OUTGOING_CALL } EDirection; - typedef boost::signals2::signal state_changed_signal_t; + typedef boost::signals2::signal state_changed_signal_t; // on current channel changed signal typedef boost::function channel_changed_callback_t; @@ -58,7 +58,6 @@ public: static boost::signals2::connection setCurrentVoiceChannelChangedCallback(channel_changed_callback_t cb, bool at_front = false); - LLVoiceChannel(const LLUUID& session_id, const std::string& session_name); virtual ~LLVoiceChannel(); @@ -202,4 +201,3 @@ private: }; #endif // LL_VOICECHANNEL_H - diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index f3709450d..54ca806de 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -112,8 +112,8 @@ LLVoiceClient::LLVoiceClient() : mVoiceModule(NULL), m_servicePump(NULL), - mVoiceEffectEnabled(LLCachedControl(gSavedSettings, "VoiceMorphingEnabled")), - mVoiceEffectDefault(LLCachedControl(gSavedPerAccountSettings, "VoiceEffectDefault")), + mVoiceEffectEnabled(LLCachedControl(gSavedSettings, "VoiceMorphingEnabled", true)), + mVoiceEffectDefault(LLCachedControl(gSavedPerAccountSettings, "VoiceEffectDefault", "00000000-0000-0000-0000-000000000000")), mPTTDirty(true), mPTT(true), mUsePTT(true), diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 58f8dbcf0..46edb4fa7 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -122,11 +122,11 @@ public: mRetries = retries; } - /*virtual*/ void error(U32 status, const std::string& reason) + /*virtual*/ void httpFailure(void) { LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, " << ( (mRetries > 0) ? "retrying" : "too many retries (giving up)" ) - << status << "]: " << reason << LL_ENDL; + << mStatus << "]: " << mReason << LL_ENDL; if ( mRetries > 0 ) { @@ -138,24 +138,24 @@ public: } } - /*virtual*/ void result(const LLSD& content) + /*virtual*/ void httpSuccess(void) { std::string voice_sip_uri_hostname; std::string voice_account_server_uri; - LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << ll_pretty_print_sd(content) << LL_ENDL; + LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << ll_pretty_print_sd(mContent) << LL_ENDL; - if(content.has("voice_sip_uri_hostname")) - voice_sip_uri_hostname = content["voice_sip_uri_hostname"].asString(); + if(mContent.has("voice_sip_uri_hostname")) + voice_sip_uri_hostname = mContent["voice_sip_uri_hostname"].asString(); // this key is actually misnamed -- it will be an entire URI, not just a hostname. - if(content.has("voice_account_server_name")) - voice_account_server_uri = content["voice_account_server_name"].asString(); + if(mContent.has("voice_account_server_name")) + voice_account_server_uri = mContent["voice_account_server_name"].asString(); LLVivoxVoiceClient::getInstance()->login( - content["username"].asString(), - content["password"].asString(), + mContent["username"].asString(), + mContent["password"].asString(), voice_sip_uri_hostname, voice_account_server_uri); @@ -188,8 +188,8 @@ class LLVivoxVoiceClientCapResponder : public LLHTTPClient::ResponderWithResult public: LLVivoxVoiceClientCapResponder(LLVivoxVoiceClient::state requesting_state) : mRequestingState(requesting_state) {}; - /*virtual*/ void error(U32 status, const std::string& reason); // called with bad status codes - /*virtual*/ void result(const LLSD& content); + /*virtual*/ void httpFailure(void); + /*virtual*/ void httpSuccess(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return vivoxVoiceClientCapResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLVivoxVoiceClientCapResponder"; } @@ -197,25 +197,25 @@ private: LLVivoxVoiceClient::state mRequestingState; // state }; -void LLVivoxVoiceClientCapResponder::error(U32 status, const std::string& reason) +void LLVivoxVoiceClientCapResponder::httpFailure(void) { LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder error [status:" - << status << "]: " << reason << LL_ENDL; + << mStatus << "]: " << mReason << LL_ENDL; LLVivoxVoiceClient::getInstance()->sessionTerminate(); } -void LLVivoxVoiceClientCapResponder::result(const LLSD& content) +void LLVivoxVoiceClientCapResponder::httpSuccess(void) { LLSD::map_const_iterator iter; - LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest response:" << ll_pretty_print_sd(content) << LL_ENDL; + LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest response:" << ll_pretty_print_sd(mContent) << LL_ENDL; std::string uri; std::string credentials; - if ( content.has("voice_credentials") ) + if ( mContent.has("voice_credentials") ) { - LLSD voice_credentials = content["voice_credentials"]; + LLSD voice_credentials = mContent["voice_credentials"]; if ( voice_credentials.has("channel_uri") ) { uri = voice_credentials["channel_uri"].asString(); @@ -295,6 +295,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mSessionTerminateRequested(false), mRelogRequested(false), mConnected(false), + mTerminateDaemon(false), mPump(NULL), mSpatialJoiningNum(0), @@ -567,25 +568,25 @@ void LLVivoxVoiceClient::requestVoiceAccountProvision(S32 retries) { LLViewerRegion *region = gAgent.getRegion(); - if ( region && (mVoiceEnabled || !mIsInitialized)) + // If we've not received the capability yet, return. + // the password will remain empty, so we'll remain in + // stateIdle + if ( region && + region->capabilitiesReceived() && + (mVoiceEnabled || !mIsInitialized)) { std::string url = region->getCapability("ProvisionVoiceAccountRequest"); - if ( url.empty() ) + if ( !url.empty() ) { - // we've not received the capability yet, so return. - // the password will remain empty, so we'll remain in - // stateIdle - return; + LLHTTPClient::post( + url, + LLSD(), + new LLVivoxVoiceAccountProvisionResponder(retries)); + + setState(stateConnectorStart); } - - LLHTTPClient::post( - url, - LLSD(), - new LLVivoxVoiceAccountProvisionResponder(retries)); - - setState(stateConnectorStart); } } @@ -738,7 +739,7 @@ void LLVivoxVoiceClient::stateMachine() setVoiceEnabled(false); } - if(mVoiceEnabled || !mIsInitialized) + if(mVoiceEnabled || (!mIsInitialized && !mTerminateDaemon) ) { updatePosition(); } @@ -751,11 +752,12 @@ void LLVivoxVoiceClient::stateMachine() if((getState() != stateDisabled) && (getState() != stateDisableCleanup)) { // User turned off voice support. Send the cleanup messages, close the socket, and reset. - if(!mConnected) + if(!mConnected || mTerminateDaemon) { // if voice was turned off after the daemon was launched but before we could connect to it, we may need to issue a kill. LL_INFOS("Voice") << "Disabling voice before connection to daemon, terminating." << LL_ENDL; killGateway(); + mTerminateDaemon = false; } logout(); @@ -796,7 +798,7 @@ void LLVivoxVoiceClient::stateMachine() // Voice is locked out, we must not launch the vivox daemon. setState(stateJail); } - else if(!isGatewayRunning()) + else if(!isGatewayRunning() && gSavedSettings.getBOOL("EnableVoiceChat")) { if (true) // production build, not test { @@ -1281,6 +1283,7 @@ void LLVivoxVoiceClient::stateMachine() std::stringstream errs; errs << mVoiceAccountServerURI << "\n:UDP: 3478, 3479, 5060, 5062, 12000-17000"; args["HOSTID"] = errs.str(); + mTerminateDaemon = true; LLNotificationsUtil::add("NoVoiceConnect", args); } else @@ -2759,6 +2762,7 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st std::stringstream errs; errs << mVoiceAccountServerURI << "\n:UDP: 3478, 3479, 5060, 5062, 12000-17000"; args["HOSTID"] = errs.str(); + mTerminateDaemon = true; LLNotificationsUtil::add("NoVoiceConnect", args); } else @@ -2767,6 +2771,7 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st LL_INFOS("Voice") << "Connector.Create succeeded, Vivox SDK version is " << versionID << LL_ENDL; mVoiceVersion.serverVersion = versionID; mConnectorHandle = connectorHandle; + mTerminateDaemon = false; if(getState() == stateConnectorStarting) { setState(stateConnectorStarted); @@ -6936,6 +6941,9 @@ void LLVivoxProtocolParser::processResponse(std::string tag) */ // We don't need to process this, but we also shouldn't warn on it, since that confuses people. } + else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent")) + { // Yet another ignored event + } else { LL_WARNS("VivoxProtocolParser") << "Unknown event type " << eventTypeString << LL_ENDL; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 03811e4e1..3843bbd7e 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -111,7 +111,7 @@ public: //////////////////////////// /// @name Channel stuff //@{ - // returns true if the user is currently in a proximal (local spatial) channel. + // returns true iff the user is currently in a proximal (local spatial) channel. // Note that gestures should only fire if this returns true. virtual bool inProximalChannel(); @@ -640,6 +640,8 @@ private: LLSocket::ptr_t mSocket; bool mConnected; + // We should kill the voice daemon in case of connection alert + bool mTerminateDaemon; LLPumpIO *mPump; friend class LLVivoxProtocolParser; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 0e17c77ef..7b4077798 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -339,7 +339,6 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) group->setState(LLSpatialGroup::GEOM_DIRTY); } drawable->setNumFaces(0, NULL, getTEImage(0)); - LLPipeline::sCompiles++; return TRUE; } @@ -482,7 +481,6 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) mScale.set(max_scale, max_scale, max_scale); mDrawable->movePartition(); - LLPipeline::sCompiles++; return TRUE; } diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 2c3e6fbf9..83f8d9388 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -298,7 +298,6 @@ void LLSkyTex::create(const F32 brightness) void LLSkyTex::createGLImage(S32 which) { - mTexture[which]->setNeedsAlphaAndPickMask(false); //Needed, else analyzeAlpha is called every frame for each texture. mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL); mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP); } @@ -1411,8 +1410,6 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) { setDrawRefl(-1); } - - LLPipeline::sCompiles++; return TRUE; } diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 847a1f128..f33e24199 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -107,6 +107,10 @@ LLVOTree::~LLVOTree() delete[] mData; mData = NULL; } + for(std::vector >::iterator iter = mDrawList.begin(); iter != mDrawList.end(); iter++) + { + delete (*iter)->mModelMatrix; + } } //static @@ -332,9 +336,9 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, // // Load Species-Specific data // - static const S32 MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 32 ; //frames. + static const S32 MAX_TREE_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL = 32 ; //frames. mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - mTreeImagep->setMaxVirtualSizeResetInterval(MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); //allow to wait for at most 16 frames to reset virtual size. + mTreeImagep->setMaxVirtualSizeResetInterval(MAX_TREE_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL); //allow to wait for at most 16 frames to reset virtual size. mBranchLength = sSpeciesTable[mSpecies]->mBranchLength; mTrunkLength = sSpeciesTable[mSpecies]->mTrunkLength; @@ -397,6 +401,11 @@ void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) mTrunkVel.normalize(); } } + else + { + mTrunkBend.clear(); + mTrunkVel.clear(); + } S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS; F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor; @@ -446,6 +455,10 @@ void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } } } + else + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, FALSE); + } mTrunkLOD = trunk_LOD; //return TRUE; @@ -541,6 +554,12 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(FTM_UPDATE_TREE); + for(std::vector >::iterator iter = mDrawList.begin(); iter != mDrawList.end(); iter++) + { + delete (*iter)->mModelMatrix; + } + mDrawList.clear(); + if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree. { mReferenceBuffer = NULL ; @@ -582,8 +601,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) max_vertices += sLODVertexCount[lod]; } - static LLCachedControl sRenderAnimateTrees(gSavedSettings, "RenderAnimateTrees"); - mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, sRenderAnimateTrees ? GL_STATIC_DRAW_ARB : 0); + mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE); LLStrider vertices; @@ -886,31 +904,21 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) llassert(vertex_count == max_vertices); llassert(index_count == max_indices); } - - static LLCachedControl sRenderAnimateTrees(gSavedSettings, "RenderAnimateTrees"); - if (sRenderAnimateTrees) - { - mDrawable->getFace(0)->setVertexBuffer(mReferenceBuffer); - } - else - { - //generate tree mesh - updateMesh(); - } + + //generate tree mesh + updateMesh(); return TRUE; } void LLVOTree::updateMesh() { - LLMatrix4 matrix; - // Translate to tree base HACK - adjustment in Z plants tree underground const LLVector3 &pos_region = getPositionRegion(); //gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); - LLMatrix4 trans_mat; - trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY], pos_region.mV[VZ] - 0.1f); - trans_mat *= matrix; + LLMatrix4a trans_mat; + trans_mat.setIdentity(); + trans_mat.setTranslate_affine(pos_region - LLVector3(0.f,0.f,0.1f)); // Rotate to tree position and bend for current trunk/wind // Note that trunk stiffness controls the amount of bend at the trunk as @@ -923,16 +931,12 @@ void LLVOTree::updateMesh() LLQuaternion(90.f*DEG_TO_RAD, LLVector4(0,0,1)) * getRotation(); - LLMatrix4 rot_mat(rot); - rot_mat *= trans_mat; + + LLMatrix4a rot_mat = trans_mat; + rot_mat.mul(LLQuaternion2(rot)); F32 radius = getScale().magVec()*0.05f; - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = - scale_mat.mMatrix[1][1] = - scale_mat.mMatrix[2][2] = radius; - - scale_mat *= rot_mat; + rot_mat.applyScale_affine(radius); // const F32 THRESH_ANGLE_FOR_BILLBOARD = 15.f; // const F32 BLEND_RANGE_FOR_BILLBOARD = 3.f; @@ -949,78 +953,102 @@ void LLVOTree::updateMesh() LLFace* facep = mDrawable->getFace(0); if (!facep) return; - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); - buff->allocateBuffer(vert_count, index_count, TRUE); - facep->setVertexBuffer(buff); - LLStrider vertices; - LLStrider normals; + LLStrider vertices; + LLStrider normals; LLStrider tex_coords; LLStrider indices; U16 idx_offset = 0; - buff->getVertexStrider(vertices); - buff->getNormalStrider(normals); - buff->getTexCoord0Strider(tex_coords); - buff->getIndexStrider(indices); + LLVertexBuffer* buff = NULL; - genBranchPipeline(vertices, normals, tex_coords, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha); + static LLCachedControl sRenderAnimateTrees("RenderAnimateTrees", false); + if (sRenderAnimateTrees) + { + facep->setVertexBuffer(NULL); + } + else + { + buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); + buff->allocateBuffer(vert_count, index_count, TRUE); + facep->setVertexBuffer(buff); + + buff->getVertexStrider(vertices); + buff->getNormalStrider(normals); + buff->getTexCoord0Strider(tex_coords); + buff->getIndexStrider(indices); + } + + genBranchPipeline(vertices, normals, tex_coords, indices, idx_offset, rot_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha); - mReferenceBuffer->flush(); - buff->flush(); + if(buff) + { + mReferenceBuffer->flush(); + buff->flush(); + } } -void LLVOTree::appendMesh(LLStrider& vertices, - LLStrider& normals, +void LLVOTree::appendMesh(LLStrider& vertices, + LLStrider& normals, LLStrider& tex_coords, LLStrider& indices, U16& cur_idx, - LLMatrix4& matrix, - LLMatrix4& norm_mat, + LLMatrix4a& matrix, + LLMatrix4a& norm_mat, S32 vert_start, S32 vert_count, S32 index_count, S32 index_offset) { - LLStrider v; - LLStrider n; + LLStrider v; + LLStrider n; LLStrider t; LLStrider idx; - mReferenceBuffer->getVertexStrider(v); - mReferenceBuffer->getNormalStrider(n); - mReferenceBuffer->getTexCoord0Strider(t); - mReferenceBuffer->getIndexStrider(idx); - - //copy/transform vertices into mesh - check - for (S32 i = 0; i < vert_count; i++) - { - U16 index = vert_start + i; - *vertices++ = v[index] * matrix; - LLVector3 norm = n[index] * norm_mat; - norm.normalize(); - *normals++ = norm; - *tex_coords++ = t[index]; - } - - //copy offset indices into mesh - check - for (S32 i = 0; i < index_count; i++) + static LLCachedControl sRenderAnimateTrees(gSavedSettings, "RenderAnimateTrees"); + if(sRenderAnimateTrees) //Instead of manipulating the vbo, use the reference vbo and apply the transformation matrix to the matrix stack at draw-time. { - U16 index = index_offset + i; - *indices++ = idx[index]-vert_start+cur_idx; + LLDrawInfo* draw_info = new LLDrawInfo(vert_start,vert_start+vert_count-1,index_count,index_offset,NULL,mReferenceBuffer); + draw_info->mModelMatrix = new LLMatrix4a(matrix); //Make sure these are deleted before clearing/destructing mDrawList! + mDrawList.push_back(draw_info); } + else + { + mReferenceBuffer->getVertexStrider(v); + mReferenceBuffer->getNormalStrider(n); + mReferenceBuffer->getTexCoord0Strider(t); + mReferenceBuffer->getIndexStrider(idx); + + //copy/transform vertices into mesh - check + for (S32 i = 0; i < vert_count; i++) + { + U16 index = vert_start + i; + matrix.affineTransform(v[index],*vertices++); + LLVector4a& norm = *normals++; + norm_mat.perspectiveTransform(n[index],norm); + norm.normalize3fast(); + *tex_coords++ = t[index]; + } - //increment index offset - check - cur_idx += vert_count; + //copy offset indices into mesh - check + for (S32 i = 0; i < index_count; i++) + { + U16 index = index_offset + i; + *indices++ = idx[index]-vert_start+cur_idx; + } + + //increment index offset - check + cur_idx += vert_count; + } } -void LLVOTree::genBranchPipeline(LLStrider& vertices, - LLStrider& normals, +void LLVOTree::genBranchPipeline(LLStrider& vertices, + LLStrider& normals, LLStrider& tex_coords, LLStrider& indices, U16& index_offset, - LLMatrix4& matrix, + LLMatrix4a& matrix, S32 trunk_LOD, S32 stop_level, U16 depth, @@ -1049,46 +1077,44 @@ void LLVOTree::genBranchPipeline(LLStrider& vertices, { llassert(sLODIndexCount[trunk_LOD] > 0); width = scale * length * aspect; - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = width; - scale_mat.mMatrix[1][1] = width; - scale_mat.mMatrix[2][2] = scale*length; - scale_mat *= matrix; - glh::matrix4f norm((F32*) scale_mat.mMatrix); - LLMatrix4 norm_mat = LLMatrix4(norm.inverse().transpose().m); + LLMatrix4a scale_mat = matrix; + scale_mat.applyScale_affine(width,width,scale*length); + LLMatrix4a norm_mat = scale_mat; norm_mat.invert(); + norm_mat.transpose(); + appendMesh(vertices, normals, tex_coords, indices, index_offset, scale_mat, norm_mat, sLODVertexOffset[trunk_LOD], sLODVertexCount[trunk_LOD], sLODIndexCount[trunk_LOD], sLODIndexOffset[trunk_LOD]); } - + + LLMatrix4a trans_matrix = matrix; + trans_matrix.applyTranslation_affine(0.f,0.f,scale*length); + const LLMatrix4a& trans_mat = trans_matrix; + // Recurse to create more branches for (S32 i=0; i < (S32)branches; i++) { - LLMatrix4 trans_mat; - trans_mat.setTranslation(0,0,scale*length); - trans_mat *= matrix; LLQuaternion rot = LLQuaternion(20.f*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)) * LLQuaternion(droop*DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f)) * LLQuaternion(((constant_twist + ((i%2==0)?twist:-twist))*i)*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)); - - LLMatrix4 rot_mat(rot); - rot_mat *= trans_mat; + + LLMatrix4a rot_mat = trans_mat; + rot_mat.mul(LLQuaternion2(rot)); genBranchPipeline(vertices, normals, tex_coords, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha); } // Recurse to continue trunk if (trunk_depth) { - LLMatrix4 trans_mat; - trans_mat.setTranslation(0,0,scale*length); - trans_mat *= matrix; - LLMatrix4 rot_mat(70.5f*DEG_TO_RAD, LLVector4(0,0,1)); - rot_mat *= trans_mat; // rotate a bit around Z when ascending + static const LLMatrix4a srot_mat = gGL.genRot(70.5f,0.f,0.f,1.f); + LLMatrix4a rot_mat; + rot_mat.setMul(trans_mat, srot_mat); // rotate a bit around Z when ascending + genBranchPipeline(vertices, normals, tex_coords, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha); } } @@ -1098,15 +1124,12 @@ void LLVOTree::genBranchPipeline(LLStrider& vertices, // Append leaves as two 90 deg crossed quads with leaf textures // { - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = - scale_mat.mMatrix[1][1] = - scale_mat.mMatrix[2][2] = scale*mLeafScale; + LLMatrix4a scale_mat = matrix; + scale_mat.applyScale_affine(scale*mLeafScale); - scale_mat *= matrix; - - glh::matrix4f norm((F32*) scale_mat.mMatrix); - LLMatrix4 norm_mat = LLMatrix4(norm.inverse().transpose().m); + LLMatrix4a norm_mat = scale_mat; + norm_mat.invert(); + norm_mat.transpose(); appendMesh(vertices, normals, tex_coords, indices, index_offset, scale_mat, norm_mat, 0, LEAF_VERTICES, LEAF_INDICES, 0); } @@ -1150,132 +1173,6 @@ void LLVOTree::calcNumVerts(U32& vert_count, U32& index_count, S32 trunk_LOD, S3 } } -U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, F32 alpha) -{ - U32 ret = 0; - // - // Draws a tree by recursing, drawing branches and then a 'leaf' texture. - // If stop_level = -1, simply draws the whole tree as a billboarded texture - // - - static F32 constant_twist; - static F32 width = 0; - - //F32 length = ((scale == 1.f)? mTrunkLength:mBranchLength); - //F32 aspect = ((scale == 1.f)? mTrunkAspect:mBranchAspect); - F32 length = ((trunk_depth || (scale == 1.f))? mTrunkLength:mBranchLength); - F32 aspect = ((trunk_depth || (scale == 1.f))? mTrunkAspect:mBranchAspect); - - constant_twist = 360.f/branches; - - if (!LLPipeline::sReflectionRender && stop_level >= 0) - { - // - // Draw the tree using recursion - // - if (depth > stop_level) - { - { - llassert(sLODIndexCount[trunk_LOD] > 0); - width = scale * length * aspect; - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = width; - scale_mat.mMatrix[1][1] = width; - scale_mat.mMatrix[2][2] = scale*length; - scale_mat *= matrix; - - gGL.loadMatrix((F32*) scale_mat.mMatrix); - gGL.syncMatrices(); - glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_LOD], GL_UNSIGNED_SHORT, indicesp + sLODIndexOffset[trunk_LOD]); - gPipeline.addTrianglesDrawn(LEAF_INDICES); - stop_glerror(); - ret += sLODIndexCount[trunk_LOD]; - } - - // Recurse to create more branches - for (S32 i=0; i < (S32)branches; i++) - { - LLMatrix4 trans_mat; - trans_mat.setTranslation(0,0,scale*length); - trans_mat *= matrix; - - LLQuaternion rot = - LLQuaternion(20.f*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)) * - LLQuaternion(droop*DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f)) * - LLQuaternion(((constant_twist + ((i%2==0)?twist:-twist))*i)*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)); - - LLMatrix4 rot_mat(rot); - rot_mat *= trans_mat; - - ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha); - } - // Recurse to continue trunk - if (trunk_depth) - { - LLMatrix4 trans_mat; - trans_mat.setTranslation(0,0,scale*length); - trans_mat *= matrix; - - LLMatrix4 rot_mat(70.5f*DEG_TO_RAD, LLVector4(0,0,1)); - rot_mat *= trans_mat; // rotate a bit around Z when ascending - ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha); - } - } - else - { - // - // Draw leaves as two 90 deg crossed quads with leaf textures - // - { - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = - scale_mat.mMatrix[1][1] = - scale_mat.mMatrix[2][2] = scale*mLeafScale; - - scale_mat *= matrix; - - - gGL.loadMatrix((F32*) scale_mat.mMatrix); - gGL.syncMatrices(); - glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp); - gPipeline.addTrianglesDrawn(LEAF_INDICES); - stop_glerror(); - ret += LEAF_INDICES; - } - } - } - else - { - // - // Draw the tree as a single billboard texture - // - - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = - scale_mat.mMatrix[1][1] = - scale_mat.mMatrix[2][2] = mBillboardScale*mBillboardRatio; - - scale_mat *= matrix; - - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.translatef(0.0, -0.5, 0.0); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - gGL.loadMatrix((F32*) scale_mat.mMatrix); - gGL.syncMatrices(); - glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp); - gPipeline.addTrianglesDrawn(LEAF_INDICES); - stop_glerror(); - ret += LEAF_INDICES; - - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } - - return ret; -} - void LLVOTree::updateRadius() { if (mDrawable.isNull()) @@ -1370,8 +1267,8 @@ LLTreePartition::LLTreePartition() void LLVOTree::generateSilhouetteVertices(std::vector &vertices, std::vector &normals, const LLVector3& obj_cam_vec, - const LLMatrix4& local_matrix, - const LLMatrix3& normal_matrix) + const LLMatrix4a& local_matrix_, + const LLMatrix4a& normal_matrix) { vertices.clear(); normals.clear(); @@ -1379,6 +1276,8 @@ void LLVOTree::generateSilhouetteVertices(std::vector &vertices, F32 height = mBillboardScale; // *mBillboardRatio * 0.5; F32 width = height * mTrunkAspect; + LLMatrix4 local_matrix(local_matrix_.getF32ptr()); + LLVector3 position1 = LLVector3(-width * 0.5, 0, 0) * local_matrix; LLVector3 position2 = LLVector3(-width * 0.5, 0, height) * local_matrix; LLVector3 position3 = LLVector3(width * 0.5, 0, height) * local_matrix; @@ -1468,9 +1367,13 @@ void LLVOTree::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_poi // compose final matrix LLMatrix4 local_matrix; local_matrix.initAll(scale, rotation, position); + LLMatrix4a lmat; + lmat.loadu(local_matrix); + LLMatrix4a nmat; + nmat.setIdentity(); generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, - LLVector3(0, 0, 0), local_matrix, LLMatrix3()); + LLVector3(0, 0, 0), lmat, nmat); nodep->mSilhouetteExists = TRUE; } diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 4932c25d1..7fc46e0b9 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -85,24 +85,24 @@ public: void updateMesh(); - void appendMesh(LLStrider& vertices, - LLStrider& normals, + void appendMesh(LLStrider& vertices, + LLStrider& normals, LLStrider& tex_coords, LLStrider& indices, U16& idx_offset, - LLMatrix4& matrix, - LLMatrix4& norm_mat, + LLMatrix4a& matrix, + LLMatrix4a& norm_mat, S32 vertex_offset, S32 vertex_count, S32 index_count, S32 index_offset); - void genBranchPipeline(LLStrider& vertices, - LLStrider& normals, + void genBranchPipeline(LLStrider& vertices, + LLStrider& normals, LLStrider& tex_coords, LLStrider& indices, U16& index_offset, - LLMatrix4& matrix, + LLMatrix4a& matrix, S32 trunk_LOD, S32 stop_level, U16 depth, @@ -113,9 +113,6 @@ public: F32 branches, F32 alpha); - U32 drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, F32 alpha); - - /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, @@ -196,6 +193,8 @@ protected: U32 mFrameCount; + std::vector > mDrawList; + typedef std::map SpeciesMap; static SpeciesMap sSpeciesTable; @@ -210,8 +209,8 @@ private: void generateSilhouetteVertices(std::vector &vertices, std::vector &normals, const LLVector3& view_vec, - const LLMatrix4& mat, - const LLMatrix3& norm_mat); + const LLMatrix4a& mat, + const LLMatrix4a& norm_mat); }; #endif diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c73511f08..7010d8c7f 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -343,13 +343,13 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, mTextureAnimp = new LLViewerTextureAnim(this); mTexAnimMode = 0; } - else - { - if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) - { - mTextureAnimp->reset(); - } - } + else + { + if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) + { + mTextureAnimp->reset(); + } + } mTextureAnimp->unpackTAMessage(mesgsys, block_num); } @@ -564,29 +564,28 @@ void LLVOVolume::animateTextures() if (!facep->mTextureMatrix) { - facep->mTextureMatrix = new LLMatrix4(); + facep->mTextureMatrix = new LLMatrix4a(); } - LLMatrix4& tex_mat = *facep->mTextureMatrix; + LLMatrix4a& tex_mat = *facep->mTextureMatrix; tex_mat.setIdentity(); LLVector3 trans ; { - trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); + tex_mat.setTranslate_affine(LLVector3(-0.5f, -0.5f, 0.f)); } - LLVector3 scale(scale_s, scale_t, 1.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); + LLVector3 scale(scale_s, scale_t, 1.f); + + tex_mat.setMul(gGL.genRot(rot*RAD_TO_DEG,0.f,0.f,-1.f),tex_mat); //left mul - tex_mat.rotate(quat); + LLMatrix4a scale_mat; + scale_mat.setIdentity(); + scale_mat.applyScale_affine(scale); + tex_mat.setMul(scale_mat, tex_mat); //left mul - LLMatrix4 mat; - mat.initAll(scale, LLQuaternion(), LLVector3()); - tex_mat *= mat; - - tex_mat.translate(trans); - } + tex_mat.translate_affine(trans); + } } else { @@ -1510,93 +1509,53 @@ void LLVOVolume::updateRelativeXform(bool force_identity) { //rigged volume (which is in agent space) is used for generating bounding boxes etc //inverse of render matrix should go to partition space mRelativeXform = getRenderMatrix(); - - F32* dst = (F32*) mRelativeXformInvTrans.mMatrix; - F32* src = (F32*) mRelativeXform.mMatrix; - dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; - dst[3] = src[4]; dst[4] = src[5]; dst[5] = src[6]; - dst[6] = src[8]; dst[7] = src[9]; dst[8] = src[10]; - + mRelativeXformInvTrans = mRelativeXform; mRelativeXform.invert(); mRelativeXformInvTrans.transpose(); } else if (drawable->isActive() || force_identity) { // setup relative transforms - LLQuaternion delta_rot; - LLVector3 delta_pos, delta_scale; - - //matrix from local space to parent relative/global space + bool use_identity = force_identity || drawable->isSpatialRoot(); - delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation(); - delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition(); - delta_scale = mDrawable->getScale(); - // Vertex transform (4x4) - LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot; - LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot; - LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot; - - mRelativeXform.initRows(LLVector4(x_axis, 0.f), - LLVector4(y_axis, 0.f), - LLVector4(z_axis, 0.f), - LLVector4(delta_pos, 1.f)); - - - // compute inverse transpose for normals - // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); - // mRelativeXformInvTrans.invert(); - // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); - // grumble - invert is NOT a matrix invert, so we do it by hand: - - LLMatrix3 rot_inverse = LLMatrix3(~delta_rot); - - LLMatrix3 scale_inverse; - scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / delta_scale.mV[VX], - LLVector3(0.0, 1.0, 0.0) / delta_scale.mV[VY], - LLVector3(0.0, 0.0, 1.0) / delta_scale.mV[VZ]); - - - mRelativeXformInvTrans = rot_inverse * scale_inverse; + if(use_identity) + { + mRelativeXform.setIdentity(); + mRelativeXform.applyScale_affine(mDrawable->getScale()); + } + else + { + mRelativeXform = LLQuaternion2(mDrawable->getRotation()); + mRelativeXform.applyScale_affine(mDrawable->getScale()); + mRelativeXform.setTranslate_affine(mDrawable->getPosition()); + } + mRelativeXformInvTrans = mRelativeXform; + mRelativeXformInvTrans.invert(); mRelativeXformInvTrans.transpose(); } else { - LLVector3 pos = getPosition(); - LLVector3 scale = getScale(); - LLQuaternion rot = getRotation(); - + LLVector4a pos; + pos.load3(getPosition().mV); + LLQuaternion2 rot(getRotation()); if (mParent) { - pos *= mParent->getRotation(); - pos += mParent->getPosition(); - rot *= mParent->getRotation(); + LLMatrix4a lrot = LLQuaternion2(mParent->getRotation()); + lrot.rotate(pos,pos); + LLVector4a lpos; + lpos.load3(mParent->getPosition().mV); + pos.add(lpos); + rot.mul(LLQuaternion2(mParent->getRotation())); } - - //LLViewerRegion* region = getRegion(); - //pos += region->getOriginAgent(); - - LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot; - LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot; - LLVector3 z_axis = LLVector3(0.f, 0.f, scale.mV[VZ]) * rot; - mRelativeXform.initRows(LLVector4(x_axis, 0.f), - LLVector4(y_axis, 0.f), - LLVector4(z_axis, 0.f), - LLVector4(pos, 1.f)); - - // compute inverse transpose for normals - LLMatrix3 rot_inverse = LLMatrix3(~rot); - - LLMatrix3 scale_inverse; - scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / scale.mV[VX], - LLVector3(0.0, 1.0, 0.0) / scale.mV[VY], - LLVector3(0.0, 0.0, 1.0) / scale.mV[VZ]); - - - mRelativeXformInvTrans = rot_inverse * scale_inverse; + mRelativeXform = rot; + mRelativeXform.applyScale_affine(getScale()); + mRelativeXform.setTranslate_affine(LLVector3(pos.getF32ptr())); + mRelativeXformInvTrans = mRelativeXform; + mRelativeXformInvTrans.invert(); mRelativeXformInvTrans.transpose(); } } @@ -1734,11 +1693,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) // Update face flags updateFaceFlags(); - if(compiled) - { - LLPipeline::sCompiles++; - } - mVolumeChanged = FALSE; mLODChanged = FALSE; mSculptChanged = FALSE; @@ -3032,10 +2986,10 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p } updateRelativeXform(); - LLMatrix4 trans_mat = mRelativeXform; + LLMatrix4a trans_mat = mRelativeXform; if (mDrawable->isStatic()) { - trans_mat.translate(getRegion()->getOriginAgent()); + trans_mat.translate_affine(getRegion()->getOriginAgent()); } volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask()); @@ -3082,7 +3036,7 @@ BOOL LLVOVolume::isHUDAttachment() const } -const LLMatrix4 LLVOVolume::getRenderMatrix() const +const LLMatrix4a& LLVOVolume::getRenderMatrix() const { if (mDrawable->isActive() && !mDrawable->isRoot()) { @@ -3564,7 +3518,7 @@ void LLVOVolume::onShift(const LLVector4a &shift_vector) updateRelativeXform(); } -const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const +const LLMatrix4a& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const { if (mVolumeImpl) { @@ -3651,7 +3605,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() || LLFloaterInspect::instanceExists())) + if (allow_mesh_picking && (gFloaterTools->getVisible() || LLFloaterInspect::findInstance())) { updateRiggedVolume(); //genBBoxes(FALSE); @@ -3833,7 +3787,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& bool LLVOVolume::treatAsRigged() { - return (gFloaterTools->getVisible() || LLFloaterInspect::instanceExists()) && + return (gFloaterTools->getVisible() || LLFloaterInspect::findInstance()) && isAttachment() && mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED); @@ -3924,7 +3878,6 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons //build matrix palette LLMatrix4a mp[JOINT_COUNT]; - LLMatrix4* mat = (LLMatrix4*) mp; U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT); @@ -3939,8 +3892,9 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } if (joint) { - mat[j] = skin->mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); + LLMatrix4a mat; + mat.loadu((F32*)skin->mInvBindMatrix[j].mMatrix); + mp[j].setMul(joint->getWorldMatrix(), mat); } } @@ -4183,13 +4137,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, return; } - const LLMatrix4* tex_mat = NULL; + const LLMatrix4a* tex_mat = NULL; if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) { tex_mat = facep->mTextureMatrix; } - const LLMatrix4* model_mat = NULL; + const LLMatrix4a* model_mat = NULL; LLDrawable* drawable = facep->getDrawable(); @@ -4206,6 +4160,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, model_mat = &(drawable->getRegion()->mRenderMatrix); } + if(model_mat && model_mat->isIdentity()) + { + model_mat = NULL; + } + //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); @@ -4558,8 +4517,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) vobj->isMesh() && gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); - //bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); - bool is_rigged = false; static const LLCachedControl alt_batching("SHAltBatching",true); @@ -5577,8 +5534,6 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac LLViewerTexture* tex = facep->getTexture(); LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams(); - //bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic(); - static const LLCachedControl alt_batching("SHAltBatching",true); if (!alt_batching && distance_sort) { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 3b6955951..e70a6a64d 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -86,7 +86,7 @@ public: virtual bool isVolumeUnique() const = 0; // Do we need a unique LLVolume instance? virtual bool isVolumeGlobal() const = 0; // Are we in global space? virtual bool isActive() const = 0; // Is this object currently active? - virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0; + virtual const LLMatrix4a& getWorldMatrix(LLXformMatrix* xform) const = 0; virtual void updateRelativeXform(bool force_identity = false) = 0; virtual U32 getID() const = 0; virtual void preRebuild() = 0; @@ -113,6 +113,16 @@ public: (1 << LLVertexBuffer::TYPE_COLOR) }; + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + public: LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); /*virtual*/ void markDead(); // Override (and call through to parent) to clean up media references @@ -133,9 +143,9 @@ public: /*virtual*/ BOOL setParent(LLViewerObject* parent); S32 getLOD() const { return mLOD; } const LLVector3 getPivotPositionAgent() const; - const LLMatrix4& getRelativeXform() const { return mRelativeXform; } - const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } - /*virtual*/ const LLMatrix4 getRenderMatrix() const; + const LLMatrix4a& getRelativeXform() const { return mRelativeXform; } + const LLMatrix4a& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } + /*virtual*/ const LLMatrix4a& getRenderMatrix() const; typedef std::map texture_cost_t; U32 getRenderCost(texture_cost_t &textures) const; /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL, F32* unscaled_value = NULL) const; @@ -161,7 +171,7 @@ public: BOOL getVolumeChanged() const { return mVolumeChanged; } /*virtual*/ F32 getRadius() const { return mVObjRadius; }; - const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const; + const LLMatrix4a& getWorldMatrix(LLXformMatrix* xform) const; void markForUpdate(BOOL priority) { LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; } void faceMappingChanged() { mFaceMappingChanged=TRUE; }; @@ -365,8 +375,8 @@ private: BOOL mLODChanged; BOOL mSculptChanged; F32 mSpotLightPriority; - LLMatrix4 mRelativeXform; - LLMatrix3 mRelativeXformInvTrans; + LL_ALIGN_16(LLMatrix4a mRelativeXform); + LL_ALIGN_16(LLMatrix4a mRelativeXformInvTrans); BOOL mVolumeChanged; F32 mVObjRadius; LLVolumeInterface *mVolumeImpl; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index b4ab34d36..516429f22 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -247,7 +247,6 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) buff->flush(); mDrawable->movePartition(); - LLPipeline::sCompiles++; return TRUE; } diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index a0c303bf9..96239a22b 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -484,8 +484,6 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) updateStarColors(); updateStarGeometry(drawable); - LLPipeline::sCompiles++; - return TRUE; } diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 26303187d..6ba6a5ef9 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -390,24 +390,23 @@ void LLWaterParamManager::update(LLViewerCamera * cam) if(gPipeline.canUseVertexShaders()) { //transform water plane to eye space - glh::vec3f norm(0.f, 0.f, 1.f); - glh::vec3f p(0.f, 0.f, gAgent.getRegion()->getWaterHeight()+0.1f); + LLVector4a enorm(0.f, 0.f, 1.f); + LLVector4a ep(0.f, 0.f, gAgent.getRegion()->getWaterHeight()+0.1f); - F32 modelView[16]; - for (U32 i = 0; i < 16; i++) - { - modelView[i] = (F32) gGLModelView[i]; - } + const LLMatrix4a& mat = gGLModelView; + LLMatrix4a invtrans = mat; + invtrans.invert(); + invtrans.transpose(); - glh::matrix4f mat(modelView); - glh::matrix4f invtrans = mat.inverse().transpose(); - glh::vec3f enorm; - glh::vec3f ep; - invtrans.mult_matrix_vec(norm, enorm); - enorm.normalize(); - mat.mult_matrix_vec(p, ep); + invtrans.perspectiveTransform(enorm,enorm); + enorm.normalize3fast(); + mat.affineTransform(ep,ep); - mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); + ep.setAllDot3(ep,enorm); + ep.negate(); + enorm.copyComponent<3>(ep); + + mWaterPlane.set(enorm.getF32ptr()); LLVector3 sunMoonDir; if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index 514db939c..29a498777 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -41,23 +41,23 @@ #include "llagent.h" #include "llappviewer.h" #include "llfloaterwebcontent.h" +#include "hippogridmanager.h" #include "llparcel.h" #include "llsd.h" +#include "llalertdialog.h" #include "llui.h" #include "lluri.h" +#include "sgversion.h" #include "llviewercontrol.h" -#include "llviewermedia.h" #include "llviewernetwork.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llviewerwindow.h" #include "llnotificationsutil.h" -#include "llalertdialog.h" - -#include "sgversion.h" bool on_load_url_external_response(const LLSD& notification, const LLSD& response, bool async ); + class URLLoader : public LLAlertDialog::URLLoader { virtual void load(const std::string& url , bool force_open_externally) @@ -208,17 +208,11 @@ std::string LLWeb::escapeURL(const std::string& url) return escaped_url; } +std::string getLoginUriDomain(); //static std::string LLWeb::expandURLSubstitutions(const std::string &url, const LLSD &default_subs) { - gCurrentVersion = llformat("%s %d.%d.%d.%d", - gVersionChannel, - gVersionMajor, - gVersionMinor, - gVersionPatch, - gVersionBuild ); - LLSD substitution = default_subs; substitution["VERSION"] = gCurrentVersion; substitution["VERSION_MAJOR"] = gVersionMajor; @@ -226,8 +220,15 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url, substitution["VERSION_PATCH"] = gVersionPatch; substitution["VERSION_BUILD"] = gVersionBuild; substitution["CHANNEL"] = gVersionChannel; - substitution["GRID"] = LLViewerLogin::getInstance()->getGridLabel(); - substitution["GRID_LOWERCASE"] = utf8str_tolower(LLViewerLogin::getInstance()->getGridLabel()); + const HippoGridInfo* grid(gHippoGridManager->getCurrentGrid()); + std::string gridId(grid->isSecondLife() ? getLoginUriDomain() : grid->getGridName()); + if (grid->isSecondLife()) + { + gridId = gridId.substr(0, gridId.find('.')); + } + + substitution["GRID"] = gridId; + substitution["GRID_LOWERCASE"] = utf8str_tolower(gridId); substitution["OS"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple(); substitution["SESSION_ID"] = gAgent.getSessionID(); substitution["FIRST_LOGIN"] = gAgent.isFirstLogin(); diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index 75d60f985..eec761c85 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -69,20 +69,16 @@ public: { } - /*virtual*/ void completedRaw( - U32 status, - const std::string& reason, - const LLChannelDescriptors& channels, - const buffer_ptr_t& buffer) + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { LLBufferStream istr(channels, buffer.get()); std::stringstream strstrm; strstrm << istr.rdbuf(); const std::string body = strstrm.str(); - if (status != 200) + if (mStatus != HTTP_OK) { - llwarns << "Failed to get upload config (" << status << ")" << llendl; + llwarns << "Failed to get upload config (" << mStatus << ")" << llendl; LLWebProfile::reportImageUploadStatus(false); return; } @@ -133,15 +129,11 @@ class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient:: LOG_CLASS(LLWebProfileResponders::PostImageRedirectResponder); public: - /*virtual*/ void completedRaw( - U32 status, - const std::string& reason, - const LLChannelDescriptors& channels, - const buffer_ptr_t& buffer) + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { - if (status != 200) + if (mStatus != HTTP_OK) { - llwarns << "Failed to upload image: " << status << " " << reason << llendl; + llwarns << "Failed to upload image: " << mStatus << " " << mReason << llendl; LLWebProfile::reportImageUploadStatus(false); return; } @@ -173,35 +165,33 @@ class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::Responde public: /*virtual*/ bool needsHeaders(void) const { return true; } - /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& received_headers) + /*virtual*/ void completedHeaders(void) { // Server abuses 303 status; Curl can't handle it because it tries to resent // the just uploaded data, which fails // (CURLE_SEND_FAIL_REWIND: Send failed since rewinding of the data stream failed). // Handle it manually. - if (status == HTTP_SEE_OTHER) + if (mStatus == HTTP_SEE_OTHER) { AIHTTPHeaders headers; headers.addHeader("Accept", "*/*"); headers.addHeader("Cookie", LLWebProfile::getAuthCookie()); headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); std::string redir_url; - received_headers.getFirstValue("location", redir_url); + mReceivedHeaders.getFirstValue("location", redir_url); LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << LL_ENDL; LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers); } else { - llwarns << "Unexpected POST status: " << status << " " << reason << llendl; - LL_DEBUGS("Snapshots") << "received_headers: [" << received_headers << "]" << LL_ENDL; + llwarns << "Unexpected POST status: " << mStatus << " " << mReason << llendl; + LL_DEBUGS("Snapshots") << "received_headers: [" << mReceivedHeaders << "]" << LL_ENDL; LLWebProfile::reportImageUploadStatus(false); } } // Override just to suppress warnings. - /*virtual*/ void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const buffer_ptr_t& buffer) + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { } diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index e6eb7299c..33c9c3cf7 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -101,7 +101,7 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() { mID = ++sCount; } -/*virtual*/ void LLEnvironmentRequestResponder::result(const LLSD& unvalidated_content) +/*virtual*/ void LLEnvironmentRequestResponder::httpSuccess(void) { LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL; @@ -113,22 +113,22 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() { LL_WARNS("WindlightCaps") << "Ignoring responder. Current region is invalid." << LL_ENDL; } - else if (unvalidated_content[0]["regionID"].asUUID().isNull()) + else if (mContent[0]["regionID"].asUUID().isNull()) { LL_WARNS("WindlightCaps") << "Ignoring responder. Response from invalid region." << LL_ENDL; } - else if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + else if (mContent[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) { LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting " - << gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID() + << gAgent.getRegion()->getRegionID() << " but got " << mContent[0]["regionID"].asUUID() << ") - ignoring..." << LL_ENDL; } else { - LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content); + LLEnvManagerNew::getInstance()->onRegionSettingsResponse(mContent); } } -/*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason) +/*virtual*/ void LLEnvironmentRequestResponder::httpFailure(void) { LL_INFOS("WindlightCaps") << "Got an error, not using region windlight..." << LL_ENDL; LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD()); @@ -174,33 +174,33 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content) /**** * LLEnvironmentApplyResponder ****/ -/*virtual*/ void LLEnvironmentApplyResponder::result(const LLSD& content) +/*virtual*/ void LLEnvironmentApplyResponder::httpSuccess(void) { - if (content["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + if (mContent["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) { LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently " - << gAgent.getRegion()->getRegionID() << ", reply is from " << content["regionID"].asUUID() + << gAgent.getRegion()->getRegionID() << ", reply is from " << mContent["regionID"].asUUID() << "); ignoring..." << LL_ENDL; return; } - else if (content["success"].asBoolean()) + else if (mContent["success"].asBoolean()) { - LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << content["regionID"].asUUID() << LL_ENDL; + LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << mContent["regionID"].asUUID() << LL_ENDL; LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true); } else { - LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings! Reason from sim: " << content["fail_reason"].asString() << LL_ENDL; + LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings! Reason from sim: " << mContent["fail_reason"].asString() << LL_ENDL; LLSD args(LLSD::emptyMap()); - args["FAIL_REASON"] = content["fail_reason"].asString(); + args["FAIL_REASON"] = mContent["fail_reason"].asString(); LLNotificationsUtil::add("WLRegionApplyFail", args); LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false); } } -/*virtual*/ void LLEnvironmentApplyResponder::error(U32 status, const std::string& reason) +/*virtual*/ void LLEnvironmentApplyResponder::httpFailure(void) { std::stringstream msg; - msg << reason << " (Code " << status << ")"; + msg << mReason << " (Code " << mStatus << ")"; LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! Reason: " << msg.str() << LL_ENDL; diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h index cba1088f2..6194400a0 100644 --- a/indra/newview/llwlhandlers.h +++ b/indra/newview/llwlhandlers.h @@ -55,8 +55,8 @@ class LLEnvironmentRequestResponder: public LLHTTPClient::ResponderWithResult { LOG_CLASS(LLEnvironmentRequestResponder); public: - /*virtual*/ void result(const LLSD& content); - /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ void httpSuccess(void); + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return environmentRequestResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLEnvironmentRequestResponder"; } @@ -98,9 +98,9 @@ public: * fail_reason : string * } */ - /*virtual*/ void result(const LLSD& content); + /*virtual*/ void httpSuccess(void); - /*virtual*/ void error(U32 status, const std::string& reason); // non-200 errors only + /*virtual*/ void httpFailure(void); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return environmentApplyResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLEnvironmentApplyResponder"; } diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index af93ec553..8e1b1e4be 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -68,6 +68,7 @@ #include #include + // // Globals // @@ -160,18 +161,19 @@ void LLWorld::setRegionSize(const U32& width, const U32& length) mWidthInMeters = mWidth * mScale; } + LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) { llinfos << "Add region with handle: " << region_handle << " on host " << host << llendl; LLViewerRegion *regionp = getRegionFromHandle(region_handle); if (regionp) { - llinfos << "Region exists, removing it " << llendl; LLHost old_host = regionp->getHost(); // region already exists! if (host == old_host && regionp->isAlive()) { // This is a duplicate for the same host and it's alive, don't bother. + llinfos << "Region already exists and is alive, using existing region" << llendl; return regionp; } @@ -189,6 +191,10 @@ LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) // matches, because all the agent state for the new camera is completely different. removeRegion(old_host); } + else + { + llinfos << "Region does not exist, creating new one" << llendl; + } U32 iindex = 0; U32 jindex = 0; @@ -199,8 +205,8 @@ LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) S32 x = (S32)(iindex/256); //MegaRegion S32 y = (S32)(jindex/256); //MegaRegion // Aurora Sim - llinfos << "Adding new region (" << x << ":" << y << ")" << llendl; - llinfos << "Host: " << host << llendl; + llinfos << "Adding new region (" << x << ":" << y << ")" + << " on host: " << host << llendl; LLVector3d origin_global; @@ -272,7 +278,7 @@ LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) if (neighborp && last_neighborp != neighborp) { - //llinfos << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << llendl; + //LL_INFOS() << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << LL_ENDL; regionp->connectNeighbor(neighborp, dir); last_neighborp = neighborp; } @@ -341,6 +347,7 @@ void LLWorld::removeRegion(const LLHost &host) mVisibleRegionList.remove(regionp); mRegionRemovedSignal(regionp); + //double check all objects of this region are removed. gObjectList.clearAllMapObjectsInRegion(regionp) ; //llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ; @@ -1345,6 +1352,14 @@ static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim"); void process_enable_simulator(LLMessageSystem *msg, void **user_data) { LLFastTimer t(FTM_ENABLE_SIMULATOR); + + if (!gAgent.getRegion()) + return; + + static const LLCachedControl connectToNeighbors(gSavedSettings, "AlchemyConnectToNeighbors"); + if (!connectToNeighbors && ((gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL) || (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE))) + return; + // enable the appropriate circuit for this simulator and // add its values into the gSimulator structure U64 handle; @@ -1540,20 +1555,19 @@ void LLWorld::getAvatars(std::vector* avatar_ids, std::vectorisDead() && !pVOAvatar->isSelf() && !pVOAvatar->mIsDummy) { + LLVector3d pos_global = pVOAvatar->getPositionGlobal(); LLUUID uuid = pVOAvatar->getID(); - if(!uuid.isNull()) + + if (!uuid.isNull() + && dist_vec_squared(pos_global, relative_to) <= radius_squared) { - LLVector3d pos_global = pVOAvatar->getPositionGlobal(); - if(dist_vec_squared(pos_global, relative_to) <= radius_squared) + if(positions != NULL) { - if(positions != NULL) - { - positions->push_back(pos_global); - } - if(avatar_ids !=NULL) - { - avatar_ids->push_back(uuid); - } + positions->push_back(pos_global); + } + if(avatar_ids !=NULL) + { + avatar_ids->push_back(uuid); } } } diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 4c02d875e..2d76879e2 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -525,6 +525,13 @@ void LLWorldMapView::draw() llfloor(left + 3), llfloor(bottom + 2), LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); + static const LLCachedControl show_region_positions("SFMapShowRegionPositions"); + if (show_region_positions) + font->renderUTF8( + llformat("(%d, %d)", llfloor(info->getGlobalOrigin().mdV[VX]/256), llfloor(info->getGlobalOrigin().mdV[VY])/256), 0, + llfloor(left + 3), llfloor(bottom + 14), + LLColor4::white, + LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); } } } diff --git a/indra/newview/llxmlrpcresponder.cpp b/indra/newview/llxmlrpcresponder.cpp index 6fbc05ca1..2dbfa9148 100644 --- a/indra/newview/llxmlrpcresponder.cpp +++ b/indra/newview/llxmlrpcresponder.cpp @@ -163,15 +163,15 @@ void XMLRPCResponder::completed_headers(U32 status, std::string const& reason, A mTransferInfo = *info; } // Call base class implementation. - LegacyPolledResponder::completed_headers(status, reason, info); + ResponderWithCompleted::completed_headers(status, reason, info); } -void XMLRPCResponder::completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) +void XMLRPCResponder::completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { - if (mCode == CURLE_OK && !is_internal_http_error(status)) + if (mCode == CURLE_OK && !is_internal_http_error(mStatus)) { mBufferSize = buffer->count(channels.in()); - if (200 <= status && status < 400) + if (200 <= mStatus && mStatus < 400) { char* ptr = NULL; char* buf = NULL; diff --git a/indra/newview/llxmlrpcresponder.h b/indra/newview/llxmlrpcresponder.h index 4a5f29077..5ee44794b 100644 --- a/indra/newview/llxmlrpcresponder.h +++ b/indra/newview/llxmlrpcresponder.h @@ -90,7 +90,7 @@ private: XMLRPC_VALUE mV; }; -class XMLRPCResponder : public LLHTTPClient::LegacyPolledResponder { +class XMLRPCResponder : public LLHTTPClient::ResponderWithCompleted { private: AITransferInfo mTransferInfo; S32 mBufferSize; @@ -110,7 +110,7 @@ public: /*virtual*/ bool forbidReuse(void) const { return true; } /*virtual*/ void received_HTTP_header(void) { mReceivedHTTPHeader = true; LLHTTPClient::ResponderBase::received_HTTP_header(); } /*virtual*/ void completed_headers(U32 status, std::string const& reason, AITransferInfo* info); - /*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer); + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return XMLRPCResponder_timeout; } /*virtual*/ char const* getName(void) const { return "XMLRPCResponder"; } }; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4e40e2a89..7af2dc21e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -153,7 +153,7 @@ const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f; const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40; const S32 MAX_OFFSCREEN_GEOMETRY_CHANGES_PER_FRAME = 10; const U32 REFLECTION_MAP_RES = 128; -const U32 DEFERRED_VB_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; +const U32 AUX_VB_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; // Max number of occluders to search for. JC const S32 MAX_OCCLUDER_COUNT = 2; @@ -170,7 +170,7 @@ BOOL gAvatarBacklight = FALSE; BOOL gDebugPipeline = FALSE; LLPipeline gPipeline; -const LLMatrix4* gGLLastMatrix = NULL; +const LLMatrix4a* gGLLastMatrix = NULL; LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Geometry"); LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass"); @@ -249,67 +249,49 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size); U32 nhpo2(U32 v); LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage); -glh::matrix4f glh_copy_matrix(F32* src) +const LLMatrix4a& glh_get_current_modelview() { - glh::matrix4f ret; - ret.set_value(src); - return ret; + return gGLModelView; } -glh::matrix4f glh_get_current_modelview() +const LLMatrix4a& glh_get_current_projection() { - return glh_copy_matrix(gGLModelView); + return gGLProjection; } -glh::matrix4f glh_get_current_projection() +inline const LLMatrix4a& glh_get_last_modelview() { - return glh_copy_matrix(gGLProjection); + return gGLLastModelView; } -glh::matrix4f glh_get_last_modelview() +inline const LLMatrix4a& glh_get_last_projection() { - return glh_copy_matrix(gGLLastModelView); + return gGLLastProjection; } -glh::matrix4f glh_get_last_projection() +void glh_set_current_modelview(const LLMatrix4a& mat) { - return glh_copy_matrix(gGLLastProjection); + gGLModelView = mat; } -void glh_copy_matrix(const glh::matrix4f& src, F32* dst) +void glh_set_current_projection(const LLMatrix4a& mat) { - for (U32 i = 0; i < 16; i++) - { - dst[i] = src.m[i]; - } + gGLProjection = mat; } -void glh_set_current_modelview(const glh::matrix4f& mat) +inline void glh_set_last_modelview(const LLMatrix4a& mat) { - glh_copy_matrix(mat, gGLModelView); + gGLLastModelView = mat; } -void glh_set_current_projection(glh::matrix4f& mat) +void glh_set_last_projection(const LLMatrix4a& mat) { - glh_copy_matrix(mat, gGLProjection); -} - -glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar) -{ - glh::matrix4f ret( - 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left), - 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom), - 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear), - 0.f, 0.f, 0.f, 1.f); - - return ret; + gGLLastProjection = mat; } void display_update_camera(bool tiling=false); //---------------------------------------- -S32 LLPipeline::sCompiles = 0; - BOOL LLPipeline::sPickAvatar = TRUE; BOOL LLPipeline::sDynamicLOD = TRUE; BOOL LLPipeline::sShowHUDAttachments = TRUE; @@ -329,7 +311,6 @@ BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE; BOOL LLPipeline::sAutoMaskAlphaNonDeferred = FALSE; BOOL LLPipeline::sDisableShaders = FALSE; BOOL LLPipeline::sRenderBump = TRUE; -BOOL LLPipeline::sBakeSunlight = FALSE; BOOL LLPipeline::sNoAlpha = FALSE; BOOL LLPipeline::sUseFarClip = TRUE; BOOL LLPipeline::sShadowRender = FALSE; @@ -348,7 +329,7 @@ BOOL LLPipeline::sRenderDeferred = FALSE; BOOL LLPipeline::sMemAllocationThrottled = FALSE; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; -BOOL LLPipeline::sRenderingHUDs; +BOOL LLPipeline::sRenderingHUDs = FALSE; static LLCullResult* sCull = NULL; @@ -383,10 +364,6 @@ LLPipeline::LLPipeline() : mMeanBatchSize(0), mTrianglesDrawn(0), mNumVisibleNodes(0), - mVerticesRelit(0), - mLightingChanges(0), - mGeometryChanges(0), - mNumVisibleFaces(0), mInitialized(FALSE), mVertexShadersEnabled(FALSE), @@ -600,7 +577,7 @@ void LLPipeline::cleanup() mInitialized = FALSE; - mDeferredVB = NULL; + mAuxScreenRectVB = NULL; mCubeVB = NULL; } @@ -798,6 +775,8 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) { + mAuxScreenRectVB = NULL; + refreshCachedSettings(); U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); if (res_mod > 1 && res_mod < resX && res_mod < resY) @@ -1837,11 +1816,6 @@ void LLPipeline::resetFrameStats() mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount; } mTrianglesDrawn = 0; - sCompiles = 0; - mVerticesRelit = 0; - mLightingChanges = 0; - mGeometryChanges = 0; - mNumVisibleFaces = 0; if (mOldRenderDebugMask != mRenderDebugMask) { @@ -2339,11 +2313,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); - gGL.loadMatrix(gGLLastProjection); + gGL.loadMatrix(glh_get_last_projection()); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); gGLLastMatrix = NULL; - gGL.loadMatrix(gGLLastModelView); + gGL.loadMatrix(glh_get_last_modelview()); LLGLDisable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); @@ -2378,8 +2352,8 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl } } - glh::matrix4f modelview = glh_get_last_modelview(); - glh::matrix4f proj = glh_get_last_projection(); + const LLMatrix4a& modelview = glh_get_last_modelview(); + const LLMatrix4a& proj = glh_get_last_projection(); LLGLUserClipPlane clip(plane, modelview, proj, water_clip != 0 && LLPipeline::sReflectionRender); LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -2558,18 +2532,6 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d dest.bindTarget(); dest.clear(GL_DEPTH_BUFFER_BIT); - - if(mDeferredVB.isNull()) - { - 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); - } if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE) { @@ -2590,8 +2552,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d { LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } dest.flush(); @@ -2684,7 +2645,6 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) if (update_complete && assertInitialized()) { drawablep->setState(LLDrawable::BUILT); - mGeometryChanges++; } return update_complete; } @@ -3474,9 +3434,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } } - - - mNumVisibleFaces += drawablep->getNumFaces(); } @@ -4105,17 +4062,14 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) assertInitialized(); - F32 saved_modelview[16]; - F32 saved_projection[16]; + LLMatrix4a saved_modelview; + LLMatrix4a saved_projection; //HACK: preserve/restore matrices around HUD render if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { - for (U32 i = 0; i < 16; i++) - { - saved_modelview[i] = gGLModelView[i]; - saved_projection[i] = gGLProjection[i]; - } + saved_modelview = glh_get_current_modelview(); + saved_projection = glh_get_current_projection(); } /////////////////////////////////////////// @@ -4219,7 +4173,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { occlude = FALSE; gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); LLGLSLShader::bindNoShader(); doOcclusion(camera); } @@ -4230,7 +4184,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLFastTimer t(FTM_POOLRENDER); gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); for( S32 i = 0; i < poolp->getNumPasses(); i++ ) { @@ -4279,13 +4233,13 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLVertexBuffer::unbind(); gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); if (occlude) { occlude = FALSE; gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); LLGLSLShader::bindNoShader(); doOcclusion(camera); } @@ -4348,11 +4302,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) //HACK: preserve/restore matrices around HUD render if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { - for (U32 i = 0; i < 16; i++) - { - gGLModelView[i] = saved_modelview[i]; - gGLProjection[i] = saved_projection[i]; - } + glh_set_current_modelview(saved_modelview); + glh_set_current_projection(saved_projection); } } @@ -4414,7 +4365,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) LLFastTimer t(FTM_DEFERRED_POOLRENDER); gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) { @@ -4458,7 +4409,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) } gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); gGL.setColorMask(true, false); } @@ -4491,7 +4442,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) { occlude = FALSE; gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); LLGLSLShader::bindNoShader(); doOcclusion(camera/*, mScreen, mOcclusionDepth, &mDeferredDepth*/); gGL.setColorMask(true, false); @@ -4503,7 +4454,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) LLFastTimer t(FTM_POST_DEFERRED_POOLRENDER); gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ ) { @@ -4545,17 +4496,17 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) } gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); if (occlude) { occlude = FALSE; gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); LLGLSLShader::bindNoShader(); doOcclusion(camera); gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); } } @@ -4581,7 +4532,7 @@ void LLPipeline::renderGeomShadow(LLCamera& camera) poolp->prerender() ; gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ ) { @@ -4620,7 +4571,7 @@ void LLPipeline::renderGeomShadow(LLCamera& camera) } gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); } @@ -4695,7 +4646,7 @@ void LLPipeline::renderPhysicsDisplay() if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) { gGL.pushMatrix(); - gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + gGL.multMatrix(bridge->mDrawable->getRenderMatrix()); bridge->renderPhysicsShapes(); gGL.popMatrix(); } @@ -4720,7 +4671,7 @@ void LLPipeline::renderDebug() gGL.color4f(1,1,1,1); gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); gGL.setColorMask(true, false); bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); @@ -4797,7 +4748,7 @@ void LLPipeline::renderDebug() if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) { gGL.pushMatrix(); - gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + gGL.multMatrix(bridge->mDrawable->getRenderMatrix()); bridge->renderDebug(); gGL.popMatrix(); } @@ -4992,7 +4943,7 @@ void LLPipeline::renderDebug() gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); gGL.pushMatrix(); - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); gGLLastMatrix = NULL; for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) @@ -5013,7 +4964,7 @@ void LLPipeline::renderDebug() if (bridge) { gGL.pushMatrix(); - gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + gGL.multMatrix(bridge->mDrawable->getRenderMatrix()); } F32 alpha = llclamp((F32) (size-count)/size, 0.f, 1.f); @@ -5409,13 +5360,15 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) if (for_edit) { LLColor4 diffuse(1.f, 1.f, 1.f, 0.f); - LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light - LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); - LLMatrix4 camera_rot(camera_mat.getMat3()); + LLVector4a light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light + LLMatrix4a camera_rot = LLViewerCamera::getInstance()->getModelview(); + camera_rot.extractRotation_affine(); camera_rot.invert(); - LLVector4 light_pos = light_pos_cam * camera_rot; + LLVector4a light_pos; - light_pos.normalize(); + camera_rot.rotate(light_pos_cam,light_pos); + + light_pos.normalize3fast(); LLLightState* light = gGL.getLight(1); @@ -5424,7 +5377,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) light->setDiffuse(diffuse); light->setAmbient(LLColor4::black); light->setSpecular(LLColor4::black); - light->setPosition(light_pos); + light->setPosition(LLVector4(light_pos.getF32ptr())); light->setConstantAttenuation(1.f); light->setLinearAttenuation(0.f); light->setQuadraticAttenuation(0.f); @@ -5528,11 +5481,11 @@ void LLPipeline::resetLocalLights() pLight->setConstantAttenuation(0.f); pLight->setDiffuse(LLColor4::black); pLight->setLinearAttenuation(0.f); - pLight->setPosition(LLVector4(0.f,0.f,0.f,0.f)); + pLight->setPosition(LLVector4(0.f,0.f,1.f,0.f)); pLight->setQuadraticAttenuation(0.f); pLight->setSpecular(LLColor4::black); pLight->setSpotCutoff(0.f); - pLight->setSpotDirection(LLVector3(0.f,0.f,0.f)); + pLight->setSpotDirection(LLVector3(0.f,0.f,-1.f)); pLight->setSpotExponent(0.f); pLight->disable(); } @@ -6801,7 +6754,7 @@ void LLPipeline::doResetVertexBuffers() mResetVertexBuffers = false; mCubeVB = NULL; - mDeferredVB = NULL; + mAuxScreenRectVB = NULL; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -6846,7 +6799,6 @@ void LLPipeline::doResetVertexBuffers() LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable"); LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs;// && gSavedSettings.getBOOL("RenderVBOMappingDisable") ; //Temporary workaround for vbo mapping being straight up broken - sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight"); sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); @@ -6858,48 +6810,58 @@ void LLPipeline::doResetVertexBuffers() void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture) { assertInitialized(); - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); gGLLastMatrix = NULL; mSimplePool->pushBatches(type, mask, texture, batch_texture); - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); gGLLastMatrix = NULL; } void LLPipeline::renderMaskedObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture) { assertInitialized(); - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); gGLLastMatrix = NULL; mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); gGLLastMatrix = NULL; } void apply_cube_face_rotation(U32 face) { + static const LLMatrix4a x_90 = gGL.genRot( 90.f, 1.f, 0.f, 0.f ); + static const LLMatrix4a y_90 = gGL.genRot( 90.f, 0.f, 1.f, 0.f ); + static const LLMatrix4a x_90_neg = gGL.genRot( -90.f, 1.f, 0.f, 0.f ); + static const LLMatrix4a y_90_neg = gGL.genRot( -90.f, 0.f, 1.f, 0.f ); + + static const LLMatrix4a x_180 = gGL.genRot( 180.f, 1.f, 0.f, 0.f ); + static const LLMatrix4a y_180 = gGL.genRot( 180.f, 0.f, 1.f, 0.f ); + static const LLMatrix4a z_180 = gGL.genRot( 180.f, 0.f, 0.f, 1.f ); + switch (face) { case 0: - gGL.rotatef(90.f, 0, 1, 0); - gGL.rotatef(180.f, 1, 0, 0); + + gGL.rotatef(y_90); + gGL.rotatef(x_180); break; case 2: - gGL.rotatef(-90.f, 1, 0, 0); + gGL.rotatef(x_90_neg); break; case 4: - gGL.rotatef(180.f, 0, 1, 0); - gGL.rotatef(180.f, 0, 0, 1); + gGL.rotatef(y_180); + gGL.rotatef(z_180); break; case 1: - gGL.rotatef(-90.f, 0, 1, 0); - gGL.rotatef(180.f, 1, 0, 0); + gGL.rotatef(y_90_neg); + gGL.rotatef(x_180); break; case 3: - gGL.rotatef(90, 1, 0, 0); + gGL.rotatef(x_90); break; case 5: - gGL.rotatef(180, 0, 0, 1); + gGL.rotatef(z_180); break; } } @@ -6981,10 +6943,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b //U32 res_mod = RenderResolutionDivisor;//.get(); - LLVector2 tc1(0,0); - LLVector2 tc2((F32) mScreen.getWidth()*2, - (F32) mScreen.getHeight()*2); - /*if (res_mod > 1) { tc2 /= (F32) res_mod; @@ -7029,29 +6987,36 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b llassert(zoom_factor > 0.0); // Non-zero, non-negative. const F32 tile_size = 1.0/zoom_factor; - tc1 = tile*tile_size; // Top left texture coordinates - tc2 = (tile+LLVector2(1,1))*tile_size; // Bottom right texture coordinates + LLVector2 tc1 = tile*tile_size; // Top left texture coordinates + LLVector2 tc2 = (tile+LLVector2(1,1))*tile_size; // Bottom right texture coordinates LLGLEnable blend(GL_BLEND); gGL.setSceneBlendType(LLRender::BT_ADD); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.color4f(1,1,1,1); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,1); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(1,-1); - - gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); - gGL.vertex2f(1,1); + + LLPointer buff = new LLVertexBuffer(AUX_VB_MASK, 0); + buff->allocateBuffer(4, 0, true); + LLStrider vert; + LLStrider texcoord0, texcoord1; + buff->getVertexStrider(vert); + buff->getTexCoord0Strider(texcoord0); + buff->getTexCoord1Strider(texcoord1); - gGL.end(); + vert[0].set(-1.f,-1.f,0.f); + vert[1].set(-1.f,1.f,0.f); + vert[2].set(1.f,-1.f,0.f); + vert[3].set(1.f,1.f,0.f); + + //Texcoord 0 is actually for texture 1, which is unbound and thus all components = 0,0,0,0. Just zero out the texcoords. + texcoord0[0] = texcoord0[1] = texcoord0[2] = texcoord0[3] = LLVector2::zero; + + texcoord1[0].set(tc1.mV[0], tc1.mV[1]); + texcoord1[1].set(tc1.mV[0], tc2.mV[1]); + texcoord1[2].set(tc2.mV[0], tc1.mV[1]); + texcoord1[3].set(tc2.mV[0], tc2.mV[1]); + + buff->setBuffer(AUX_VB_MASK); + buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 4); - gGL.flush(); gGL.setSceneBlendType(LLRender::BT_ALPHA); } @@ -7095,26 +7060,14 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGL.color4f(1,1,1,1); gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); - 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(); + + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); gGL.getTexUnit(0)->unbind(mScreen.getUsage()); mGlow[1].flush(); } - tc1.setVec(0,0); - tc2.setVec(2,2); - // power of two between 1 and 1024 U32 glowResPow = RenderGlowResolutionPow; const U32 glow_res = llmax(1, @@ -7152,17 +7105,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); } - 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(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD1); mGlow[i%2].flush(); } @@ -7181,9 +7124,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - tc2.setVec((F32) mScreen.getWidth(), - (F32) mScreen.getHeight()); - gGL.flush(); LLVertexBuffer::unbind(); @@ -7325,17 +7265,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - 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(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); unbindDeferredShader(*shader); mDeferredLight.flush(); @@ -7360,17 +7290,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - 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(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); unbindDeferredShader(*shader); mScreen.flush(); @@ -7414,17 +7334,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1); shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1); - 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(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); unbindDeferredShader(*shader); @@ -7457,17 +7367,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); } - 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(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); unbindDeferredShader(*shader); @@ -7497,13 +7397,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b mDeferredLight.bindTexture(0, channel); } - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex2f(-1,-1); - gGL.vertex2f(-1,3); - gGL.vertex2f(3,-1); - gGL.end(); - - gGL.flush(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); shader->unbind(); @@ -7533,13 +7427,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y); shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y); - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex2f(-1,-1); - gGL.vertex2f(-1,3); - gGL.vertex2f(3,-1); - gGL.end(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); - gGL.flush(); shader->unbind(); } } @@ -7550,32 +7439,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b tc2 /= (F32) res_mod; }*/ - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; - LLPointer buff = new LLVertexBuffer(mask, 0); - buff->allocateBuffer(3,0,TRUE); - - LLStrider v; - LLStrider uv1; - LLStrider uv2; - - buff->getVertexStrider(v); - buff->getTexCoord0Strider(uv1); - buff->getTexCoord1Strider(uv2); - - uv1[0] = LLVector2(0, 0); - uv1[1] = LLVector2(0, 2); - uv1[2] = LLVector2(2, 0); - - uv2[0] = LLVector2(0, 0); - uv2[1] = LLVector2(0, tc2.mV[1]*2.f); - uv2[2] = LLVector2(tc2.mV[0]*2.f, 0); - - v[0] = LLVector3(-1,-1,0); - v[1] = LLVector3(-1,3,0); - v[2] = LLVector3(3,-1,0); - - buff->flush(); - LLGLDisable blend(GL_BLEND); if (LLGLSLShader::sNoFixedFunction) @@ -7595,8 +7458,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - buff->setBuffer(mask); - buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1); if (LLGLSLShader::sNoFixedFunction) { @@ -7624,27 +7486,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGL.setColorMask(true, false); - LLVector2 tc1(0,0); - LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, - (F32) gViewerWindow->getWorldViewHeightRaw()*2); - LLGLEnable blend(GL_BLEND); gGL.color4f(1,1,1,0.75f); gGL.getTexUnit(0)->bind(&mPhysicsDisplay); - gGL.begin(LLRender::TRIANGLES); - 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(); - gGL.flush(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); if (LLGLSLShader::sNoFixedFunction) { @@ -7747,10 +7594,10 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n stop_glerror(); - glh::matrix4f projection = glh_get_current_projection(); - glh::matrix4f inv_proj = projection.inverse(); + LLMatrix4a inv_proj = glh_get_current_projection(); + inv_proj.invert(); - shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); + shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.getF32ptr()); shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0], (F32) gGLViewport[1], (F32) gGLViewport[2], @@ -7834,18 +7681,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n if(shader.getUniformLocation(LLShaderMgr::DEFERRED_SHADOW_MATRIX) >= 0) { - F32 mat[16*6]; - for (U32 i = 0; i < 16; i++) - { - mat[i] = mSunShadowMatrix[0].m[i]; - mat[i+16] = mSunShadowMatrix[1].m[i]; - mat[i+32] = mSunShadowMatrix[2].m[i]; - mat[i+48] = mSunShadowMatrix[3].m[i]; - mat[i+64] = mSunShadowMatrix[4].m[i]; - mat[i+80] = mSunShadowMatrix[5].m[i]; - } - - shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mat); + shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mSunShadowMatrix[0].getF32ptr()); stop_glerror(); } @@ -7858,7 +7694,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n { cube_map->enable(channel); cube_map->bind(); - F32* m = gGLModelView; + const F32* m = glh_get_current_modelview().getF32ptr(); F32 mat[] = { m[0], m[1], m[2], m[4], m[5], m[6], @@ -7893,7 +7729,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset); shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias); - shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV); + shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.getF32ptr()); shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mShadow[0].getWidth(), mShadow[0].getHeight()); shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight()); shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff); @@ -7902,8 +7738,10 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0) { - glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); - shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m); + LLMatrix4a norm_mat = glh_get_current_modelview(); + norm_mat.invert(); + norm_mat.transpose(); + shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.getF32ptr()); } shader.uniform1f(LLShaderMgr::DEFERRED_DOWNSAMPLED_DEPTH_SCALE, llclamp(RenderSSAOResolutionScale.get(),.01f,1.f)); @@ -7968,26 +7806,10 @@ void LLPipeline::renderDeferredLighting() LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); - glh::matrix4f mat = glh_copy_matrix(gGLModelView); - - if(mDeferredVB.isNull()) - { - 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); - } - { setupHWLights(NULL); //to set mSunDir; - LLVector4 dir(mSunDir, 0.f); - glh::vec4f tc(dir.mV); - mat.mult_matrix_vec(tc); - mTransformedSunDir.set(tc.v); + mTransformedSunDir.load3(mSunDir.mV); + glh_get_current_modelview().rotate(mTransformedSunDir,mTransformedSunDir); } gGL.pushMatrix(); @@ -8009,12 +7831,9 @@ void LLPipeline::renderDeferredLighting() mDeferredDownsampledDepth.clear(GL_DEPTH_BUFFER_BIT); bindDeferredShader(gDeferredDownsampleDepthNearestProgram, 0); gDeferredDownsampleDepthNearestProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredDownsampledDepth.getWidth()/ssao_scale, mDeferredDownsampledDepth.getHeight()/ssao_scale); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); { LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } mDeferredDownsampledDepth.flush(); unbindDeferredShader(gDeferredDownsampleDepthNearestProgram); @@ -8032,12 +7851,9 @@ void LLPipeline::renderDeferredLighting() glViewport(0,0,mDeferredDownsampledDepth.getWidth(),mDeferredDownsampledDepth.getHeight()); gDeferredSSAOProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredDownsampledDepth.getWidth()/ssao_scale, mDeferredDownsampledDepth.getHeight()/ssao_scale); } - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); { LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } mScreen.flush(); unbindDeferredShader(gDeferredSSAOProgram); @@ -8050,47 +7866,10 @@ void LLPipeline::renderDeferredLighting() { //paint shadow/SSAO light map (direct lighting lightmap) LLFastTimer ftm(FTM_SUN_SHADOW); bindDeferredShader(gDeferredSunProgram, 0); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); glClearColor(1,1,1,1); mDeferredLight.clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); - /*glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); - - const U32 slice = 32; - F32 offset[slice*3]; - for (U32 i = 0; i < 4; i++) - { - for (U32 j = 0; j < 8; j++) - { - glh::vec3f v; - v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); -#if 0 - // Singu note: the call to mult_matrix_vec can crash, because it attempts to divide by zero. - v.normalize(); - inv_trans.mult_matrix_vec(v); -#else - // However, because afterwards we normalize the vector anyway, there is an alternative - // way to calculate the same thing without the division (which happens to be faster, too). - glh::vec4f src(v, v.length()); // Make a copy of the source and extent it with its length. - glh::vec4f dst; - inv_trans.mult_matrix_vec(src, dst); // Do a normal 4D multiplication. - dst.get_value(v[0], v[1], v[2], dst[3]); // Copy the first 3 coordinates to v. - // At this point v is equal to what it used to be, except for a constant factor (v.length() * dst[3]), - // but that doesn't matter because the next step is normalizaton. The old computation would crash - // if v.length() is zero in the commented out v.normalize(), and in inv_trans.mult_matrix_vec(v) - // if dst[3] is zero (which some times happens). Now we will only crash if v.length() is zero - // and well in the next line (but this never happens). --Aleric -#endif - v.normalize(); - offset[(i*8+j)*3+0] = v.v[0]; - offset[(i*8+j)*3+1] = v.v[2]; - offset[(i*8+j)*3+2] = v.v[1]; - } - } - - gDeferredSunProgram.uniform3fv(sOffset, slice, offset);*/ - gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight()); //Enable bilinear filtering, as the screen tex resolution may not match current framebuffer resolution. Eg, half-res SSAO @@ -8105,9 +7884,7 @@ void LLPipeline::renderDeferredLighting() { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } if (channel > -1) @@ -8131,7 +7908,6 @@ void LLPipeline::renderDeferredLighting() glClearColor(0,0,0,0); bindDeferredShader(gDeferredBlurLightProgram); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); LLVector3 go = RenderShadowGaussian; const U32 kern_length = 4; F32 blur_size = RenderShadowBlurSize; @@ -8158,16 +7934,13 @@ void LLPipeline::renderDeferredLighting() { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } mScreen.flush(); unbindDeferredShader(gDeferredBlurLightProgram); bindDeferredShader(gDeferredBlurLightProgram, 1); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); mDeferredLight.bindTarget(); gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); @@ -8175,9 +7948,7 @@ void LLPipeline::renderDeferredLighting() { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } mDeferredLight.flush(); unbindDeferredShader(gDeferredBlurLightProgram); @@ -8212,9 +7983,7 @@ void LLPipeline::renderDeferredLighting() gGL.pushMatrix(); gGL.loadIdentity(); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); gGL.popMatrix(); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -8353,11 +8122,12 @@ void LLPipeline::renderDeferredLighting() fullscreen_spot_lights.push_back(drawablep); continue; } - - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); + + glh_get_current_modelview().affineTransform(center,center); + + LLVector4 tc(center.getF32ptr()); + tc.mV[VW] = s; + fullscreen_lights.push_back(tc); light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); } } @@ -8446,8 +8216,7 @@ void LLPipeline::renderDeferredLighting() gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); far_z = 0.f; count = 0; - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); unbindDeferredShader(gDeferredMultiLightProgram[idx]); } } @@ -8456,8 +8225,6 @@ void LLPipeline::renderDeferredLighting() gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) { LLFastTimer ftm(FTM_PROJECTORS); @@ -8465,14 +8232,13 @@ void LLPipeline::renderDeferredLighting() LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); F32 s = volume->getLightRadius()*1.5f; sVisibleLightCount++; - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); + glh_get_current_modelview().affineTransform(center,center); setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); @@ -8482,11 +8248,11 @@ void LLPipeline::renderDeferredLighting() col.mV[1] = powf(col.mV[1], 2.2f); col.mV[2] = powf(col.mV[2], 2.2f);*/ - gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, center.getF32ptr()); gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); @@ -8518,7 +8284,6 @@ void LLPipeline::renderDeferredLighting() mScreen.bindTarget(); // Apply gamma correction to the frame here. gDeferredPostGammaCorrectProgram.bind(); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); S32 channel = 0; channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); if (channel > -1) @@ -8529,7 +8294,7 @@ void LLPipeline::renderDeferredLighting() gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight()); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); gGL.getTexUnit(channel)->unbind(mScreen.getUsage()); gDeferredPostGammaCorrectProgram.unbind(); @@ -8643,21 +8408,10 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); - glh::matrix4f mat = glh_copy_matrix(gGLModelView); - - 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); - glh::vec4f tc(dir.mV); - mat.mult_matrix_vec(tc); - mTransformedSunDir.set(tc.v); + mTransformedSunDir.load3(mSunDir.mV); + glh_get_current_modelview().rotate(mTransformedSunDir,mTransformedSunDir); } gGL.pushMatrix(); @@ -8679,12 +8433,9 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) mDeferredDownsampledDepth.clear(GL_DEPTH_BUFFER_BIT); bindDeferredShader(gDeferredDownsampleDepthNearestProgram, 0); gDeferredDownsampleDepthNearestProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredDownsampledDepth.getWidth()/ssao_scale, mDeferredDownsampledDepth.getHeight()/ssao_scale); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); { LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } mDeferredDownsampledDepth.flush(); unbindDeferredShader(gDeferredDownsampleDepthNearestProgram); @@ -8702,12 +8453,9 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) glViewport(0,0,mDeferredDownsampledDepth.getWidth(),mDeferredDownsampledDepth.getHeight()); gDeferredSSAOProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredDownsampledDepth.getWidth()/ssao_scale, mDeferredDownsampledDepth.getHeight()/ssao_scale); } - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); { LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } mScreen.flush(); unbindDeferredShader(gDeferredSSAOProgram); @@ -8720,31 +8468,10 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) { //paint shadow/SSAO light map (direct lighting lightmap) LLFastTimer ftm(FTM_SUN_SHADOW); bindDeferredShader(gDeferredSunProgram); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); glClearColor(1,1,1,1); mDeferredLight.clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); - /*glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); - - const U32 slice = 32; - F32 offset[slice*3]; - for (U32 i = 0; i < 4; i++) - { - for (U32 j = 0; j < 8; j++) - { - glh::vec3f v; - v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); - v.normalize(); - inv_trans.mult_matrix_vec(v); - v.normalize(); - offset[(i*8+j)*3+0] = v.v[0]; - offset[(i*8+j)*3+1] = v.v[2]; - offset[(i*8+j)*3+2] = v.v[1]; - } - } - - gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset);*/ gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight()); //Enable bilinear filtering, as the screen tex resolution may not match current framebuffer resolution. Eg, half-res SSAO @@ -8759,9 +8486,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } if (channel > -1) @@ -8804,9 +8529,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) gGL.pushMatrix(); gGL.loadIdentity(); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); gGL.popMatrix(); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -8950,10 +8673,11 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) continue; } - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); + glh_get_current_modelview().affineTransform(center,center); + + LLVector4 tc(center.getF32ptr()); + tc.mV[VW] = s; + fullscreen_lights.push_back(tc); light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); } } @@ -9002,12 +8726,6 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) 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); @@ -9051,8 +8769,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); far_z = 0.f; count = 0; - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } } @@ -9062,8 +8779,6 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) { LLFastTimer ftm(FTM_PROJECTORS); @@ -9071,14 +8786,13 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); F32 s = volume->getLightRadius()*1.5f; sVisibleLightCount++; - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); + glh_get_current_modelview().affineTransform(center,center); setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); @@ -9088,11 +8802,11 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) col.mV[1] = powf(col.mV[1], 2.2f); col.mV[2] = powf(col.mV[2], 2.2f);*/ - gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, center.getF32ptr()); gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + drawFullScreenRect(LLVertexBuffer::MAP_VERTEX); } gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); @@ -9227,12 +8941,14 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) LLVector3 origin = np - at_axis*dist; //matrix from volume space to agent space - LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); + LLMatrix4 light_mat_(quat, LLVector4(origin,1.f)); - glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); - glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent; - - glh::matrix4f screen_to_light = light_to_screen.inverse(); + LLMatrix4a light_mat; + light_mat.loadu(light_mat_.mMatrix[0]); + LLMatrix4a light_to_screen; + light_to_screen.setMul(glh_get_current_modelview(),light_mat); + LLMatrix4a screen_to_light = light_to_screen; + screen_to_light.invert(); F32 s = volume->getLightRadius()*1.5f; F32 near_clip = dist; @@ -9243,31 +8959,29 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) F32 fovy = fov * RAD_TO_DEG; F32 aspect = width/height; - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); + LLVector4a p1(0, 0, -(near_clip+0.01f)); + LLVector4a p2(0, 0, -(near_clip+1.f)); - glh::vec3f p1(0, 0, -(near_clip+0.01f)); - glh::vec3f p2(0, 0, -(near_clip+1.f)); + LLVector4a screen_origin(LLVector4a::getZero()); - glh::vec3f screen_origin(0, 0, 0); + light_to_screen.affineTransform(p1,p1); + light_to_screen.affineTransform(p2,p2); + light_to_screen.affineTransform(screen_origin,screen_origin); - light_to_screen.mult_matrix_vec(p1); - light_to_screen.mult_matrix_vec(p2); - light_to_screen.mult_matrix_vec(screen_origin); + LLVector4a n; + n.setSub(p2,p1); + n.normalize3fast(); - glh::vec3f n = p2-p1; - n.normalize(); - F32 proj_range = far_clip - near_clip; - glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip); - screen_to_light = trans * light_proj * screen_to_light; - shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.m); + LLMatrix4a light_proj = gGL.genPersp(fovy, aspect, near_clip, far_clip); + light_proj.setMul(gGL.genNDCtoWC(),light_proj); + screen_to_light.setMul(light_proj,screen_to_light); + + shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.getF32ptr()); shader.uniform1f(LLShaderMgr::PROJECTOR_NEAR, near_clip); - shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.v); - shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.v); - shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.v); + shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.getF32ptr()); + shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.getF32ptr()); + shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.getF32ptr()); shader.uniform1f(LLShaderMgr::PROJECTOR_RANGE, proj_range); shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIANCE, params.mV[2]); S32 s_idx = -1; @@ -9418,8 +9132,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.pushRenderTypeMask(); - glh::matrix4f projection = glh_get_current_projection(); - glh::matrix4f mat; + const LLMatrix4a projection = glh_get_current_projection(); stop_glerror(); LLPlane plane; @@ -9474,24 +9187,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.pushMatrix(); - mat.set_scale(glh::vec3f(1,1,-1)); - mat.set_translate(glh::vec3f(0,0,height*2.f)); + const LLMatrix4a saved_modelview = glh_get_current_modelview(); - glh::matrix4f current = glh_get_current_modelview(); - - mat = current * mat; + LLMatrix4a mat; + mat.setIdentity(); + mat.getRow<2>().negate(); + mat.setTranslate_affine(LLVector3(0.f,0.f,height*2.f)); + mat.setMul(saved_modelview,mat); glh_set_current_modelview(mat); - gGL.loadMatrix(mat.m); + gGL.loadMatrix(mat); LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE); - glh::matrix4f inv_mat = mat.inverse(); + LLMatrix4a inv_mat = mat; + inv_mat.invert(); - glh::vec3f origin(0,0,0); - inv_mat.mult_matrix_vec(origin); + LLVector4a origin; + origin.clear(); + inv_mat.affineTransform(origin,origin); - camera.setOrigin(origin.v); + camera.setOrigin(origin.getF32ptr()); glCullFace(GL_FRONT); @@ -9598,7 +9314,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glCullFace(GL_BACK); gGL.popMatrix(); mWaterRef.flush(); - glh_set_current_modelview(current); + glh_set_current_modelview(saved_modelview); LLPipeline::sUseOcclusion = occlusion; } @@ -9639,10 +9355,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) { //clip out geometry on the same side of water as the camera - mat = glh_get_current_modelview(); LLPlane plane(-pnorm, -(pd+pad)); - LLGLUserClipPlane clip_plane(plane, mat, projection); + LLGLUserClipPlane clip_plane(plane, glh_get_current_modelview(), projection); static LLCullResult result; updateCull(camera, result, water_clip, &plane); stateSort(camera, result); @@ -9707,77 +9422,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } } -glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) -{ - glh::matrix4f ret; - - LLVector3 dirN; - LLVector3 upN; - LLVector3 lftN; - - lftN = dir % up; - lftN.normVec(); - - upN = lftN % dir; - upN.normVec(); - - dirN = dir; - dirN.normVec(); - - ret.m[ 0] = lftN[0]; - ret.m[ 1] = upN[0]; - ret.m[ 2] = -dirN[0]; - ret.m[ 3] = 0.f; - - ret.m[ 4] = lftN[1]; - ret.m[ 5] = upN[1]; - ret.m[ 6] = -dirN[1]; - ret.m[ 7] = 0.f; - - ret.m[ 8] = lftN[2]; - ret.m[ 9] = upN[2]; - ret.m[10] = -dirN[2]; - ret.m[11] = 0.f; - - ret.m[12] = -(lftN*pos); - ret.m[13] = -(upN*pos); - ret.m[14] = dirN*pos; - ret.m[15] = 1.f; - - return ret; -} - -glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) -{ - glh::matrix4f ret; - ret.m[ 0] = 2/(max[0]-min[0]); - ret.m[ 4] = 0; - ret.m[ 8] = 0; - ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]); - - ret.m[ 1] = 0; - ret.m[ 5] = 2/(max[1]-min[1]); - ret.m[ 9] = 0; - ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]); - - ret.m[ 2] = 0; - ret.m[ 6] = 0; - ret.m[10] = 2/(max[2]-min[2]); - ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]); - - ret.m[ 3] = 0; - ret.m[ 7] = 0; - ret.m[11] = 0; - ret.m[15] = 1; - - return ret; -} - static LLFastTimer::DeclareTimer FTM_SHADOW_RENDER("Render Shadows"); static LLFastTimer::DeclareTimer FTM_SHADOW_ALPHA("Alpha Shadow"); static LLFastTimer::DeclareTimer FTM_SHADOW_SIMPLE("Simple Shadow"); -void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion, U32 target_width) +void LLPipeline::renderShadow(const LLMatrix4a& view, const LLMatrix4a& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion, U32 target_width) { LLFastTimer t(FTM_SHADOW_RENDER); @@ -9824,10 +9473,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera //generate shadow map gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); - gGL.loadMatrix(proj.m); + gGL.loadMatrix(proj); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(view); //Why was glh_get_current_modelview() used instead of view? stop_glerror(); gGLLastMatrix = NULL; @@ -9906,7 +9555,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gDeferredShadowCubeProgram.bind(); gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(glh_get_current_modelview()); //LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1]; @@ -10135,13 +9784,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON); } - F64 last_modelview[16]; - F64 last_projection[16]; - for (U32 i = 0; i < 16; i++) - { //store last_modelview of world camera - last_modelview[i] = gGLLastModelView[i]; - last_projection[i] = gGLLastProjection[i]; - } + LLMatrix4a last_modelview = glh_get_last_modelview(); + LLMatrix4a last_projection = glh_get_last_projection(); pushRenderTypeMask(); andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, @@ -10187,13 +9831,14 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //get sun view matrix //store current projection/modelview matrix - glh::matrix4f saved_proj = glh_get_current_projection(); - glh::matrix4f saved_view = glh_get_current_modelview(); - glh::matrix4f inv_view = saved_view.inverse(); + const LLMatrix4a saved_proj = glh_get_current_projection(); + const LLMatrix4a saved_view = glh_get_current_modelview(); + LLMatrix4a inv_view(saved_view); + inv_view.invert(); + + LLMatrix4a view[6]; + LLMatrix4a proj[6]; - glh::matrix4f view[6]; - glh::matrix4f proj[6]; - //clip contains parallel split distances for 3 splits LLVector3 clip = RenderShadowClipPlanes; @@ -10202,9 +9847,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //far clip on last split is minimum of camera view distance and 128 mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); - clip = RenderShadowOrthoClipPlanes; - mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); - //currently used for amount to extrude frusta corners for constructing shadow frusta //LLVector3 n = RenderShadowNearDist; //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; @@ -10220,8 +9862,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLVector3 lightDir = -mSunDir; lightDir.normVec(); - glh::vec3f light_dir(lightDir.mV); - //create light space camera matrix LLVector3 at = lightDir; @@ -10278,9 +9918,10 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //get good split distances for frustum for (U32 i = 0; i < fp.size(); ++i) { - glh::vec3f v(fp[i].mV); - saved_view.mult_matrix_vec(v); - fp[i].setVec(v.v); + LLVector4a v; + v.load3(fp[i].mV); + saved_view.affineTransform(v,v); + fp[i].setVec(v.getF32ptr()); } min = fp[0]; @@ -10402,9 +10043,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } mShadow[j].flush(); - mShadowError.mV[j] = 0.f; - mShadowFOV.mV[j] = 0.f; - continue; } @@ -10420,15 +10058,16 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLVector3 origin; //get a temporary view projection - view[j] = look(camera.getOrigin(), lightDir, -up); + view[j] = gGL.genLook(camera.getOrigin(), lightDir, -up); std::vector wpf; for (U32 i = 0; i < fp.size(); i++) { - glh::vec3f p = glh::vec3f(fp[i].mV); - view[j].mult_matrix_vec(p); - wpf.push_back(LLVector3(p.v)); + LLVector4a p; + p.load3(fp[i].mV); + view[j].affineTransform(p,p); + wpf.push_back(LLVector3(p.getF32ptr())); } min = wpf[0]; @@ -10513,24 +10152,21 @@ void LLPipeline::generateSunShadow(LLCamera& camera) bfb = lp.mV[1]-bfm*lp.mV[0]; //calculate error - mShadowError.mV[j] = 0.f; + F32 shadow_error = 0.f; for (U32 i = 0; i < wpf.size(); ++i) { F32 lx = (wpf[i].mV[1]-bfb)/bfm; - mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); + shadow_error += fabsf(wpf[i].mV[0]-lx); } - mShadowError.mV[j] /= wpf.size(); - mShadowError.mV[j] /= size.mV[0]; + shadow_error /= wpf.size(); + shadow_error /= size.mV[0]; - if (mShadowError.mV[j] > RenderShadowErrorCutoff) + if (shadow_error > RenderShadowErrorCutoff) { //just use ortho projection - mShadowFOV.mV[j] = -1.f; origin.clearVec(); - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); + proj[j] = gGL.genOrtho(min.mV[0], max.mV[0], min.mV[1], max.mV[1], -max.mV[2], -min.mV[2]); } else { @@ -10569,8 +10205,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f); - mShadowFOV.mV[j] = fovx; - if (fovx < cutoff && fovz > cutoff) { //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff @@ -10598,7 +10232,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) fovx = acos(fovx); fovz = acos(fovz); - mShadowFOV.mV[j] = cutoff; } @@ -10618,37 +10251,29 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (fovx > cutoff) { //just use ortho projection origin.clearVec(); - mShadowError.mV[j] = -1.f; - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); + proj[j] = gGL.genOrtho(min.mV[0], max.mV[0], min.mV[1], max.mV[1], -max.mV[2], -min.mV[2]); } else { //get perspective projection - view[j] = view[j].inverse(); + view[j].invert(); + LLVector4a origin_agent; + origin_agent.load3(origin.mV); - glh::vec3f origin_agent(origin.mV); - //translate view to origin - view[j].mult_matrix_vec(origin_agent); + view[j].affineTransform(origin_agent,origin_agent); - eye = LLVector3(origin_agent.v); + eye = LLVector3(origin_agent.getF32ptr()); - if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowFrustOrigin[j] = eye; - } - - view[j] = look(LLVector3(origin_agent.v), lightDir, -up); + view[j] = gGL.genLook(LLVector3(origin_agent.getF32ptr()), lightDir, -up); F32 fx = 1.f/tanf(fovx); F32 fz = 1.f/tanf(fovz); - proj[j] = glh::matrix4f(-fx, 0, 0, 0, - 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), - 0, 0, -fz, 0, - 0, -1.f, 0, 0); + proj[j].setRow<0>(LLVector4a( -fx, 0.f, 0.f)); + proj[j].setRow<1>(LLVector4a( 0.f, (yfar+ynear)/(ynear-yfar), 0.f, -1.f)); + proj[j].setRow<2>(LLVector4a( 0.f, 0.f, -fz)); + proj[j].setRow<3>(LLVector4a( 0.f, (2.f*yfar*ynear)/(ynear-yfar), 0.f)); } } } @@ -10666,26 +10291,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip); - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); - glh_set_current_modelview(view[j]); glh_set_current_projection(proj[j]); - for (U32 i = 0; i < 16; i++) - { - gGLLastModelView[i] = mShadowModelview[j].m[i]; - gGLLastProjection[i] = mShadowProjection[j].m[i]; - } + glh_set_last_modelview(mShadowModelview[j]); + glh_set_last_projection(mShadowProjection[j]); mShadowModelview[j] = view[j]; mShadowProjection[j] = proj[j]; - - mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; + + mSunShadowMatrix[j].setMul(gGL.genNDCtoWC(),proj[j]); + mSunShadowMatrix[j].mul_affine(view[j]); + mSunShadowMatrix[j].mul_affine(inv_view); stop_glerror(); @@ -10791,9 +10409,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLMatrix4 mat(quat, LLVector4(origin, 1.f)); - view[i+4] = glh::matrix4f((F32*) mat.mMatrix); + view[i+4].loadu(mat.mMatrix[0]); - view[i+4] = view[i+4].inverse(); + view[i+4].invert(); //get perspective matrix F32 near_clip = dist+0.01f; @@ -10803,29 +10421,22 @@ void LLPipeline::generateSunShadow(LLCamera& camera) F32 fovy = fov * RAD_TO_DEG; F32 aspect = width/height; - - proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); + proj[i+4] = gGL.genPersp(fovy, aspect, near_clip, far_clip); glh_set_current_modelview(view[i+4]); glh_set_current_projection(proj[i+4]); - mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; - - for (U32 j = 0; j < 16; j++) - { - gGLLastModelView[j] = mShadowModelview[i+4].m[j]; - gGLLastProjection[j] = mShadowProjection[i+4].m[j]; - } + glh_set_last_modelview(mShadowModelview[i+4]); + glh_set_last_projection(mShadowProjection[i+4]); mShadowModelview[i+4] = view[i+4]; mShadowProjection[i+4] = proj[i+4]; + mSunShadowMatrix[i+4].setMul(gGL.genNDCtoWC(),proj[i+4]); + mSunShadowMatrix[i+4].mul_affine(view[i+4]); + mSunShadowMatrix[i+4].mul_affine(inv_view); + LLCamera shadow_cam = camera; shadow_cam.setFar(far_clip); shadow_cam.setOrigin(origin); @@ -10864,18 +10475,15 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { glh_set_current_modelview(view[1]); glh_set_current_projection(proj[1]); - gGL.loadMatrix(view[1].m); + gGL.loadMatrix(view[1]); gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadMatrix(proj[1].m); + gGL.loadMatrix(proj[1]); gGL.matrixMode(LLRender::MM_MODELVIEW); } gGL.setColorMask(true, false); - for (U32 i = 0; i < 16; i++) - { - gGLLastModelView[i] = last_modelview[i]; - gGLLastProjection[i] = last_projection[i]; - } + glh_set_last_modelview(last_modelview); + glh_set_last_projection(last_projection); popRenderTypeMask(); @@ -11034,18 +10642,19 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) F32 distance = (pos-camera.getOrigin()).length(); F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; F32 aspect = tdim.mV[0]/tdim.mV[1]; - glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); + LLMatrix4a persp = gGL.genPersp(fov, aspect, 1.f, 256.f); glh_set_current_projection(persp); - gGL.loadMatrix(persp.m); + gGL.loadMatrix(persp); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); - glh::matrix4f mat; - camera.getOpenGLTransform(mat.m); + LLMatrix4a mat; + camera.getOpenGLTransform(mat.getF32ptr()); - mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; + mat.setMul(OGL_TO_CFR_ROTATION, mat); + + gGL.loadMatrix(mat); - gGL.loadMatrix(mat.m); glh_set_current_modelview(mat); glClearColor(0.0f,0.0f,0.0f,0.0f); @@ -11458,3 +11067,31 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id ) } */ +void LLPipeline::drawFullScreenRect(U32 data_mask) +{ + if(mAuxScreenRectVB.isNull()) + { + mAuxScreenRectVB = new LLVertexBuffer(AUX_VB_MASK, 0); + mAuxScreenRectVB->allocateBuffer(3, 0, true); + LLStrider vert; + LLStrider tc0, tc1; + mAuxScreenRectVB->getVertexStrider(vert); + mAuxScreenRectVB->getTexCoord0Strider(tc0); + mAuxScreenRectVB->getTexCoord1Strider(tc1); + + vert[0].set(-1.f,-1.f,0.f); + vert[1].set(3.f,-1.f,0.f); + vert[2].set(-1.f,3.f,0.f); + + tc0[0].set(0.f, 0.f); + tc0[1].set(mScreen.getWidth()*2.f, 0.f); + tc0[2].set(0.f, mScreen.getHeight()*2.f); + + tc1[0].set(0.f, 0.f); + tc1[1].set(2.f, 0.f); + tc1[2].set(0.f, 2.f); + } + mAuxScreenRectVB->setBuffer(data_mask); + mAuxScreenRectVB->drawArrays(LLRender::TRIANGLES, 0, 3); +} + diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index da5e6a6b3..589c2a3e4 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -81,14 +81,10 @@ BOOL compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon = 0); BOOL setup_hud_matrices(); // use whole screen to render hud BOOL setup_hud_matrices(const LLRect& screen_region); // specify portion of screen (in pixels) to render hud attachments from (for picking) -glh::matrix4f glh_copy_matrix(F32* src); -glh::matrix4f glh_get_current_modelview(); -void glh_set_current_modelview(const glh::matrix4f& mat); -glh::matrix4f glh_get_current_projection(); -void glh_set_current_projection(glh::matrix4f& mat); -glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar); -glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); -glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up); +const LLMatrix4a& glh_get_current_modelview(); +void glh_set_current_modelview(const LLMatrix4a& mat); +const LLMatrix4a& glh_get_current_projection(); +void glh_set_current_projection(const LLMatrix4a& mat); extern LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY; extern LLFastTimer::DeclareTimer FTM_RENDER_GRASS; @@ -112,6 +108,7 @@ extern LLFastTimer::DeclareTimer FTM_PIPELINE; extern LLFastTimer::DeclareTimer FTM_CLIENT_COPY; +LL_ALIGN_PREFIX(16) class LLPipeline { public: @@ -306,7 +303,7 @@ public: void generateSunShadow(LLCamera& camera); - void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader, BOOL use_occlusion, U32 target_width); + void renderShadow(const LLMatrix4a& view, const LLMatrix4a& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader, BOOL use_occlusion, U32 target_width); void renderHighlights(); void renderDebug(); void renderPhysicsDisplay(); @@ -434,6 +431,8 @@ private: bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; }; void hideDrawable( LLDrawable *pDrawable ); void unhideDrawable( LLDrawable *pDrawable ); + + void drawFullScreenRect( U32 data_mask ); public: enum {GPU_CLASS_MAX = 3 }; @@ -552,11 +551,6 @@ public: LLSpatialPartition* getSpatialPartition(LLViewerObject* vobj); - void updateCamera(BOOL reset = FALSE); - - LLVector3 mFlyCamPosition; - LLQuaternion mFlyCamRotation; - BOOL mBackfaceCull; S32 mBatchCount; S32 mMatrixOpCount; @@ -566,18 +560,6 @@ public: S32 mMeanBatchSize; S32 mTrianglesDrawn; S32 mNumVisibleNodes; - S32 mVerticesRelit; - - S32 mDebugTextureUploadCost; - S32 mDebugSculptUploadCost; - S32 mDebugMeshUploadCost; - - S32 mLightingChanges; - S32 mGeometryChanges; - - S32 mNumVisibleFaces; - - static S32 sCompiles; static BOOL sShowHUDAttachments; static BOOL sForceOldBakedUpload; // If true will not use capabilities to upload baked textures. @@ -587,7 +569,6 @@ public: static BOOL sAutoMaskAlphaNonDeferred; static BOOL sDisableShaders; // if TRUE, rendering will be done without shaders static BOOL sRenderBump; - static BOOL sBakeSunlight; static BOOL sNoAlpha; static BOOL sUseFarClip; static BOOL sShadowRender; @@ -610,61 +591,57 @@ public: static F32 sMinRenderSize; static BOOL sRenderingHUDs; - //screen texture +public: + //screen texture LLRenderTarget mScreen; LLRenderTarget mDeferredScreen; +private: LLRenderTarget mFXAABuffer; - LLRenderTarget mEdgeMap; +public: LLRenderTarget mDeferredDepth; +private: LLRenderTarget mDeferredDownsampledDepth; LLRenderTarget mOcclusionDepth; LLRenderTarget mDeferredLight; +public: LLMultisampleBuffer mSampleBuffer; +private: LLRenderTarget mPhysicsDisplay; //utility buffer for rendering post effects, gets abused by renderDeferredLighting - LLPointer mDeferredVB; + LLPointer mAuxScreenRectVB; +public: //utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1] LLPointer mCubeVB; +private: //sun shadow map LLRenderTarget mShadow[6]; LLRenderTarget mShadowOcclusion[6]; std::vector mShadowFrustPoints[4]; - LLVector4 mShadowError; - LLVector4 mShadowFOV; - LLVector3 mShadowFrustOrigin[4]; +public: LLCamera mShadowCamera[8]; +private: LLVector3 mShadowExtents[4][2]; - glh::matrix4f mSunShadowMatrix[6]; - glh::matrix4f mShadowModelview[6]; - glh::matrix4f mShadowProjection[6]; - glh::matrix4f mGIMatrix; - glh::matrix4f mGIMatrixProj; - glh::matrix4f mGIModelview; - glh::matrix4f mGIProjection; - glh::matrix4f mGINormalMatrix; - glh::matrix4f mGIInvProj; - LLVector2 mGIRange; - F32 mGILightRadius; + LLMatrix4a mSunShadowMatrix[6]; + LLMatrix4a mShadowModelview[6]; + LLMatrix4a mShadowProjection[6]; LLPointer mShadowSpotLight[2]; F32 mSpotLightFade[2]; LLPointer mTargetShadowSpotLight[2]; LLVector4 mSunClipPlanes; - LLVector4 mSunOrthoClipPlanes; - - LLVector2 mScreenScale; - +public: //water reflection texture LLRenderTarget mWaterRef; //water distortion texture (refraction) LLRenderTarget mWaterDis; +private: //texture for making the glow LLRenderTarget mGlow[2]; @@ -675,14 +652,15 @@ public: LLColor4 mSunDiffuse; LLVector3 mSunDir; - LLVector3 mTransformedSunDir; + LL_ALIGN_16(LLVector4a mTransformedSunDir); +public: BOOL mInitialized; BOOL mVertexShadersEnabled; S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback -protected: +private: BOOL mRenderTypeEnabled[NUM_RENDER_TYPES]; std::stack mRenderTypeEnableStack; @@ -847,13 +825,13 @@ public: //debug use static U32 sCurRenderPoolType ; -}; +} LL_ALIGN_POSTFIX(16); void render_bbox(const LLVector3 &min, const LLVector3 &max); void render_hud_elements(); extern LLPipeline gPipeline; extern BOOL gDebugPipeline; -extern const LLMatrix4* gGLLastMatrix; +extern const LLMatrix4a* gGLLastMatrix; #endif diff --git a/indra/newview/qtoolalign.cpp b/indra/newview/qtoolalign.cpp index 2b09c7cf2..240bbffcb 100644 --- a/indra/newview/qtoolalign.cpp +++ b/indra/newview/qtoolalign.cpp @@ -123,7 +123,7 @@ BOOL QToolAlign::findSelectedManipulator(S32 x, S32 y) { LLVector4 translation(mBBox.getCenterAgent()); transform.initRotTrans(mBBox.getRotation(), translation); - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + LLMatrix4 cfr(OGL_TO_CFR_ROTATION.getF32ptr()); transform *= cfr; LLMatrix4 window_scale; F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom; @@ -136,8 +136,8 @@ BOOL QToolAlign::findSelectedManipulator(S32 x, S32 y) { transform.initAll(LLVector3(1.f, 1.f, 1.f), mBBox.getRotation(), mBBox.getCenterAgent()); - LLMatrix4 projection_matrix = LLViewerCamera::getInstance()->getProjection(); - LLMatrix4 model_matrix = LLViewerCamera::getInstance()->getModelview(); + LLMatrix4 projection_matrix( LLViewerCamera::getInstance()->getProjection().getF32ptr() ); + LLMatrix4 model_matrix( LLViewerCamera::getInstance()->getModelview().getF32ptr() ); transform *= model_matrix; transform *= projection_matrix; diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 2ea2646cb..b746cda4a 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -21,9 +21,11 @@ #include "rlvhandler.h" // ============================================================================ -// RlvActions member functions +// Communication/Avatar interaction // +bool RlvActions::s_BlockNamesContexts[SNC_COUNT] = { 0 }; + // Checked: 2010-11-30 (RLVa-1.3.0) bool RlvActions::canReceiveIM(const LLUUID& idSender) { @@ -60,6 +62,10 @@ bool RlvActions::canStartIM(const LLUUID& idRecipient) ( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIMTO)) || (!gRlvHandler.isException(RLV_BHVR_STARTIMTO, idRecipient)) ) ); } +// ============================================================================ +// Movement +// + // Checked: 2010-12-11 (RLVa-1.2.2) bool RlvActions::canAcceptTpOffer(const LLUUID& idSender) { @@ -84,6 +90,10 @@ bool RlvActions::autoAcceptTeleportRequest(const LLUUID& idRequester) return ((idRequester.notNull()) && (gRlvHandler.isException(RLV_BHVR_ACCEPTTPREQUEST, idRequester))) || (gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTPREQUEST)); } +// ============================================================================ +// World interaction +// + // Checked: 2010-03-07 (RLVa-1.2.0) bool RlvActions::canStand() { @@ -97,6 +107,10 @@ bool RlvActions::canShowLocation() return !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC); } +// ============================================================================ +// Helper functions +// + // Checked: 2013-05-10 (RLVa-1.4.9) bool RlvActions::hasBehaviour(ERlvBehaviour eBhvr) { diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index 58d90780a..fbc8ab12b 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -25,9 +25,9 @@ class RlvActions { - // ============= - // Communication - // ============= + // ================================ + // Communication/Avatar interaction + // ================================ public: /* * Returns true if the user is allowed to receive IMs from the specified sender (can be an avatar or a group) @@ -44,6 +44,19 @@ public: */ static bool canStartIM(const LLUUID& idRecipient); // @startim and @startimto + /* + * Returns true if an avatar's name should be hidden for the requested operation/context + * (This is used to hide an avatar name in one case but not a near-identical case - such as teleporting a friend vs a nearby agent - + * in a way that limits the amount of code that needs to be changed to carry context from one function to another) + */ + enum EShowNamesContext { SNC_TELEPORTOFFER = 0, SNC_TELEPORTREQUEST, SNC_COUNT }; + static bool canShowName(EShowNamesContext eContext) { return (eContext < SNC_COUNT) ? !s_BlockNamesContexts[eContext] : false; } + static void setShowName(EShowNamesContext eContext, bool fShowName) { if ( (eContext < SNC_COUNT) && (isRlvEnabled()) ) { s_BlockNamesContexts[eContext] = !fShowName; } } + +protected: + // Backwards logic so that we can initialize to 0 and it won't block when we forget to/don't check if RLVa is disabled + static bool s_BlockNamesContexts[SNC_COUNT]; + // ======== // Movement // ======== diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp index aa1f83153..46327d8c2 100644 --- a/indra/newview/rlvui.cpp +++ b/indra/newview/rlvui.cpp @@ -261,8 +261,12 @@ void RlvUIEnabler::onToggleShowLoc() { bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC); - // RELEASE-RLVa: [SL-2.0.1] Check that the code below still evaluates to *only* LLNavigationBar::instance().mCmbLocation->refresh() - //LLAppViewer::instance()->handleLoginComplete(); + /* Singu TODO: LLNavigationBar + if (LLNavigationBar::instanceExists()) + LLNavigationBar::instance().refreshLocationCtrl(); + if (LLPanelTopInfoBar::instanceExists()) + LLPanelTopInfoBar::instance().update(); + */ if (!fEnable) { diff --git a/indra/llcommon/roles_constants.h b/indra/newview/roles_constants.h similarity index 98% rename from indra/llcommon/roles_constants.h rename to indra/newview/roles_constants.h index aa7ea3e5f..a75ad6b5b 100644 --- a/indra/llcommon/roles_constants.h +++ b/indra/newview/roles_constants.h @@ -53,7 +53,7 @@ enum LLRoleChangeType // KNOWN HOLES: use these for any single bit powers you need // bit 0x1 << 46 -// bit 0x1 << 49 and above +// bit 0x1 << 52 and above // These powers were removed to make group roles simpler // bit 0x1 << 41 (GP_ACCOUNTING_VIEW) @@ -146,6 +146,9 @@ const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session +// Group Banning +const U64 GP_GROUP_BAN_ACCESS = 0x1LL << 51; // Allows access to ban / un-ban agents from a group. + const U64 GP_DEFAULT_MEMBER = GP_ACCOUNTING_ACCOUNTABLE | GP_LAND_ALLOW_SET_HOME | GP_NOTICES_RECEIVE diff --git a/indra/newview/scriptcounter.cpp b/indra/newview/scriptcounter.cpp index 3d9ea682f..f8d2aafd4 100644 --- a/indra/newview/scriptcounter.cpp +++ b/indra/newview/scriptcounter.cpp @@ -34,6 +34,7 @@ #include "scriptcounter.h" #include "llavatarnamecache.h" +#include "llviewerregion.h" #include "llselectmgr.h" #include "lltrans.h" #include "llvoavatar.h" @@ -54,13 +55,19 @@ namespace } } +std::map ScriptCounter::sCheckMap; + ScriptCounter::ScriptCounter(bool do_delete, LLViewerObject* object) -: doDelete(do_delete) +: LLInstanceTracker(object->getID()) +, doDelete(do_delete) , foo(object) , inventories() , objectCount() , requesting(true) , scriptcount() +, checking() +, mRunningCount() +, mMonoCount() { llassert(foo); // Object to ScriptCount must not be null } @@ -152,15 +159,47 @@ void ScriptCounter::inventoryChanged(LLViewerObject* obj, LLInventoryObject::obj end = inv->end(); } } + else + { + const LLUUID& id = asset->getUUID(); + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_GetScriptRunning); + msg->nextBlockFast(_PREHASH_Script); + msg->addUUIDFast(_PREHASH_ObjectID, obj->getID()); + msg->addUUIDFast(_PREHASH_ItemID, id); + msg->sendReliable(obj->getRegion()->getHost()); + sCheckMap[id] = this; + ++checking; + } } } + summarize(); +} + +void ScriptCounter::processRunningReply(LLMessageSystem* msg) +{ + BOOL is; + msg->getBOOLFast(_PREHASH_Script, _PREHASH_Running, is); + if (is) ++mRunningCount; + msg->getBOOLFast(_PREHASH_Script, "Mono", is); + if (is) ++mMonoCount; + --checking; + + summarize(); +} + +void ScriptCounter::summarize() +{ // Done requesting and there are no more inventories to receive - if (!requesting && !inventories) + // And we're not checking any scripts for running/mono properties + if (!requesting && !inventories && !checking) { LLStringUtil::format_map_t args; args["SCRIPTS"] = stringize(scriptcount); args["OBJECTS"] = stringize(objectCount); + args["RUNNING"] = stringize(mRunningCount); + args["MONO"] = stringize(mMonoCount); if (foo->isAvatar()) LLAvatarNameCache::get(foo->getID(), boost::bind(countedScriptsOnAvatar, args, _2)); else diff --git a/indra/newview/scriptcounter.h b/indra/newview/scriptcounter.h index 0f3afcf75..78fd32058 100644 --- a/indra/newview/scriptcounter.h +++ b/indra/newview/scriptcounter.h @@ -33,7 +33,7 @@ #include "llvoinventorylistener.h" -class ScriptCounter : public LLVOInventoryListener +class ScriptCounter : public LLInstanceTracker, public LLVOInventoryListener { public: ScriptCounter(bool do_delete, LLViewerObject* object); @@ -45,6 +45,9 @@ public: private: void requestInventoriesFor(LLViewerObject* object); void requestInventoryFor(LLViewerObject* object); + friend void process_script_running_reply(LLMessageSystem* msg, void**); + void processRunningReply(LLMessageSystem* msg); + void summarize(); // Check if finished, if so, output and destroy. bool doDelete; LLViewerObject* foo; @@ -52,6 +55,10 @@ private: int objectCount; bool requesting; int scriptcount; + static std::map sCheckMap; // Map of scripts being checked running/mono and by which instance + int checking; // Number of scripts being counter by this instance + int mRunningCount; + int mMonoCount; }; #endif //SCRIPTCOUNTER_H diff --git a/indra/newview/skins/apollo/keywords.ini b/indra/newview/skins/apollo/keywords.ini index fd30d7cf5..8d0fd6b71 100644 --- a/indra/newview/skins/apollo/keywords.ini +++ b/indra/newview/skins/apollo/keywords.ini @@ -489,6 +489,15 @@ PRIM_PHYSICS_SHAPE_PRIM Use the normal prim shape for physics (th PRIM_PHYSICS_SHAPE_NONE Use the convex hull of the prim shape for physics (this is the default for mesh objects) PRIM_PHYSICS_SHAPE_CONVEX Ignore this prim in the physics shape. This cannot be applied to the root prim. +PRIM_SPECULAR Used to get or set the specular map texture settings of a prim's face. +PRIM_NORMAL Used to get or set the normal map texture settings of a prim's face. + +PRIM_ALPHA_MODE Used to specify how the alpha channel of the diffuse texture should affect rendering of a prims face. +PRIM_ALPHA_MODE_NONE Render the diffuse texture as though the alpha channel were nonexistent. +PRIM_ALPHA_MODE_BLEND Render the diffuse texture with alpha-blending. +PRIM_ALPHA_MODE_MASK Render the prim face in alpha-masked mode. +PRIM_ALPHA_MODE_EMISSIVE Render the prim face in emissivity mode. + MASK_BASE Base permissions MASK_OWNER Owner permissions MASK_GROUP Group permissions @@ -554,6 +563,7 @@ REGION_FLAG_SANDBOX Used with llGetRegionFlags to find if a r REGION_FLAG_DISABLE_COLLISIONS Used with llGetRegionFlags to find if a region has disabled collisions REGION_FLAG_DISABLE_PHYSICS Used with llGetRegionFlags to find if a region has disabled physics REGION_FLAG_BLOCK_FLY Used with llGetRegionFlags to find if a region blocks flying +REGION_FLAG_BLOCK_FLYOVER Used with llGetRegionFlags to find if a region enforces higher altitude parcel access rules REGION_FLAG_ALLOW_DIRECT_TELEPORT Used with llGetRegionFlags to find if a region allows direct teleports REGION_FLAG_RESTRICT_PUSHOBJECT Used with llGetRegionFlags to find if a region restricts llPushObject() calls diff --git a/indra/newview/skins/default/colors_base.xml b/indra/newview/skins/default/colors_base.xml index f7b934f81..f3d78b9e9 100644 --- a/indra/newview/skins/default/colors_base.xml +++ b/indra/newview/skins/default/colors_base.xml @@ -151,7 +151,7 @@ - + diff --git a/indra/newview/skins/default/textures/Refresh_Off.png b/indra/newview/skins/default/textures/Refresh_Off.png new file mode 100644 index 000000000..a8acfda74 Binary files /dev/null and b/indra/newview/skins/default/textures/Refresh_Off.png differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_avatar.tga b/indra/newview/skins/default/textures/icn_toolbar_avatar.tga new file mode 100644 index 000000000..0a1a235f3 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_avatar.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_destinations.tga b/indra/newview/skins/default/textures/icn_toolbar_destinations.tga new file mode 100644 index 000000000..0a1a235f3 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_destinations.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_joystick.tga b/indra/newview/skins/default/textures/icn_toolbar_joystick.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_joystick.tga differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 92938cd5c..fb9c6c1e3 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -415,4 +415,5 @@ + diff --git a/indra/newview/skins/default/xui/de/floater_directory.xml b/indra/newview/skins/default/xui/de/floater_directory.xml index 4aaf3e691..7dfa569bd 100644 --- a/indra/newview/skins/default/xui/de/floater_directory.xml +++ b/indra/newview/skins/default/xui/de/floater_directory.xml @@ -1,6 +1,31 @@ + + Suchen... + Nicht gefunden. + @@ -85,18 +85,18 @@ + Loading... Done - http://search.secondlife.com/ + [APP_SITE]/404 http://search.secondlife.com/ diff --git a/indra/newview/skins/default/xui/en-us/floater_directory2.xml b/indra/newview/skins/default/xui/en-us/floater_directory2.xml deleted file mode 100644 index 7d8fa681c..000000000 --- a/indra/newview/skins/default/xui/en-us/floater_directory2.xml +++ /dev/null @@ -1,652 +0,0 @@ - - - - - - Searching... - - - None Found. - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/floater_object_weights.xml b/indra/newview/skins/default/xui/en-us/floater_object_weights.xml new file mode 100644 index 000000000..1c6581c63 --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/floater_object_weights.xml @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/floater_perm_prefs.xml b/indra/newview/skins/default/xui/en-us/floater_perm_prefs.xml index f80937110..03ce82ec4 100644 --- a/indra/newview/skins/default/xui/en-us/floater_perm_prefs.xml +++ b/indra/newview/skins/default/xui/en-us/floater_perm_prefs.xml @@ -1,15 +1,67 @@ - - - + diff --git a/indra/newview/skins/default/xui/en-us/floater_toolbar_prefs.xml b/indra/newview/skins/default/xui/en-us/floater_toolbar_prefs.xml index d3ac8a2c2..f2166ff83 100644 --- a/indra/newview/skins/default/xui/en-us/floater_toolbar_prefs.xml +++ b/indra/newview/skins/default/xui/en-us/floater_toolbar_prefs.xml @@ -1,5 +1,5 @@ - + @@ -15,8 +15,8 @@ - - + + @@ -30,9 +30,9 @@ - + - + @@ -45,10 +45,10 @@ - + - + @@ -62,11 +62,11 @@ - + - + @@ -75,12 +75,14 @@ + - + - + + diff --git a/indra/newview/skins/default/xui/en-us/floater_tools.xml b/indra/newview/skins/default/xui/en-us/floater_tools.xml index 09bb81cb4..4afe0d4a9 100644 --- a/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -5,6 +5,13 @@ name="toolbox floater" rect_control="ToolboxRect" sound_flags="0" title="" short_title="Build" width="272"> + + Primitives: [OBJ_COUNT], LI: [LAND_IMPACT] + + + Remaining capacity [LAND_CAPACITY]. + + + + + + + + + + [RES_X] x [RES_Y] diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml index b3f801f14..a43d828f6 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml @@ -8,6 +8,7 @@ + Logging Options: diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml index 0baf30023..877b8f254 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml @@ -4,7 +4,9 @@ Mouse Sensitivity: + + UI Hidden in mouselook: @@ -13,6 +15,7 @@ Movement Options: + Camera Options: Camera View Angle: diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_web.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_web.xml index f47912224..21df1ad7a 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_web.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_web.xml @@ -3,7 +3,7 @@ Use external web browser (Firefox, Safari, Internet Explorer) - Use built-in web browser + Use built-in web browser Browser cache: + + + + + + + + +