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 83eddcd95..f5ec8fc98 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 aab482327..f60430ed9 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,143 @@ class AIEngine extern AIEngine gMainThreadEngine; extern AIEngine gStateMachineThreadEngine; +#ifndef STATE_MACHINE_PROFILING +#ifndef LL_RELEASE_FOR_DOWNLOAD +#define STATE_MACHINE_PROFILING 1 +#endif +#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 + }; +#if !STATE_MACHINE_PROFILING + StateTimerBase(const std::string& name) : mData(name) {} + ~StateTimerBase() {} + protected: + 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 + protected: + // 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 +435,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 2891cbb77..193c2e0d4 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 3ee510007..97f3b297e 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/develop.py b/indra/develop.py index 0c732cc02..024bd92cb 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -221,6 +221,7 @@ class UnixSetup(PlatformSetup): exe_suffixes = ('',) def __init__(self): + PlatformSetup.__init__(self) super(UnixSetup, self).__init__() self.generator = 'Unix Makefiles' @@ -263,6 +264,7 @@ class UnixSetup(PlatformSetup): class LinuxSetup(UnixSetup): def __init__(self): + UnixSetup.__init__(self) super(LinuxSetup, self).__init__() try: self.debian_sarge = open('/etc/debian_version').read().strip() == '3.1' @@ -384,6 +386,7 @@ class LinuxSetup(UnixSetup): class DarwinSetup(UnixSetup): def __init__(self): + UnixSetup.__init__(self) super(DarwinSetup, self).__init__() self.generator = 'Xcode' @@ -457,6 +460,7 @@ class WindowsSetup(PlatformSetup): exe_suffixes = ('.exe', '.bat', '.com') def __init__(self): + PlatformSetup.__init__(self) super(WindowsSetup, self).__init__() self._generator = None self.incredibuild = False @@ -497,7 +501,10 @@ class WindowsSetup(PlatformSetup): return 'win32' def build_dirs(self): - return ['build-' + self.generator] + if self.word_size == 64: + return ['build-' + self.generator + '-Win64'] + else: + return ['build-' + self.generator] def cmake_commandline(self, src_dir, build_dir, opts, simple): args = dict( diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 1d05da7f3..3d3420961 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -983,19 +983,19 @@ BOOL LLAvatarAppearance::loadSkeletonNode () mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]); mRoot->addChild(mMeshLOD[MESH_ID_HEAD]); - LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull"); + LLJoint *skull = mRoot->findJoint("mSkull"); if (skull) { skull->addChild(mMeshLOD[MESH_ID_HAIR] ); } - LLAvatarJoint *eyeL = (LLAvatarJoint*)mRoot->findJoint("mEyeLeft"); + LLJoint *eyeL = mRoot->findJoint("mEyeLeft"); if (eyeL) { eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] ); } - LLAvatarJoint *eyeR = (LLAvatarJoint*)mRoot->findJoint("mEyeRight"); + LLJoint *eyeR = mRoot->findJoint("mEyeRight"); if (eyeR) { eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] ); diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp index cff862a20..b40475fdc 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); } } @@ -124,7 +125,8 @@ void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive ) iter != mChildren.end(); ++iter) { LLAvatarJoint* joint = dynamic_cast(*iter); - joint->setSkeletonComponents(comp, recursive); + if (joint) + joint->setSkeletonComponents(comp, recursive); } } } @@ -138,8 +140,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); } } } @@ -150,7 +153,8 @@ void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix iter != mChildren.end(); ++iter) { LLAvatarJoint* joint = dynamic_cast(*iter); - joint->updateFaceSizes(num_vertices, num_indices, pixel_area); + if (joint) + joint->updateFaceSizes(num_vertices, num_indices, pixel_area); } } @@ -160,7 +164,8 @@ void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, iter != mChildren.end(); ++iter) { LLAvatarJoint* joint = dynamic_cast(*iter); - joint->updateFaceData(face, pixel_area, damp_wind, terse_update); + if (joint) + joint->updateFaceData(face, pixel_area, damp_wind, terse_update); } } @@ -170,7 +175,8 @@ void LLAvatarJoint::updateJointGeometry() iter != mChildren.end(); ++iter) { LLAvatarJoint* joint = dynamic_cast(*iter); - joint->updateJointGeometry(); + if (joint) + joint->updateJointGeometry(); } } @@ -184,6 +190,9 @@ BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate) iter != mChildren.end(); ++iter) { LLAvatarJoint* joint = dynamic_cast(*iter); + if (!joint) + continue; + F32 jointLOD = joint->getLOD(); if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD) @@ -213,7 +222,8 @@ void LLAvatarJoint::dump() iter != mChildren.end(); ++iter) { LLAvatarJoint* joint = dynamic_cast(*iter); - joint->dump(); + if (joint) + joint->dump(); } } @@ -260,7 +270,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..7a9508968 100644 --- a/indra/llappearance/llavatarjointmesh.cpp +++ b/indra/llappearance/llavatarjointmesh.cpp @@ -83,30 +83,28 @@ LLSkinJoint::~LLSkinJoint() //----------------------------------------------------------------------------- // LLSkinJoint::setupSkinJoint() //----------------------------------------------------------------------------- -BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint) +void LLSkinJoint::setupSkinJoint( LLJoint *joint) { + mRootToJointSkinOffset.clearVec(); + mRootToParentJointSkinOffset.clearVec(); + // find the named joint - mJoint = joint; - if ( !mJoint ) + if (!(mJoint = joint)) { llinfos << "Can't find joint" << llendl; + return; } // compute the inverse root skin matrix - mRootToJointSkinOffset.clearVec(); - - LLVector3 rootSkinOffset; - while (joint) + do { - rootSkinOffset += joint->getSkinOffset(); - joint = (LLAvatarJoint*)joint->getParent(); - } + mRootToJointSkinOffset -= joint->getSkinOffset(); + } while (joint = joint->getParent()); - mRootToJointSkinOffset = -rootSkinOffset; mRootToParentJointSkinOffset = mRootToJointSkinOffset; mRootToParentJointSkinOffset += mJoint->getSkinOffset(); - return TRUE; + return; } @@ -307,15 +305,14 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) for (jn = 0; jn < numJointNames; jn++) { //llinfos << "Setting up joint " << jointNames[jn] << llendl; - LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) ); - mSkinJoints[jn].setupSkinJoint( joint ); + mSkinJoints[jn].setupSkinJoint( getRoot()->findJoint(jointNames[jn]) ); } } // setup joint array if (!mMesh->isLOD()) { - setupJoint((LLAvatarJoint*)getRoot()); + setupJoint(getRoot()); } // llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl; @@ -324,7 +321,7 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) //----------------------------------------------------------------------------- // setupJoint() //----------------------------------------------------------------------------- -void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) +void LLAvatarJointMesh::setupJoint(LLJoint* current_joint) { // llinfos << "Mesh: " << getName() << llendl; @@ -345,7 +342,7 @@ void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == ¤t_joint->getParent()->getWorldMatrix()) { // ...then just add ourselves - LLAvatarJoint* jointp = js.mJoint; + LLJoint* jointp = js.mJoint; mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); // llinfos << "joint " << joint_count << js.mJoint->getName() << llendl; // joint_count++; @@ -366,8 +363,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/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h index 53b82c50a..5dece5972 100644 --- a/indra/llappearance/llavatarjointmesh.h +++ b/indra/llappearance/llavatarjointmesh.h @@ -49,9 +49,9 @@ class LLSkinJoint public: LLSkinJoint(); ~LLSkinJoint(); - BOOL setupSkinJoint( LLAvatarJoint *joint); + void setupSkinJoint( LLJoint *joint); - LLAvatarJoint *mJoint; + LLJoint* mJoint; LLVector3 mRootToJointSkinOffset; LLVector3 mRootToParentJointSkinOffset; }; @@ -122,7 +122,7 @@ public: void setMesh( LLPolyMesh *mesh ); // Sets up joint matrix data for rendering - void setupJoint(LLAvatarJoint* current_joint); + void setupJoint(LLJoint* current_joint); // Sets ID for picking void setMeshID( S32 id ) {mMeshID = id;} 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/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..2908405ea 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.43429448190325182765112891891661f; 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 08de6771e..0cbf02c83 100644 --- a/indra/llmath/llplane.h +++ b/indra/llmath/llplane.h @@ -101,7 +101,7 @@ public: } private: - LLVector4a mV; + LL_ALIGN_16(LLVector4a mV); } LL_ALIGN_POSTFIX(16); diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp index 5835a67d0..699eaf2ab 100644 --- a/indra/llmath/llquaternion.cpp +++ b/indra/llmath/llquaternion.cpp @@ -58,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, @@ -136,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); } @@ -219,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); } @@ -425,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 @@ -838,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 70a021e6a..349af0552 100644 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -304,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/llvector4a.h b/indra/llmath/llvector4a.h index 79d0a4455..2e958b308 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -128,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; @@ -170,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 ); @@ -282,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 b5f594b99..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 @@ -1649,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; @@ -2184,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; @@ -3670,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); 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/aicurlperservice.cpp b/indra/llmessage/aicurlperservice.cpp index 570a7e5b2..fb8427da4 100644 --- a/indra/llmessage/aicurlperservice.cpp +++ b/indra/llmessage/aicurlperservice.cpp @@ -610,7 +610,7 @@ void AIPerService::purge(void) per_service_w->mCapabilityType[i].mQueuedRequests.clear(); if (is_approved((AICapabilityType)i)) { - llassert(total_queued_w->approved >= s); + llassert(total_queued_w->approved >= (S32)s); total_queued_w->approved -= s; } } diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index b9c76d90b..a37a9f916 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -936,6 +936,7 @@ P(fetchScriptLimitsRegionSummaryResponder); P(fnPtrResponder); P(floaterPermsResponder); P2(gamingDataReceived, transfer_22s_connect_10s); +P(groupBanDataResponder); P2(groupMemberDataResponder, transfer_300s); P2(groupProposalBallotResponder, transfer_300s); P(homeLocationResponder); diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index d820283f5..d6aca358e 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -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/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/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/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/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/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/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index c592fccfb..544966479 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -46,16 +46,36 @@ static LLRegisterWidget r("radio_group"); +/* + * A checkbox control with use_radio_style == true. + */ +class LLRadioCtrl : public LLCheckBoxCtrl +{ +public: + LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const std::string& value = "", const LLFontGL* font = NULL, commit_callback_t commit_callback = NULL); + /*virtual*/ ~LLRadioCtrl(); + + virtual LLXMLNodePtr getXML(bool save_children = true) const; + /*virtual*/ void setValue(const LLSD& value); + + LLSD getPayload() { return mPayload; } +protected: + friend class LLUICtrlFactory; + + LLSD mPayload; // stores data that this item represents in the radio group +}; + LLRadioGroup::LLRadioGroup(const std::string& name, const LLRect& rect, S32 initial_index, commit_callback_t commit_callback, - BOOL border) : + bool border, bool allow_deselect) : LLUICtrl(name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP), - mSelectedIndex(initial_index) + mSelectedIndex(initial_index), + mAllowDeselect(allow_deselect) { init(border); } -void LLRadioGroup::init(BOOL border) +void LLRadioGroup::init(bool border) { if (border) { @@ -67,12 +87,19 @@ void LLRadioGroup::init(BOOL border) } - - LLRadioGroup::~LLRadioGroup() { } +// virtual +BOOL LLRadioGroup::postBuild() +{ + if (!mRadioButtons.empty()) + { + mRadioButtons[0]->setTabStop(true); + } + return TRUE; +} // virtual void LLRadioGroup::setEnabled(BOOL enabled) @@ -133,16 +160,39 @@ void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled) BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event) { - if (index < 0 || index >= (S32)mRadioButtons.size()) + if ((S32)mRadioButtons.size() <= index ) { return FALSE; } + if (mSelectedIndex >= 0) + { + LLRadioCtrl* old_radio_item = mRadioButtons[mSelectedIndex]; + old_radio_item->setTabStop(false); + old_radio_item->setValue( FALSE ); + } + else + { + mRadioButtons[0]->setTabStop(false); + } + mSelectedIndex = index; + if (mSelectedIndex >= 0) + { + LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex]; + radio_item->setTabStop(true); + radio_item->setValue( TRUE ); + + if (hasFocus()) + { + radio_item->focusFirstItem(FALSE, FALSE); + } + } + if (!from_event) { - setControlValue(getSelectedIndex()); + setControlValue(getValue()); } return TRUE; @@ -207,41 +257,23 @@ BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask) return handled; } -void LLRadioGroup::draw() +BOOL LLRadioGroup::handleMouseDown(S32 x, S32 y, MASK mask) { - S32 current_button = 0; - - BOOL take_focus = FALSE; - if (gFocusMgr.childHasKeyboardFocus(this)) + // grab focus preemptively, before child button takes mousecapture + // + if (hasTabStop()) { - take_focus = TRUE; + focusFirstItem(FALSE, FALSE); } - for (button_list_t::iterator iter = mRadioButtons.begin(); - iter != mRadioButtons.end(); ++iter) - { - LLRadioCtrl* radio = *iter; - BOOL selected = (current_button == mSelectedIndex); - radio->setValue( selected ); - if (take_focus && selected && !gFocusMgr.childHasKeyboardFocus(radio)) - { - // don't flash keyboard focus when navigating via keyboard - BOOL DONT_FLASH = FALSE; - radio->focusFirstItem(FALSE, DONT_FLASH); - } - current_button++; - } - - LLView::draw(); + return LLUICtrl::handleMouseDown(x, y, mask); } - // When adding a button, we need to ensure that the radio // group gets a message when the button is clicked. -LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font ) +LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font, const std::string& payload) { - // Highlight will get fixed in draw method above - LLRadioCtrl* radio = new LLRadioCtrl(name, rect, label, font, boost::bind(&LLRadioGroup::onClickButton, this, _1)); + LLRadioCtrl* radio = new LLRadioCtrl(name, rect, label, payload, font, boost::bind(&LLRadioGroup::onClickButton, this, _1)); addChild(radio); mRadioButtons.push_back(radio); return radio; @@ -252,7 +284,7 @@ LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::st void LLRadioGroup::onClickButton(LLUICtrl* ctrl) { - // llinfos << "LLRadioGroup::onClickButton" << llendl; + // LL_INFOS() << "LLRadioGroup::onClickButton" << LL_ENDL; LLRadioCtrl* clicked_radio = dynamic_cast(ctrl); if (!clicked_radio) return; @@ -263,9 +295,15 @@ void LLRadioGroup::onClickButton(LLUICtrl* ctrl) LLRadioCtrl* radio = *iter; if (radio == clicked_radio) { - // llinfos << "clicked button " << counter << llendl; - setSelectedIndex(index); - setControlValue(index); + if (index == mSelectedIndex && mAllowDeselect) + { + // don't select anything + setSelectedIndex(-1); + } + else + { + setSelectedIndex(index); + } // BUG: Calls click callback even if button didn't actually change onCommit(); @@ -281,13 +319,12 @@ void LLRadioGroup::onClickButton(LLUICtrl* ctrl) void LLRadioGroup::setValue( const LLSD& value ) { - std::string value_name = value.asString(); int idx = 0; for (button_list_t::const_iterator iter = mRadioButtons.begin(); iter != mRadioButtons.end(); ++iter) { LLRadioCtrl* radio = *iter; - if (radio->getName() == value_name) + if (radio->getPayload().asString() == value.asString()) { setSelectedIndex(idx); idx = -1; @@ -304,8 +341,7 @@ void LLRadioGroup::setValue( const LLSD& value ) } else { - llwarns << "LLRadioGroup::setValue: radio_item with name=\"" << value_name << "\" not found, radio_group values are set by radio_item name not value. Falling back on LLUICtrl::setValue." << llendl; - LLUICtrl::setValue(value); + setSelectedIndex(-1, TRUE); } } } @@ -317,7 +353,7 @@ LLSD LLRadioGroup::getValue() const for (button_list_t::const_iterator iter = mRadioButtons.begin(); iter != mRadioButtons.end(); ++iter) { - if (idx == index) return LLSD((*iter)->getName()); + if (idx == index) return LLSD((*iter)->getPayload()); ++idx; } return LLSD(); @@ -333,6 +369,7 @@ LLXMLNodePtr LLRadioGroup::getXML(bool save_children) const // Attributes node->createChild("draw_border", TRUE)->setBoolValue(mHasBorder); + node->createChild("allow_deselect", TRUE)->setBoolValue(mAllowDeselect); // Contents @@ -355,17 +392,21 @@ LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory U32 initial_value = 0; node->getAttributeU32("initial_value", initial_value); - BOOL draw_border = TRUE; - node->getAttributeBOOL("draw_border", draw_border); + bool draw_border = true; + node->getAttribute_bool("draw_border", draw_border); + + bool allow_deselect = false; + node->getAttribute_bool("allow_deselect", allow_deselect); LLRect rect; createRect(node, rect, parent, LLRect()); - LLRadioGroup* radio_group = new LLRadioGroup("radio_group", + LLRadioGroup* radio_group = new LLRadioGroup("radio_group", rect, initial_value, NULL, - draw_border); + draw_border, + allow_deselect); const std::string& contents = node->getValue(); @@ -406,7 +447,13 @@ LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory createRect(child, item_rect, radio_group, rect); std::string item_label = child->getTextContents(); - LLRadioCtrl* radio = radio_group->addRadioButton("radio", item_label, item_rect, font); + child->getAttributeString("label", item_label); + std::string item_name("radio"); + child->getAttributeString("name", item_name); + std::string payload(item_name); // Support old-style name as payload + child->getAttributeString("value", payload); + child->getAttributeString("initial_value", payload); // Synonym + LLRadioCtrl* radio = radio_group->addRadioButton(item_name, item_label, item_rect, font, payload); radio->initFromXML(child, radio_group); } @@ -432,11 +479,10 @@ LLUUID LLRadioGroup::getCurrentID() const BOOL LLRadioGroup::setSelectedByValue(const LLSD& value, BOOL selected) { S32 idx = 0; - std::string value_string = value.asString(); for (button_list_t::const_iterator iter = mRadioButtons.begin(); iter != mRadioButtons.end(); ++iter) { - if((*iter)->getName() == value_string) + if((*iter)->getPayload().asString() == value.asString()) { setSelectedIndex(idx); return TRUE; @@ -455,11 +501,10 @@ LLSD LLRadioGroup::getSelectedValue() BOOL LLRadioGroup::isSelected(const LLSD& value) const { S32 idx = 0; - std::string value_string = value.asString(); for (button_list_t::const_iterator iter = mRadioButtons.begin(); iter != mRadioButtons.end(); ++iter) { - if((*iter)->getName() == value_string) + if((*iter)->getPayload().asString() == value.asString()) { if (idx == mSelectedIndex) { @@ -481,6 +526,17 @@ BOOL LLRadioGroup::operateOnAll(EOperation op) return FALSE; } +LLRadioCtrl::LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const std::string& value, const LLFontGL* font, commit_callback_t commit_callback) +: LLCheckBoxCtrl(name, rect, label, font, commit_callback, FALSE, RADIO_STYLE), + mPayload(value) +{ + setTabStop(FALSE); + // use name as default "Value" for backwards compatibility + if (value.empty()) + { + mPayload = name; + } +} LLRadioCtrl::~LLRadioCtrl() { @@ -499,7 +555,7 @@ LLXMLNodePtr LLRadioCtrl::getXML(bool save_children) const node->setName(LL_RADIO_ITEM_TAG); - node->setStringValue(getLabel()); + node->createChild("value", TRUE)->setStringValue(mPayload); return node; } diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index 3cc042217..e21c7bc1f 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -37,26 +37,6 @@ #include "llcheckboxctrl.h" #include "llctrlselectioninterface.h" - -/* - * A checkbox control with use_radio_style == true. - */ -class LLRadioCtrl : public LLCheckBoxCtrl -{ -public: - LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const LLFontGL* font = NULL, - commit_callback_t commit_callback = NULL) : - LLCheckBoxCtrl(name, rect, label, font, commit_callback, FALSE, RADIO_STYLE) - { - setTabStop(FALSE); - } - /*virtual*/ ~LLRadioCtrl(); - - virtual LLXMLNodePtr getXML(bool save_children = true) const; - /*virtual*/ void setValue(const LLSD& value); -}; - - /* * An invisible view containing multiple mutually exclusive toggling * buttons (usually radio buttons). Automatically handles the mutex @@ -66,25 +46,32 @@ class LLRadioGroup : public LLUICtrl, public LLCtrlSelectionInterface { public: - // Radio group constructor. Doesn't rely on - // needing a control + + // Radio group constructor. Doesn't rely on needing a control LLRadioGroup(const std::string& name, const LLRect& rect, S32 initial_index, commit_callback_t commit_callback, - BOOL border = TRUE); + bool border = true, bool allow_deselect = false); + +protected: + friend class LLUICtrlFactory; + +public: virtual ~LLRadioGroup(); + virtual BOOL postBuild(); + + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleKeyHere(KEY key, MASK mask); virtual void setEnabled(BOOL enabled); virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); void setIndexEnabled(S32 index, BOOL enabled); - // return the index value of the selected item S32 getSelectedIndex() const { return mSelectedIndex; } - // set the index value programatically BOOL setSelectedIndex(S32 index, BOOL from_event = FALSE); @@ -92,14 +79,10 @@ public: virtual void setValue(const LLSD& value ); virtual LLSD getValue() const; - // Draw the group, but also fix the highlighting based on the control. - void draw(); - // You must use this method to add buttons to a radio group. // Don't use addChild -- it won't set the callback function // correctly. - LLRadioCtrl* addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font); - LLRadioCtrl* getRadioButton(const S32& index) { return mRadioButtons[index]; } + class LLRadioCtrl* addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font, const std::string& payload = ""); // Update the control as needed. Userdata must be a pointer to the button. void onClickButton(LLUICtrl* clicked_radio); @@ -123,14 +106,15 @@ public: private: // protected function shared by the two constructors. - void init(BOOL border); + void init(bool border); S32 mSelectedIndex; - typedef std::vector button_list_t; + + typedef std::vector button_list_t; button_list_t mRadioButtons; - BOOL mHasBorder; + bool mHasBorder; + bool mAllowDeselect; // user can click on an already selected option to deselect it }; - #endif 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/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/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/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index a29c5378e..f2db11f26 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; @@ -161,9 +172,8 @@ LLWinImm LLWinImm::sTheInstance; LLWinImm::LLWinImm() : mHImmDll(NULL) { // Check system metrics - if ( !GetSystemMetrics( SM_DBCSENABLED ) ) + if ( !GetSystemMetrics( SM_IMMENABLED ) ) 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)) { @@ -660,7 +671,7 @@ LLWindowWin32::~LLWindowWin32() delete [] mSupportedResolutions; mSupportedResolutions = NULL; - delete mWindowClassName; + delete [] mWindowClassName; mWindowClassName = NULL; } @@ -749,7 +760,7 @@ void LLWindowWin32::close() LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; // Don't process events in our mainWindowProc any longer. - SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL); + SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL); // // Make sure we don't leave a blank toolbar button. ShowWindow(mWindowHandle, SW_HIDE); @@ -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,7 +1882,11 @@ 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; - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr(h_wnd, GWLP_USERDATA); + // 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); // if (NULL != window_imp) @@ -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; // Broke first double click every session. + } + // 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 @@ -3379,7 +3282,6 @@ void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url, bool async) { sei.fMask = SEE_MASK_ASYNCOK; } - else { sei.fMask = SEE_MASK_FLAG_DDEWAIT; 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 b6244c690..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 @@ -333,6 +337,7 @@ set(viewer_SOURCE_FILES llmaterialmgr.cpp llmediactrl.cpp llmediadataclient.cpp + llmediafilter.cpp llmediaremotectrl.cpp llmenucommands.cpp llmenuoptionpathfindingrebakenavmesh.cpp @@ -368,6 +373,8 @@ set(viewer_SOURCE_FILES llpanelface.cpp llpanelgeneral.cpp llpanelgroup.cpp + llpanelgroupbulk.cpp + llpanelgroupbulkban.cpp llpanelgroupgeneral.cpp llpanelgroupinvite.cpp llpanelgrouplandmoney.cpp @@ -591,7 +598,6 @@ set(viewer_SOURCE_FILES sgversion.cpp shcommandhandler.cpp shfloatermediaticker.cpp - slfloatermediafilter.cpp wlfPanel_AdvSettings.cpp ) @@ -706,6 +712,7 @@ set(viewer_HEADER_FILES llfloateractivespeakers.h llfloaterauction.h llfloaterautoreplacesettings.h + llfloateravatar.h llfloateravatarinfo.h llfloateravatarlist.h llfloateravatarpicker.h @@ -727,6 +734,7 @@ set(viewer_HEADER_FILES llfloatercolorpicker.h llfloatercustomize.h llfloaterdaycycle.h + llfloaterdestinations.h llfloaterdirectory.h llfloaterdisplayname.h llfloatereditui.h @@ -739,6 +747,7 @@ set(viewer_HEADER_FILES llfloaterfriends.h llfloatergesture.h llfloatergodtools.h + llfloatergroupbulkban.h llfloatergroupinfo.h llfloatergroupinvite.h llfloatergroups.h @@ -754,6 +763,7 @@ set(viewer_HEADER_FILES llfloaterlandholdings.h llfloaterlandmark.h llfloatermap.h + llfloatermediafilter.h llfloatermediasettings.h llfloatermemleak.h llfloatermessagelog.h @@ -856,6 +866,7 @@ set(viewer_HEADER_FILES llmaterialmgr.h llmediactrl.h llmediadataclient.h + llmediafilter.h llmediaremotectrl.h llmenucommands.h llmenuoptionpathfindingrebakenavmesh.h @@ -891,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 @@ -1117,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 @@ -1284,6 +1298,7 @@ if (WINDOWS) shell32 user32 Vfw32 + Wbemuuid winspool ) 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 aefaae3c4..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 @@ -1021,6 +1015,17 @@ 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 @@ -3150,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 @@ -3172,17 +3188,6 @@ This should be as low as possible, but too low may break functionality Value 2 - AvatarRotateThresholdMouselook - - Comment - Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when in mouselook (degrees) - Persist - 1 - Type - F32 - Value - 120 - AvatarBakedTextureUploadTimeout Comment @@ -6091,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 @@ -14711,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 @@ -17909,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 @@ -18583,6 +18648,17 @@ This should be as low as possible, but too low may break functionality 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 d59a38a80..8be48da2d 100644 --- a/indra/newview/app_settings/settings_ascent.xml +++ b/indra/newview/app_settings/settings_ascent.xml @@ -102,6 +102,17 @@ Value 1 + AlchemyConnectToNeighbors + + Comment + If false, disconnect from neighboring regions and all further neighbors on teleport + Persist + 1 + Type + Boolean + Value + 1 + AlchemyLookAtLines Comment @@ -1008,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 @@ -1162,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 @@ -1384,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_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/ascentprefsvan.cpp b/indra/newview/ascentprefsvan.cpp index c9f2b937c..6a51b580f 100644 --- a/indra/newview/ascentprefsvan.cpp +++ b/indra/newview/ascentprefsvan.cpp @@ -129,6 +129,7 @@ void LLPrefsAscentVan::refreshValues() mUnfocusedFloatersOpaque = gSavedSettings.getBOOL("FloaterUnfocusedBackgroundOpaque"); mCompleteNameProfiles = gSavedSettings.getBOOL("SinguCompleteNameProfiles"); mScriptErrorsStealFocus = gSavedSettings.getBOOL("LiruScriptErrorsStealFocus"); + mConnectToNeighbors = gSavedSettings.getBOOL("AlchemyConnectToNeighbors"); //Tags\Colors ---------------------------------------------------------------------------- mAscentBroadcastTag = gSavedSettings.getBOOL("AscentBroadcastTag"); @@ -199,6 +200,7 @@ void LLPrefsAscentVan::cancel() 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 2e7753d10..b45adf652 100644 --- a/indra/newview/ascentprefsvan.h +++ b/indra/newview/ascentprefsvan.h @@ -65,6 +65,7 @@ private: 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 e079cf4e5..ddbfca284 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -33,12 +33,14 @@ #include "chatbar_as_cmdline.h" +#include "llavatarnamecache.h" #include "llcalc.h" #include "llchatbar.h" #include "llagent.h" #include "llagentcamera.h" #include "llagentui.h" +#include "llavataractions.h" #include "llviewerregion.h" #include "llworld.h" #include "lleventtimer.h" @@ -215,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"); @@ -251,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; } } } @@ -289,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; } @@ -428,7 +437,14 @@ 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; } diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index f11871ea5..c097b42fd 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -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/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/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 1f3c8be57..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 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/llagent.cpp b/indra/newview/llagent.cpp index 051a68fcd..7fb21ab0d 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1293,25 +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 (gAgentCamera.cameraMouselook() && gSavedSettings.getBOOL("UseRealisticMouselook")) - { - look_down_limit = 160.f * DEG_TO_RAD; - look_up_limit = 20.f * DEG_TO_RAD; - } - else 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)) { diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 16c7cd3fd..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,7 @@ void LLAgentCamera::updateCamera() validateFocusObject(); - bool realistic_ml(gSavedSettings.getBOOL("UseRealisticMouselook")); + static const LLCachedControl realistic_ml("UseRealisticMouselook"); if (isAgentAvatarValid() && !realistic_ml && gAgentAvatarp->isSitting() && @@ -1492,16 +1493,14 @@ void LLAgentCamera::updateCamera() if (realistic_ml) { LLQuaternion agent_rot(gAgent.getFrameAgent().getQuaternion()); - if (isAgentAvatarValid()) - if (LLViewerObject* parent = static_cast(gAgentAvatarp->getParent())) - if (static_cast(gAgentAvatarp->getRoot())->flagCameraDecoupled()) - agent_rot *= parent->getRenderRotation(); + 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 { - LLVector3 diff = mCameraPositionAgent - head_pos; - diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation(); + const LLVector3 diff((mCameraPositionAgent - head_pos) * ~gAgentAvatarp->mRoot->getWorldRotation()); gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff); } @@ -1795,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); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 217332797..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 diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 35f731bff..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" @@ -747,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/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp index 97e2cf19e..dfbc63114 100644 --- a/indra/newview/llclassifiedstatsresponder.cpp +++ b/indra/newview/llclassifiedstatsresponder.cpp @@ -59,7 +59,7 @@ void LLClassifiedStatsResponder::httpSuccess(void) 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) { diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 8263c0868..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(); } @@ -1209,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); @@ -1274,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; } @@ -1587,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..99e8c20ef 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -281,7 +281,7 @@ void LLDrawPoolAlpha::render(S32 pass) gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } - gGL.diffuseColor4f(0.9,0,0,0.4); + gGL.diffuseColor4f(0.9f,0.f,0.f,0.4f); LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f); gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ; @@ -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..d2973dc02 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()); } } @@ -1605,7 +1595,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP)); LLColor4 col = mat->getSpecularLightColor(); - F32 spec = mat->getSpecularLightExponent()/255.f; + F32 spec = llmax(0.0001f, mat->getSpecularLightExponent() / 255.f); F32 env = mat->getEnvironmentIntensity()/255.f; @@ -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/llface.cpp b/indra/newview/llface.cpp index d4718c2bf..86b840c03 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -206,7 +206,7 @@ void LLFace::destroy() if (mTextureMatrix) { - delete mTextureMatrix; + ll_aligned_free_16(mTextureMatrix); mTextureMatrix = NULL; if (mDrawablep.notNull()) @@ -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) { @@ -1349,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; @@ -1409,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) { @@ -1550,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) @@ -1712,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()); } } } @@ -1739,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 @@ -1854,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 { @@ -1935,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; @@ -2053,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; @@ -2065,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++; @@ -2529,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(); } @@ -2545,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(); } @@ -2605,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/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/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/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/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/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/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/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/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp index f95d82f23..2f4d5954c 100644 --- a/indra/newview/llfloaterobjectweights.cpp +++ b/indra/newview/llfloaterobjectweights.cpp @@ -117,9 +117,9 @@ void LLFloaterObjectWeights::onOpen() // virtual void LLFloaterObjectWeights::onWeightsUpdate(const SelectionCost& selection_cost) { - mSelectedDownloadWeight->setText(llformat("%.1f", selection_cost.mNetworkCost)); - mSelectedPhysicsWeight->setText(llformat("%.1f", selection_cost.mPhysicsCost)); - mSelectedServerWeight->setText(llformat("%.1f", selection_cost.mSimulationCost)); + 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)); diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index 0f32bae79..aa6b76c87 100644 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -233,6 +233,11 @@ private: 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) { diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index a452d1368..403b04099 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -341,9 +341,15 @@ void LLPreferenceCore::setPersonalInfo(const std::string& visibility, bool im_vi ////////////////////////////////////////////// // 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"); } diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 644049c07..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(); diff --git a/indra/newview/llfloaterregionrestarting.cpp b/indra/newview/llfloaterregionrestarting.cpp index 84e5ea934..a5eeeeecc 100644 --- a/indra/newview/llfloaterregionrestarting.cpp +++ b/indra/newview/llfloaterregionrestarting.cpp @@ -154,10 +154,10 @@ void LLFloaterRegionRestarting::draw() if (!alchemyRegionShake || isMinimized()) // If we're minimized, leave the user alone return; - const F32 SHAKE_INTERVAL = 0.025; - const F32 SHAKE_TOTAL_DURATION = 1.8; // the length of the default alert tone for this - const F32 SHAKE_INITIAL_MAGNITUDE = 1.5; - const F32 SHAKE_HORIZONTAL_BIAS = 0.25; + const F32 SHAKE_INTERVAL = 0.025f; + const F32 SHAKE_TOTAL_DURATION = 1.8f; // the length of the default alert tone for this + const F32 SHAKE_INITIAL_MAGNITUDE = 1.5f; + const F32 SHAKE_HORIZONTAL_BIAS = 0.25f; F32 time_shaking; if (SHAKE_START == sShakeState) 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 266beb7ce..9d7e2c0be 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -1787,7 +1787,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater, bool de child_list_t::const_iterator it, end=childs->end(); for (it=childs->begin(); it!=end; ++it) { - LLRadioCtrl *ctrl = dynamic_cast(*it); + LLView* ctrl = *it; if (ctrl && (ctrl->getName() == "texture")) { ctrl->setLabelArg("[UPLOADFEE]", fee); diff --git a/indra/newview/llfloatertest.cpp b/indra/newview/llfloatertest.cpp index 22628dc09..46d0978e7 100644 --- a/indra/newview/llfloatertest.cpp +++ b/indra/newview/llfloatertest.cpp @@ -81,8 +81,6 @@ private: LLIconCtrl* mIcon; LLLineEditor* mLineEditor; LLRadioGroup* mRadioGroup; - LLRadioCtrl* mRadio1; - LLRadioCtrl* mRadio2; LLScrollContainer* mScroll; LLScrollListCtrl* mScrollList; LLTabContainer* mTab; 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 74ef47853..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,8 +1953,147 @@ 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 { @@ -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/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/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 323263d76..d06d823ca 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); @@ -2846,6 +2851,14 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) restoreItem(); return; } + // Move displaced inventory to lost and found + else if ("move_to_lost_and_found" == action) + { + gInventory.changeCategoryParent(getCategory(), gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND), TRUE); + gInventory.addChangedMask(LLInventoryObserver::REBUILD, mUUID); + gInventory.notifyObservers(); + } + // #ifdef DELETE_SYSTEM_FOLDERS else if ("delete_system_folder" == action) { @@ -2943,12 +2956,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 +2964,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 +3324,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 @@ -3359,6 +3373,14 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) mWearables=TRUE; } } + // Move displaced inventory to lost and found + else if (!isAgentInventory()) + { + const LLUUID& library(gInventory.getLibraryRootFolderID()); + if (library != mUUID && !gInventory.isObjectDescendentOf(mUUID, library)) + mItems.push_back(std::string("Move to Lost And Found")); + } + // // Preemptively disable system folder removal if more than one item selected. if ((flags & FIRST_SELECTED_ITEM) == 0) @@ -3387,7 +3409,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 +3471,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 +3517,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 +3870,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 +3891,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 +4006,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 +4234,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 +4271,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 +4884,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 +5260,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 +5270,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 +5314,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 +5581,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 +5836,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 +5857,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 +5941,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 +5968,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 +6086,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.h b/indra/newview/llinventorymodel.h index 507549b6c..a7136cb5a 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -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/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/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index c0ec144ce..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" 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/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 6df1d8717..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() { @@ -219,17 +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"); @@ -273,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 4d51734dc..92351de9a 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -766,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) @@ -774,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 @@ -1004,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 @@ -1086,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 { @@ -1163,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) @@ -1236,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); } @@ -1900,6 +1771,7 @@ void LLMeshLODResponder::completedRaw(LLChannelDescriptors const& channels, { 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); @@ -1918,12 +1790,14 @@ void LLMeshLODResponder::completedRaw(LLChannelDescriptors const& channels, 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); @@ -1932,6 +1806,7 @@ void LLMeshLODResponder::completedRaw(LLChannelDescriptors const& channels, if (file.getSize() >= offset+size) { + AIStateMachine::StateTimer timer("WriteData"); file.seek(offset); file.write(data, size); LLMeshRepository::sCacheBytesWritten += size; @@ -2157,6 +2032,7 @@ void LLMeshHeaderResponder::completedRaw(LLChannelDescriptors const& channels, 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); @@ -2173,17 +2049,23 @@ void LLMeshHeaderResponder::completedRaw(LLChannelDescriptors const& channels, S32 data_size = buffer->countAfter(channels.in(), NULL); - U8* data = NULL; + static const U32 BUFF_MAX_STATIC_SIZE = 16384; //If we exceed this size just bump the vector back to BUFF_MAX_STATIC_SIZE after we're done. + static std::vector data(BUFF_MAX_STATIC_SIZE); + if (data_size > (S32)data.size()) + data.resize(data_size); + else + memset(&data[0] + data_size, 0, data.size() - data_size); if (data_size > 0) { - data = new U8[data_size]; - buffer->readAfter(channels.in(), NULL, data, data_size); + AIStateMachine::StateTimer timer("readAfter"); + buffer->readAfter(channels.in(), NULL, &data[0], data_size); } LLMeshRepository::sBytesReceived += llmin(data_size, 4096); - bool success = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size); + AIStateMachine::StateTimer timer("headerReceived"); + bool success = gMeshRepo.mThread->headerReceived(mMeshParams, &data[0], data_size); llassert(success); @@ -2193,7 +2075,7 @@ void LLMeshHeaderResponder::completedRaw(LLChannelDescriptors const& channels, << "Unable to parse mesh header: " << 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(); @@ -2225,33 +2107,30 @@ void LLMeshHeaderResponder::completedRaw(LLChannelDescriptors const& channels, //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_to_write = llmin(bytes_remaining, data_size); + file.write(&data[0], bytes_to_write); + if (bytes_remaining == bytes && bytes_to_write < bytes_remaining) + { + memset(&data[0], 0, data.size()); + } + bytes_remaining -= llmin(bytes_remaining, bytes_to_write); } } } } - delete [] data; + if (data.size() > BUFF_MAX_STATIC_SIZE) + data.resize(BUFF_MAX_STATIC_SIZE); } 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 70127907b..2e34271a1 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -53,7 +53,8 @@ LLNameListCtrl::LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL : LLScrollListCtrl(name, rect, NULL, allow_multiple_selection, draw_border,draw_heading), mNameColumnIndex(name_column_index), mAllowCallingCardDrop(false), - mNameSystem(name_system) + mNameSystem(name_system), + mPendingLookupsRemaining(0) { setToolTip(tooltip); } @@ -203,6 +204,17 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( 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; } @@ -254,6 +266,8 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) { selectNthItem(idx); // not sure whether this is needed, taken from previous implementation deleteSingleItem(idx); + + mPendingLookupsRemaining--; } } @@ -292,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 712decf52..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, @@ -155,6 +157,16 @@ private: const LLCachedControl mNameSystem; 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/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 43ebbcc34..1d4e23ded 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -97,8 +97,22 @@ 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"); } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index a6bda4cb8..fe39b0afa 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -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/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 9fccb989a..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) { @@ -812,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) @@ -844,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; @@ -881,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) @@ -929,6 +1013,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() { // Can't remove other owners. cb_enable = FALSE; + can_ban_members = FALSE; break; } } @@ -1012,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) { @@ -1025,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); } @@ -1083,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) { @@ -1095,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()) @@ -1111,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 @@ -1177,7 +1315,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, FALSE); } - // static void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data) { @@ -1548,15 +1685,15 @@ 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; @@ -1623,7 +1760,6 @@ void LLPanelGroupMembersSubTab::updateMembers() mMembersList->deleteAllItems(); } - LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); LLTimer update_time; @@ -1681,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) { @@ -1705,7 +1864,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab(const std::string& name, const mMemberVisibleCheck(NULL), mDeleteRoleButton(NULL), mCreateRoleButton(NULL), - + mFirstOpen(TRUE), mHasRoleChange(FALSE) { } @@ -1805,6 +1964,7 @@ void LLPanelGroupRolesSubTab::deactivate() lldebugs << "LLPanelGroupRolesSubTab::deactivate()" << llendl; LLPanelGroupSubTab::deactivate(); + mFirstOpen = FALSE; } bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg) @@ -1812,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 @@ -1822,7 +1988,7 @@ bool LLPanelGroupRolesSubTab::apply(std::string& mesg) lldebugs << "LLPanelGroupRolesSubTab::apply()" << llendl; saveRoleChanges(true); - + mFirstOpen = FALSE; LLGroupMgr::getInstance()->sendGroupRoleChanges(mGroupID); notifyObservers(); @@ -1959,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) @@ -1982,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(); } @@ -2161,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); @@ -2203,6 +2450,7 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force) mHasRoleChange = TRUE; notifyObservers(); + } bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check) @@ -2222,7 +2470,6 @@ bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& return false; } - // static void LLPanelGroupRolesSubTab::onPropertiesKey(LLLineEditor* ctrl, void* user_data) { @@ -2400,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) { @@ -2581,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 b5c5b54a5..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,6 +205,8 @@ 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, const LLUUID& av_id); @@ -212,6 +225,7 @@ protected: LLScrollListCtrl* mAssignedRolesList; LLScrollListCtrl* mAllowedActionsList; LLButton* mEjectBtn; + LLButton* mBanBtn; BOOL mChanged; BOOL mPendingMemberUpdate; @@ -225,6 +239,7 @@ protected: avatar_name_cache_connection_map_t mAvatarNameCacheConnections; }; + class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab { public: @@ -265,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); @@ -286,6 +306,7 @@ protected: std::string mRemoveEveryoneTxt; }; + class LLPanelGroupActionsSubTab : public LLPanelGroupSubTab { public: @@ -303,6 +324,8 @@ public: virtual void update(LLGroupChange gc); void handleActionSelect(); + + virtual void setGroupID(const LLUUID& id); protected: LLScrollListCtrl* mActionList; LLScrollListCtrl* mActionRoles; @@ -312,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/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 e9a38ba79..74712a649 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -741,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 { 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/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index bfc518326..1ef801423 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1869,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. /* diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 1195fb834..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()); } } @@ -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(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 1eef9a463..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)) 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 a0feb0063..2d0501ff5 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -875,10 +875,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update) } } } -/*prep# - virtual void httpFailure(void) - llwarns << "httpFailure: " << dumpResponse() << llendl; - */ + void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id) { LLPointer speakerp = findSpeaker(speaker_id); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 9d17dc7d0..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" @@ -325,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 // @@ -1256,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); @@ -1574,7 +1588,8 @@ 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; @@ -1582,6 +1597,13 @@ bool idle_startup() 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 @@ -1723,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; @@ -2419,6 +2442,14 @@ bool idle_startup() { 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); @@ -2633,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; @@ -4082,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. @@ -4175,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/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/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index c1ea44d7a..dfcee38e7 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -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/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/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 7e07a2b80..ef609c4a9 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -629,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) @@ -826,6 +828,8 @@ 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)); 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/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index e46299f9d..2ce476092 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -146,6 +146,8 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy ) iter != mChildren.end(); ++iter) { LLAvatarJoint* joint = dynamic_cast(*iter); + if (!joint) + continue; F32 jointLOD = joint->getLOD(); if (pixelArea >= jointLOD || sDisableLOD) { 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 3487ade1b..479b877ad 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -36,6 +36,7 @@ #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" @@ -59,7 +60,7 @@ 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, UNKNOWN }; +enum EControllerType { NONE, SPACE_NAV, XBOX, DS3, UNKNOWN }; static EControllerType sType = NONE; // Control cursor instead of avatar? @@ -79,10 +80,43 @@ enum XBoxKeys 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 - || desc.find("OUYA") != 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 } // @@ -267,6 +301,7 @@ void LLViewerJoystick::init(bool autoenable) } updateEnabled(autoenable); + const std::string desc(getDescription()); if (mDriverState == JDS_INITIALIZED) { sControlCursor = false; @@ -282,20 +317,33 @@ void LLViewerJoystick::init(bool autoenable) gSavedSettings.setString("JoystickInitialized", "SpaceNavigator"); } } - else if (isXboxLike(getDescription())) + else if (isXboxLike(desc)) { sType = XBOX; // It's an Xbox controller, we have defaults for it. - if (gSavedSettings.getString("JoystickInitialized") != "XboxController") + 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(); - gSavedSettings.setString("JoystickInitialized", "XboxController"); + 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 or 360 controller + // It's not a Space Navigator, 360 controller, or DualShock 3 sType = UNKNOWN; gSavedSettings.setString("JoystickInitialized", "UnknownDevice"); } @@ -312,7 +360,7 @@ void LLViewerJoystick::init(bool autoenable) // if (mDriverState == JDS_INITIALIZED) { - llinfos << "Joystick = " << getDescription() << llendl; + llinfos << "Joystick = " << desc << llendl; } // #endif @@ -531,7 +579,7 @@ void LLViewerJoystick::cursorSlide(F32 inc) void LLViewerJoystick::cursorPush(F32 inc) { static F32 prev_inc = 0.f; // Smooth a little. - if (!is_approx_zero(0.001)) + if (!is_approx_zero(inc)) { S32 x, y; LLUI::getMousePositionScreen(&x, &y); @@ -546,6 +594,7 @@ 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); @@ -730,7 +779,7 @@ void LLViewerJoystick::moveAvatar(bool reset) bool is_zero = true; static bool button_held = false; - if (mBtn[sType == XBOX ? XBOX_L_STICK_CLICK : 1] == 1) + if (mBtn[sType == XBOX ? XBOX_L_STICK_CLICK : sType == DS3 ? DS3_L_STICK_CLICK : 1] == 1) { // If AutomaticFly is enabled, then button1 merely causes a // jump (as the up/down axis already controls flying) if on the @@ -1168,11 +1217,13 @@ void LLViewerJoystick::scanJoystick() static bool toggle_cursor = false; // Xbox 360 support - if (sType == XBOX) + if (sType == XBOX || sType == DS3) { + bool ds3 = sType == DS3; // Special command keys ... // - Back = toggle flycam - if (mBtn[XBOX_BACK_KEY] == 1) + U8 key = ds3 ? (U8)DS3_SELECT_KEY : (U8)XBOX_BACK_KEY; + if (mBtn[key] == 1) { if (!toggle_flycam) toggle_flycam = toggleFlycam(); } @@ -1182,7 +1233,8 @@ void LLViewerJoystick::scanJoystick() } // - Start = toggle cursor/camera control - if (mBtn[XBOX_START_KEY] == 1) + key = ds3 ? (U8)DS3_START_KEY : (U8)XBOX_START_KEY; + if (mBtn[key] == 1) { if (!toggle_cursor) toggle_cursor = toggleCursor(); } @@ -1193,40 +1245,45 @@ void LLViewerJoystick::scanJoystick() // Toggle mouselook ... static bool right_stick_click_down = false; - if (!!mBtn[XBOX_R_STICK_CLICK] != right_stick_click_down) + 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[XBOX_R_STICK_CLICK]) // Note: Setting, not comparing. + 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; - if (!!mBtn[XBOX_Y_KEY] != esc_down) + key = ds3 ? (U8)DS3_TRIANGLE_KEY : (U8)XBOX_Y_KEY; + if (!!mBtn[key] != esc_down) { - esc_down = mBtn[XBOX_Y_KEY]; + esc_down = mBtn[key]; (gKeyboard->*(esc_down ? &LLKeyboard::handleTranslatedKeyDown : &LLKeyboard::handleTranslatedKeyDown))(KEY_ESCAPE, mask); } // Alt static bool alt_down = false; - if (!!mBtn[XBOX_A_KEY] != alt_down) + key = ds3 ? (U8)DS3_X_KEY : (U8)XBOX_A_KEY; + if (!!mBtn[key] != alt_down) { - gKeyboard->setControllerKey(KEY_ALT, alt_down = mBtn[XBOX_A_KEY]); + gKeyboard->setControllerKey(KEY_ALT, alt_down = mBtn[key]); } // Ctrl static bool ctrl_down = false; - if (!!mBtn[XBOX_X_KEY] != ctrl_down) + key = ds3 ? (U8)DS3_SQUARE_KEY : (U8)XBOX_X_KEY; + if (!!mBtn[key] != ctrl_down) { - gKeyboard->setControllerKey(KEY_CONTROL, ctrl_down = mBtn[XBOX_X_KEY]); + gKeyboard->setControllerKey(KEY_CONTROL, ctrl_down = mBtn[key]); } // Shift static bool shift_down = false; - if (!!mBtn[XBOX_B_KEY] != shift_down) + key = ds3 ? (U8)DS3_CIRCLE_KEY : (U8)XBOX_B_KEY; + if (!!mBtn[key] != shift_down) { - gKeyboard->setControllerKey(KEY_SHIFT, shift_down = mBtn[XBOX_B_KEY]); + gKeyboard->setControllerKey(KEY_SHIFT, shift_down = mBtn[key]); } // Mouse clicks ... @@ -1234,20 +1291,36 @@ void LLViewerJoystick::scanJoystick() LLUI::getMousePositionScreen(&coord.mX, &coord.mY); static bool m1_down = false; static F32 last_m1 = 0; - if (!!mBtn[XBOX_L_BUMP_KEY] != m1_down) + key = ds3 ? (U8)DS3_L1_KEY : (U8)XBOX_L_BUMP_KEY; + if (!!mBtn[key] != m1_down) { - m1_down = mBtn[XBOX_L_BUMP_KEY]; + 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; - if (!!mBtn[XBOX_R_BUMP_KEY] != m2_down) + key = ds3 ? (U8)DS3_R1_KEY : (U8)XBOX_R_BUMP_KEY; + if (!!mBtn[key] != m2_down) { - m2_down = mBtn[XBOX_R_BUMP_KEY]; + 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 // @@ -1303,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; @@ -1317,8 +1390,10 @@ void LLViewerJoystick::setSNDefaults() #endif //gViewerWindow->alertXml("CacheWillClear"); - const bool xbox = sType == XBOX; - llinfos << "restoring " << (xbox ? "Xbox Controller" : "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 @@ -1331,58 +1406,59 @@ void LLViewerJoystick::setSNDefaults() 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", xbox ? -1 : 4); // roll - gSavedSettings.setS32("JoystickAxis4", xbox ? 4 : 3); // pitch - gSavedSettings.setS32("JoystickAxis5", xbox ? 3 : 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", !xbox && 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", (xbox ? 0.43f : 1.f) * platformScaleAvXZ); - gSavedSettings.setF32("AvatarAxisScale1", (xbox ? 0.43f : 1.f) * platformScaleAvXZ); - gSavedSettings.setF32("AvatarAxisScale2", xbox ? 0.43f : 1.f); - gSavedSettings.setF32("AvatarAxisScale4", (xbox ? 4.f : .1f) * platformScale); - gSavedSettings.setF32("AvatarAxisScale5", (xbox ? 4.f : .1f) * platformScale); - gSavedSettings.setF32("AvatarAxisScale3", (xbox ? 4.f : 0.f) * platformScale); - gSavedSettings.setF32("BuildAxisScale1", (xbox ? 0.8f : .3f) * platformScale); - gSavedSettings.setF32("BuildAxisScale2", (xbox ? 0.8f : .3f) * platformScale); - gSavedSettings.setF32("BuildAxisScale0", (xbox ? 1.6f : .3f) * platformScale); - gSavedSettings.setF32("BuildAxisScale4", (xbox ? 1.f : .3f) * platformScale); - gSavedSettings.setF32("BuildAxisScale5", (xbox ? 2.f : .3f) * platformScale); - gSavedSettings.setF32("BuildAxisScale3", (xbox ? 1.f : .3f) * platformScale); - gSavedSettings.setF32("FlycamAxisScale1", (xbox ? 16.f : 2.f) * platformScale); - gSavedSettings.setF32("FlycamAxisScale2", (xbox ? 16.f : 2.f) * platformScale); - gSavedSettings.setF32("FlycamAxisScale0", (xbox ? 25.f : 2.1f) * platformScale); // Z Scale - gSavedSettings.setF32("FlycamAxisScale4", (xbox ? -4.f : .1f) * platformScale); - gSavedSettings.setF32("FlycamAxisScale5", (xbox ? 4.f : .15f) * platformScale); - gSavedSettings.setF32("FlycamAxisScale3", (xbox ? 4.f : 0.f) * platformScale); - gSavedSettings.setF32("FlycamAxisScale6", (xbox ? 4.f : 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", xbox ? .2f : .1f); - gSavedSettings.setF32("AvatarAxisDeadZone1", xbox ? .2f : .1f); - gSavedSettings.setF32("AvatarAxisDeadZone2", xbox ? .2f : .1f); - gSavedSettings.setF32("AvatarAxisDeadZone3", xbox ? .2f : 1.f); - gSavedSettings.setF32("AvatarAxisDeadZone4", xbox ? .2f : .02f); - gSavedSettings.setF32("AvatarAxisDeadZone5", xbox ? .2f : .01f); - gSavedSettings.setF32("BuildAxisDeadZone0", xbox ? .02f : .01f); - gSavedSettings.setF32("BuildAxisDeadZone1", xbox ? .02f : .01f); - gSavedSettings.setF32("BuildAxisDeadZone2", xbox ? .02f : .01f); - gSavedSettings.setF32("BuildAxisDeadZone3", xbox ? .02f : .01f); - gSavedSettings.setF32("BuildAxisDeadZone4", xbox ? .02f : .01f); - gSavedSettings.setF32("BuildAxisDeadZone5", xbox ? .02f : .01f); - gSavedSettings.setF32("FlycamAxisDeadZone0", xbox ? .2f : .01f); - gSavedSettings.setF32("FlycamAxisDeadZone1", xbox ? .2f : .01f); - gSavedSettings.setF32("FlycamAxisDeadZone2", xbox ? .2f : .01f); - gSavedSettings.setF32("FlycamAxisDeadZone3", xbox ? .1f : .01f); - gSavedSettings.setF32("FlycamAxisDeadZone4", xbox ? .25f : .01f); - gSavedSettings.setF32("FlycamAxisDeadZone5", xbox ? .25f : .01f); - gSavedSettings.setF32("FlycamAxisDeadZone6", xbox ? .2f : 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", xbox ? 3.f : 6.f); + gSavedSettings.setF32("AvatarFeathering", game ? 3.f : 6.f); gSavedSettings.setF32("BuildFeathering", 12.f); - gSavedSettings.setF32("FlycamFeathering", xbox ? 1.f : 5.f); + gSavedSettings.setF32("FlycamFeathering", game ? 1.f : 5.f); } diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h index 308f52bc6..058821bcd 100644 --- a/indra/newview/llviewerjoystick.h +++ b/indra/newview/llviewerjoystick.h @@ -67,7 +67,7 @@ public: bool getOverrideCamera() { return mOverrideCamera; } void setOverrideCamera(bool val); bool toggleFlycam(); - void setSNDefaults(); + void setSNDefaults(S32 type = 0); std::string getDescription(); protected: diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 7f73a760d..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); @@ -6471,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 { @@ -8762,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 { @@ -8974,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) @@ -9291,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 @@ -9489,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"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 36462930b..1c5ed208f 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3801,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; } @@ -6309,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); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ee9bdf4ba..9ea0c19d5 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2903,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; @@ -3719,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/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index c7e900238..2f9317090 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -758,7 +758,7 @@ public: // show an error to the user? llwarns << "Application level error when fetching object " - << "cost. Message: " << mContent["error"]["message"].asString() + << "cost. Message: " << mContent["error"]["message"].asString() << ", identifier: " << mContent["error"]["identifier"].asString() << llendl; @@ -871,7 +871,7 @@ public: LLUUID object_id = iter->asUUID(); // Check to see if the request contains data for the object - if ( mContent.has(iter->asString()) ) + if (mContent.has(iter->asString())) { const LLSD& data = mContent[iter->asString()]; @@ -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 311170c27..cbc64d533 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -321,6 +321,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, { // Moved this up... -> mWidth = region_width_meters; // + + mRenderMatrix.setIdentity(); + mImpl->mOriginGlobal = from_region_handle(handle); updateRenderMatrix(); @@ -547,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) @@ -1719,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"); 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/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..6f41b62f8 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -757,8 +757,8 @@ void LLViewerTexture::removeFace(U32 ch, LLFace* facep) if(mNumFaces[ch] > 1) { S32 index = facep->getIndexInTex(ch) ; - llassert(index < mFaceList[ch].size()); - llassert(index < mNumFaces[ch]); + llassert(index < (S32)mFaceList[ch].size()); + llassert(index < (S32)mNumFaces[ch]); mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]] ; mFaceList[ch][index]->setIndexInTex(ch, index) ; } @@ -808,8 +808,8 @@ void LLViewerTexture::removeVolume(LLVOVolume* volumep) if(mNumVolumes > 1) { S32 index = volumep->getIndexInTex() ; - llassert(index < mVolumeList.size()); - llassert(index < mNumVolumes); + llassert(index < (S32)mVolumeList.size()); + llassert(index < (S32)mNumVolumes); mVolumeList[index] = mVolumeList[--mNumVolumes] ; mVolumeList[index]->setIndexInTex(index) ; } @@ -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 1fff45ad1..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 diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f5d81a7c5..802105235 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1651,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()); } } @@ -1709,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()); } } @@ -1835,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 ); @@ -1924,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; @@ -4123,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); @@ -4140,17 +4142,16 @@ 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", 60.0); static const LLCachedControl s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0); - static const LLCachedControl s_pelvis_rot_threshold_ml(gSavedSettings, "AvatarRotateThresholdMouselook", 120.f); - - F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); + 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 = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_ml, s_pelvis_rot_threshold_fast); + pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR; } pelvis_rot_threshold *= DEG_TO_RAD; @@ -5282,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 @@ -5345,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(); @@ -5353,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); @@ -6619,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); @@ -8844,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); @@ -8859,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); } } 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 61de510d5..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; } @@ -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/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 8277cb08a..4411ce17e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -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) { @@ -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(); @@ -4343,7 +4302,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); - specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); + specColor.mV[3] = llmax(0.0001f, mat->getSpecularLightExponent() * (1.f / 255.f)); draw_info->mSpecColor = specColor; draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); @@ -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/llworld.cpp b/indra/newview/llworld.cpp index 8dab3dbb9..8e1b1e4be 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1352,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; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4e40e2a89..3afd7bc47 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(); @@ -7404,9 +7324,9 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b if (!LLViewerCamera::getInstance()->cameraUnderWater()) { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2f); } else { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0f); } shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); @@ -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); @@ -7452,22 +7362,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b if (!LLViewerCamera::getInstance()->cameraUnderWater()) { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2f); } else { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0f); } - 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/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/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_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index 188c19b15..ad0eae39d 100644 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -1,5 +1,5 @@ - + @@ -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 21afeea9c..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_settings_debug.xml b/indra/newview/skins/default/xui/en-us/floater_settings_debug.xml index 1f6f81634..042081971 100644 --- a/indra/newview/skins/default/xui/en-us/floater_settings_debug.xml +++ b/indra/newview/skins/default/xui/en-us/floater_settings_debug.xml @@ -12,10 +12,10 @@ name="comment_text" word_wrap="true" /> - + True - + False 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/menu_avs_list.xml b/indra/newview/skins/default/xui/en-us/menu_avs_list.xml index 53fff36bd..2ba08eaaa 100644 --- a/indra/newview/skins/default/xui/en-us/menu_avs_list.xml +++ b/indra/newview/skins/default/xui/en-us/menu_avs_list.xml @@ -44,6 +44,10 @@ + + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_inventory.xml b/indra/newview/skins/default/xui/en-us/menu_inventory.xml index a248c26de..6f0f02133 100644 --- a/indra/newview/skins/default/xui/en-us/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en-us/menu_inventory.xml @@ -227,6 +227,9 @@ name="Delete" width="128"> + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_login.xml b/indra/newview/skins/default/xui/en-us/menu_login.xml index 666cce9b4..441c2e0e8 100644 --- a/indra/newview/skins/default/xui/en-us/menu_login.xml +++ b/indra/newview/skins/default/xui/en-us/menu_login.xml @@ -13,6 +13,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_radar.xml b/indra/newview/skins/default/xui/en-us/menu_radar.xml index 6104e9b1a..0a9e734aa 100644 --- a/indra/newview/skins/default/xui/en-us/menu_radar.xml +++ b/indra/newview/skins/default/xui/en-us/menu_radar.xml @@ -137,6 +137,10 @@ + + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/indra/newview/skins/default/xui/en-us/menu_viewer.xml index 6ed62ea1c..d2d6765bd 100644 --- a/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -357,11 +357,6 @@ - - - - + + + + + + + + + + @@ -614,31 +619,36 @@ - + - - + + - - + + - - + + - - + + - + - @@ -1025,6 +1035,10 @@ + + + + diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index 3fb2d93fe..f1315772a 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -151,7 +151,7 @@ icon="alert.tga" name="MediaAlert" type="alert"> -The owner of this parcel has requested the following [TYPE] URL to be loaded by your viewer: +The owner of this parcel has requested the following [MEDIA_TYPE] URL to be loaded by your viewer: [URL] @@ -179,12 +179,25 @@ You may choose to allow or deny the corresponding domain or in-world scripted ob text="Whitelist"/> - + -Media/audio URLs for [DOMAIN] now [LISTED] + icon="alertmodal.tga" + name="AddToMediaList" + type="alertmodal"> +Enter a domain name to be added to the [LIST]: + confirm +
+ +
+ + + + + + + + + [RES_X] x [RES_Y] diff --git a/indra/newview/skins/default/xui/en-us/panel_region_general.xml b/indra/newview/skins/default/xui/en-us/panel_region_general.xml index c3437082d..8053be932 100644 --- a/indra/newview/skins/default/xui/en-us/panel_region_general.xml +++ b/indra/newview/skins/default/xui/en-us/panel_region_general.xml @@ -31,8 +31,8 @@ left="205" name="terraform_help" width="18" /> - + + + + + + + + +
- + diff --git a/indra/newview/skins/default/xui/es/menu_pie_object.xml b/indra/newview/skins/default/xui/es/menu_pie_object.xml index 3f970ffe0..b3efc2df7 100644 --- a/indra/newview/skins/default/xui/es/menu_pie_object.xml +++ b/indra/newview/skins/default/xui/es/menu_pie_object.xml @@ -22,14 +22,16 @@ + + + + + - - - diff --git a/indra/newview/skins/default/xui/es/menu_radar.xml b/indra/newview/skins/default/xui/es/menu_radar.xml index 727312896..49ebbddc0 100644 --- a/indra/newview/skins/default/xui/es/menu_radar.xml +++ b/indra/newview/skins/default/xui/es/menu_radar.xml @@ -41,6 +41,7 @@ + @@ -53,6 +54,7 @@ + diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index 6d20bf29b..ae190c5b7 100644 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -1,12 +1,12 @@ - - - + + + - - + + @@ -55,7 +55,6 @@ - @@ -75,7 +74,6 @@ - @@ -121,16 +119,18 @@ + + - - - - - + + + + + @@ -194,7 +194,7 @@ - + @@ -209,13 +209,13 @@ - + - + @@ -224,9 +224,10 @@ + - + diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index 710397a8e..738278898 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -91,18 +91,20 @@ Puedes escoger aceptar o denegar el dominio correspondiente o el script en el mu