diff options
Diffstat (limited to 'indra')
103 files changed, 3186 insertions, 3047 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 452fd5f356..aa1d50b993 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -128,6 +128,17 @@ if (LINUX)    # Let's actually get a numerical version of gxx's version    STRING(REGEX REPLACE ".* ([0-9])\\.([0-9])\\.([0-9]).*" "\\1\\2\\3" CXX_VERSION_NUMBER ${CXX_VERSION}) +  # Hacks to work around gcc 4.1 TC build pool machines which can't process pragma warning disables +  # This is pure rubbish; I wish there was another way. +  # +  if(${CXX_VERSION_NUMBER} LESS 420) +    set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-uninitialized -Wno-unused-variable -Wno-unused-function ${CMAKE_CXX_FLAGS}") +  endif (${CXX_VERSION_NUMBER} LESS 420) + +  if(${CXX_VERSION_NUMBER} GREATER 459) +    set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}") +  endif (${CXX_VERSION_NUMBER} GREATER 459) +    # gcc 4.3 and above don't like the LL boost and also    # cause warnings due to our use of deprecated headers    if(${CXX_VERSION_NUMBER} GREATER 429) @@ -218,7 +229,7 @@ if (LINUX OR DARWIN)    set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs")    if (NOT GCC_DISABLE_FATAL_WARNINGS) -    set(GCC_WARNINGS "${GCC_WARNINGS} -Werror") +#    set(GCC_WARNINGS "${GCC_WARNINGS} -Werror")    endif (NOT GCC_DISABLE_FATAL_WARNINGS)    set(GCC_CXX_WARNINGS "${GCC_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor") diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index c32e357da3..1551b0e3f7 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -266,6 +266,7 @@ elseif(LINUX)          libdb-5.1.so          libexpat.so          libexpat.so.1 +        libfreetype.so.6          libglod.so          libgmock_main.so          libgmock.so.0 diff --git a/indra/cmake/FreeType.cmake b/indra/cmake/FreeType.cmake index 43a9d282d0..c9a90a9a8d 100644 --- a/indra/cmake/FreeType.cmake +++ b/indra/cmake/FreeType.cmake @@ -7,13 +7,7 @@ if (STANDALONE)    pkg_check_modules(FREETYPE REQUIRED freetype2)  else (STANDALONE)    use_prebuilt_binary(freetype) -  if (LINUX) -    set(FREETYPE_INCLUDE_DIRS -        ${LIBS_PREBUILT_DIR}/include) -  else (LINUX) -    set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) -  endif (LINUX) - +  set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)    set(FREETYPE_LIBRARIES freetype)  endif (STANDALONE) diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt index 98ebdc7487..5263b59584 100644 --- a/indra/linux_crash_logger/CMakeLists.txt +++ b/indra/linux_crash_logger/CMakeLists.txt @@ -12,6 +12,7 @@ include(LLVFS)  include(LLXML)  include(Linking)  include(UI) +include(FreeType)  include_directories(      ${LLCOMMON_INCLUDE_DIRS} @@ -53,6 +54,7 @@ target_link_libraries(linux-crash-logger      ${LLCOMMON_LIBRARIES}      ${UI_LIBRARIES}      ${DB_LIBRARIES} +    ${FREETYPE_LIBRARIES}      )  add_custom_target(linux-crash-logger-target ALL diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index 0d0b85ba60..35508e0a87 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -38,8 +38,6 @@  // Constants  //-----------------------------------------------------------------------------  const LLQuaternion EDIT_MOTION_WRIST_ROTATION(F_PI_BY_TWO * 0.7f, LLVector3(1.0f, 0.0f, 0.0f)); -const F32 TARGET_LAG_HALF_LIFE	= 0.1f;		// half-life of IK targeting -const F32 TORSO_LAG_HALF_LIFE = 0.2f;  const F32 MAX_TIME_DELTA = 2.f; //max two seconds a frame for calculating interpolation  S32 LLEditingMotion::sHandPose = LLHandMotion::HAND_POSE_RELAXED_R; @@ -232,7 +230,7 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)  		mIKSolver.solve();  		// use blending... -		F32 slerp_amt = LLCriticalDamp::getInterpolant(TARGET_LAG_HALF_LIFE); +		F32 slerp_amt = LLCriticalDamp::getInterpolant(InterpDeltaTargetLagHalfLife);  		shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot);  		elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot); @@ -258,3 +256,4 @@ void LLEditingMotion::onDeactivate()  // End + diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 15a58a8389..1eddd0f449 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -182,8 +182,8 @@ BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask)  	LLQuaternion	currentRootRotWorld = mRootJoint->getWorldRotation();  	LLQuaternion	currentInvRootRotWorld = ~currentRootRotWorld; -	F32 head_slerp_amt = LLCriticalDamp::getInterpolant(HEAD_LOOKAT_LAG_HALF_LIFE); -	F32 torso_slerp_amt = LLCriticalDamp::getInterpolant(TORSO_LOOKAT_LAG_HALF_LIFE); +	F32 head_slerp_amt = LLCriticalDamp::getInterpolant(InterpDeltaHeadLookAtLagHalfLife); +	F32 torso_slerp_amt = LLCriticalDamp::getInterpolant(InterpDeltaTorsoLookAtLagHalfLife);  	LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); @@ -530,3 +530,4 @@ void LLEyeMotion::onDeactivate()  }  // End + diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index c6f45bffa2..f394cf2635 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1031,11 +1031,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  	if (constraint->mSharedData->mChainLength != 0 &&  		dist_vec_squared(root_pos, target_pos) * 0.95f > constraint->mTotalLength * constraint->mTotalLength)  	{ -		constraint->mWeight = lerp(constraint->mWeight, 0.f, LLCriticalDamp::getInterpolant(0.1f)); +		constraint->mWeight = lerp(constraint->mWeight, 0.f, LLCriticalDamp::getInterpolant(InterpDeltaSmaller));  	}  	else  	{ -		constraint->mWeight = lerp(constraint->mWeight, 1.f, LLCriticalDamp::getInterpolant(0.3f)); +		constraint->mWeight = lerp(constraint->mWeight, 1.f, LLCriticalDamp::getInterpolant(InterpDeltaSmallish));  	}  	F32 weight = constraint->mWeight * ((shared_data->mEaseOutStopTime == 0.f) ? 1.f :  @@ -1084,7 +1084,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  			F32 time_constant = 1.f / clamp_rescale(constraint->mFixupDistanceRMS, 0.f, 0.5f, 0.2f, 8.f);  //			llinfos << "Interpolant " << LLCriticalDamp::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;  			positions[joint_num] = lerp(positions[joint_num], kinematic_position,  -				LLCriticalDamp::getInterpolant(time_constant, FALSE)); +				LLCriticalDamp::getInterpolant(time_constant));  		}  		S32 iteration_count; @@ -2304,3 +2304,4 @@ LLKeyframeMotion::JointConstraint::~JointConstraint()  }  // End + diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp index d52eb89a5c..d17c123e54 100644 --- a/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/indra/llcharacter/llkeyframewalkmotion.cpp @@ -287,7 +287,7 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)  		F32 desired_speed_multiplier = llclamp(speed / foot_speed, min_speed_multiplier, ANIM_SPEED_MAX);  		// blend towards new speed adjustment value -		F32 new_speed_adjust = lerp(mAdjustedSpeed, desired_speed_multiplier, LLCriticalDamp::getInterpolant(SPEED_ADJUST_TIME_CONSTANT)); +		F32 new_speed_adjust = lerp(mAdjustedSpeed, desired_speed_multiplier, LLCriticalDamp::getInterpolant(InterpDeltaSpeedAdjustTime));  		// limit that rate at which the speed adjustment changes  		F32 speedDelta = llclamp(new_speed_adjust - mAdjustedSpeed, -SPEED_ADJUST_MAX_SEC * delta_time, SPEED_ADJUST_MAX_SEC * delta_time); @@ -305,8 +305,8 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)  	{	// standing/turning  		// damp out speed adjustment to 0 -		mAnimSpeed = lerp(mAnimSpeed, 1.f, LLCriticalDamp::getInterpolant(0.2f)); -		//mPelvisOffset = lerp(mPelvisOffset, LLVector3::zero, LLCriticalDamp::getInterpolant(0.2f)); +		mAnimSpeed = lerp(mAnimSpeed, 1.f, LLCriticalDamp::getInterpolant(InterpDeltaSmall)); +		//mPelvisOffset = lerp(mPelvisOffset, LLVector3::zero, LLCriticalDamp::getInterpolant(InterpDeltaSmall));  	}  	// broadcast walk speed change @@ -383,10 +383,11 @@ BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask)  	F32 target_roll = llclamp(ang_vel.mV[VZ], -4.f, 4.f) * roll_factor;  	// roll is critically damped interpolation between current roll and angular velocity-derived target roll -	mRoll = lerp(mRoll, target_roll, LLCriticalDamp::getInterpolant(0.1f)); +	mRoll = lerp(mRoll, target_roll, LLCriticalDamp::getInterpolant(InterpDeltaSmaller));  	LLQuaternion roll(mRoll, LLVector3(0.f, 0.f, 1.f));  	mPelvisState->setRotation(roll);  	return TRUE;  } + diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp index 2551f125d0..d4db0d84c9 100644 --- a/indra/llcharacter/llmotion.cpp +++ b/indra/llcharacter/llmotion.cpp @@ -73,7 +73,7 @@ void LLMotion::fadeOut()  {  	if (mFadeWeight > 0.01f)  	{ -		mFadeWeight = lerp(mFadeWeight, 0.f, LLCriticalDamp::getInterpolant(0.15f)); +		mFadeWeight = lerp(mFadeWeight, 0.f, LLCriticalDamp::getInterpolant(InterpDeltaFadeWeight));  	}  	else  	{ @@ -88,7 +88,7 @@ void LLMotion::fadeIn()  {  	if (mFadeWeight < 0.99f)  	{ -		mFadeWeight = lerp(mFadeWeight, 1.f, LLCriticalDamp::getInterpolant(0.15f)); +		mFadeWeight = lerp(mFadeWeight, 1.f, LLCriticalDamp::getInterpolant(InterpDeltaFadeWeight));  	}  	else  	{ @@ -169,3 +169,4 @@ BOOL LLMotion::canDeprecate()  }  // End + diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp index 489aef923c..6ce6ce31d6 100644 --- a/indra/llcharacter/lltargetingmotion.cpp +++ b/indra/llcharacter/lltargetingmotion.cpp @@ -106,7 +106,7 @@ BOOL LLTargetingMotion::onActivate()  //-----------------------------------------------------------------------------  BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask)  { -	F32 slerp_amt = LLCriticalDamp::getInterpolant(TORSO_TARGET_HALF_LIFE); +	F32 slerp_amt = LLCriticalDamp::getInterpolant(InterpDeltaTorsoTargetLagHalfLife);  	LLVector3 target;  	LLVector3* lookAtPoint = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); @@ -169,3 +169,4 @@ void LLTargetingMotion::onDeactivate()  // End + diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index e019c17280..0c2ceebb52 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -121,6 +121,7 @@ set(llcommon_HEADER_FILES      linden_common.h      linked_lists.h      llaccountingcost.h +    llalignedarray.h      llallocator.h      llallocator_heap_profile.h      llagentconstants.h diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h new file mode 100644 index 0000000000..ed8fd31205 --- /dev/null +++ b/indra/llcommon/llalignedarray.h @@ -0,0 +1,139 @@ +/**  + * @file llalignedarray.h + * @brief A static array which obeys alignment restrictions and mimics std::vector accessors. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLALIGNEDARRAY_H +#define LL_LLALIGNEDARRAY_H + +#include "llmemory.h" + +template <class T, U32 alignment> +class LLAlignedArray +{ +public: +	T* mArray; +	U32 mElementCount; +	U32 mCapacity; + +	LLAlignedArray(); +	~LLAlignedArray(); + +	void push_back(const T& elem); +	U32 size() const { return mElementCount; } +	void resize(U32 size); +	T* append(S32 N); +	T& operator[](int idx); +	const T& operator[](int idx) const; +}; + +template <class T, U32 alignment> +LLAlignedArray<T, alignment>::LLAlignedArray() +{ +	llassert(alignment >= 16); +	mArray = NULL; +	mElementCount = 0; +	mCapacity = 0; +} + +template <class T, U32 alignment> +LLAlignedArray<T, alignment>::~LLAlignedArray() +{ +	ll_aligned_free(mArray); +	mArray = NULL; +	mElementCount = 0; +	mCapacity = 0; +} + +template <class T, U32 alignment> +void LLAlignedArray<T, alignment>::push_back(const T& elem) +{ +	T* old_buf = NULL; +	if (mCapacity <= mElementCount) +	{ +		mCapacity++; +		mCapacity *= 2; +		T* new_buf = (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment); +		if (mArray) +		{ +			ll_memcpy_nonaliased_aligned_16((char*)new_buf, (char*)mArray, sizeof(T)*mElementCount); +		} +		old_buf = mArray; +		mArray = new_buf; +	} + +	mArray[mElementCount++] = elem; + +	//delete old array here to prevent error on a.push_back(a[0]) +	ll_aligned_free(old_buf); +} + +template <class T, U32 alignment> +void LLAlignedArray<T, alignment>::resize(U32 size) +{ +	if (mCapacity < size) +	{ +		mCapacity = size+mCapacity*2; +		T* new_buf = mCapacity > 0 ? (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment) : NULL; +		if (mArray) +		{ +			ll_memcpy_nonaliased_aligned_16((char*) new_buf, (char*) mArray, sizeof(T)*mElementCount); +			ll_aligned_free(mArray); +		} + +		/*for (U32 i = mElementCount; i < mCapacity; ++i) +		{ +			new(new_buf+i) T(); +		}*/ +		mArray = new_buf; +	} + +	mElementCount = size; +} + + +template <class T, U32 alignment> +T& LLAlignedArray<T, alignment>::operator[](int idx) +{ +	llassert(idx < mElementCount); +	return mArray[idx]; +} + +template <class T, U32 alignment> +const T& LLAlignedArray<T, alignment>::operator[](int idx) const +{ +	llassert(idx < mElementCount); +	return mArray[idx]; +} + +template <class T, U32 alignment> +T* LLAlignedArray<T, alignment>::append(S32 N) +{ +	U32 sz = size(); +	resize(sz+N); +	return &((*this)[sz]); +} + +#endif + diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index a536a06ea5..afa06df23e 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -38,7 +38,7 @@ typedef LLAtomic32<U32> LLAtomicU32;  class LLErrorThread;  class LLLiveFile;  #if LL_LINUX -typedef struct siginfo siginfo_t; +#include <signal.h>  #endif  typedef void (*LLAppErrorHandler)(); diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp index 87d79b1ee0..27fef0e6dc 100644 --- a/indra/llcommon/llcriticaldamp.cpp +++ b/indra/llcommon/llcriticaldamp.cpp @@ -32,8 +32,9 @@  // static members  //-----------------------------------------------------------------------------  LLFrameTimer LLCriticalDamp::sInternalTimer; -std::map<F32, F32> LLCriticalDamp::sInterpolants;  F32 LLCriticalDamp::sTimeDelta; +F32	LLCriticalDamp::sInterpolants[kNumCachedInterpolants]; +F32 LLCriticalDamp::sInterpolatedValues[kNumCachedInterpolants];  //-----------------------------------------------------------------------------  // LLCriticalDamp() @@ -41,6 +42,17 @@ F32 LLCriticalDamp::sTimeDelta;  LLCriticalDamp::LLCriticalDamp()  {  	sTimeDelta = 0.f; + +	// Init the core interpolant values (to which many, many enums map) +	// +	setInterpolantConstant(InterpDelta_0_025, 0.025f); +	setInterpolantConstant(InterpDelta_0_05,  0.05f ); +	setInterpolantConstant(InterpDelta_0_06,  0.06f); +	setInterpolantConstant(InterpDelta_0_10,  0.10f); +	setInterpolantConstant(InterpDelta_0_15,  0.15f); +	setInterpolantConstant(InterpDelta_0_20,  0.20f); +	setInterpolantConstant(InterpDelta_0_25,  0.25f); +	setInterpolantConstant(InterpDelta_0_30,  0.30f);  }  // static @@ -51,39 +63,10 @@ void LLCriticalDamp::updateInterpolants()  {  	sTimeDelta = sInternalTimer.getElapsedTimeAndResetF32(); -	F32 time_constant; - -	for (std::map<F32, F32>::iterator iter = sInterpolants.begin(); -		 iter != sInterpolants.end(); iter++) -	{ -		time_constant = iter->first; -		F32 new_interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant); -		new_interpolant = llclamp(new_interpolant, 0.f, 1.f); -		sInterpolants[time_constant] = new_interpolant; -	} -}  - -//----------------------------------------------------------------------------- -// getInterpolant() -//----------------------------------------------------------------------------- -F32 LLCriticalDamp::getInterpolant(const F32 time_constant, BOOL use_cache) -{ -	if (time_constant == 0.f) +	U32 i; +	for (i = 0; i < kNumCachedInterpolants; i++)  	{ -		return 1.f; +		sInterpolatedValues[i] = llclamp(sTimeDelta / sInterpolants[ i], 0.0f, 1.0f);  	} - -	if (use_cache && sInterpolants.count(time_constant)) -	{ -		return sInterpolants[time_constant]; -	} -	 -	F32 interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant); -	interpolant = llclamp(interpolant, 0.f, 1.f); -	if (use_cache) -	{ -		sInterpolants[time_constant] = interpolant; -	} - -	return interpolant;  } + diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h index 52f052ae25..19a2ddb77a 100644 --- a/indra/llcommon/llcriticaldamp.h +++ b/indra/llcommon/llcriticaldamp.h @@ -32,22 +32,98 @@  #include "llframetimer.h" +// These enums each represent one fixed-time delta value +// that we interpolate once given the actual sTimeDelta time +// that has passed. This allows us to calculate the interp portion +// of those values once and then look them up repeatedly per frame. +// +enum InterpDelta +{	 +	InterpDelta_0_025,		// 0.025 +	InterpDeltaTeenier					= InterpDelta_0_025, +	InterpDeltaFolderOpenTime			= InterpDelta_0_025, +	InterpDeltaFolderCloseTime			= InterpDelta_0_025, +	InterpDeltaCameraFocusHalfLife		= InterpDelta_0_025,	// USED TO BE ZERO.... + +	InterpDelta_0_05,		// 0.05 +	InterpDeltaTeeny		= InterpDelta_0_05, + +	InterpDelta_0_06,		// 0.06 +	InterpDeltaObjectDampingConstant	= InterpDelta_0_06,	 +	InterpDeltaCameraZoomHalfLife		= InterpDelta_0_06, +	InterpDeltaFovZoomHalfLife			= InterpDelta_0_06, +	InterpDeltaManipulatorScaleHalfLife	= InterpDelta_0_06, +	InterpDeltaContextFadeTime			= InterpDelta_0_06, + +	InterpDelta_0_10,		// 0.10 +	InterpDeltaSmaller					= InterpDelta_0_10, +	InterpDeltaTargetLagHalfLife		= InterpDelta_0_10, +	InterpDeltaSpeedAdjustTime			= InterpDelta_0_10, + +	InterpDelta_0_15,		// 0.15 +	InterpDeltaFadeWeight				= InterpDelta_0_15, +	InterpDeltaHeadLookAtLagHalfLife	= InterpDelta_0_15, + +	InterpDelta_0_20,		// 0.20 +	InterpDeltaSmall					= InterpDelta_0_20, +	InterpDeltaTorsoLagHalfLife			= InterpDelta_0_20, +	InterpDeltaPositionDampingTC		= InterpDelta_0_20, + +	InterpDelta_0_25,		// 0.25 +	InterpDeltaCameraLagHalfLife		= InterpDelta_0_25, +	InterpDeltaTorsoTargetLagHalfLife	= InterpDelta_0_25, +	InterpDeltaTorsoLookAtLagHalfLife	= InterpDelta_0_25, + +	InterpDelta_0_30,		// 0.3 +	InterpDeltaSmallish		= InterpDelta_0_30, + +	// Dynamically set interpolants which use setInterpolantConstant +	// +	InterpDeltaCameraSmoothingHalfLife,	 +	InterpDeltaBehindnessLag, +	InterpDeltaFocusLag, +	InterpDeltaPositionLag, +	InterpDeltaOpenTime, +	InterpDeltaCloseTime,		 + +	kNumCachedInterpolants +}; +  class LL_COMMON_API LLCriticalDamp   {  public:  	LLCriticalDamp(); -	// MANIPULATORS +	// Updates all the known interp delta values for fast lookup in calls to getInterpolant(InterpDelta) +	//  	static void updateInterpolants(); +	static inline void setInterpolantConstant(InterpDelta whichDelta, const F32 time_constant) +	{ +		llassert(whichDelta < kNumCachedInterpolants); +		sInterpolants[whichDelta] = time_constant; +	} +  	// ACCESSORS -	static F32 getInterpolant(const F32 time_constant, BOOL use_cache = TRUE); +	static inline F32 getInterpolant(InterpDelta whichDelta) +	{ +		llassert(whichDelta < kNumCachedInterpolants); +		return sInterpolatedValues[whichDelta]; +	} + +	static inline F32 getInterpolant(const F32 time_constant) +	{ +		return llclamp((sTimeDelta / time_constant), 0.0f, 1.0f); +	}  protected:	  	static LLFrameTimer sInternalTimer;	// frame timer for calculating deltas -	static std::map<F32, F32> 	sInterpolants; +	//static std::map<F32, F32> 	sInterpolants; +	static F32					sInterpolants[kNumCachedInterpolants]; +	static F32					sInterpolatedValues[kNumCachedInterpolants];  	static F32					sTimeDelta;  };  #endif  // LL_LLCRITICALDAMP_H + diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp index 0804be358f..65ef4322f6 100644 --- a/indra/llcommon/llinstancetracker.cpp +++ b/indra/llcommon/llinstancetracker.cpp @@ -42,4 +42,5 @@ void * & LLInstanceTrackerBase::getInstances(InstanceTrackType t)  	// key DOES exist, insert() simply returns (iterator, false). One lookup  	// handles both cases.  	return sInstanceTrackerData[t]; -}
\ No newline at end of file +} + diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index e725bdd9fa..528af83b8f 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -36,19 +36,68 @@ class LLMutex ;  #define LL_CHECK_MEMORY  #endif +LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); + +#ifdef SHOW_ASSERT +#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment)) +#else +#define ll_assert_aligned(ptr,alignment) +#endif + +#include <xmmintrin.h> + +template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)  +{  +	return reinterpret_cast<T*>( +		(reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF); +} + +template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)  +{  +	return reinterpret_cast<T*>( +		(reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F); +} + +#if LL_LINUX || LL_DARWIN + +#define			LL_ALIGN_PREFIX(x) +#define			LL_ALIGN_POSTFIX(x)		__attribute__((aligned(x))) + +#elif LL_WINDOWS + +#define			LL_ALIGN_PREFIX(x)		__declspec(align(x)) +#define			LL_ALIGN_POSTFIX(x) + +#else +#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined" +#endif + +#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) +  inline void* ll_aligned_malloc( size_t size, int align )  { +#if defined(LL_WINDOWS) +	return _aligned_malloc(size, align); +#else  	void* mem = malloc( size + (align - 1) + sizeof(void*) );  	char* aligned = ((char*)mem) + sizeof(void*);  	aligned += align - ((uintptr_t)aligned & (align - 1));  	((void**)aligned)[-1] = mem;  	return aligned; +#endif  }  inline void ll_aligned_free( void* ptr )  { -	free( ((void**)ptr)[-1] ); +#if defined(LL_WINDOWS) +	_aligned_free(ptr); +#else +	if (ptr) +	{ +		free( ((void**)ptr)[-1] ); +	} +#endif  }  #if !LL_USE_TCMALLOC diff --git a/indra/llcommon/llstaticstringtable.h b/indra/llcommon/llstaticstringtable.h index 05b0848e30..d7e0e8a08d 100644 --- a/indra/llcommon/llstaticstringtable.h +++ b/indra/llcommon/llstaticstringtable.h @@ -1,81 +1,82 @@ -/** 
 - * @file llstringtable.h
 - * @brief The LLStringTable class provides a _fast_ method for finding
 - * unique copies of strings.
 - *
 - * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_STATIC_STRING_TABLE_H
 -#define LL_STATIC_STRING_TABLE_H
 -
 -#include "lldefs.h"
 -#include <boost/unordered_map.hpp>
 -#include "llstl.h"
 -
 -class LLStaticHashedString
 -{
 -public:
 -
 -	LLStaticHashedString(const std::string& s)
 -	{
 -		string_hash = makehash(s);
 -		string		= s;
 -	}
 -
 -	const std::string&	String() const { return string;		}
 -	size_t				Hash()	 const { return string_hash;  }
 -
 -	bool operator==(const LLStaticHashedString& b) const { return Hash() == b.Hash(); }
 -
 -protected:
 -
 -	size_t makehash(const std::string& s)
 -	{
 -		size_t len = s.size();
 -		const char* c = s.c_str();
 -		size_t hashval = 0;
 -		for (size_t i=0; i<len; i++)
 -		{
 -			hashval = ((hashval<<5) + hashval) + *c++;
 -		}
 -		return hashval;
 -	}
 -
 -	std::string string;
 -	size_t		string_hash;
 -};
 -
 -struct LLStaticStringHasher
 -{
 -	enum { bucket_size = 8 };
 -	size_t operator()(const LLStaticHashedString& key_value) const { return key_value.Hash(); }
 -	bool operator()(const LLStaticHashedString& left, const LLStaticHashedString& right) const { return left.Hash() < right.Hash(); }
 -};
 -
 -template< typename MappedObject >
 -class LL_COMMON_API LLStaticStringTable
 -	: public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
 -{
 -};
 -
 -#endif
\ No newline at end of file +/**  + * @file llstringtable.h + * @brief The LLStringTable class provides a _fast_ method for finding + * unique copies of strings. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_STATIC_STRING_TABLE_H +#define LL_STATIC_STRING_TABLE_H + +#include "lldefs.h" +#include <boost/unordered_map.hpp> +#include "llstl.h" + +class LLStaticHashedString +{ +public: + +	LLStaticHashedString(const std::string& s) +	{ +		string_hash = makehash(s); +		string		= s; +	} + +	const std::string&	String() const { return string;		} +	size_t				Hash()	 const { return string_hash;  } + +	bool operator==(const LLStaticHashedString& b) const { return Hash() == b.Hash(); } + +protected: + +	size_t makehash(const std::string& s) +	{ +		size_t len = s.size(); +		const char* c = s.c_str(); +		size_t hashval = 0; +		for (size_t i=0; i<len; i++) +		{ +			hashval = ((hashval<<5) + hashval) + *c++; +		} +		return hashval; +	} + +	std::string string; +	size_t		string_hash; +}; + +struct LLStaticStringHasher +{ +	enum { bucket_size = 8 }; +	size_t operator()(const LLStaticHashedString& key_value) const { return key_value.Hash(); } +	bool   operator()(const LLStaticHashedString& left, const LLStaticHashedString& right) const { return left.Hash() < right.Hash(); } +}; + +template< typename MappedObject > +class LL_COMMON_API LLStaticStringTable +	: public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher > +{ +}; + +#endif + diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index c4cefdb4fa..d141298f69 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -107,15 +107,14 @@ public:  	inline void rotate(const LLVector4a& v, LLVector4a& res)  	{ +		LLVector4a y,z; +  		res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); -		res.mul(mMatrix[0]); -		 -		LLVector4a y;  		y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); -		y.mul(mMatrix[1]); - -		LLVector4a z;  		z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); +		 +		res.mul(mMatrix[0]); +		y.mul(mMatrix[1]);  		z.mul(mMatrix[2]);  		res.add(y); diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h index 01458521ec..cebd2ace7d 100644 --- a/indra/llmath/llsimdmath.h +++ b/indra/llmath/llsimdmath.h @@ -39,34 +39,6 @@  #include <stdint.h>  #endif -template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)  -{  -	return reinterpret_cast<T*>( -		(reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF); -} - -template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)  -{  -	return reinterpret_cast<T*>( -		(reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F); -} - -#if LL_LINUX || LL_DARWIN - -#define			LL_ALIGN_PREFIX(x) -#define			LL_ALIGN_POSTFIX(x)		__attribute__((aligned(x))) - -#elif LL_WINDOWS - -#define			LL_ALIGN_PREFIX(x)		__declspec(align(x)) -#define			LL_ALIGN_POSTFIX(x) - -#else -#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined" -#endif - -#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) -  #include <xmmintrin.h>  #include <emmintrin.h> diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp index 6edeb0fefe..570fa41a43 100644 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -41,55 +41,7 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast<const LLVector4a&> ( F  /*static */void LLVector4a::memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes)  { -	assert(src != NULL); -	assert(dst != NULL); -	assert(bytes > 0); -	assert((bytes % sizeof(F32))== 0);  -	ll_assert_aligned(src,16); -	ll_assert_aligned(dst,16); -	assert(bytes%16==0); - -	F32* end = dst + (bytes / sizeof(F32) ); - -	if (bytes > 64) -	{ -		F32* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst); -		 -		//at least 64 (16*4) bytes before the end of the destination, switch to 16 byte copies -		F32* end_64 = end-16; -		 -		_mm_prefetch((char*)begin_64, _MM_HINT_NTA); -		_mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA); -		_mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA); -		_mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA); -		 -		while (dst < begin_64) -		{ -			copy4a(dst, src); -			dst += 4; -			src += 4; -		} -		 -		while (dst < end_64) -		{ -			_mm_prefetch((char*)src + 512, _MM_HINT_NTA); -			_mm_prefetch((char*)dst + 512, _MM_HINT_NTA); -			copy4a(dst, src); -			copy4a(dst+4, src+4); -			copy4a(dst+8, src+8); -			copy4a(dst+12, src+12); -			 -			dst += 16; -			src += 16; -		} -	} - -	while (dst < end) -	{ -		copy4a(dst, src); -		dst += 4; -		src += 4; -	} +        ll_memcpy_nonaliased_aligned_16((char*)dst, (char*)src, bytes);  }  void LLVector4a::setRotated( const LLRotation& rot, const LLVector4a& vec ) diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index 7c52ffef21..35a67204ec 100644 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -460,16 +460,13 @@ inline void LLVector4a::setMax(const LLVector4a& lhs, const LLVector4a& rhs)  	mQ = _mm_max_ps(lhs.mQ, rhs.mQ);  } -// Set this to  (c * lhs) + rhs * ( 1 - c) +// Set this to  lhs + (rhs-lhs)*c  inline void LLVector4a::setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F32 c)  { -	LLVector4a a = lhs; -	a.mul(c); -	 -	LLVector4a b = rhs; -	b.mul(1.f-c); -	 -	setAdd(a, b); +	LLVector4a t; +	t.setSub(rhs,lhs); +	t.mul(c); +	setAdd(lhs, t);  }  inline LLBool32 LLVector4a::isFinite3() const diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c476f8593b..602f2c29e5 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -94,6 +94,8 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1;  extern BOOL gDebugGL; +bool less_than_max_mag(const LLVector4a& vec); +  BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)  {      	LLVector3 test = (pt2-pt1)%(pt3-pt2); @@ -474,7 +476,7 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3  	const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };  	F32 scale = 0.5f;  	F32 t, t_step, t_first, t_fraction, ang, ang_step; -	LLVector3 pt1,pt2; +	LLVector4a pt1,pt2;  	F32 begin  = params.getBegin();  	F32 end    = params.getEnd(); @@ -497,20 +499,21 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3  	// Starting t and ang values for the first face  	t = t_first;  	ang = 2.0f*F_PI*(t*ang_scale + offset); -	pt1.setVec(cos(ang)*scale,sin(ang)*scale, t); +	pt1.set(cos(ang)*scale,sin(ang)*scale, t);  	// Increment to the next point.  	// pt2 is the end point on the fractional face  	t += t_step;  	ang += ang_step; -	pt2.setVec(cos(ang)*scale,sin(ang)*scale,t); +	pt2.set(cos(ang)*scale,sin(ang)*scale,t);  	t_fraction = (begin - t_first)*sides;  	// Only use if it's not almost exactly on an edge.  	if (t_fraction < 0.9999f)  	{ -		LLVector3 new_pt = lerp(pt1, pt2, t_fraction); +		LLVector4a new_pt; +		new_pt.setLerp(pt1, pt2, t_fraction);  		mProfile.push_back(new_pt);  	} @@ -518,12 +521,17 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3  	while (t < end)  	{  		// Iterate through all the integer steps of t. -		pt1.setVec(cos(ang)*scale,sin(ang)*scale,t); +		pt1.set(cos(ang)*scale,sin(ang)*scale,t);  		if (mProfile.size() > 0) { -			LLVector3 p = mProfile[mProfile.size()-1]; +			LLVector4a p = mProfile[mProfile.size()-1];  			for (S32 i = 0; i < split && mProfile.size() > 0; i++) { -				mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1)); +				//mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1)); +				LLVector4a new_pt; +				new_pt.setSub(pt1, p); +				new_pt.mul(1.0f/(float)(split+1) * (float)(i+1)); +				new_pt.add(p); +				mProfile.push_back(new_pt);  			}  		}  		mProfile.push_back(pt1); @@ -536,18 +544,25 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3  	// pt1 is the first point on the fractional face  	// pt2 is the end point on the fractional face -	pt2.setVec(cos(ang)*scale,sin(ang)*scale,t); +	pt2.set(cos(ang)*scale,sin(ang)*scale,t);  	// Find the fraction that we need to add to the end point.  	t_fraction = (end - (t - t_step))*sides;  	if (t_fraction > 0.0001f)  	{ -		LLVector3 new_pt = lerp(pt1, pt2, t_fraction); +		LLVector4a new_pt; +		new_pt.setLerp(pt1, pt2, t_fraction);  		if (mProfile.size() > 0) { -			LLVector3 p = mProfile[mProfile.size()-1]; +			LLVector4a p = mProfile[mProfile.size()-1];  			for (S32 i = 0; i < split && mProfile.size() > 0; i++) { -				mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1)); +				//mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1)); + +				LLVector4a pt1; +				pt1.setSub(new_pt, p); +				pt1.mul(1.0f/(float)(split+1) * (float)(i+1)); +				pt1.add(p); +				mProfile.push_back(pt1);  			}  		}  		mProfile.push_back(new_pt); @@ -568,7 +583,7 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3  		if (params.getHollow() <= 0)  		{  			// put center point if not hollow. -			mProfile.push_back(LLVector3(0,0,0)); +			mProfile.push_back(LLVector4a(0,0,0));  		}  	}  	else @@ -581,103 +596,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3  	mTotal = mProfile.size();  } -void LLProfile::genNormals(const LLProfileParams& params) -{ -	S32 count = mProfile.size(); - -	S32 outer_count; -	if (mTotalOut) -	{ -		outer_count = mTotalOut; -	} -	else -	{ -		outer_count = mTotal / 2; -	} - -	mEdgeNormals.resize(count * 2); -	mEdgeCenters.resize(count * 2); -	mNormals.resize(count); - -	LLVector2 pt0,pt1; - -	BOOL hollow = (params.getHollow() > 0); - -	S32 i0, i1, i2, i3, i4; - -	// Parametrically generate normal -	for (i2 = 0; i2 < count; i2++) -	{ -		mNormals[i2].mV[0] = mProfile[i2].mV[0]; -		mNormals[i2].mV[1] = mProfile[i2].mV[1]; -		if (hollow && (i2 >= outer_count)) -		{ -			mNormals[i2] *= -1.f; -		} -		if (mNormals[i2].magVec() < 0.001) -		{ -			// Special case for point at center, get adjacent points. -			i1 = (i2 - 1) >= 0 ? i2 - 1 : count - 1; -			i0 = (i1 - 1) >= 0 ? i1 - 1 : count - 1; -			i3 = (i2 + 1) < count ? i2 + 1 : 0; -			i4 = (i3 + 1) < count ? i3 + 1 : 0; - -			pt0.setVec(mProfile[i1].mV[VX] + mProfile[i1].mV[VX] - mProfile[i0].mV[VX],  -				mProfile[i1].mV[VY] + mProfile[i1].mV[VY] - mProfile[i0].mV[VY]); -			pt1.setVec(mProfile[i3].mV[VX] + mProfile[i3].mV[VX] - mProfile[i4].mV[VX],  -				mProfile[i3].mV[VY] + mProfile[i3].mV[VY] - mProfile[i4].mV[VY]); - -			mNormals[i2] = pt0 + pt1; -			mNormals[i2] *= 0.5f; -		} -		mNormals[i2].normVec(); -	} - -	S32 num_normal_sets = isConcave() ? 2 : 1; -	for (S32 normal_set = 0; normal_set < num_normal_sets; normal_set++) -	{ -		S32 point_num; -		for (point_num = 0; point_num < mTotal; point_num++) -		{ -			LLVector3 point_1 = mProfile[point_num]; -			point_1.mV[VZ] = 0.f; - -			LLVector3 point_2; -			 -			if (isConcave() && normal_set == 0 && point_num == (mTotal - 1) / 2) -			{ -				point_2 = mProfile[mTotal - 1]; -			} -			else if (isConcave() && normal_set == 1 && point_num == mTotal - 1) -			{ -				point_2 = mProfile[(mTotal - 1) / 2]; -			} -			else -			{ -				LLVector3 delta_pos; -				S32 neighbor_point = (point_num + 1) % mTotal; -				while(delta_pos.magVecSquared() < 0.01f * 0.01f) -				{ -					point_2 = mProfile[neighbor_point]; -					delta_pos = point_2 - point_1; -					neighbor_point = (neighbor_point + 1) % mTotal; -					if (neighbor_point == point_num) -					{ -						break; -					} -				} -			} - -			point_2.mV[VZ] = 0.f; -			LLVector3 face_normal = (point_2 - point_1) % LLVector3::z_axis; -			face_normal.normVec(); -			mEdgeNormals[normal_set * count + point_num] = face_normal; -			mEdgeCenters[normal_set * count + point_num] = lerp(point_1, point_2, 0.5f); -		} -	} -} - -  // Hollow is percent of the original bounding box, not of this particular  // profile's geometry.  Thus, a swept triangle needs lower hollow values than  // a swept square. @@ -693,12 +611,13 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3  	Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); -	std::vector<LLVector3> pt; +	static LLAlignedArray<LLVector4a,64> pt;  	pt.resize(mTotal) ;  	for (S32 i=mTotalOut;i<mTotal;i++)  	{ -		pt[i] = mProfile[i] * box_hollow; +		pt[i] = mProfile[i]; +		pt[i].mul(box_hollow);  	}  	S32 j=mTotal-1; @@ -844,8 +763,8 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai  		detail = MIN_LOD;  	} -	mProfile.clear(); -	mFaces.clear(); +	mProfile.resize(0); +	mFaces.resize(0);  	// Generate the face data  	S32 i; @@ -877,10 +796,12 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai  				addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE);  			} +			LLVector4a scale(1,1,4,1); +  			for (i = 0; i <(S32) mProfile.size(); i++)  			{  				// Scale by 4 to generate proper tex coords. -				mProfile[i].mV[2] *= 4.f; +				mProfile[i].mul(scale);  			}  			if (hollow) @@ -913,10 +834,11 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai  	case  LL_PCODE_PROFILE_EQUALTRI:  		{  			genNGon(params, 3,0, 0, 1, split); +			LLVector4a scale(1,1,3,1);  			for (i = 0; i <(S32) mProfile.size(); i++)  			{  				// Scale by 3 to generate proper tex coords. -				mProfile[i].mV[2] *= 3.f; +				mProfile[i].mul(scale);  			}  			if (path_open) @@ -1094,8 +1016,6 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai  			addFace(mTotal-2, 2,0.5,LL_FACE_PROFILE_END, TRUE);  		}  	} -	 -	//genNormals(params);  	return TRUE;  } @@ -1379,25 +1299,29 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en  	// the path begins at the correct cut.  	F32 step= 1.0f / sides;  	F32 t	= params.getBegin(); -	pt		= vector_append(mPath, 1); +	pt		= mPath.append(1);  	ang		= 2.0f*F_PI*revolutions * t;  	s		= sin(ang)*lerp(radius_start, radius_end, t);	  	c		= cos(ang)*lerp(radius_start, radius_end, t); -	pt->mPos.setVec(0 + lerp(0,params.getShear().mV[0],s) +	pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)  					  + lerp(-skew ,skew, t) * 0.5f,  					c + lerp(0,params.getShear().mV[1],s),   					s); -	pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t); -	pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t); +	pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), +		hole_y * lerp(taper_y_begin, taper_y_end, t), +		0,1);  	pt->mTexT  = t;  	// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02  	twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);  	// Rotate the point around the circle's center.  	qang.setQuat   (ang,path_axis); -	pt->mRot   = twist * qang; + +	LLMatrix3 rot(twist * qang); + +	pt->mRot.loadu(rot);  	t+=step; @@ -1408,51 +1332,55 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en  	// Run through the non-cut dependent points.  	while (t < params.getEnd())  	{ -		pt		= vector_append(mPath, 1); +		pt		= mPath.append(1);  		ang = 2.0f*F_PI*revolutions * t;  		c   = cos(ang)*lerp(radius_start, radius_end, t);  		s   = sin(ang)*lerp(radius_start, radius_end, t); -		pt->mPos.setVec(0 + lerp(0,params.getShear().mV[0],s) +		pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)  					      + lerp(-skew ,skew, t) * 0.5f,  						c + lerp(0,params.getShear().mV[1],s),   						s); -		pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t); -		pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t); +		pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), +					hole_y * lerp(taper_y_begin, taper_y_end, t), +					0,1);  		pt->mTexT  = t;  		// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02  		twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);  		// Rotate the point around the circle's center.  		qang.setQuat   (ang,path_axis); -		pt->mRot	= twist * qang; - +		LLMatrix3 tmp(twist*qang); +		pt->mRot.loadu(tmp); +		  		t+=step;  	}  	// Make one final pass for the end cut.  	t = params.getEnd(); -	pt		= vector_append(mPath, 1); +	pt		= mPath.append(1);  	ang = 2.0f*F_PI*revolutions * t;  	c   = cos(ang)*lerp(radius_start, radius_end, t);  	s   = sin(ang)*lerp(radius_start, radius_end, t); -	pt->mPos.setVec(0 + lerp(0,params.getShear().mV[0],s) +	pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)  					  + lerp(-skew ,skew, t) * 0.5f,  					c + lerp(0,params.getShear().mV[1],s),   					s); -	pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t); -	pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t); +	pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), +				   hole_y * lerp(taper_y_begin, taper_y_end, t), +				   0,1);  	pt->mTexT  = t;  	// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02  	twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);  	// Rotate the point around the circle's center.  	qang.setQuat   (ang,path_axis); -	pt->mRot   = twist * qang; - +	LLMatrix3 tmp(twist*qang); +	pt->mRot.loadu(tmp); +	  	mTotal = mPath.size();  } @@ -1549,7 +1477,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,  	mDirty = FALSE;  	S32 np = 2; // hardcode for line -	mPath.clear(); +	mPath.resize(0);  	mOpen = TRUE;  	// Is this 0xf0 mask really necessary?  DK 03/02/05 @@ -1575,12 +1503,16 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,  			for (S32 i=0;i<np;i++)  			{  				F32 t = lerp(params.getBegin(),params.getEnd(),(F32)i * mStep); -				mPath[i].mPos.setVec(lerp(0,params.getShear().mV[0],t), +				mPath[i].mPos.set(lerp(0,params.getShear().mV[0],t),  									 lerp(0,params.getShear().mV[1],t),  									 t - 0.5f); -				mPath[i].mRot.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1); -				mPath[i].mScale.mV[0] = lerp(start_scale.mV[0],end_scale.mV[0],t); -				mPath[i].mScale.mV[1] = lerp(start_scale.mV[1],end_scale.mV[1],t); +				LLQuaternion quat; +				quat.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1); +				LLMatrix3 tmp(quat); +				mPath[i].mRot.loadu(tmp); +				mPath[i].mScale.set(lerp(start_scale.mV[0],end_scale.mV[0],t), +									lerp(start_scale.mV[1],end_scale.mV[1],t), +									0,1);  				mPath[i].mTexT        = t;  			}  		} @@ -1617,7 +1549,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,  			F32 toggle = 0.5f;  			for (S32 i=0;i<(S32)mPath.size();i++)  			{ -				mPath[i].mPos.mV[0] = toggle; +				mPath[i].mPos.getF32ptr()[0] = toggle;  				if (toggle == 0.5f)  					toggle = -0.5f;  				else @@ -1638,13 +1570,16 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,  		for (S32 i=0;i<np;i++)  		{  			F32 t = (F32)i * mStep; -			mPath[i].mPos.setVec(0, +			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)); -			mPath[i].mScale.mV[0] = lerp(1,params.getScale().mV[0],t); -			mPath[i].mScale.mV[1] = lerp(1,params.getScale().mV[1],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; -			mPath[i].mRot.setQuat(F_PI * params.getTwist() * t,1,0,0); +			LLQuaternion quat; +			quat.setQuat(F_PI * params.getTwist() * t,1,0,0); +			LLMatrix3 tmp(quat); +			mPath[i].mRot.loadu(tmp);  		}  		break; @@ -1668,11 +1603,15 @@ BOOL LLDynamicPath::generate(const LLPathParams& params, F32 detail, S32 split,  		// Path hasn't been generated yet.  		// Some algorithms later assume at least TWO path points.  		resizePath(2); +		LLQuaternion quat; +		quat.setQuat(0,0,0); +		LLMatrix3 tmp(quat); +  		for (U32 i = 0; i < 2; i++)  		{ -			mPath[i].mPos.setVec(0, 0, 0); -			mPath[i].mRot.setQuat(0, 0, 0); -			mPath[i].mScale.setVec(1, 1); +			mPath[i].mPos.set(0, 0, 0); +			mPath[i].mRot.loadu(tmp); +			mPath[i].mScale.set(1, 1, 0, 1);  			mPath[i].mTexT = 0;  		}  	} @@ -2045,7 +1984,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge  	mHullIndices = NULL;  	mNumHullPoints = 0;  	mNumHullIndices = 0; - +	  	// set defaults  	if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)  	{ @@ -2105,6 +2044,7 @@ LLVolume::~LLVolume()  BOOL LLVolume::generate()  { +	LL_CHECK_MEMORY  	llassert_always(mProfilep);  	//Added 10.03.05 Dave Parks @@ -2141,20 +2081,6 @@ BOOL LLVolume::generate()  		mLODScaleBias.setVec(0.6f, 0.6f, 0.6f);  	} -	//******************************************************************** -	//debug info, to be removed -	if((U32)(mPathp->mPath.size() * mProfilep->mProfile.size()) > (1u << 20)) -	{ -		llinfos << "sizeS: " << mPathp->mPath.size() << " sizeT: " << mProfilep->mProfile.size() << llendl ; -		llinfos << "path_detail : " << path_detail << " split: " << split << " profile_detail: " << profile_detail << llendl ; -		llinfos << mParams << llendl ; -		llinfos << "more info to check if mProfilep is deleted or not." << llendl ; -		llinfos << mProfilep->mNormals.size() << " : " << mProfilep->mFaces.size() << " : " << mProfilep->mEdgeNormals.size() << " : " << mProfilep->mEdgeCenters.size() << llendl ; - -		llerrs << "LLVolume corrupted!" << llendl ; -	} -	//******************************************************************** -  	BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split);  	BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split); @@ -2163,21 +2089,6 @@ BOOL LLVolume::generate()  		S32 sizeS = mPathp->mPath.size();  		S32 sizeT = mProfilep->mProfile.size(); -		//******************************************************************** -		//debug info, to be removed -		if((U32)(sizeS * sizeT) > (1u << 20)) -		{ -			llinfos << "regenPath: " << (S32)regenPath << " regenProf: " << (S32)regenProf << llendl ; -			llinfos << "sizeS: " << sizeS << " sizeT: " << sizeT << llendl ; -			llinfos << "path_detail : " << path_detail << " split: " << split << " profile_detail: " << profile_detail << llendl ; -			llinfos << mParams << llendl ; -			llinfos << "more info to check if mProfilep is deleted or not." << llendl ; -			llinfos << mProfilep->mNormals.size() << " : " << mProfilep->mFaces.size() << " : " << mProfilep->mEdgeNormals.size() << " : " << mProfilep->mEdgeCenters.size() << llendl ; - -			llerrs << "LLVolume corrupted!" << llendl ; -		} -		//******************************************************************** -  		sNumMeshPoints -= mMesh.size();  		mMesh.resize(sizeT * sizeS);  		sNumMeshPoints += mMesh.size();		 @@ -2185,22 +2096,39 @@ BOOL LLVolume::generate()  		//generate vertex positions  		// Run along the path. +		LLVector4a* dst = mMesh.mArray; +  		for (S32 s = 0; s < sizeS; ++s)  		{ -			LLVector2  scale = mPathp->mPath[s].mScale; -			LLQuaternion rot = mPathp->mPath[s].mRot; +			F32* scale = mPathp->mPath[s].mScale.getF32ptr(); +			 +			F32 sc [] =  +			{ scale[0], 0, 0, 0, +				0, scale[1], 0, 0, +				0, 0, scale[2], 0, +					0, 0, 0, 1 }; +			 +			LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix); +			LLMatrix4 scale_mat(sc); +			 +			scale_mat *= rot; +			 +			LLMatrix4a rot_mat; +			rot_mat.loadu(scale_mat); +			 +			LLVector4a* profile = mProfilep->mProfile.mArray; +			LLVector4a* end_profile = profile+sizeT; +			LLVector4a offset = mPathp->mPath[s].mPos; + +			LLVector4a tmp;  			// Run along the profile. -			for (S32 t = 0; t < sizeT; ++t) +			while (profile < end_profile)  			{ -				S32 m = s*sizeT + t; -				Point& pt = mMesh[m]; -				 -				pt.mPos.mV[0] = mProfilep->mProfile[t].mV[0] * scale.mV[0]; -				pt.mPos.mV[1] = mProfilep->mProfile[t].mV[1] * scale.mV[1]; -				pt.mPos.mV[2] = 0.0f; -				pt.mPos       = pt.mPos * rot; -				pt.mPos      += mPathp->mPath[s].mPos; +				rot_mat.rotate(*profile++, tmp); +				dst->setAdd(tmp,offset); +				llassert(less_than_max_mag(*dst)); +				++dst;  			}  		} @@ -2210,9 +2138,11 @@ BOOL LLVolume::generate()  			LLFaceID id = iter->mFaceID;  			mFaceMask |= id;  		} -		 +		LL_CHECK_MEMORY  		return TRUE;  	} + +	LL_CHECK_MEMORY  	return FALSE;  } @@ -2790,14 +2720,16 @@ void LLVolume::createVolumeFaces()  } -inline LLVector3 sculpt_rgb_to_vector(U8 r, U8 g, U8 b) +inline LLVector4a sculpt_rgb_to_vector(U8 r, U8 g, U8 b)  {  	// maps RGB values to vector values [0..255] -> [-0.5..0.5] -	LLVector3 value; -	value.mV[VX] = r / 255.f - 0.5f; -	value.mV[VY] = g / 255.f - 0.5f; -	value.mV[VZ] = b / 255.f - 0.5f; +	LLVector4a value; +	LLVector4a sub(0.5f, 0.5f, 0.5f); +	value.set(r,g,b); +	value.mul(1.f/255.f); +	value.sub(sub); +	  	return value;  } @@ -2817,21 +2749,21 @@ inline U32 sculpt_st_to_index(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_w  } -inline LLVector3 sculpt_index_to_vector(U32 index, const U8* sculpt_data) +inline LLVector4a sculpt_index_to_vector(U32 index, const U8* sculpt_data)  { -	LLVector3 v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); +	LLVector4a v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]);  	return v;  } -inline LLVector3 sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) +inline LLVector4a sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)  {  	U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components);  	return sculpt_index_to_vector(index, sculpt_data);  } -inline LLVector3 sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) +inline LLVector4a sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)  {  	U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); @@ -2853,15 +2785,26 @@ F32 LLVolume::sculptGetSurfaceArea()  		for (S32 t = 0; t < sizeT-1; t++)  		{  			// get four corners of quad -			LLVector3 p1 = mMesh[(s  )*sizeT + (t  )].mPos; -			LLVector3 p2 = mMesh[(s+1)*sizeT + (t  )].mPos; -			LLVector3 p3 = mMesh[(s  )*sizeT + (t+1)].mPos; -			LLVector3 p4 = mMesh[(s+1)*sizeT + (t+1)].mPos; +			LLVector4a& p1 = mMesh[(s  )*sizeT + (t  )]; +			LLVector4a& p2 = mMesh[(s+1)*sizeT + (t  )]; +			LLVector4a& p3 = mMesh[(s  )*sizeT + (t+1)]; +			LLVector4a& p4 = mMesh[(s+1)*sizeT + (t+1)];  			// compute the area of the quad by taking the length of the cross product of the two triangles -			LLVector3 cross1 = (p1 - p2) % (p1 - p3); -			LLVector3 cross2 = (p4 - p2) % (p4 - p3); -			area += (cross1.magVec() + cross2.magVec()) / 2.f; +			LLVector4a v0,v1,v2,v3; +			v0.setSub(p1,p2); +			v1.setSub(p1,p3); +			v2.setSub(p4,p2); +			v3.setSub(p4,p3); + +			LLVector4a cross1, cross2; +			cross1.setCross3(v0,v1); +			cross2.setCross3(v2,v3); + +			//LLVector3 cross1 = (p1 - p2) % (p1 - p3); +			//LLVector3 cross2 = (p4 - p2) % (p4 - p3); +			 +			area += (cross1.getLength3() + cross2.getLength3()).getF32() / 2.f;  		}  	} @@ -2882,17 +2825,19 @@ void LLVolume::sculptGeneratePlaceholder()  		for (S32 t = 0; t < sizeT; t++)  		{  			S32 i = t + line; -			Point& pt = mMesh[i]; +			LLVector4a& pt = mMesh[i];  			F32 u = (F32)s/(sizeS-1);  			F32 v = (F32)t/(sizeT-1);  			const F32 RADIUS = (F32) 0.3; -					 -			pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); -			pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); -			pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS); +			 +			F32* p = pt.getF32ptr(); + +			p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); +			p[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); +			p[2] = (F32)(cos(F_PI * v) * RADIUS);  		}  		line += sizeT; @@ -2917,7 +2862,7 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8  		for (S32 t = 0; t < sizeT; t++)  		{  			S32 i = t + line; -			Point& pt = mMesh[i]; +			LLVector4a& pt = mMesh[i];  			S32 reversed_t = t; @@ -2974,11 +2919,12 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8  				}  			} -			pt.mPos = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data); +			pt = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data);  			if (sculpt_mirror)  			{ -				pt.mPos.mV[VX] *= -1.f; +				LLVector4a scale(-1.f,1,1,1); +				pt.mul(scale);  			}  		} @@ -3560,627 +3506,6 @@ bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 h  	return true;  } -S32 *LLVolume::getTriangleIndices(U32 &num_indices) const -{ -	S32 expected_num_triangle_indices = getNumTriangleIndices(); -	if (expected_num_triangle_indices > MAX_VOLUME_TRIANGLE_INDICES) -	{ -		// we don't allow LLVolumes with this many vertices -		llwarns << "Couldn't allocate triangle indices" << llendl; -		num_indices = 0; -		return NULL; -	} - -	S32* index = new S32[expected_num_triangle_indices]; -	S32 count = 0; - -	// Let's do this totally diffently, as we don't care about faces... -	// Counter-clockwise triangles are forward facing... - -	BOOL open = getProfile().isOpen(); -	BOOL hollow = (mParams.getProfileParams().getHollow() > 0); -	BOOL path_open = getPath().isOpen(); -	S32 size_s, size_s_out, size_t; -	S32 s, t, i; -	size_s = getProfile().getTotal(); -	size_s_out = getProfile().getTotalOut(); -	size_t = getPath().mPath.size(); - -	// NOTE -- if the construction of the triangles below ever changes -	// then getNumTriangleIndices() method may also have to be updated. - -	if (open)		/* Flawfinder: ignore */ -	{ -		if (hollow) -		{ -			// Open hollow -- much like the closed solid, except we  -			// we need to stitch up the gap between s=0 and s=size_s-1 - -			for (t = 0; t < size_t - 1; t++) -			{ -				// The outer face, first cut, and inner face -				for (s = 0; s < size_s - 1; s++) -				{ -					i  = s + t*size_s; -					index[count++]  = i;				// x,y -					index[count++]  = i + 1;			// x+1,y -					index[count++]  = i + size_s;		// x,y+1 -	 -					index[count++]  = i + size_s;		// x,y+1 -					index[count++]  = i + 1;			// x+1,y -					index[count++]  = i + size_s + 1;	// x+1,y+1 -				} - -				// The other cut face -				index[count++]  = s + t*size_s;		// x,y -				index[count++]  = 0 + t*size_s;		// x+1,y -				index[count++]  = s + (t+1)*size_s;	// x,y+1 -	 -				index[count++]  = s + (t+1)*size_s;	// x,y+1 -				index[count++]  = 0 + t*size_s;		// x+1,y -				index[count++]  = 0 + (t+1)*size_s;	// x+1,y+1 -			} - -			// Do the top and bottom caps, if necessary -			if (path_open) -			{ -				// Top cap -				S32 pt1 = 0; -				S32 pt2 = size_s-1; -				S32 i   = (size_t - 1)*size_s; - -				while (pt2 - pt1 > 1) -				{ -					// Use the profile points instead of the mesh, since you want -					// the un-transformed profile distances. -					LLVector3 p1 = getProfile().mProfile[pt1]; -					LLVector3 p2 = getProfile().mProfile[pt2]; -					LLVector3 pa = getProfile().mProfile[pt1+1]; -					LLVector3 pb = getProfile().mProfile[pt2-1]; - -					p1.mV[VZ] = 0.f; -					p2.mV[VZ] = 0.f; -					pa.mV[VZ] = 0.f; -					pb.mV[VZ] = 0.f; - -					// Use area of triangle to determine backfacing -					F32 area_1a2, area_1ba, area_21b, area_2ab; -					area_1a2 =  (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) + -								(pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) + -								(p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]); - -					area_1ba =  (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -								(pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) + -								(pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]); - -					area_21b =  (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) + -								(p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -								(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); - -					area_2ab =  (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) + -								(pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) + -								(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); - -					BOOL use_tri1a2 = TRUE; -					BOOL tri_1a2 = TRUE; -					BOOL tri_21b = TRUE; - -					if (area_1a2 < 0) -					{ -						tri_1a2 = FALSE; -					} -					if (area_2ab < 0) -					{ -						// Can't use, because it contains point b -						tri_1a2 = FALSE; -					} -					if (area_21b < 0) -					{ -						tri_21b = FALSE; -					} -					if (area_1ba < 0) -					{ -						// Can't use, because it contains point b -						tri_21b = FALSE; -					} - -					if (!tri_1a2) -					{ -						use_tri1a2 = FALSE; -					} -					else if (!tri_21b) -					{ -						use_tri1a2 = TRUE; -					} -					else -					{ -						LLVector3 d1 = p1 - pa; -						LLVector3 d2 = p2 - pb; - -						if (d1.magVecSquared() < d2.magVecSquared()) -						{ -							use_tri1a2 = TRUE; -						} -						else -						{ -							use_tri1a2 = FALSE; -						} -					} - -					if (use_tri1a2) -					{ -						index[count++] = pt1 + i; -						index[count++] = pt1 + 1 + i; -						index[count++] = pt2 + i; -						pt1++; -					} -					else -					{ -						index[count++] = pt1 + i; -						index[count++] = pt2 - 1 + i; -						index[count++] = pt2 + i; -						pt2--; -					} -				} - -				// Bottom cap -				pt1          = 0; -				pt2          = size_s-1; -				while (pt2 - pt1 > 1) -				{ -					// Use the profile points instead of the mesh, since you want -					// the un-transformed profile distances. -					LLVector3 p1 = getProfile().mProfile[pt1]; -					LLVector3 p2 = getProfile().mProfile[pt2]; -					LLVector3 pa = getProfile().mProfile[pt1+1]; -					LLVector3 pb = getProfile().mProfile[pt2-1]; - -					p1.mV[VZ] = 0.f; -					p2.mV[VZ] = 0.f; -					pa.mV[VZ] = 0.f; -					pb.mV[VZ] = 0.f; - -					// Use area of triangle to determine backfacing -					F32 area_1a2, area_1ba, area_21b, area_2ab; -					area_1a2 =  (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) + -								(pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) + -								(p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]); - -					area_1ba =  (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -								(pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) + -								(pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]); - -					area_21b =  (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) + -								(p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -								(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); - -					area_2ab =  (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) + -								(pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) + -								(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); - -					BOOL use_tri1a2 = TRUE; -					BOOL tri_1a2 = TRUE; -					BOOL tri_21b = TRUE; - -					if (area_1a2 < 0) -					{ -						tri_1a2 = FALSE; -					} -					if (area_2ab < 0) -					{ -						// Can't use, because it contains point b -						tri_1a2 = FALSE; -					} -					if (area_21b < 0) -					{ -						tri_21b = FALSE; -					} -					if (area_1ba < 0) -					{ -						// Can't use, because it contains point b -						tri_21b = FALSE; -					} - -					if (!tri_1a2) -					{ -						use_tri1a2 = FALSE; -					} -					else if (!tri_21b) -					{ -						use_tri1a2 = TRUE; -					} -					else -					{ -						LLVector3 d1 = p1 - pa; -						LLVector3 d2 = p2 - pb; - -						if (d1.magVecSquared() < d2.magVecSquared()) -						{ -							use_tri1a2 = TRUE; -						} -						else -						{ -							use_tri1a2 = FALSE; -						} -					} - -					if (use_tri1a2) -					{ -						index[count++] = pt1; -						index[count++] = pt2; -						index[count++] = pt1 + 1; -						pt1++; -					} -					else -					{ -						index[count++] = pt1; -						index[count++] = pt2; -						index[count++] = pt2 - 1; -						pt2--; -					} -				} -			} -		} -		else -		{ -			// Open solid - -			for (t = 0; t < size_t - 1; t++) -			{ -				// Outer face + 1 cut face -				for (s = 0; s < size_s - 1; s++) -				{ -					i  = s + t*size_s; - -					index[count++]  = i;				// x,y -					index[count++]  = i + 1;			// x+1,y -					index[count++]  = i + size_s;		// x,y+1 - -					index[count++]  = i + size_s;		// x,y+1 -					index[count++]  = i + 1;			// x+1,y -					index[count++]  = i + size_s + 1;	// x+1,y+1 -				} - -				// The other cut face -				index[count++] = (size_s - 1) + (t*size_s);		// x,y -				index[count++] = 0 + t*size_s;					// x+1,y -				index[count++] = (size_s - 1) + (t+1)*size_s;	// x,y+1 - -				index[count++] = (size_s - 1) + (t+1)*size_s;	// x,y+1 -				index[count++] = 0 + (t*size_s);				// x+1,y -				index[count++] = 0 + (t+1)*size_s;				// x+1,y+1 -			} - -			// Do the top and bottom caps, if necessary -			if (path_open) -			{ -				for (s = 0; s < size_s - 2; s++) -				{ -					index[count++] = s+1; -					index[count++] = s; -					index[count++] = size_s - 1; -				} - -				// We've got a top cap -				S32 offset = (size_t - 1)*size_s; -				for (s = 0; s < size_s - 2; s++) -				{ -					// Inverted ordering from bottom cap. -					index[count++] = offset + size_s - 1; -					index[count++] = offset + s; -					index[count++] = offset + s + 1; -				} -			} -		} -	} -	else if (hollow) -	{ -		// Closed hollow -		// Outer face -		 -		for (t = 0; t < size_t - 1; t++) -		{ -			for (s = 0; s < size_s_out - 1; s++) -			{ -				i  = s + t*size_s; - -				index[count++]  = i;				// x,y -				index[count++]  = i + 1;			// x+1,y -				index[count++]  = i + size_s;		// x,y+1 - -				index[count++]  = i + size_s;		// x,y+1 -				index[count++]  = i + 1;			// x+1,y -				index[count++]  = i + 1 + size_s;	// x+1,y+1 -			} -		} - -		// Inner face -		// Invert facing from outer face -		for (t = 0; t < size_t - 1; t++) -		{ -			for (s = size_s_out; s < size_s - 1; s++) -			{ -				i  = s + t*size_s; - -				index[count++]  = i;				// x,y -				index[count++]  = i + 1;			// x+1,y -				index[count++]  = i + size_s;		// x,y+1 - -				index[count++]  = i + size_s;		// x,y+1 -				index[count++]  = i + 1;			// x+1,y -				index[count++]  = i + 1 + size_s;	// x+1,y+1 -			} -		} - -		// Do the top and bottom caps, if necessary -		if (path_open) -		{ -			// Top cap -			S32 pt1 = 0; -			S32 pt2 = size_s-1; -			S32 i   = (size_t - 1)*size_s; - -			while (pt2 - pt1 > 1) -			{ -				// Use the profile points instead of the mesh, since you want -				// the un-transformed profile distances. -				LLVector3 p1 = getProfile().mProfile[pt1]; -				LLVector3 p2 = getProfile().mProfile[pt2]; -				LLVector3 pa = getProfile().mProfile[pt1+1]; -				LLVector3 pb = getProfile().mProfile[pt2-1]; - -				p1.mV[VZ] = 0.f; -				p2.mV[VZ] = 0.f; -				pa.mV[VZ] = 0.f; -				pb.mV[VZ] = 0.f; - -				// Use area of triangle to determine backfacing -				F32 area_1a2, area_1ba, area_21b, area_2ab; -				area_1a2 =  (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) + -							(pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) + -							(p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]); - -				area_1ba =  (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -							(pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) + -							(pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]); - -				area_21b =  (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) + -							(p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -							(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); - -				area_2ab =  (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) + -							(pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) + -							(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); - -				BOOL use_tri1a2 = TRUE; -				BOOL tri_1a2 = TRUE; -				BOOL tri_21b = TRUE; - -				if (area_1a2 < 0) -				{ -					tri_1a2 = FALSE; -				} -				if (area_2ab < 0) -				{ -					// Can't use, because it contains point b -					tri_1a2 = FALSE; -				} -				if (area_21b < 0) -				{ -					tri_21b = FALSE; -				} -				if (area_1ba < 0) -				{ -					// Can't use, because it contains point b -					tri_21b = FALSE; -				} - -				if (!tri_1a2) -				{ -					use_tri1a2 = FALSE; -				} -				else if (!tri_21b) -				{ -					use_tri1a2 = TRUE; -				} -				else -				{ -					LLVector3 d1 = p1 - pa; -					LLVector3 d2 = p2 - pb; - -					if (d1.magVecSquared() < d2.magVecSquared()) -					{ -						use_tri1a2 = TRUE; -					} -					else -					{ -						use_tri1a2 = FALSE; -					} -				} - -				if (use_tri1a2) -				{ -					index[count++] = pt1 + i; -					index[count++] = pt1 + 1 + i; -					index[count++] = pt2 + i; -					pt1++; -				} -				else -				{ -					index[count++] = pt1 + i; -					index[count++] = pt2 - 1 + i; -					index[count++] = pt2 + i; -					pt2--; -				} -			} - -			// Bottom cap -			pt1          = 0; -			pt2          = size_s-1; -			while (pt2 - pt1 > 1) -			{ -				// Use the profile points instead of the mesh, since you want -				// the un-transformed profile distances. -				LLVector3 p1 = getProfile().mProfile[pt1]; -				LLVector3 p2 = getProfile().mProfile[pt2]; -				LLVector3 pa = getProfile().mProfile[pt1+1]; -				LLVector3 pb = getProfile().mProfile[pt2-1]; - -				p1.mV[VZ] = 0.f; -				p2.mV[VZ] = 0.f; -				pa.mV[VZ] = 0.f; -				pb.mV[VZ] = 0.f; - -				// Use area of triangle to determine backfacing -				F32 area_1a2, area_1ba, area_21b, area_2ab; -				area_1a2 =  (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) + -							(pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) + -							(p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]); - -				area_1ba =  (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -							(pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) + -							(pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]); - -				area_21b =  (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) + -							(p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -							(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); - -				area_2ab =  (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) + -							(pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) + -							(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); - -				BOOL use_tri1a2 = TRUE; -				BOOL tri_1a2 = TRUE; -				BOOL tri_21b = TRUE; - -				if (area_1a2 < 0) -				{ -					tri_1a2 = FALSE; -				} -				if (area_2ab < 0) -				{ -					// Can't use, because it contains point b -					tri_1a2 = FALSE; -				} -				if (area_21b < 0) -				{ -					tri_21b = FALSE; -				} -				if (area_1ba < 0) -				{ -					// Can't use, because it contains point b -					tri_21b = FALSE; -				} - -				if (!tri_1a2) -				{ -					use_tri1a2 = FALSE; -				} -				else if (!tri_21b) -				{ -					use_tri1a2 = TRUE; -				} -				else -				{ -					LLVector3 d1 = p1 - pa; -					LLVector3 d2 = p2 - pb; - -					if (d1.magVecSquared() < d2.magVecSquared()) -					{ -						use_tri1a2 = TRUE; -					} -					else -					{ -						use_tri1a2 = FALSE; -					} -				} - -				if (use_tri1a2) -				{ -					index[count++] = pt1; -					index[count++] = pt2; -					index[count++] = pt1 + 1; -					pt1++; -				} -				else -				{ -					index[count++] = pt1; -					index[count++] = pt2; -					index[count++] = pt2 - 1; -					pt2--; -				} -			} -		}		 -	} -	else -	{ -		// Closed solid.  Easy case. -		for (t = 0; t < size_t - 1; t++) -		{ -			for (s = 0; s < size_s - 1; s++) -			{ -				// Should wrap properly, but for now... -				i  = s + t*size_s; - -				index[count++]  = i;				// x,y -				index[count++]  = i + 1;			// x+1,y -				index[count++]  = i + size_s;		// x,y+1 - -				index[count++]  = i + size_s;		// x,y+1 -				index[count++]  = i + 1;			// x+1,y -				index[count++]  = i + size_s + 1;	// x+1,y+1 -			} -		} - -		// Do the top and bottom caps, if necessary -		if (path_open) -		{ -			// bottom cap -			for (s = 1; s < size_s - 2; s++) -			{ -				index[count++] = s+1; -				index[count++] = s; -				index[count++] = 0; -			} - -			// top cap -			S32 offset = (size_t - 1)*size_s; -			for (s = 1; s < size_s - 2; s++) -			{ -				// Inverted ordering from bottom cap. -				index[count++] = offset; -				index[count++] = offset + s; -				index[count++] = offset + s + 1; -			} -		} -	} - -#ifdef LL_DEBUG -	// assert that we computed the correct number of indices -	if (count != expected_num_triangle_indices ) -	{ -		llerrs << "bad index count prediciton:" -			<< "  expected=" << expected_num_triangle_indices  -			<< " actual=" << count << llendl; -	} -#endif - -#if 0 -	// verify that each index does not point beyond the size of the mesh -	S32 num_vertices = mMesh.size(); -	for (i = 0; i < count; i+=3) -	{ -		llinfos << index[i] << ":" << index[i+1] << ":" << index[i+2] << llendl; -		llassert(index[i] < num_vertices); -		llassert(index[i+1] < num_vertices); -		llassert(index[i+2] < num_vertices); -	} -#endif - -	num_indices = count; -	return index; -} -  void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts)  { //attempt to approximate the number of triangles that will result from generating a volume LoD set for the   	//supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost @@ -4198,63 +3523,6 @@ void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts)  	}  } -S32 LLVolume::getNumTriangleIndices() const -{ -	BOOL profile_open = getProfile().isOpen(); -	BOOL hollow = (mParams.getProfileParams().getHollow() > 0); -	BOOL path_open = getPath().isOpen(); - -	S32 size_s, size_s_out, size_t; -	size_s = getProfile().getTotal(); -	size_s_out = getProfile().getTotalOut(); -	size_t = getPath().mPath.size(); - -	S32 count = 0; -	if (profile_open)		/* Flawfinder: ignore */ -	{ -		if (hollow) -		{ -			// Open hollow -- much like the closed solid, except we  -			// we need to stitch up the gap between s=0 and s=size_s-1 -			count = (size_t - 1) * (((size_s -1) * 6) + 6); -		} -		else -		{ -			count = (size_t - 1) * (((size_s -1) * 6) + 6);  -		} -	} -	else if (hollow) -	{ -		// Closed hollow -		// Outer face -		count = (size_t - 1) * (size_s_out - 1) * 6; - -		// Inner face -		count += (size_t - 1) * ((size_s - 1) - size_s_out) * 6; -	} -	else -	{ -		// Closed solid.  Easy case. -		count = (size_t - 1) * (size_s - 1) * 6; -	} - -	if (path_open) -	{ -		S32 cap_triangle_count = size_s - 3; -		if ( profile_open -			|| hollow ) -		{ -			cap_triangle_count = size_s - 2; -		} -		if ( cap_triangle_count > 0 ) -		{ -			// top and bottom caps -			count += cap_triangle_count * 2 * 3; -		} -	} -	return count; -} -  S32 LLVolume::getNumTriangles(S32* vcount) const  { @@ -5180,6 +4448,7 @@ LLVolumeFace::LLVolumeFace() :  	mNumS(0),  	mNumT(0),  	mNumVertices(0), +	mNumAllocatedVertices(0),  	mNumIndices(0),  	mPositions(NULL),  	mNormals(NULL), @@ -5204,6 +4473,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)  	mNumS(0),  	mNumT(0),  	mNumVertices(0), +	mNumAllocatedVertices(0),  	mNumIndices(0),  	mPositions(NULL),  	mNormals(NULL), @@ -5241,8 +4511,6 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  	freeData(); -	LLVector4a::memcpyNonAliased16((F32*) mExtents, (F32*) src.mExtents, 3*sizeof(LLVector4a)); -  	resizeVertices(src.mNumVertices);  	resizeIndices(src.mNumIndices); @@ -5258,12 +4526,6 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  		{  			LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size);  		} -		else -		{ -			ll_aligned_free_16(mTexCoords) ; -			mTexCoords = NULL ; -		} -  		if (src.mBinormals)  		{ @@ -5311,12 +4573,13 @@ LLVolumeFace::~LLVolumeFace()  void LLVolumeFace::freeData()  { -	ll_aligned_free_16(mPositions); +	ll_aligned_free(mPositions);  	mPositions = NULL; -	ll_aligned_free_16( mNormals); + +	//normals and texture coordinates are part of the same buffer as mPositions, do not free them separately  	mNormals = NULL; -	ll_aligned_free_16(mTexCoords);  	mTexCoords = NULL; +  	ll_aligned_free_16(mIndices);  	mIndices = NULL;  	ll_aligned_free_16(mBinormals); @@ -5334,52 +4597,23 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)  	delete mOctree;  	mOctree = NULL; +	LL_CHECK_MEMORY  	BOOL ret = FALSE ;  	if (mTypeMask & CAP_MASK)  	{  		ret = createCap(volume, partial_build); +		LL_CHECK_MEMORY  	}  	else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK))  	{  		ret = createSide(volume, partial_build); +		LL_CHECK_MEMORY  	}  	else  	{  		llerrs << "Unknown/uninitialized face type!" << llendl;  	} -	//update the range of the texture coordinates -	if(ret) -	{ -		mTexCoordExtents[0].setVec(1.f, 1.f) ; -		mTexCoordExtents[1].setVec(0.f, 0.f) ; - -		for(U32 i = 0 ; i < mNumVertices ; i++) -		{ -			if(mTexCoordExtents[0].mV[0] > mTexCoords[i].mV[0]) -			{ -				mTexCoordExtents[0].mV[0] = mTexCoords[i].mV[0] ; -			} -			if(mTexCoordExtents[1].mV[0] < mTexCoords[i].mV[0]) -			{ -				mTexCoordExtents[1].mV[0] = mTexCoords[i].mV[0] ; -			} - -			if(mTexCoordExtents[0].mV[1] > mTexCoords[i].mV[1]) -			{ -				mTexCoordExtents[0].mV[1] = mTexCoords[i].mV[1] ; -			} -			if(mTexCoordExtents[1].mV[1] < mTexCoords[i].mV[1]) -			{ -				mTexCoordExtents[1].mV[1] = mTexCoords[i].mV[1] ; -			}			 -		} -		mTexCoordExtents[0].mV[0] = llmax(0.f, mTexCoordExtents[0].mV[0]) ; -		mTexCoordExtents[0].mV[1] = llmax(0.f, mTexCoordExtents[0].mV[1]) ; -		mTexCoordExtents[1].mV[0] = llmin(1.f, mTexCoordExtents[1].mV[0]) ; -		mTexCoordExtents[1].mV[1] = llmin(1.f, mTexCoordExtents[1].mV[1]) ; -	} -  	return ret ;  } @@ -5495,22 +4729,13 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  		}  	} -	llassert(new_face.mNumIndices == mNumIndices); -	llassert(new_face.mNumVertices <= mNumVertices); - -	if (angle_cutoff > 1.f && !mNormals) +	// Only swap data if we've actually optimized the mesh +	// +	if (new_face.mNumVertices <= mNumVertices)  	{ -		ll_aligned_free_16(new_face.mNormals); -		new_face.mNormals = NULL; +		llassert(new_face.mNumIndices == mNumIndices); +		swapData(new_face);  	} - -	if (!mTexCoords) -	{ -		ll_aligned_free_16(new_face.mTexCoords); -		new_face.mTexCoords = NULL; -	} - -	swapData(new_face);  }  class LLVCacheTriangleData; @@ -5710,35 +4935,44 @@ public:  	void updateScores()  	{ -		for (U32 i = MaxSizeVertexCache; i < MaxSizeVertexCache+3; ++i) -		{ //trailing 3 vertices aren't actually in the cache for scoring purposes -			if (mCache[i]) +		LLVCacheVertexData** data_iter = mCache+MaxSizeVertexCache; +		LLVCacheVertexData** end_data = mCache+MaxSizeVertexCache+3; + +		while(data_iter != end_data) +		{ +			LLVCacheVertexData* data = *data_iter++; +			//trailing 3 vertices aren't actually in the cache for scoring purposes +			if (data)  			{ -				mCache[i]->mCacheTag = -1; +				data->mCacheTag = -1;  			}  		} -		for (U32 i = 0; i < MaxSizeVertexCache; ++i) +		data_iter = mCache; +		end_data = mCache+MaxSizeVertexCache; + +		while (data_iter != end_data)  		{ //update scores of vertices in cache -			if (mCache[i]) +			LLVCacheVertexData* data = *data_iter++; +			if (data)  			{ -				mCache[i]->mScore = find_vertex_score(*(mCache[i])); -				llassert(mCache[i]->mCacheTag == i); +				data->mScore = find_vertex_score(*data);  			}  		}  		mBestTriangle = NULL;  		//update triangle scores -		for (U32 i = 0; i < MaxSizeVertexCache+3; ++i) +		data_iter = mCache; +		end_data = mCache+MaxSizeVertexCache+3; + +		while (data_iter != end_data)  		{ -			LLVCacheVertexData* data = mCache[i]; +			LLVCacheVertexData* data = *data_iter++;  			if (data)  			{ -				U32 count = data->mTriangles.size(); - -				for (U32 j = 0; j < count; ++j) +				for (std::vector<LLVCacheTriangleData*>::iterator iter = data->mTriangles.begin(), end_iter = data->mTriangles.end(); iter != end_iter; ++iter)  				{ -					LLVCacheTriangleData* tri = data->mTriangles[j]; +					LLVCacheTriangleData* tri = *iter;  					if (tri->mActive)  					{  						tri->mScore = tri->mVertex[0]->mScore; @@ -5755,13 +4989,17 @@ public:  		}  		//knock trailing 3 vertices off the cache -		for (U32 i = MaxSizeVertexCache; i < MaxSizeVertexCache+3; ++i) +		data_iter = mCache+MaxSizeVertexCache; +		end_data = mCache+MaxSizeVertexCache+3; +		while (data_iter != end_data)  		{ -			if (mCache[i]) +			LLVCacheVertexData* data = *data_iter; +			if (data)  			{ -				llassert(mCache[i]->mCacheTag == -1); -				mCache[i] = NULL; +				llassert(data->mCacheTag == -1); +				*data_iter = NULL;  			} +			++data_iter;  		}  	}  }; @@ -5896,10 +5134,10 @@ void LLVolumeFace::cacheOptimize()  	//allocate space for new buffer  	S32 num_verts = mNumVertices; -	LLVector4a* pos = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); -	LLVector4a* norm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);  	S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; -	LLVector2* tc = (LLVector2*) ll_aligned_malloc_16(size); +	LLVector4a* pos = (LLVector4a*) ll_aligned_malloc(sizeof(LLVector4a)*2*num_verts+size, 64); +	LLVector4a* norm = pos + num_verts; +	LLVector2* tc = (LLVector2*) (norm + num_verts);  	LLVector4a* wght = NULL;  	if (mWeights) @@ -5947,9 +5185,8 @@ void LLVolumeFace::cacheOptimize()  		mIndices[i] = new_idx[mIndices[i]];  	} -	ll_aligned_free_16(mPositions); -	ll_aligned_free_16(mNormals); -	ll_aligned_free_16(mTexCoords); +	ll_aligned_free(mPositions); +	// DO NOT free mNormals and mTexCoords as they are part of mPositions buffer  	ll_aligned_free_16(mWeights);  	ll_aligned_free_16(mBinormals); @@ -6071,18 +5308,15 @@ void	LerpPlanarVertex(LLVolumeFace::VertexData& v0,  BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  { -	const std::vector<LLVolume::Point>& mesh = volume->getMesh(); -	const std::vector<LLVector3>& profile = volume->getProfile().mProfile; +	LL_CHECK_MEMORY		 + +	const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh(); +	const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;  	S32 max_s = volume->getProfile().getTotal();  	S32 max_t = volume->getPath().mPath.size();  	// S32 i; -	S32 num_vertices = 0, num_indices = 0;  	S32	grid_size = (profile.size()-1)/4; -	S32	quad_count = (grid_size * grid_size); - -	num_vertices = (grid_size+1)*(grid_size+1); -	num_indices = quad_count * 4;  	LLVector4a& min = mExtents[0];  	LLVector4a& max = mExtents[1]; @@ -6102,9 +5336,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  		VertexData baseVert;  		for(S32 t = 0; t < 4; t++)  		{ -			corners[t].getPosition().load3( mesh[offset + (grid_size*t)].mPos.mV); -			corners[t].mTexCoord.mV[0] = profile[grid_size*t].mV[0]+0.5f; -			corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t].mV[1]; +			corners[t].getPosition().load4a(mesh[offset + (grid_size*t)].getF32ptr()); +			corners[t].mTexCoord.mV[0] = profile[grid_size*t][0]+0.5f; +			corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t][1];  		}  		{ @@ -6185,6 +5419,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  		mCenter->mul(0.5f);   	} +	llassert(less_than_max_mag(mExtents[0])); +	llassert(less_than_max_mag(mExtents[1])); +  	if (!partial_build)  	{  		resizeIndices(grid_size*grid_size*6); @@ -6215,6 +5452,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  		}  	} +	LL_CHECK_MEMORY  	return TRUE;  } @@ -6233,8 +5471,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	S32 num_vertices = 0, num_indices = 0; -	const std::vector<LLVolume::Point>& mesh = volume->getMesh(); -	const std::vector<LLVector3>& profile = volume->getProfile().mProfile; +	const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh(); +	const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;  	// All types of caps have the same number of vertices and indices  	num_vertices = profile.size(); @@ -6254,13 +5492,14 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	{  		resizeVertices(num_vertices);  		allocateBinormals(num_vertices); -  		if (!partial_build)  		{  			resizeIndices(num_indices);  		}  	} +	LL_CHECK_MEMORY; +  	S32 max_s = volume->getProfile().getTotal();  	S32 max_t = volume->getPath().mPath.size(); @@ -6291,35 +5530,68 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	LLVector4a* binorm = (LLVector4a*) mBinormals;  	// Copy the vertices into the array -	for (S32 i = 0; i < num_vertices; i++) + +	const LLVector4a* src = mesh.mArray+offset; +	const LLVector4a* end = src+num_vertices; +	 +	min = *src; +	max = min; +	 +	 +	const LLVector4a* p = profile.mArray; + +	if (mTypeMask & TOP_MASK)  	{ -		if (mTypeMask & TOP_MASK) -		{ -			tc[i].mV[0] = profile[i].mV[0]+0.5f; -			tc[i].mV[1] = profile[i].mV[1]+0.5f; -		} -		else +		min_uv.set((*p)[0]+0.5f, +					(*p)[1]+0.5f); + +		max_uv = min_uv; + +		while(src < end)  		{ -			// Mirror for underside. -			tc[i].mV[0] = profile[i].mV[0]+0.5f; -			tc[i].mV[1] = 0.5f - profile[i].mV[1]; -		} +			tc->mV[0] = (*p)[0]+0.5f; +			tc->mV[1] = (*p)[1]+0.5f; -		pos[i].load3(mesh[i + offset].mPos.mV); +			llassert(less_than_max_mag(*src)); +			update_min_max(min,max,*src); +			update_min_max(min_uv, max_uv, *tc); -		if (i == 0) -		{ -			max = pos[i]; -			min = max; -			min_uv = max_uv = tc[i]; +			*pos = *src; +		 +			++p; +			++tc; +			++src; +			++pos;  		} -		else +	} +	else +	{ + +		min_uv.set((*p)[0]+0.5f, +				   0.5f - (*p)[1]); +		max_uv = min_uv; + +		while(src < end)  		{ -			update_min_max(min,max,pos[i]); -			update_min_max(min_uv, max_uv, tc[i]); +			// Mirror for underside. +			tc->mV[0] = (*p)[0]+0.5f; +			tc->mV[1] = 0.5f - (*p)[1]; +		 +			llassert(less_than_max_mag(*src)); +			update_min_max(min,max,*src); +			update_min_max(min_uv, max_uv, *tc); +		 +			*pos = *src; +		 +			++p; +			++tc; +			++src; +			++pos;  		}  	} +	LL_CHECK_MEMORY +  	mCenter->setAdd(min, max);  	mCenter->mul(0.5f);  @@ -6356,15 +5628,25 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))  	{ -		pos[num_vertices] = *mCenter; -		tc[num_vertices] = cuv; +		*pos++ = *mCenter; +		*tc++ = cuv;  		num_vertices++;  	} -		 -	for (S32 i = 0; i < num_vertices; i++) +	 +	LL_CHECK_MEMORY + +	F32* dst_binorm = (F32*) binorm; +	F32* end_binorm = (F32*) (binorm+num_vertices); + +	F32* dst_norm = (F32*) norm; +	 +	while (dst_binorm < end_binorm)  	{ -		binorm[i].load4a(binormal.getF32ptr()); -		norm[i].load4a(normal.getF32ptr()); +		binormal.store4a(dst_binorm); +		normal.store4a(dst_norm); + +		dst_binorm += 4; +		dst_norm += 4;  	}  	if (partial_build) @@ -6385,33 +5667,38 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  			{  				// Use the profile points instead of the mesh, since you want  				// the un-transformed profile distances. -				LLVector3 p1 = profile[pt1]; -				LLVector3 p2 = profile[pt2]; -				LLVector3 pa = profile[pt1+1]; -				LLVector3 pb = profile[pt2-1]; +				const LLVector4a& p1 = profile[pt1]; +				const LLVector4a& p2 = profile[pt2]; +				const LLVector4a& pa = profile[pt1+1]; +				const LLVector4a& pb = profile[pt2-1]; + +				const F32* p1V = p1.getF32ptr(); +				const F32* p2V = p2.getF32ptr(); +				const F32* paV = pa.getF32ptr(); +				const F32* pbV = pb.getF32ptr(); -				p1.mV[VZ] = 0.f; -				p2.mV[VZ] = 0.f; -				pa.mV[VZ] = 0.f; -				pb.mV[VZ] = 0.f; +				//p1.mV[VZ] = 0.f; +				//p2.mV[VZ] = 0.f; +				//pa.mV[VZ] = 0.f; +				//pb.mV[VZ] = 0.f;  				// Use area of triangle to determine backfacing  				F32 area_1a2, area_1ba, area_21b, area_2ab; -				area_1a2 =  (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) + -							(pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) + -							(p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]); +				area_1a2 =  (p1V[0]*paV[1] - paV[0]*p1V[1]) + +							(paV[0]*p2V[1] - p2V[0]*paV[1]) + +							(p2V[0]*p1V[1] - p1V[0]*p2V[1]); -				area_1ba =  (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -							(pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) + -							(pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]); +				area_1ba =  (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + +							(pbV[0]*paV[1] - paV[0]*pbV[1]) + +							(paV[0]*p1V[1] - p1V[0]*paV[1]); -				area_21b =  (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) + -							(p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -							(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); +				area_21b =  (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + +							(p1V[0]*pbV[1] - pbV[0]*p1V[1]) + +							(pbV[0]*p2V[1] - p2V[0]*pbV[1]); -				area_2ab =  (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) + -							(pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) + -							(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); +				area_2ab =  (p2V[0]*paV[1] - paV[0]*p2V[1]) + +							(paV[0]*pbV[1] - pbV[0]*paV[1]) + +							(pbV[0]*p2V[1] - p2V[0]*pbV[1]);  				BOOL use_tri1a2 = TRUE;  				BOOL tri_1a2 = TRUE; @@ -6446,10 +5733,13 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  				}  				else  				{ -					LLVector3 d1 = p1 - pa; -					LLVector3 d2 = p2 - pb; +					LLVector4a d1; +					d1.setSub(p1, pa); +					 +					LLVector4a d2;  +					d2.setSub(p2, pb); -					if (d1.magVecSquared() < d2.magVecSquared()) +					if (d1.dot3(d1) < d2.dot3(d2))  					{  						use_tri1a2 = TRUE;  					} @@ -6488,33 +5778,33 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  			{  				// Use the profile points instead of the mesh, since you want  				// the un-transformed profile distances. -				LLVector3 p1 = profile[pt1]; -				LLVector3 p2 = profile[pt2]; -				LLVector3 pa = profile[pt1+1]; -				LLVector3 pb = profile[pt2-1]; - -				p1.mV[VZ] = 0.f; -				p2.mV[VZ] = 0.f; -				pa.mV[VZ] = 0.f; -				pb.mV[VZ] = 0.f; - +				const LLVector4a& p1 = profile[pt1]; +				const LLVector4a& p2 = profile[pt2]; +				const LLVector4a& pa = profile[pt1+1]; +				const LLVector4a& pb = profile[pt2-1]; + +				const F32* p1V = p1.getF32ptr(); +				const F32* p2V = p2.getF32ptr(); +				const F32* paV = pa.getF32ptr(); +				const F32* pbV = pb.getF32ptr(); +				  				// Use area of triangle to determine backfacing  				F32 area_1a2, area_1ba, area_21b, area_2ab; -				area_1a2 =  (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) + -							(pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) + -							(p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]); +				area_1a2 =  (p1V[0]*paV[1] - paV[0]*p1V[1]) + +							(paV[0]*p2V[1] - p2V[0]*paV[1]) + +							(p2V[0]*p1V[1] - p1V[0]*p2V[1]); -				area_1ba =  (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -							(pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) + -							(pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]); +				area_1ba =  (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + +							(pbV[0]*paV[1] - paV[0]*pbV[1]) + +							(paV[0]*p1V[1] - p1V[0]*paV[1]); -				area_21b =  (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) + -							(p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) + -							(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); +				area_21b =  (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + +							(p1V[0]*pbV[1] - pbV[0]*p1V[1]) + +							(pbV[0]*p2V[1] - p2V[0]*pbV[1]); -				area_2ab =  (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) + -							(pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) + -							(pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]); +				area_2ab =  (p2V[0]*paV[1] - paV[0]*p2V[1]) + +							(paV[0]*pbV[1] - pbV[0]*paV[1]) + +							(pbV[0]*p2V[1] - p2V[0]*pbV[1]);  				BOOL use_tri1a2 = TRUE;  				BOOL tri_1a2 = TRUE; @@ -6549,10 +5839,12 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  				}  				else  				{ -					LLVector3 d1 = p1 - pa; -					LLVector3 d2 = p2 - pb; +					LLVector4a d1; +					d1.setSub(p1,pa); +					LLVector4a d2; +					d2.setSub(p2,pb); -					if (d1.magVecSquared() < d2.magVecSquared()) +					if (d1.dot3(d1) < d2.dot3(d2))  					{  						use_tri1a2 = TRUE;  					} @@ -6601,6 +5893,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	} + +	LL_CHECK_MEMORY  	return TRUE;  } @@ -6666,24 +5960,22 @@ void LLVolumeFace::createBinormals()  void LLVolumeFace::resizeVertices(S32 num_verts)  { -	ll_aligned_free_16(mPositions); -	ll_aligned_free_16(mNormals); +	ll_aligned_free(mPositions); +	//DO NOT free mNormals and mTexCoords as they are part of mPositions buffer  	ll_aligned_free_16(mBinormals); -	ll_aligned_free_16(mTexCoords); - +	  	mBinormals = NULL;  	if (num_verts)  	{ -		mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); -		ll_assert_aligned(mPositions, 16); -		mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); -		ll_assert_aligned(mNormals, 16); -  		//pad texture coordinate block end to allow for QWORD reads  		S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; -		mTexCoords = (LLVector2*) ll_aligned_malloc_16(size); -		ll_assert_aligned(mTexCoords, 16); + +		mPositions = (LLVector4a*) ll_aligned_malloc(sizeof(LLVector4a)*2*num_verts+size, 64); +		mNormals = mPositions+num_verts; +		mTexCoords = (LLVector2*) (mNormals+num_verts); + +		ll_assert_aligned(mPositions, 64);  	}  	else  	{ @@ -6693,6 +5985,7 @@ void LLVolumeFace::resizeVertices(S32 num_verts)  	}  	mNumVertices = num_verts; +	mNumAllocatedVertices = num_verts;  }  void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv) @@ -6703,27 +5996,43 @@ void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv)  void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc)  {  	S32 new_verts = mNumVertices+1; -	S32 new_size = new_verts*16; -	S32 old_size = mNumVertices*16; -	//positions -	mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_size, old_size); -	ll_assert_aligned(mPositions,16); +	if (new_verts > mNumAllocatedVertices) +	{  +		//double buffer size on expansion +		new_verts *= 2; + +		S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF; +		S32 old_tc_size = ((mNumVertices*8)+0xF) & ~0xF; + +		S32 old_vsize = mNumVertices*16; +		 +		S32 new_size = new_verts*16*2+new_tc_size; + +		LLVector4a* old_buf = mPositions; + +		mPositions = (LLVector4a*) ll_aligned_malloc(new_size, 64); +		mNormals = mPositions+new_verts; +		mTexCoords = (LLVector2*) (mNormals+new_verts); + +		//positions +		LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) old_buf, old_vsize); +		 +		//normals +		LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) (old_buf+mNumVertices), old_vsize); -	//normals -	mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_size, old_size); -	ll_assert_aligned(mNormals,16); - -	//tex coords -	new_size = ((new_verts*8)+0xF) & ~0xF; -	old_size = ((mNumVertices*8)+0xF) & ~0xF; -	mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, new_size, old_size); -	ll_assert_aligned(mTexCoords,16); +		//tex coords +		LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tc_size); +		//just clear binormals +		ll_aligned_free_16(mBinormals); -	//just clear binormals -	ll_aligned_free_16(mBinormals); -	mBinormals = NULL; +		ll_aligned_free(old_buf); + +		mNumAllocatedVertices = new_verts; + +		mBinormals = NULL; +	}  	mPositions[mNumVertices] = pos;  	mNormals[mNumVertices] = norm; @@ -6812,13 +6121,23 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  		llerrs << "Cannot append empty face." << llendl;  	} +	U32 old_vsize = mNumVertices*16; +	U32 new_vsize = new_count * 16; +	U32 old_tcsize = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF; +	U32 new_tcsize = (new_count*sizeof(LLVector2)+0xF) & ~0xF; +	U32 new_size = new_vsize * 2 + new_tcsize; +  	//allocate new buffer space -	mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a)); -	ll_assert_aligned(mPositions, 16); -	mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a)); -	ll_assert_aligned(mNormals, 16); -	mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF, (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF); -	ll_assert_aligned(mTexCoords, 16); +	LLVector4a* old_buf = mPositions; +	mPositions = (LLVector4a*) ll_aligned_malloc(new_size, 64); +	mNormals = mPositions + new_count; +	mTexCoords = (LLVector2*) (mNormals+new_count); + +	mNumAllocatedVertices = new_count; + +	LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) old_buf, old_vsize); +	LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) (old_buf+mNumVertices), old_vsize); +	LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tcsize);  	mNumVertices = new_count; @@ -6878,6 +6197,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  { +	LL_CHECK_MEMORY  	BOOL flat = mTypeMask & FLAT_MASK;  	U8 sculpt_type = volume->getParams().getSculptType(); @@ -6888,9 +6208,9 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	S32 num_vertices, num_indices; -	const std::vector<LLVolume::Point>& mesh = volume->getMesh(); -	const std::vector<LLVector3>& profile = volume->getProfile().mProfile; -	const std::vector<LLPath::PathPt>& path_data = volume->getPath().mPath; +	const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh(); +	const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile; +	const LLAlignedArray<LLPath::PathPt,64>& path_data = volume->getPath().mPath;  	S32 max_s = volume->getProfile().getTotal(); @@ -6911,15 +6231,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  		}  	} +	LL_CHECK_MEMORY +  	LLVector4a* pos = (LLVector4a*) mPositions; -	LLVector4a* norm = (LLVector4a*) mNormals;  	LLVector2* tc = (LLVector2*) mTexCoords; -	S32 begin_stex = llfloor( profile[mBeginS].mV[2] ); +	F32 begin_stex = floorf(profile[mBeginS][2]);  	S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS;  	S32 cur_vertex = 0; +	S32 end_t = mBeginT+mNumT; +	bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2; +  	// Copy the vertices into the array -	for (t = mBeginT; t < mBeginT + mNumT; t++) +	for (t = mBeginT; t < end_t; t++)  	{  		tt = path_data[t].mTexT;  		for (s = 0; s < num_s; s++) @@ -6940,11 +6264,11 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  				// Get s value for tex-coord.  				if (!flat)  				{ -					ss = profile[mBeginS + s].mV[2]; +					ss = profile[mBeginS + s][2];  				}  				else  				{ -					ss = profile[mBeginS + s].mV[2] - begin_stex; +					ss = profile[mBeginS + s][2] - begin_stex;  				}  			} @@ -6964,20 +6288,17 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  				i = mBeginS + s + max_s*t;  			} -			pos[cur_vertex].load3(mesh[i].mPos.mV); -			tc[cur_vertex] = LLVector2(ss,tt); +			llassert(less_than_max_mag(mesh[i])); +			mesh[i].store4a((F32*)(pos+cur_vertex)); +			tc[cur_vertex].set(ss,tt); -			norm[cur_vertex].clear();  			cur_vertex++; -			if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2 && s > 0) +			if (test && s > 0)  			{ - -				pos[cur_vertex].load3(mesh[i].mPos.mV); -				tc[cur_vertex] = LLVector2(ss,tt); -			 -				norm[cur_vertex].clear(); -				 +				llassert(less_than_max_mag(mesh[i])); +				mesh[i].store4a((F32*)(pos+cur_vertex)); +				tc[cur_vertex].set(ss,tt);  				cur_vertex++;  			}  		} @@ -6994,28 +6315,66 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  			}  			i = mBeginS + s + max_s*t; -			ss = profile[mBeginS + s].mV[2] - begin_stex; -			pos[cur_vertex].load3(mesh[i].mPos.mV); -			tc[cur_vertex] = LLVector2(ss,tt); -			norm[cur_vertex].clear();  -			 +			ss = profile[mBeginS + s][2] - begin_stex; + +			llassert(less_than_max_mag(mesh[i])); +			mesh[i].store4a((F32*)(pos+cur_vertex)); +			tc[cur_vertex].set(ss,tt); +						  			cur_vertex++;  		}  	} +	LL_CHECK_MEMORY -	//get bounding box for this side -	LLVector4a& face_min = mExtents[0]; -	LLVector4a& face_max = mExtents[1]; +	  	mCenter->clear(); -	face_min = face_max = pos[0]; +	LLVector4a* cur_pos = pos; +	LLVector4a* end_pos = pos + mNumVertices; -	for (U32 i = 1; i < mNumVertices; ++i) +	//get bounding box for this side +	LLVector4a face_min; +	LLVector4a face_max; +	 +	face_min = face_max = *cur_pos++; +		 +	while (cur_pos < end_pos)  	{ -		update_min_max(face_min, face_max, pos[i]); +		update_min_max(face_min, face_max, *cur_pos++); +	} + +	mExtents[0] = face_min; +	mExtents[1] = face_max; + +	U32 tc_count = mNumVertices; +	if (tc_count%2 == 1) +	{ //odd number of texture coordinates, duplicate last entry to padded end of array +		tc_count++; +		mTexCoords[mNumVertices] = mTexCoords[mNumVertices-1];  	} +	LLVector4a* cur_tc = (LLVector4a*) mTexCoords; +	LLVector4a* end_tc = (LLVector4a*) (mTexCoords+tc_count); + +	LLVector4a tc_min;  +	LLVector4a tc_max;  + +	tc_min = tc_max = *cur_tc++; + +	while (cur_tc < end_tc) +	{ +		update_min_max(tc_min, tc_max, *cur_tc++); +	} + +	F32* minp = tc_min.getF32ptr(); +	F32* maxp = tc_max.getF32ptr(); + +	mTexCoordExtents[0].mV[0] = llmin(minp[0], minp[2]); +	mTexCoordExtents[0].mV[1] = llmin(minp[1], minp[3]); +	mTexCoordExtents[1].mV[0] = llmax(maxp[0], maxp[2]); +	mTexCoordExtents[1].mV[1] = llmax(maxp[1], maxp[3]); +  	mCenter->setAdd(face_min, face_max);  	mCenter->mul(0.5f); @@ -7080,39 +6439,114 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  		}  	} +	LL_CHECK_MEMORY +  	//clear normals -	for (U32 i = 0; i < mNumVertices; i++) +	F32* dst = (F32*) mNormals; +	F32* end = (F32*) (mNormals+mNumVertices); +	LLVector4a zero = LLVector4a::getZero(); + +	while (dst < end)  	{ -		mNormals[i].clear(); +		zero.store4a(dst); +		dst += 4;  	} +	LL_CHECK_MEMORY +  	//generate normals  -	for (U32 i = 0; i < mNumIndices/3; i++) //for each triangle -	{ -		const U16* idx = &(mIndices[i*3]); -		 +	U32 count = mNumIndices/3; -		LLVector4a* v[] =  -		{	pos+idx[0], pos+idx[1], pos+idx[2] }; -		 -		LLVector4a* n[] =  -		{	norm+idx[0], norm+idx[1], norm+idx[2] }; +	LLVector4a* norm = mNormals; + +	static LLAlignedArray<LLVector4a, 64> triangle_normals; +	triangle_normals.resize(count); +	LLVector4a* output = triangle_normals.mArray; +	LLVector4a* end_output = output+count; + +	U16* idx = mIndices; + +	while (output < end_output) +	{ +		LLVector4a b,v1,v2; +		b.load4a((F32*) (pos+idx[0])); +		v1.load4a((F32*) (pos+idx[1])); +		v2.load4a((F32*) (pos+idx[2]));  		//calculate triangle normal -		LLVector4a a, b, c; +		LLVector4a a; -		a.setSub(*v[0], *v[1]); -		b.setSub(*v[0], *v[2]); -		c.setCross3(a,b); +		a.setSub(b, v1); +		b.sub(v2); + + +		LLQuad& vector1 = *((LLQuad*) &v1); +		LLQuad& vector2 = *((LLQuad*) &v2); -		n[0]->add(c); -		n[1]->add(c); -		n[2]->add(c); +		LLQuad& amQ = *((LLQuad*) &a); +		LLQuad& bmQ = *((LLQuad*) &b); + +		//v1.setCross3(t,v0); +		//setCross3(const LLVector4a& a, const LLVector4a& b) +		// Vectors are stored in memory in w, z, y, x order from high to low +		// Set vector1 = { a[W], a[X], a[Z], a[Y] } +		vector1 = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 0, 2, 1 )); +		// Set vector2 = { b[W], b[Y], b[X], b[Z] } +		vector2 = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 1, 0, 2 )); +		// mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] } +		vector2 = _mm_mul_ps( vector1, vector2 ); +		// vector3 = { a[W], a[Y], a[X], a[Z] } +		amQ = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 1, 0, 2 )); +		// vector4 = { b[W], b[X], b[Z], b[Y] } +		bmQ = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 0, 2, 1 )); +		// mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] } +		vector1 = _mm_sub_ps( vector2, _mm_mul_ps( amQ, bmQ )); + +		v1.store4a((F32*) output); + +		output++; +		idx += 3; +	} + +	idx = mIndices; + +	LLVector4a* src = triangle_normals.mArray; +	 +	for (U32 i = 0; i < count; i++) //for each triangle +	{ +		LLVector4a c; +		c.load4a((F32*) (src++)); + +		LLVector4a* n0p = norm+idx[0]; +		LLVector4a* n1p = norm+idx[1]; +		LLVector4a* n2p = norm+idx[2]; + +		idx += 3; + +		LLVector4a n0,n1,n2; +		n0.load4a((F32*) n0p); +		n1.load4a((F32*) n1p); +		n2.load4a((F32*) n2p); + +		n0.add(c); +		n1.add(c); +		n2.add(c);  		//even out quad contributions -		n[i%2+1]->add(c); +		switch (i%2+1) +		{ +			case 0: n0.add(c); break; +			case 1: n1.add(c); break; +			case 2: n2.add(c); break; +		}; + +		n0.store4a((F32*) n0p); +		n1.store4a((F32*) n1p); +		n2.store4a((F32*) n2p);  	} +	LL_CHECK_MEMORY +  	// adjust normals based on wrapping and stitching  	LLVector4a top; @@ -7244,6 +6678,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	} +	LL_CHECK_MEMORY +  	return TRUE;  } @@ -7297,3 +6733,4 @@ void calc_binormal_from_triangle(LLVector4a& binormal,  		binormal.set( 0, 1 , 0 );  	}  } + diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 99158c1c44..6b599a4126 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -37,7 +37,6 @@ class LLPath;  template <class T> class LLOctreeNode; -class LLVector4a;  class LLVolumeFace;  class LLVolume;  class LLVolumeTriangle; @@ -50,12 +49,15 @@ class LLVolumeTriangle;  #include "v3math.h"  #include "v3dmath.h"  #include "v4math.h" +#include "llvector4a.h" +#include "llmatrix4a.h"  #include "llquaternion.h"  #include "llstrider.h"  #include "v4coloru.h"  #include "llrefcount.h"  #include "llpointer.h"  #include "llfile.h" +#include "llalignedarray.h"  //============================================================================ @@ -708,16 +710,16 @@ public:  		LLFaceID  mFaceID;  	}; -	std::vector<LLVector3> mProfile;	 -	std::vector<LLVector2> mNormals; +	LLAlignedArray<LLVector4a, 64> mProfile;	 +	//LLAlignedArray<LLVector4a, 64> mNormals;  	std::vector<Face>      mFaces; -	std::vector<LLVector3> mEdgeNormals; -	std::vector<LLVector3> mEdgeCenters; + +	//LLAlignedArray<LLVector4a, 64> mEdgeNormals; +	//LLAlignedArray<LLVector4a, 64> mEdgeCenters;  	friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);  protected: -	void genNormals(const LLProfileParams& params);  	static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);  	void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); @@ -741,13 +743,29 @@ protected:  class LLPath  {  public: -	struct PathPt +	class PathPt  	{ -		LLVector3	 mPos; -		LLVector2    mScale; -		LLQuaternion mRot; +	public: +		LLMatrix4a   mRot; +		LLVector4a	 mPos; +		 +		LLVector4a   mScale;  		F32			 mTexT; -		PathPt() { mPos.setVec(0,0,0); mTexT = 0; mScale.setVec(0,0); mRot.loadIdentity(); } +		F32 pad[3]; //for alignment +		PathPt()  +		{  +			mPos.clear();  +			mTexT = 0;  +			mScale.clear();  +			mRot.setRows(LLVector4a(1,0,0,0), +						LLVector4a(0,1,0,0), +						LLVector4a(0,0,1,0)); + +			//distinguished data in the pad for debugging +			pad[0] = 3.14159f; +			pad[1] = -3.14159f; +			pad[2] = 0.585f; +		}  	};  public: @@ -779,7 +797,7 @@ public:  	friend std::ostream& operator<<(std::ostream &s, const LLPath &path);  public: -	std::vector<PathPt> mPath; +	LLAlignedArray<PathPt, 64> mPath;  protected:  	BOOL		  mOpen; @@ -912,6 +930,7 @@ public:  	LLVector2   mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.  	S32 mNumVertices; +	S32 mNumAllocatedVertices;  	S32 mNumIndices;  	LLVector4a* mPositions; @@ -950,11 +969,7 @@ protected:  	~LLVolume(); // use unref  public: -	struct Point -	{ -		LLVector3 mPos; -	}; - +		  	struct FaceParams  	{  		LLFaceID mFaceID; @@ -977,8 +992,8 @@ public:  	const LLProfile& getProfile() const						{ return *mProfilep; }  	LLPath& getPath() const									{ return *mPathp; }  	void resizePath(S32 length); -	const std::vector<Point>& getMesh() const				{ return mMesh; } -	const LLVector3& getMeshPt(const U32 i) const			{ return mMesh[i].mPos; } +	const LLAlignedArray<LLVector4a,64>&	getMesh() const				{ return mMesh; } +	const LLVector4a& getMeshPt(const U32 i) const			{ return mMesh[i]; }  	void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } @@ -993,10 +1008,7 @@ public:  	S32 getSculptLevel() const                              { return mSculptLevel; }  	void setSculptLevel(S32 level)							{ mSculptLevel = level; } -	S32 *getTriangleIndices(U32 &num_indices) const; - -	// returns number of triangle indeces required for path/profile mesh -	S32 getNumTriangleIndices() const; +	  	static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);  	S32 getNumTriangles(S32* vcount = NULL) const; @@ -1069,7 +1081,8 @@ public:  	LLVolumeParams mParams;  	LLPath *mPathp;  	LLProfile *mProfilep; -	std::vector<Point> mMesh; +	LLAlignedArray<LLVector4a,64> mMesh; +	  	BOOL mGenerateSingleFace;  	typedef std::vector<LLVolumeFace> face_list_t; diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index 0287026659..7713e553ef 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -592,6 +592,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(  	PUMP_DEBUG;  	apr_pool_t* new_pool = NULL;  	apr_status_t status = apr_pool_create(&new_pool, mPool); +	(void)status;  	apr_socket_t* socket = NULL;  	status = apr_socket_accept(  		&socket, diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp index 26cafa025f..0f33a94295 100644 --- a/indra/llmessage/llpartdata.cpp +++ b/indra/llmessage/llpartdata.cpp @@ -37,26 +37,33 @@ -const S32 PS_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; // 18 -const S32 PS_DATA_BLOCK_SIZE = 68 + PS_PART_DATA_BLOCK_SIZE; // 68 + 18 = 86 +const S32 PS_PART_DATA_GLOW_SIZE = 2; +const S32 PS_PART_DATA_BLEND_SIZE = 2; +const S32 PS_LEGACY_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; //18 +const S32 PS_SYS_DATA_BLOCK_SIZE = 68; +const S32 PS_MAX_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE+ +									PS_LEGACY_PART_DATA_BLOCK_SIZE + +									PS_PART_DATA_BLEND_SIZE + +									PS_PART_DATA_GLOW_SIZE+ +									8; //two S32 size fields + +const S32 PS_LEGACY_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE + PS_LEGACY_PART_DATA_BLOCK_SIZE; + + +const U32 PART_DATA_MASK = LLPartData::LL_PART_DATA_GLOW | LLPartData::LL_PART_DATA_BLEND; +  const F32 MAX_PART_SCALE = 4.f; -BOOL LLPartData::pack(LLDataPacker &dp) +bool LLPartData::hasGlow() const  { -	LLColor4U coloru; -	dp.packU32(mFlags, "pdflags"); -	dp.packFixed(mMaxAge, "pdmaxage", FALSE, 8, 8); -	coloru.setVec(mStartColor); -	dp.packColor4U(coloru, "pdstartcolor"); -	coloru.setVec(mEndColor); -	dp.packColor4U(coloru, "pdendcolor"); -	dp.packFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5); -	dp.packFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5); -	dp.packFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5); -	dp.packFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5); -	return TRUE; +	return mStartGlow > 0.f || mEndGlow > 0.f; +} + +bool LLPartData::hasBlendFunc() const +{ +	return mBlendFuncSource != LLPartData::LL_PART_BF_SOURCE_ALPHA || mBlendFuncDest != LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;  }  LLSD LLPartData::asLLSD() const @@ -68,6 +75,11 @@ LLSD LLPartData::asLLSD() const  	sd["pdendcolor"] = ll_sd_from_color4(mEndColor);  	sd["pdstartscale"] = ll_sd_from_vector2(mStartScale);  	sd["pdendscale"] = ll_sd_from_vector2(mEndScale); +	sd["pdstartglow"] =	mStartGlow; +	sd["pdendglow"] = mEndGlow; +	sd["pdblendsource"] = (S32)mBlendFuncSource; +	sd["pdblenddest"] = (S32)mBlendFuncDest; +  	return sd;  } @@ -79,11 +91,26 @@ bool LLPartData::fromLLSD(LLSD& sd)  	mEndColor = ll_color4_from_sd(sd["pdendcolor"]);  	mStartScale = ll_vector2_from_sd(sd["pdstartscale"]);  	mEndScale = ll_vector2_from_sd(sd["pdendscale"]); + +	mStartGlow = sd.has("pdstartglow") ? sd["pdstartglow"].asReal() : 0.f; +	mEndGlow = sd.has("pdendglow") ? sd["pdendglow"].asReal() : 0.f; +	mBlendFuncSource = sd.has("pdblendsource") ? (U8)sd["pdblendsource"].asInteger() : LL_PART_BF_SOURCE_ALPHA; +	mBlendFuncDest = sd.has("pdblenddest") ? (U8)sd["pdblenddest"].asInteger() : LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; +  	return true;  } +S32 LLPartData::getSize() const +{ +	S32 size = PS_LEGACY_PART_DATA_BLOCK_SIZE; +	if (hasGlow()) size += PS_PART_DATA_GLOW_SIZE; +	if (hasBlendFunc()) size += PS_PART_DATA_BLEND_SIZE; -BOOL LLPartData::unpack(LLDataPacker &dp) +	return size; +} + + +BOOL LLPartData::unpackLegacy(LLDataPacker &dp)  {  	LLColor4U coloru; @@ -98,9 +125,81 @@ BOOL LLPartData::unpack(LLDataPacker &dp)  	dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);  	dp.unpackFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);  	dp.unpackFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5); + +	/*if (dp.hasNext()) +	{ +		U8 tmp_glow = 0; +		dp.unpackU8(tmp_glow,"pdstartglow"); +		mStartGlow = tmp_glow / 255.f; +		dp.unpackU8(tmp_glow,"pdendglow"); +		mEndGlow = tmp_glow / 255.f; +		dp.unpackU8(mBlendFuncSource,"pdblendsource"); +		dp.unpackU8(mBlendFuncDest,"pdblenddest"); +	}*/ +	 +	mStartGlow = 0.f; +	mEndGlow = 0.f; +	mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA; +	mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; +  	return TRUE;  } +BOOL LLPartData::unpack(LLDataPacker &dp) +{ +	S32 size = 0; +	dp.unpackS32(size, "partsize"); + +	unpackLegacy(dp); +	size -= PS_LEGACY_PART_DATA_BLOCK_SIZE; + +	if (mFlags & LL_PART_DATA_GLOW) +	{ +		if (size < PS_PART_DATA_GLOW_SIZE) return FALSE; + +		U8 tmp_glow = 0; +		dp.unpackU8(tmp_glow,"pdstartglow"); +		mStartGlow = tmp_glow / 255.f; +		dp.unpackU8(tmp_glow,"pdendglow"); +		mEndGlow = tmp_glow / 255.f; + +		size -= PS_PART_DATA_GLOW_SIZE; +	} +	else +	{ +		mStartGlow = 0.f; +		mEndGlow = 0.f; +	} + +	if (mFlags & LL_PART_DATA_BLEND) +	{ +		if (size < PS_PART_DATA_BLEND_SIZE) return FALSE; +		dp.unpackU8(mBlendFuncSource,"pdblendsource"); +		dp.unpackU8(mBlendFuncDest,"pdblenddest"); +		size -= PS_PART_DATA_BLEND_SIZE; +	} +	else +	{ +		mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA; +		mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; +	} + +	if (size > 0) +	{ //leftover bytes, unrecognized parameters +		U8 feh = 0; +		while (size > 0) +		{ //read remaining bytes in block +			dp.unpackU8(feh, "whippang"); +			size--; +		} + +		//this particle system won't display properly, better to not show anything +		return FALSE; +	} + + +	return TRUE; +}  void LLPartData::setFlags(const U32 flags)  { @@ -148,6 +247,18 @@ void LLPartData::setEndAlpha(const F32 alpha)  	mEndColor.mV[3] = alpha;  } +// static +bool LLPartData::validBlendFunc(S32 func) +{ +	if (func >= 0 +		&& func < LL_PART_BF_COUNT +		&& func != UNSUPPORTED_DEST_ALPHA +		&& func != UNSUPPORTED_ONE_MINUS_DEST_ALPHA) +	{ +		return true; +	} +	return false; +}  LLPartSysData::LLPartSysData()  { @@ -160,6 +271,10 @@ LLPartSysData::LLPartSysData()  	mPartData.mStartScale = LLVector2(1.f, 1.f);  	mPartData.mEndScale = LLVector2(1.f, 1.f);  	mPartData.mMaxAge = 10.0; +	mPartData.mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA; +	mPartData.mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; +	mPartData.mStartGlow = 0.f; +	mPartData.mEndGlow = 0.f;  	mMaxAge = 0.0;  	mStartAge = 0.0; @@ -175,38 +290,7 @@ LLPartSysData::LLPartSysData()  	mNumParticles = 0;  } - -BOOL LLPartSysData::pack(LLDataPacker &dp) -{ -	dp.packU32(mCRC, "pscrc"); -	dp.packU32(mFlags, "psflags"); -	dp.packU8(mPattern, "pspattern"); -	dp.packFixed(mMaxAge, "psmaxage", FALSE, 8, 8); -	dp.packFixed(mStartAge, "psstartage", FALSE, 8, 8); -	dp.packFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5); -	dp.packFixed(mOuterAngle, "psouterangle", FALSE, 3, 5); -	dp.packFixed(mBurstRate, "psburstrate", FALSE, 8, 8); -	dp.packFixed(mBurstRadius, "psburstradius", FALSE, 8, 8); -	dp.packFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8); -	dp.packFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8); -	dp.packU8(mBurstPartCount, "psburstpartcount"); - -	dp.packFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7); -	dp.packFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7); -	dp.packFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7); - -	dp.packFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7); -	dp.packFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7); -	dp.packFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7); - -	dp.packUUID(mPartImageID, "psuuid"); -	dp.packUUID(mTargetUUID, "pstargetuuid"); -	mPartData.pack(dp); -	return TRUE; -} - - -BOOL LLPartSysData::unpack(LLDataPacker &dp) +BOOL LLPartSysData::unpackSystem(LLDataPacker &dp)  {  	dp.unpackU32(mCRC, "pscrc");  	dp.unpackU32(mFlags, "psflags"); @@ -232,10 +316,48 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp)  	dp.unpackUUID(mPartImageID, "psuuid");  	dp.unpackUUID(mTargetUUID, "pstargetuuid"); -	mPartData.unpack(dp);  	return TRUE;  } +BOOL LLPartSysData::unpackLegacy(LLDataPacker &dp) +{ +	unpackSystem(dp); +	mPartData.unpackLegacy(dp); + +	return TRUE; +} + +BOOL LLPartSysData::unpack(LLDataPacker &dp) +{ +	// syssize is currently unused.  Adding now when modifying the 'version to make extensible in the future +	S32 size = 0; +	dp.unpackS32(size, "syssize"); +	 +	if (size != PS_SYS_DATA_BLOCK_SIZE) +	{ //unexpected size, this viewer doesn't know how to parse this particle system +		 +		//skip to LLPartData block +		U8 feh = 0; +		 +		for (U32 i = 0; i < size; ++i) +		{ +			dp.unpackU8(feh, "whippang"); +		} +				 +		dp.unpackS32(size, "partsize"); +		//skip LLPartData block +		for (U32 i = 0; i < size; ++i) +		{ +			dp.unpackU8(feh, "whippang"); +		} +		return FALSE; +	} + +	unpackSystem(dp); +	 +	return mPartData.unpack(dp); +} +  std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)  {  	s << "Flags: " << std::hex << data.mFlags; @@ -253,7 +375,7 @@ std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)  BOOL LLPartSysData::isNullPS(const S32 block_num)  { -	U8 ps_data_block[PS_DATA_BLOCK_SIZE]; +	U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE];  	U32 crc;  	S32 size; @@ -264,14 +386,28 @@ BOOL LLPartSysData::isNullPS(const S32 block_num)  	{  		return TRUE;  	} -	else if (size != PS_DATA_BLOCK_SIZE) +	 +	if (size > PS_MAX_DATA_BLOCK_SIZE)  	{ -		llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl; +		//size is too big, newer particle version unsupported  		return TRUE;  	} -	gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE); -	LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE); +	gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); + +	LLDataPackerBinaryBuffer dp(ps_data_block, size); +	if (size > PS_LEGACY_DATA_BLOCK_SIZE) +	{ +		// non legacy systems pack a size before the CRC +		S32 tmp = 0; +		dp.unpackS32(tmp, "syssize"); + +		if (tmp > PS_SYS_DATA_BLOCK_SIZE) +		{ //unknown system data block size, don't know how to parse it, treat as NULL +			return TRUE; +		} +	} +  	dp.unpackU32(crc, "crc");  	if (crc == 0) @@ -281,50 +417,37 @@ BOOL LLPartSysData::isNullPS(const S32 block_num)  	return FALSE;  } - -//static -BOOL LLPartSysData::packNull() -{ -	U8 ps_data_block[PS_DATA_BLOCK_SIZE]; -	gMessageSystem->addBinaryData("PSBlock", ps_data_block, 0); -	return TRUE; -} - - -BOOL LLPartSysData::packBlock() -{ -	U8 ps_data_block[PS_DATA_BLOCK_SIZE]; - -	LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE); -	pack(dp); - -	// Add to message -	gMessageSystem->addBinaryData("PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE); - -	return TRUE; -}                                          - -  BOOL LLPartSysData::unpackBlock(const S32 block_num)  { -	U8 ps_data_block[PS_DATA_BLOCK_SIZE]; +	U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE];  	// Check size of block  	S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock"); -	if (size != PS_DATA_BLOCK_SIZE) +	if (size > PS_MAX_DATA_BLOCK_SIZE)  	{ -		llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl; +		// Larger packets are newer and unsupported  		return FALSE;  	}  	// Get from message -	gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE); +	gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); -	LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE); -	unpack(dp); +	LLDataPackerBinaryBuffer dp(ps_data_block, size); -	return TRUE; +	if (size == PS_LEGACY_DATA_BLOCK_SIZE) +	{ +		return unpackLegacy(dp); +	} +	else +	{ +		return unpack(dp); +	} +} + +bool LLPartSysData::isLegacyCompatible() const +{ +	return !mPartData.hasGlow() && !mPartData.hasBlendFunc();  }  void LLPartSysData::clampSourceParticleRate() diff --git a/indra/llmessage/llpartdata.h b/indra/llmessage/llpartdata.h index a4ef058b30..80a52b79dd 100644 --- a/indra/llmessage/llpartdata.h +++ b/indra/llmessage/llpartdata.h @@ -70,7 +70,12 @@ enum LLPSScriptFlags  	LLPS_SRC_TARGET_UUID,  	LLPS_SRC_OMEGA,  	LLPS_SRC_ANGLE_BEGIN, -	LLPS_SRC_ANGLE_END +	LLPS_SRC_ANGLE_END, + +	LLPS_PART_BLEND_FUNC_SOURCE, +	LLPS_PART_BLEND_FUNC_DEST, +	LLPS_PART_START_GLOW, +	LLPS_PART_END_GLOW  }; @@ -83,12 +88,17 @@ public:  		mParameter(0.f)  	{  	} +	BOOL unpackLegacy(LLDataPacker &dp);  	BOOL unpack(LLDataPacker &dp); +  	BOOL pack(LLDataPacker &dp);  	LLSD asLLSD() const;  	operator LLSD() const {return asLLSD(); }  	bool fromLLSD(LLSD& sd); +	bool hasGlow() const; +	bool hasBlendFunc() const; +  	// Masks for the different particle flags  	enum  	{ @@ -102,17 +112,39 @@ public:  		LL_PART_TARGET_LINEAR_MASK =	0x80,		// Particle uses a direct linear interpolation  		LL_PART_EMISSIVE_MASK =			0x100,		// Particle is "emissive", instead of being lit  		LL_PART_BEAM_MASK =				0x200,		// Particle is a "beam" connecting source and target +		LL_PART_RIBBON_MASK =			0x400,		// Particles are joined together into one continuous triangle strip  		// Not implemented yet!  		//LL_PART_RANDOM_ACCEL_MASK =		0x100,		// Particles have random acceleration  		//LL_PART_RANDOM_VEL_MASK =		0x200,		// Particles have random velocity shifts"  		//LL_PART_TRAIL_MASK =			0x400,		// Particles have historical "trails" +		//sYSTEM SET FLAGS +		LL_PART_DATA_GLOW =				0x10000, +		LL_PART_DATA_BLEND =			0x20000, +  		// Viewer side use only!  		LL_PART_HUD =					0x40000000,  		LL_PART_DEAD_MASK =				0x80000000,  	}; +	enum +	{ +		LL_PART_BF_ONE = 0, +		LL_PART_BF_ZERO = 1, +		LL_PART_BF_DEST_COLOR = 2, +		LL_PART_BF_SOURCE_COLOR = 3, +		LL_PART_BF_ONE_MINUS_DEST_COLOR = 4, +		LL_PART_BF_ONE_MINUS_SOURCE_COLOR = 5, +		UNSUPPORTED_DEST_ALPHA = 6, +		LL_PART_BF_SOURCE_ALPHA = 7, +		UNSUPPORTED_ONE_MINUS_DEST_ALPHA = 8, +		LL_PART_BF_ONE_MINUS_SOURCE_ALPHA = 9, +		LL_PART_BF_COUNT = 10 +	}; + +	static bool validBlendFunc(S32 func); +  	void setFlags(const U32 flags);  	void setMaxAge(const F32 max_age);  	void setStartScale(const F32 xs, F32 ys); @@ -126,6 +158,9 @@ public:  	friend class LLPartSysData;  	friend class LLViewerPartSourceScript; +private: +	S32 getSize() const; +  	// These are public because I'm really lazy...  public:  	U32					mFlags;						// Particle state/interpolators in effect @@ -137,6 +172,12 @@ public:  	LLVector3			mPosOffset;					// Offset from source if using FOLLOW_SOURCE  	F32					mParameter;					// A single floating point parameter + +	F32					mStartGlow; +	F32					mEndGlow; +	 +	U8					mBlendFuncSource; +	U8					mBlendFuncDest;  }; @@ -146,15 +187,13 @@ public:  	LLPartSysData();  	BOOL unpack(LLDataPacker &dp); -	BOOL pack(LLDataPacker &dp); - -	 +	BOOL unpackLegacy(LLDataPacker &dp);  	BOOL unpackBlock(const S32 block_num); -	BOOL packBlock(); - -	static BOOL packNull(); +		  	static BOOL isNullPS(const S32 block_num); // Returns FALSE if this is a "NULL" particle system (i.e. no system) +	bool isLegacyCompatible() const; +  	// Different masks for effects on the source  	enum  	{ @@ -187,7 +226,12 @@ public:  	void clampSourceParticleRate();  	friend std::ostream&	 operator<<(std::ostream& s, const LLPartSysData &data);		// Stream a + +	S32 getdataBlockSize() const; +private: +	BOOL unpackSystem(LLDataPacker &dp); +  public:  	// Public because I'm lazy.... diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 5ed05e2201..ef6eb75a6b 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -186,27 +186,73 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  	LLVolumeFace::VertexMapData::PointMap point_map; -	for (U32 i = 0; i < idx.getCount(); i += idx_stride) +	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; + +	for (U32 i = 0; i < index_count; i += idx_stride)  	{  		LLVolumeFace::VertexData cv;  		if (pos_source)  		{ +			// guard against model data specifiying out of range indices or verts +			// +			if (((i + pos_offset) > index_count) +			 || ((idx[i+pos_offset]*3+2) > vertex_count)) +			{ +				return LLModel::BAD_ELEMENT; +			} +  			cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0],  								v[idx[i+pos_offset]*3+1],  								v[idx[i+pos_offset]*3+2])); + +			if (!cv.getPosition().isFinite3()) +			{ +				return LLModel::BAD_ELEMENT; +			}  		}  		if (tc_source)  		{ +			// guard against model data specifiying out of range indices or tcs +			// +			if (((i + tc_offset) > index_count) +			 || ((idx[i+pos_offset]*2+1) > tc_count)) +			{ +				return LLModel::BAD_ELEMENT; +			} +  			cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0],  								tc[idx[i+tc_offset]*2+1]); + +			if (!cv.mTexCoord.isFinite()) +			{ +				llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl; +				return LLModel::BAD_ELEMENT; +			}  		}  		if (norm_source)  		{ +			// guard against model data specifiying out of range indices or norms +			// +			if (((i + norm_offset) > index_count) +				|| ((idx[i+norm_offset]*3+2) > norm_count)) +			{ +				return LLModel::BAD_ELEMENT; +			} +  			cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0],  								n[idx[i+norm_offset]*3+1],  								n[idx[i+norm_offset]*3+2])); + +			if (!cv.getNormal().isFinite3()) +			{ +				llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl; +				return LLModel::BAD_ELEMENT; +			}  		}  		BOOL found = FALSE; @@ -261,13 +307,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  			LLVolumeFace& new_face = *face_list.rbegin();  			if (!norm_source)  			{ -				ll_aligned_free_16(new_face.mNormals); +				//ll_aligned_free_16(new_face.mNormals);  				new_face.mNormals = NULL;  			}  			if (!tc_source)  			{ -				ll_aligned_free_16(new_face.mTexCoords); +				//ll_aligned_free_16(new_face.mTexCoords);  				new_face.mTexCoords = NULL;  			} @@ -292,13 +338,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  		LLVolumeFace& new_face = *face_list.rbegin();  		if (!norm_source)  		{ -			ll_aligned_free_16(new_face.mNormals); +			//ll_aligned_free_16(new_face.mNormals);  			new_face.mNormals = NULL;  		}  		if (!tc_source)  		{ -			ll_aligned_free_16(new_face.mTexCoords); +			//ll_aligned_free_16(new_face.mTexCoords);  			new_face.mTexCoords = NULL;  		}  	} @@ -364,6 +410,11 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  	LLVolumeFace::VertexMapData::PointMap point_map; +	U32 index_count  = idx.getCount(); +	U32 vertex_count = pos_source  ? v.getCount()  : 0; +	U32 tc_count     = tc_source   ? tc.getCount() : 0; +	U32 norm_count   = norm_source ? n.getCount()  : 0; +  	U32 cur_idx = 0;  	for (U32 i = 0; i < vcount.getCount(); ++i)  	{ //for each polygon @@ -376,22 +427,65 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  			if (pos_source)  			{ +				// guard against model data specifiying out of range indices or verts +				// +				if (((i + pos_offset) > index_count) +				 || ((idx[i+pos_offset]*3+2) > vertex_count)) +				{ +					return LLModel::BAD_ELEMENT; +				} +  				cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0],  									v[idx[cur_idx+pos_offset]*3+1],  									v[idx[cur_idx+pos_offset]*3+2]); + +				if (!cv.getPosition().isFinite3()) +				{ +					llwarns << "Found NaN while loading positions from DAE-Model, invalid model." << llendl; +					return LLModel::BAD_ELEMENT; +				} +  			}  			if (tc_source)  			{ +				// guard against model data specifiying out of range indices or tcs +				// +				if (((i + pos_offset) > index_count) +				 || ((idx[cur_idx+tc_offset]*2+1) > tc_count)) +				{ +					return LLModel::BAD_ELEMENT; +				} +  				cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0],  									tc[idx[cur_idx+tc_offset]*2+1]); + +				if (!cv.mTexCoord.isFinite()) +				{ +					llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl; +					return LLModel::BAD_ELEMENT; +				}  			}  			if (norm_source)  			{ +				// guard against model data specifiying out of range indices or norms +				// +				if (((i + pos_offset) > index_count) +				 || ((idx[cur_idx+norm_offset]*3+2) > norm_count)) +				{ +					return LLModel::BAD_ELEMENT; +				} +  				cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0],  									n[idx[cur_idx+norm_offset]*3+1],  									n[idx[cur_idx+norm_offset]*3+2]); + +				if (!cv.getNormal().isFinite3()) +				{ +					llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl; +					return LLModel::BAD_ELEMENT; +				}  			}  			cur_idx += idx_stride; @@ -480,13 +574,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  				LLVolumeFace& new_face = *face_list.rbegin();  				if (!norm_source)  				{ -					ll_aligned_free_16(new_face.mNormals); +					//ll_aligned_free_16(new_face.mNormals);  					new_face.mNormals = NULL;  				}  				if (!tc_source)  				{ -					ll_aligned_free_16(new_face.mTexCoords); +					//ll_aligned_free_16(new_face.mTexCoords);  					new_face.mTexCoords = NULL;  				} @@ -514,13 +608,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  		LLVolumeFace& new_face = *face_list.rbegin();  		if (!norm_source)  		{ -			ll_aligned_free_16(new_face.mNormals); +			//ll_aligned_free_16(new_face.mNormals);  			new_face.mNormals = NULL;  		}  		if (!tc_source)  		{ -			ll_aligned_free_16(new_face.mTexCoords); +			//ll_aligned_free_16(new_face.mTexCoords);  			new_face.mTexCoords = NULL;  		}  	} @@ -632,6 +726,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  				vert.getPosition().set(v->get(v_idx),  								v->get(v_idx+1),  								v->get(v_idx+2)); + +				if (!vert.getPosition().isFinite3()) +				{ +					llwarns << "Found NaN while loading position data from DAE-Model, invalid model." << llendl; +					return LLModel::BAD_ELEMENT; +				}  			}  			//bounds check n and t lookups because some FBX to DAE converters @@ -644,6 +744,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  				vert.getNormal().set(n->get(n_idx),  								n->get(n_idx+1),  								n->get(n_idx+2)); + +				if (!vert.getNormal().isFinite3()) +				{ +					llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl; +					return LLModel::BAD_ELEMENT; +				}  			}  			else  			{ @@ -657,6 +763,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  				t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount());  				vert.mTexCoord.setVec(t->get(t_idx),  								t->get(t_idx+1));								 + +				if (!vert.mTexCoord.isFinite()) +				{ +					llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl; +					return LLModel::BAD_ELEMENT; +				}  			}  			else  			{ @@ -730,13 +842,13 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  		LLVolumeFace& new_face = *face_list.rbegin();  		if (!n)  		{ -			ll_aligned_free_16(new_face.mNormals); +			//ll_aligned_free_16(new_face.mNormals);  			new_face.mNormals = NULL;  		}  		if (!t)  		{ -			ll_aligned_free_16(new_face.mTexCoords); +			//ll_aligned_free_16(new_face.mTexCoords);  			new_face.mTexCoords = NULL;  		}  	} @@ -1036,7 +1148,7 @@ void LLModel::setVolumeFaceData(  	}  	else  	{ -		ll_aligned_free_16(face.mNormals); +		//ll_aligned_free_16(face.mNormals);  		face.mNormals = NULL;  	} @@ -1047,7 +1159,7 @@ void LLModel::setVolumeFaceData(  	}  	else  	{ -		ll_aligned_free_16(face.mTexCoords); +		//ll_aligned_free_16(face.mTexCoords);  		face.mTexCoords = NULL;  	} @@ -1246,7 +1358,7 @@ void LLModel::generateNormals(F32 angle_cutoff)  		}  		else  		{ -			ll_aligned_free_16(new_face.mTexCoords); +			//ll_aligned_free_16(new_face.mTexCoords);  			new_face.mTexCoords = NULL;  		} diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 89f1f36297..58bd346c15 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -741,7 +741,7 @@ bool LLGLManager::initGL()  #if LL_WINDOWS  	if (mHasDebugOutput && gDebugGL)  	{ //setup debug output callback -		//glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE); +		glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);  		glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);  		glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);  	} @@ -1478,7 +1478,7 @@ void do_assert_glerror()  void assert_glerror()  { -	if (!gGLActive) +/*	if (!gGLActive)  	{  		//llwarns << "GL used while not active!" << llendl; @@ -1487,8 +1487,13 @@ void assert_glerror()  			//ll_fail("GL used while not active");  		}  	} +*/ -	if (gDebugGL)  +	if (!gDebugGL)  +	{ +		//funny looking if for branch prediction -- gDebugGL is almost always false and assert_glerror is called often +	} +	else  	{  		do_assert_glerror();  	} diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index a4d7872ec2..ef2648ae98 100755 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -709,9 +709,12 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  					mMipLevels = wpo2(llmax(w, h)); -					//use legacy mipmap generation mode -					glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE); -					 +					if (!gGLManager.mHasFramebufferObject) +					{ +						//use legacy mipmap generation mode +						glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE); +					} +										  					LLImageGL::setManualImage(mTarget, 0, mFormatInternal,  								 w, h,   								 mFormatPrimary, mFormatType, @@ -726,6 +729,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  						glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);  						stop_glerror();  					} + +					if (gGLManager.mHasFramebufferObject) +					{ +						glGenerateMipmap(mTarget); +					}  				}  			}  			else @@ -1057,6 +1065,16 @@ void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 n  {  	bool empty = true; +	if (LLRender::sGLCoreProfile) +	{ +		switch (format) +		{ +			case GL_LUMINANCE8: format = GL_RGB8; break; +			case GL_LUMINANCE8_ALPHA8: +			case GL_ALPHA8: format = GL_RGBA8; break; +		} +	} +  	dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);  	if (iter != sDeadTextureList[type].end()) @@ -1084,6 +1102,16 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip  {  	if (gGLManager.mInited)  	{ +		if (LLRender::sGLCoreProfile) +		{ +			switch (format) +			{ +				case GL_LUMINANCE8: format = GL_RGB8; break; +				case GL_LUMINANCE8_ALPHA8: +				case GL_ALPHA8: format = GL_RGBA8; break; +			} +		} +  		if (format == 0 ||  type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)  		{ //unknown internal format or unknown number of mip levels, not safe to reuse  			glDeleteTextures(numTextures, textures); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 5801946a74..14962fe58e 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1070,6 +1070,16 @@ LLRender::~LLRender()  void LLRender::init()  { +	if (sGLCoreProfile && !LLVertexBuffer::sUseVAO) +	{ //bind a dummy vertex array object so we're core profile compliant +#ifdef GL_ARB_vertex_array_object +		U32 ret; +		glGenVertexArrays(1, &ret); +		glBindVertexArray(ret); +#endif +	} + +  	llassert_always(mBuffer.isNull()) ;  	stop_glerror();  	mBuffer = new LLVertexBuffer(immediate_mask, 0); diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b6a9a6b653..825f80a6dc 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -974,7 +974,9 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedUniforms.push_back("texture_matrix1");  	mReservedUniforms.push_back("texture_matrix2");  	mReservedUniforms.push_back("texture_matrix3"); -	llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_MATRIX3+1); +	mReservedUniforms.push_back("object_plane_s"); +	mReservedUniforms.push_back("object_plane_t"); +	llassert(mReservedUniforms.size() == LLShaderMgr::OBJECT_PLANE_T+1);  	mReservedUniforms.push_back("viewport"); @@ -1116,6 +1118,48 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedUniforms.push_back("bloomMap");  	mReservedUniforms.push_back("projectionMap"); +	mReservedUniforms.push_back("matrixPalette"); +	 +	 +	mReservedUniforms.reserve(12); +	mReservedUniforms.push_back("screenTex"); +	mReservedUniforms.push_back("screenDepth"); +	mReservedUniforms.push_back("refTex"); +	mReservedUniforms.push_back("eyeVec"); +	mReservedUniforms.push_back("time"); +	mReservedUniforms.push_back("d1"); +	mReservedUniforms.push_back("d2"); +	mReservedUniforms.push_back("lightDir"); +	mReservedUniforms.push_back("specular"); +	mReservedUniforms.push_back("lightExp"); +	mReservedUniforms.push_back("waterFogColor"); +	mReservedUniforms.push_back("waterFogDensity"); +	mReservedUniforms.push_back("waterFogKS"); +	mReservedUniforms.push_back("refScale"); +	mReservedUniforms.push_back("waterHeight"); +	mReservedUniforms.push_back("waterPlane"); +	mReservedUniforms.push_back("normScale"); +	mReservedUniforms.push_back("fresnelScale"); +	mReservedUniforms.push_back("fresnelOffset"); +	mReservedUniforms.push_back("blurMultiplier"); +	mReservedUniforms.push_back("sunAngle"); +	mReservedUniforms.push_back("scaledAngle"); +	mReservedUniforms.push_back("sunAngle2"); +	 +	mReservedUniforms.push_back("camPosLocal"); + +	mReservedUniforms.push_back("gWindDir"); +	mReservedUniforms.push_back("gSinWaveParams"); +	mReservedUniforms.push_back("gGravity"); + +	mReservedUniforms.push_back("detail_0"); +	mReservedUniforms.push_back("detail_1"); +	mReservedUniforms.push_back("detail_2"); +	mReservedUniforms.push_back("detail_3"); +	mReservedUniforms.push_back("alpha_ramp"); + +	mReservedUniforms.push_back("origin"); +  	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);  	std::set<std::string> dupe_check; diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 7a16b7c20f..77e90372e0 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -47,6 +47,8 @@ public:  		TEXTURE_MATRIX1,  		TEXTURE_MATRIX2,  		TEXTURE_MATRIX3, +		OBJECT_PLANE_S, +		OBJECT_PLANE_T,  		VIEWPORT,  		LIGHT_POSITION,  		LIGHT_DIRECTION, @@ -164,7 +166,49 @@ public:  		DEFERRED_LIGHT,  		DEFERRED_BLOOM,  		DEFERRED_PROJECTION, +		 +		AVATAR_MATRIX, + +		WATER_SCREENTEX, +		WATER_SCREENDEPTH, +		WATER_REFTEX, +		WATER_EYEVEC, +		WATER_TIME, +		WATER_WAVE_DIR1, +		WATER_WAVE_DIR2, +		WATER_LIGHT_DIR, +		WATER_SPECULAR, +		WATER_SPECULAR_EXP, +		WATER_FOGCOLOR, +		WATER_FOGDENSITY, +		WATER_FOGKS, +		WATER_REFSCALE, +		WATER_WATERHEIGHT, +		WATER_WATERPLANE, +		WATER_NORM_SCALE, +		WATER_FRESNEL_SCALE, +		WATER_FRESNEL_OFFSET, +		WATER_BLUR_MULTIPLIER, +		WATER_SUN_ANGLE, +		WATER_SCALED_ANGLE, +		WATER_SUN_ANGLE2, +		 +		WL_CAMPOSLOCAL, + +		AVATAR_WIND, +		AVATAR_SINWAVE, +		AVATAR_GRAVITY, + +		TERRAIN_DETAIL0, +		TERRAIN_DETAIL1, +		TERRAIN_DETAIL2, +		TERRAIN_DETAIL3, +		TERRAIN_ALPHARAMP, +		 +		SHINY_ORIGIN, +  		END_RESERVED_UNIFORMS +  	} eGLSLReservedUniforms;  	// singleton pattern implementation diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index f152911b24..f8ab085aac 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -202,7 +202,7 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)  			glBufferDataARB(mType, size, 0, mUsage);  			if (mUsage != GL_DYNAMIC_COPY_ARB)  			{ //data will be provided by application -				ret = (U8*) ll_aligned_malloc_16(size); +				ret = (U8*) ll_aligned_malloc(size, 64);  			}  		}  		else @@ -256,7 +256,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)  	llassert(vbo_block_size(size) == size);  	deleteBuffer(name); -	ll_aligned_free_16((U8*) buffer); +	ll_aligned_free((U8*) buffer);  	if (mType == GL_ARRAY_BUFFER_ARB)  	{ @@ -310,7 +310,7 @@ void LLVBOPool::cleanup()  			if (r.mClientData)  			{ -				ll_aligned_free_16((void*) r.mClientData); +				ll_aligned_free((void*) r.mClientData);  			}  			l.pop_front(); @@ -1298,7 +1298,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)  		//actually allocate space for the vertex buffer if using VBO mapping  		flush(); -		if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO)) +		if (gGLManager.mHasVertexArrayObject && useVBOs() && (sUseVAO))  		{  #if GL_ARB_vertex_array_object  			mGLArray = getVAOName(); @@ -1454,21 +1454,18 @@ bool LLVertexBuffer::useVBOs() const  //---------------------------------------------------------------------------- -bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count) +bool expand_region(LLVertexBuffer::MappedRegion& region, S32 start, S32 end)  { -	S32 end = index+count; -	S32 region_end = region.mIndex+region.mCount; -	  	if (end < region.mIndex || -		index > region_end) +		start > region.mEnd)  	{ //gap exists, do not merge  		return false;  	} -	S32 new_end = llmax(end, region_end); -	S32 new_index = llmin(index, region.mIndex); -	region.mIndex = new_index; -	region.mCount = new_end-new_index; +	region.mEnd = llmax(end, region.mEnd); +	region.mIndex = llmin(start, region.mIndex); +	region.mCount = region.mEnd-region.mIndex; +  	return true;  } @@ -1478,7 +1475,6 @@ static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER("VBO Map");  // Map for data access  volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)  { -	bindGLBuffer(true);  	if (mFinal)  	{  		llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl; @@ -1499,23 +1495,23 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo  			bool mapped = false;  			//see if range is already mapped -			for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) +			S32 start_index = mOffsets[type]+index*sTypeSize[type]; +			S32 end_index = start_index+count*sTypeSize[type]; + +			for (std::vector<MappedRegion>::iterator iter = mMappedVertexRegions.begin(), end = mMappedVertexRegions.end(); iter != end; ++iter)  			{ -				MappedRegion& region = mMappedVertexRegions[i]; -				if (region.mType == type) +				MappedRegion& region = *iter; +				if (expand_region(region, index, end_index))  				{ -					if (expand_region(region, index, count)) -					{ -						mapped = true; -						break; -					} +					mapped = true; +					break;  				}  			}  			if (!mapped)  			{  				//not already mapped, map new region -				MappedRegion region(type, mMappable && map_range ? -1 : index, count); +				MappedRegion region(mMappable && map_range ? -1 : start_index, end_index-start_index);  				mMappedVertexRegions.push_back(region);  			}  		} @@ -1539,6 +1535,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo  			{  				volatile U8* src = NULL;  				waitFence(); +				bindGLBuffer();  				if (gGLManager.mHasMapBufferRange)  				{  					if (map_range) @@ -1657,7 +1654,6 @@ static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map");  volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)  { -	bindGLIndices(true);  	if (mFinal)  	{  		llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl; @@ -1676,12 +1672,14 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range  				count = mNumIndices-index;  			} +			S32 end = index+count; +  			bool mapped = false;  			//see if range is already mapped  			for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)  			{  				MappedRegion& region = mMappedIndexRegions[i]; -				if (expand_region(region, index, count)) +				if (expand_region(region, index, end))  				{  					mapped = true;  					break; @@ -1691,7 +1689,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range  			if (!mapped)  			{  				//not already mapped, map new region -				MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count); +				MappedRegion region(mMappable && map_range ? -1 : index, count);  				mMappedIndexRegions.push_back(region);  			}  		} @@ -1707,23 +1705,23 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range  			sMappedCount++;  			stop_glerror();	 -			if (gDebugGL && useVBOs()) -			{ -				GLint elem = 0; -				glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); - -				if (elem != mGLIndices) -				{ -					llerrs << "Wrong index buffer bound!" << llendl; -				} -			} -  			if(!mMappable)  			{  				map_range = false;  			}  			else  			{ +				bindGLIndices(); +				if (gDebugGL && useVBOs()) +				{ +					GLint elem = 0; +					glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + +					if (elem != mGLIndices) +					{ +						llerrs << "Wrong index buffer bound!" << llendl; +					} +				}  				volatile U8* src = NULL;  				waitFence();  				if (gGLManager.mHasMapBufferRange) @@ -1837,7 +1835,7 @@ void LLVertexBuffer::unmapBuffer()  		llassert(mUsage != GL_DYNAMIC_COPY_ARB);  		LLFastTimer t(FTM_VBO_UNMAP); -		bindGLBuffer(true); +		bindGLBuffer();  		updated_all = mIndexLocked; //both vertex and index buffers done updating  		if(!mMappable) @@ -1848,8 +1846,8 @@ void LLVertexBuffer::unmapBuffer()  				for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)  				{  					const MappedRegion& region = mMappedVertexRegions[i]; -					S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; -					S32 length = sTypeSize[region.mType]*region.mCount; +					S32 offset = region.mIndex; +					S32 length = region.mCount;  					glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);  					stop_glerror();  				} @@ -1873,8 +1871,8 @@ void LLVertexBuffer::unmapBuffer()  					for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)  					{  						const MappedRegion& region = mMappedVertexRegions[i]; -						S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; -						S32 length = sTypeSize[region.mType]*region.mCount; +						S32 offset = region.mIndex; +						S32 length = region.mCount;  						if (gGLManager.mHasMapBufferRange)  						{  							LLFastTimer t(FTM_VBO_FLUSH_RANGE); @@ -2083,7 +2081,6 @@ bool LLVertexBuffer::bindGLArray()  	if (mGLArray && sGLRenderArray != mGLArray)  	{  		{ -			LLFastTimer t(FTM_BIND_GL_ARRAY);  #if GL_ARB_vertex_array_object  			glBindVertexArray(mGLArray);  #endif @@ -2363,7 +2360,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  		if (data_mask & MAP_COLOR)  		{  			S32 loc = TYPE_COLOR; -			void* ptr = (void*)(base + mOffsets[TYPE_COLOR]); +			//bind emissive instead of color pointer if emissive is present +			void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);  			glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);  		}  		if (data_mask & MAP_EMISSIVE) @@ -2371,6 +2369,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  			S32 loc = TYPE_EMISSIVE;  			void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);  			glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + +			if (!(data_mask & MAP_COLOR)) +			{ //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps +				loc = TYPE_COLOR; +				glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); +			}  		}  		if (data_mask & MAP_WEIGHT)  		{ @@ -2453,11 +2457,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  	llglassertok();  } -LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count) -: mType(type), mIndex(index), mCount(count) +LLVertexBuffer::MappedRegion::MappedRegion(S32 index, S32 count) +: mIndex(index), mCount(count)  {  -	llassert(mType == LLVertexBuffer::TYPE_INDEX ||  -			mType < LLVertexBuffer::TYPE_TEXTURE_INDEX); +	mEnd = mIndex+mCount;	  }	 diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index a3400ae80c..52559d3505 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -104,11 +104,11 @@ public:  	class MappedRegion  	{  	public: -		S32 mType;  		S32 mIndex;  		S32 mCount; +		S32 mEnd; -		MappedRegion(S32 type, S32 index, S32 count); +		MappedRegion(S32 index, S32 count);  	};  	LLVertexBuffer(const LLVertexBuffer& rhs) diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 705fe16559..3dfcb3ffa1 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -758,11 +758,11 @@ void LLButton::draw()  		mCurGlowStrength = lerp(mCurGlowStrength,  					mFlashing ? (flash? 1.0 : 0.0)  					: mHoverGlowStrength, -					LLCriticalDamp::getInterpolant(0.05f)); +					LLCriticalDamp::getInterpolant(InterpDeltaTeeny));  	}  	else  	{ -		mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f)); +		mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(InterpDeltaTeeny));  	}  	// Draw button image, if available. @@ -1247,3 +1247,4 @@ BOOL LLButton::handleDoubleClick(S32 x, S32 y, MASK mask)  	// just treat a double click as a second click  	return handleMouseDown(x, y, mask);  } + diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index 161496b1f5..fdfaf284de 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -243,8 +243,6 @@ void LLConsole::draw()  void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color)   {  	LLSD paragraph_color_segments; -	LLColor4 lcolor=color; -	  	paragraph_color_segments[0]["text"] =wstring_to_utf8str(mParagraphText);  	LLSD color_sd = color.getValue();  	paragraph_color_segments[0]["color"]=color_sd; diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index c1cd04186b..537cc82302 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -368,7 +368,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  	const llwchar* base = wtext.c_str();  	const llwchar* cur = base;  	const llwchar* line = NULL; - +        (void)line;  	while( *cur )  	{  		if( *cur == '\n' || cur == base ) diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 4c730286da..32383b1f1d 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -229,7 +229,10 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)  	mOpenTimeConstant(p.open_time_constant),  	mCloseTimeConstant(p.close_time_constant),  	mResizeBarOverlap(p.resize_bar_overlap) -{} +{ +	LLCriticalDamp::setInterpolantConstant(InterpDeltaCloseTime, mCloseTimeConstant); +	LLCriticalDamp::setInterpolantConstant(InterpDeltaOpenTime,  mOpenTimeConstant); +}  LLLayoutStack::~LLLayoutStack()  { @@ -478,7 +481,7 @@ void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp)  		{  			LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;  			LLRect resize_bar_rect = getRect(); - +			(void)resize_bar_rect;  			LLResizeBar::Params resize_params;  			resize_params.name("resize");  			resize_params.resizing_view(lp); @@ -592,7 +595,7 @@ bool LLLayoutStack::animatePanels()  			{  				if (!mAnimatedThisFrame)  				{ -					panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(mOpenTimeConstant)); +					panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(InterpDeltaOpenTime));  					if (panelp->mVisibleAmt > 0.99f)  					{  						panelp->mVisibleAmt = 1.f; @@ -617,7 +620,7 @@ bool LLLayoutStack::animatePanels()  			{  				if (!mAnimatedThisFrame)  				{ -					panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); +					panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(InterpDeltaCloseTime));  					if (panelp->mVisibleAmt < 0.001f)  					{  						panelp->mVisibleAmt = 0.f; @@ -644,7 +647,7 @@ bool LLLayoutStack::animatePanels()  			{  				if (!mAnimatedThisFrame)  				{ -					panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); +					panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(InterpDeltaCloseTime));  				}  				if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f) @@ -855,3 +858,4 @@ void LLLayoutStack::updateResizeBarLimits()  		previous_visible_panelp = visible_panelp;  	}  } + diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index cd6cc6a75e..f142be885d 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3673,7 +3673,7 @@ void LLTearOffMenu::draw()  	if (getRect().getHeight() != mTargetHeight)  	{  		// animate towards target height -		reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f)))); +		reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(InterpDeltaTeeny))));  	}  	LLFloater::draw();  } diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 5d3bf7a670..d65b4431a8 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -493,11 +493,11 @@ void LLScrollbar::draw()  	BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y));  	if (hovered)  	{ -		mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f)); +		mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(InterpDeltaTeeny));  	}  	else  	{ -		mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f)); +		mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(InterpDeltaTeeny));  	}  	// Draw background and thumb. @@ -642,3 +642,4 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data )  {  	changeLine( mStepSize, TRUE );  } + diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 5fc2cc350d..1e64cd0df8 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -406,7 +406,7 @@ void LLTabContainer::draw()  		}  	} -	setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f))); +	setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(InterpDeltaTeeny)));  	BOOL has_scroll_arrows = !getTabsHidden() && ((mMaxScrollPos > 0) || (mScrollPosPixels > 0));  	if (!mIsVertical) @@ -2046,3 +2046,4 @@ void LLTabContainer::commitHoveredButton(S32 x, S32 y)  		}  	}  } + diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 3815eec447..ec66b6df56 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -351,7 +351,6 @@ void LLTextBase::drawSelectionBackground()  		S32 selection_left		= llmin( mSelectionStart, mSelectionEnd );  		S32 selection_right		= llmax( mSelectionStart, mSelectionEnd ); -		LLRect selection_rect = mVisibleTextRect;  		// Skip through the lines we aren't drawing.  		LLRect content_display_rect = getVisibleDocumentRect(); @@ -2241,6 +2240,8 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,  	// Figure out which line we're nearest to.  	LLRect visible_region = getVisibleDocumentRect();  	LLRect doc_rect = mDocumentView->getRect(); +	(void)visible_region; +	(void)doc_rect;  	S32 doc_y = local_y - doc_rect.mBottom; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 46fbd1e6a0..e4bd51c8ce 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -2490,7 +2490,6 @@ void LLTextEditor::updateSegments()  		mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);  		clearSegments(); -		segment_set_t::iterator insert_it = mSegments.begin();  		for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it)  		{  			insertSegment(*list_it); diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 63b7e452d2..62b6a0cd2f 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -653,7 +653,6 @@ void LLToolBar::updateLayoutAsNeeded()  	S32 max_row_length = 0;  	S32 max_length; -	S32 max_total_girth;  	S32 cur_start;  	S32 cur_row ;  	S32 row_pad_start; @@ -664,7 +663,6 @@ void LLToolBar::updateLayoutAsNeeded()  	if (orientation == LLLayoutStack::HORIZONTAL)  	{  		max_length = getRect().getWidth() - mPadLeft - mPadRight; -		max_total_girth = getRect().getHeight() - mPadTop - mPadBottom;  		row_pad_start = mPadLeft;  		row_pad_end = mPadRight;  		cur_row = mPadTop; @@ -673,7 +671,6 @@ void LLToolBar::updateLayoutAsNeeded()  	else // VERTICAL  	{  		max_length = getRect().getHeight() - mPadTop - mPadBottom; -		max_total_girth = getRect().getWidth() - mPadLeft - mPadRight;  		row_pad_start = mPadTop;  		row_pad_end = mPadBottom;  		cur_row = mPadLeft; @@ -842,6 +839,7 @@ void LLToolBar::draw()  	{  		LLRect caret_rect = caret->getRect();  		LLRect toolbar_rect = getRect(); +		(void)toolbar_rect;  		if (getOrientation(mSideType) == LLLayoutStack::HORIZONTAL)  		{  			caret->setRect(LLRect(mDragx-caret_rect.getWidth()/2+1, diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l index 307a5561a0..3f844d0fd1 100644 --- a/indra/lscript/lscript_compile/indra.l +++ b/indra/lscript/lscript_compile/indra.l @@ -355,6 +355,10 @@ extern "C" { int yyerror(const char *fmt, ...); }  "PSYS_PART_END_SCALE"	{ count(); yylval.ival = LLPS_PART_END_SCALE; return (INTEGER_CONSTANT); }  "PSYS_PART_MAX_AGE"		{ count(); yylval.ival = LLPS_PART_MAX_AGE; return (INTEGER_CONSTANT); } +"PSYS_PART_BLEND_FUNC_SOURCE"	{ count(); yylval.ival = LLPS_PART_BLEND_FUNC_SOURCE; return (INTEGER_CONSTANT); } +"PSYS_PART_BLEND_FUNC_DEST"		{ count(); yylval.ival = LLPS_PART_BLEND_FUNC_DEST; return (INTEGER_CONSTANT); } +"PSYS_PART_START_GLOW"	{ count(); yylval.ival = LLPS_PART_START_GLOW; return (INTEGER_CONSTANT); } +"PSYS_PART_END_GLOW"	{ count(); yylval.ival = LLPS_PART_END_GLOW; return (INTEGER_CONSTANT); }  "PSYS_PART_WIND_MASK"				{ count(); yylval.ival = LLPartData::LL_PART_WIND_MASK; return(INTEGER_CONSTANT); }  "PSYS_PART_INTERP_COLOR_MASK"		{ count(); yylval.ival = LLPartData::LL_PART_INTERP_COLOR_MASK; return(INTEGER_CONSTANT); } @@ -365,6 +369,16 @@ extern "C" { int yyerror(const char *fmt, ...); }  "PSYS_PART_TARGET_POS_MASK"			{ count(); yylval.ival = LLPartData::LL_PART_TARGET_POS_MASK; return(INTEGER_CONSTANT); }  "PSYS_PART_EMISSIVE_MASK"			{ count(); yylval.ival = LLPartData::LL_PART_EMISSIVE_MASK; return(INTEGER_CONSTANT); }  "PSYS_PART_TARGET_LINEAR_MASK"		{ count(); yylval.ival = LLPartData::LL_PART_TARGET_LINEAR_MASK; return(INTEGER_CONSTANT); } +"PSYS_PART_RIBBON_MASK"				{ count(); yylval.ival = LLPartData::LL_PART_RIBBON_MASK; return(INTEGER_CONSTANT); } + +"PSYS_PART_BF_ONE"						{ count(); yylval.ival = LLPartData::LL_PART_BF_ONE; return(INTEGER_CONSTANT); } +"PSYS_PART_BF_ZERO"						{ count(); yylval.ival = LLPartData::LL_PART_BF_ZERO; return(INTEGER_CONSTANT); } +"PSYS_PART_BF_DEST_COLOR"				{ count(); yylval.ival = LLPartData::LL_PART_BF_DEST_COLOR; return(INTEGER_CONSTANT); } +"PSYS_PART_BF_SOURCE_COLOR"				{ count(); yylval.ival = LLPartData::LL_PART_BF_SOURCE_COLOR; return(INTEGER_CONSTANT); } +"PSYS_PART_BF_ONE_MINUS_DEST_COLOR"		{ count(); yylval.ival = LLPartData::LL_PART_BF_ONE_MINUS_DEST_COLOR; return(INTEGER_CONSTANT); } +"PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR"	{ count(); yylval.ival = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_COLOR; return(INTEGER_CONSTANT); } +"PSYS_PART_BF_SOURCE_ALPHA"				{ count(); yylval.ival = LLPartData::LL_PART_BF_SOURCE_ALPHA; return(INTEGER_CONSTANT); } +"PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA"	{ count(); yylval.ival = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; return(INTEGER_CONSTANT); }  "PSYS_SRC_MAX_AGE"					{ count(); yylval.ival = LLPS_SRC_MAX_AGE; return(INTEGER_CONSTANT); } diff --git a/indra/lscript/lscript_execute/lscript_readlso.cpp b/indra/lscript/lscript_execute/lscript_readlso.cpp index 35caa41ae1..3cdb41ac17 100644 --- a/indra/lscript/lscript_execute/lscript_readlso.cpp +++ b/indra/lscript/lscript_execute/lscript_readlso.cpp @@ -145,7 +145,7 @@ void LLScriptLSOParse::printGlobals(LLFILE *fp)  		// get offset to skip past name  		varoffset = global_v_offset;  		offset = bytestream2integer(mRawData, global_v_offset); -		 +		(void)offset; //hush little compiler  		// get typeexport  		type = *(mRawData + global_v_offset++); @@ -262,8 +262,6 @@ void LLScriptLSOParse::printGlobalFunctions(LLFILE *fp)  		fprintf(fp, "[Function #%d] [0x%X] %s\n", function_number, orig_function_offset, name);  		fprintf(fp, "\tReturn Type: %s\n", LSCRIPTTypeNames[type]);  		type = *(mRawData + function_offset++); -		S32 params; -		params = 0;  		S32 pcount = 0;  		while (type)  		{ @@ -350,6 +348,7 @@ void LLScriptLSOParse::printStates(LLFILE *fp)  				S32 dummy;  				opcode_end = worst_case_opcode_end; +				(void)opcode_end;  				for (k = LSTT_STATE_BEGIN; k < LSTT_STATE_END; k++)  				{ @@ -357,6 +356,7 @@ void LLScriptLSOParse::printStates(LLFILE *fp)  					{  						temp_end = bytestream2integer(mRawData, read_ahead);  						dummy = bytestream2integer(mRawData, read_ahead); +						(void)dummy;  						if (  (temp_end < opcode_end)  							&&(temp_end > event_offset))  						{ diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl deleted file mode 100644 index da1b234240..0000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl +++ /dev/null @@ -1,190 +0,0 @@ -/**  - * @file giF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, 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$ - */ -  -#extension GL_ARB_texture_rectangle : enable - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2D noiseMap; - -uniform sampler2D		diffuseGIMap; -uniform sampler2D		normalGIMap; -uniform sampler2D		depthGIMap; - -uniform sampler2D		lightFunc; - -// Inputs -VARYING vec2 vary_fragcoord; - -uniform vec2 screen_res; - -uniform mat4 inv_proj; -uniform mat4 gi_mat;  //gPipeline.mGIMatrix - eye space to sun space -uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space -uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix -uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space -uniform float gi_radius; -uniform float gi_intensity; -uniform int gi_samples; -uniform vec2 gi_kern[25]; -uniform vec2 gi_scale; -uniform vec3 gi_quad; -uniform vec3 gi_spec; -uniform float gi_direction_weight; -uniform float gi_light_offset; - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).a; -	vec2 sc = pos_screen.xy*2.0; -	sc /= screen_res; -	sc -= vec2(1.0,1.0); -	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); -	vec4 pos = inv_proj * ndc; -	pos /= pos.w; -	pos.w = 1.0; -	return pos; -} - -vec4 getGIPosition(vec2 gi_tc) -{ -	float depth = texture2D(depthGIMap, gi_tc).a; -	vec2 sc = gi_tc*2.0; -	sc -= vec2(1.0, 1.0); -	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); -	vec4 pos = gi_inv_proj*ndc; -	pos.xyz /= pos.w; -	pos.w = 1.0; -	return pos; -} - -vec3 giAmbient(vec3 pos, vec3 norm) -{ -	vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); -	gi_c.xyz /= gi_c.w; - -	vec4 gi_pos = gi_mat*vec4(pos,1.0); -	vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; -	gi_norm = normalize(gi_norm); -	 -	vec2 tcx = gi_norm.xy; -	vec2 tcy = gi_norm.yx; -	 -	vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); -	 -	vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w); -	 -	//vec3 eye_dir = vec3(0,0,-1); -	//eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; -	//eye_dir = normalize(eye_dir); -	 -	//float round_x = gi_scale.x; -	//float round_y = gi_scale.y; -	 -	vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5; -	debug.xz = vec2(0.0,0.0); -	//debug = fract(debug); -	 -	float round_x = 1.0/64.0; -	float round_y = 1.0/64.0; -	 -	//gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; -	//gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; -	 -	float fda = 0.0; -	vec3 fdiff = vec3(0,0,0); -	 -	vec3 rcol = vec3(0,0,0); -	 -	float fsa = 0.0; -	 -	for (int i = -1; i < 2; i+=2 ) -	{ -		for (int j = -1; j < 2; j+=2) -		{ -			vec2 tc = vec2(i, j)*0.75; -			vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; -			//tc += gi_norm.xy*nz.z; -			tc += nz.xy*2.0; -			tc /= gi_samples; -			tc += gi_c.xy; -			 -			vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); -			vec3 lpos = getGIPosition(tc.xy).xyz; -							 -			vec3 at = lpos-gi_pos.xyz; -			float dist = dot(at,at); -			float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); -			 -			if (da > 0.0) -			{ -				//add angular attenuation -				vec3 ldir = at; -				float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0); -			 -				float ld = -dot(ldir, lnorm); -				 -				if (ang_atten > 0.0 && ld < 0.0) -				{ -					vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz; -					da = da*ang_atten; -					fda += da; -					fdiff += diff*da; -				} -			} -		} -	} - -	fdiff /= max(gi_spec.y*fda, gi_quad.z); -	fdiff = clamp(fdiff, vec3(0), vec3(1)); -	 -	vec3 ret = fda*fdiff; -	//ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z;			 - -	//fda *= nz.z; -	 -	//rcol.rgb *= gi_intensity; -	//return rcol.rgb+vary_AmblitColor.rgb*0.25; -	//return vec4(debug, 0.0); -	//return vec4(fda*fdiff, 0.0); -	return clamp(ret,vec3(0.0), vec3(1.0)); -	//return debug.xyz; -} - -void main()  -{ -	vec2 pos_screen = vary_fragcoord.xy; -	vec4 pos = getPosition(pos_screen); -	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; -	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm -	 -	frag_color.xyz = giAmbient(pos, norm); -} diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 3427d6db57..1149aec30b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -53,13 +53,11 @@ uniform vec3 specular;  uniform float lightExp;  uniform float refScale;  uniform float kd; -uniform vec2 screenRes;  uniform vec3 normScale;  uniform float fresnelScale;  uniform float fresnelOffset;  uniform float blurMultiplier; -uniform vec2 screen_res; -uniform mat4 norm_mat; //region space to screen space +uniform mat3 normal_matrix;  //bigWave is (refCoord.w, view.w);  VARYING vec4 refCoord; @@ -157,7 +155,7 @@ void main()  	//wavef.z *= 0.1f;  	//wavef = normalize(wavef); -	vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; +	vec3 screenspacewavef = normal_matrix*wavef;  	frag_data[0] = vec4(color.rgb, 0.5); // diffuse  	frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl index 0d8dab0a41..485e48537c 100644 --- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl @@ -43,13 +43,11 @@ uniform vec2 fbScale;  uniform float refScale;  uniform float znear;  uniform float zfar; -uniform float kd;  uniform vec4 waterPlane;  uniform vec3 eyeVec;  uniform vec4 waterFogColor;  uniform float waterFogDensity;  uniform float waterFogKS; -uniform vec2 screenRes;  //bigWave is (refCoord.w, view.w);  VARYING vec4 refCoord; diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl index 79bffab745..1fd7bdaa5c 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -42,8 +42,6 @@ uniform vec3 lightDir;  uniform vec3 specular;  uniform float lightExp;  uniform float refScale; -uniform float kd; -uniform vec2 screenRes;  uniform vec3 normScale;  uniform float fresnelScale;  uniform float fresnelOffset; diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 9025c7af8b..a40d9cd318 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -179,7 +179,7 @@ LLAgentCamera::LLAgentCamera() :  	clearGeneralKeys();  	clearOrbitKeys(); -	clearPanKeys(); +	clearPanKeys();	  }  // Requires gSavedSettings to be initialized. @@ -192,6 +192,9 @@ void LLAgentCamera::init()  	mDrawDistance = gSavedSettings.getF32("RenderFarClip"); +	const F32 SMOOTHING_HALF_LIFE = 0.02f; +	LLCriticalDamp::setInterpolantConstant(InterpDeltaCameraSmoothingHalfLife, gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE); +  	LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW);  	// Leave at 0.1 meters until we have real near clip management  	LLViewerCamera::getInstance()->setNear(0.1f); @@ -337,7 +340,7 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)  			LLVector3 agent_at_axis = gAgent.getAtAxis();  			agent_at_axis -= projected_vec(agent_at_axis, gAgent.getReferenceUpVector());  			agent_at_axis.normalize(); -			gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLCriticalDamp::getInterpolant(0.3f))); +			gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLCriticalDamp::getInterpolant(InterpDeltaSmall)));  		}  		setFocusOnAvatar(TRUE, ANIMATE); @@ -1246,7 +1249,7 @@ void LLAgentCamera::updateCamera()  	gAgentCamera.clearPanKeys();  	// lerp camera focus offset -	mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLCriticalDamp::getInterpolant(CAMERA_FOCUS_HALF_LIFE)); +	mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLCriticalDamp::getInterpolant(InterpDeltaCameraFocusHalfLife));  	if ( mCameraMode == CAMERA_MODE_FOLLOW )  	{ @@ -1361,10 +1364,8 @@ void LLAgentCamera::updateCamera()  		mCameraSmoothingStop = mCameraSmoothingStop || in_build_mode;  		if (cameraThirdPerson() && !mCameraSmoothingStop) -		{ -			const F32 SMOOTHING_HALF_LIFE = 0.02f; -			 -			F32 smoothing = LLCriticalDamp::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE); +		{			 +			F32 smoothing = LLCriticalDamp::getInterpolant(InterpDeltaCameraSmoothingHalfLife);  			if (!mFocusObject)  // we differentiate on avatar mode   			{ @@ -1394,7 +1395,7 @@ void LLAgentCamera::updateCamera()  	} -	mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLCriticalDamp::getInterpolant(FOV_ZOOM_HALF_LIFE)); +	mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLCriticalDamp::getInterpolant(InterpDeltaFovZoomHalfLife));  //	llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl; @@ -1809,7 +1810,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)  			if (mTargetCameraDistance != mCurrentCameraDistance)  			{ -				F32 camera_lerp_amt = LLCriticalDamp::getInterpolant(CAMERA_ZOOM_HALF_LIFE); +				F32 camera_lerp_amt = LLCriticalDamp::getInterpolant(InterpDeltaCameraZoomHalfLife);  				mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt);  			} @@ -1827,7 +1828,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)  			if (isAgentAvatarValid())  			{  				LLVector3d camera_lag_d; -				F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE); +				F32 lag_interp = LLCriticalDamp::getInterpolant(InterpDeltaCameraLagHalfLife);  				LLVector3 target_lag;  				LLVector3 vel = gAgent.getVelocity(); @@ -1872,7 +1873,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)  				}  				else  				{ -					mCameraLag = lerp(mCameraLag, LLVector3::zero, LLCriticalDamp::getInterpolant(0.15f)); +					mCameraLag = lerp(mCameraLag, LLVector3::zero, LLCriticalDamp::getInterpolant(InterpDeltaCameraLagHalfLife));  				}  				camera_lag_d.setVec(mCameraLag); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7331b93810..9bbaede68d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -537,7 +537,7 @@ static void settings_to_globals()  	LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));  	LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile"); - +	LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");  	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic");  	LLImageGL::sCompressTextures		= gSavedSettings.getBOOL("RenderCompressTextures");  	LLVOVolume::sLODFactor				= gSavedSettings.getF32("RenderVolumeLODFactor"); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 119b8d24d0..dc0e256ebb 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -254,7 +254,7 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep)  	return count;  } -static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face", true); +static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face");  LLFace*	LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)  { @@ -492,97 +492,83 @@ F32 LLDrawable::updateXform(BOOL undamped)  	BOOL damped = !undamped;  	// Position -	LLVector3 old_pos(mXform.getPosition()); -	LLVector3 target_pos; -	if (mXform.isRoot()) -	{ -		// get root position in your agent's region -		target_pos = mVObjp->getPositionAgent(); -	} -	else -	{ -		// parent-relative position -		target_pos = mVObjp->getPosition(); -	} -	 +	LLVector3 old_pos	 = mXform.getPosition(); + +	// get agent position or parent-relative position as appropriate +	// +	LLVector3 target_pos = mXform.isRoot() ? mVObjp->getPositionAgent() : mVObjp->getPosition(); +  	// Rotation  	LLQuaternion old_rot(mXform.getRotation());  	LLQuaternion target_rot = mVObjp->getRotation(); +  	//scaling  	LLVector3 target_scale = mVObjp->getScale();  	LLVector3 old_scale = mCurrentScale;  	LLVector3 dest_scale = target_scale; -	 -	// Damping -	F32 dist_squared = 0.f; -	F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera); +	LLVector3 scale_vec = old_scale-target_scale; + +	static const F32 dot_threshold = 1.0f - FLT_EPSILON; + +	F32 dist_squared = dist_vec_squared(old_pos, target_pos); +	bool translated  = dist_squared > 0.0f; +	bool rotated     = !mVObjp->getAngularVelocity().isExactlyZero() || (dot(old_rot, target_rot) < dot_threshold); +	bool scaled		 = (scale_vec * scale_vec) > MIN_INTERPOLATE_DISTANCE_SQUARED; +	 +	// Damping	  	if (damped && isVisible())  	{ -		F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); +		F32 lerp_amt = LLCriticalDamp::getInterpolant(InterpDeltaObjectDampingConstant);  		LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt); -		dist_squared = dist_vec_squared(new_pos, target_pos); +		dist_squared = dist_vec_squared(new_pos, old_pos);  		LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot); -		// FIXME: This can be negative! It is be possible for some rots to 'cancel out' pos or size changes. -		dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f; +		dist_squared += fabs(1.f - dot(new_rot, old_rot)) * 10.f;  		LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt); -		dist_squared += dist_vec_squared(new_scale, target_scale); +		dist_squared += dist_vec_squared(new_scale, old_scale); -		if ((dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED * camdist2) && -			(dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED)) +		// If our lerp isn't moving too far, substitue the lerp'd pos for our target for this frame +		// +		if (dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED)  		{  			// interpolate  			target_pos = new_pos;  			target_rot = new_rot;  			target_scale = new_scale;  		} -		else if (mVObjp->getAngularVelocity().isExactlyZero()) +		else  		{ -			// snap to final position (only if no target omega is applied) -			dist_squared = 0.0f; -			if (getVOVolume() && !isRoot()) -			{ //child prim snapping to some position, needs a rebuild -				gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); -			} +			llinfos << "skipping update due to overly large lerp" << llendl;  		}  	} -	else -	{ -		// The following fixes MAINT-1742 but breaks vehicles similar to MAINT-2275 -		// dist_squared = dist_vec_squared(old_pos, target_pos); -		// The following fixes MAINT-2247 but causes MAINT-2275 -		//dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; -		//dist_squared += dist_vec_squared(old_scale, target_scale); -	} +	if (translated || rotated || scaled) +	{  +		if (scaled) +		{ +			mCurrentScale = target_scale; +		} -	LLVector3 vec = mCurrentScale-target_scale; -	 -	if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED) -	{ //scale change requires immediate rebuild -		mCurrentScale = target_scale; -		gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); -	} -	else if (!isRoot() &&  -		 (!mVObjp->getAngularVelocity().isExactlyZero() || -			dist_squared > 0.f)) -	{ //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild  		dist_squared = 1.f; //keep this object on the move list -		if (!isState(LLDrawable::ANIMATED_CHILD)) + +		//child prim moving relative to parent, tag as needing to be rendered atomically +		// +		if (!isRoot() && !isState(LLDrawable::ANIMATED_CHILD))  		{			  			setState(LLDrawable::ANIMATED_CHILD); -			gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); -			mVObjp->dirtySpatialGroup();  		} + +		// Mark any components that need to be rebuilt based on what change transpired +		// +		if (!rotated && !scaled) +			gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); +		else +			gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); + +		mVObjp->dirtySpatialGroup();  	} -	else if (!isRoot() -		&& (   dist_vec_squared(old_pos, target_pos) > 0.f -			|| (1.f - dot(old_rot, target_rot)) > 0.f)) -        { // update child prims moved from LSL -                gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); -        }  	else if (!getVOVolume() && !isAvatar())  	{  		movePartition(); @@ -781,7 +767,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)  		}  		pos -= camera.getOrigin();	 -		mDistanceWRTCamera = llround(pos.magVec(), 0.01f); +		mDistanceWRTCamera = 20.0f;//llround(pos.magVec(), 0.01f);  		mVObjp->updateLOD();  	}  } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 94dd927d26..d8f293cc62 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -472,6 +472,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba  		{  			params.mGroup->rebuildMesh();  		} +		  		params.mVertexBuffer->setBuffer(mask);  		params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 313b310e1e..6fa16825df 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -394,10 +394,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  		if (group->mSpatialPartition->mRenderByGroup &&  		    !group->isDead())  		{ -			bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow. -				// All particle systems seem to come off the wire with texture entries which claim that they glow.  This is probably a bug in the data.  Suppress. -				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && -				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; +			static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group"); +			LLFastTimer t(FTM_RENDER_ALPHA_GROUP_LOOP); + +			bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow. + +			bool disable_cull = group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE || +				group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; + +			LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);  			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; @@ -498,32 +503,31 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					}  				} -				params.mVertexBuffer->setBuffer(mask); -				params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); -				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); +				static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_PUSH("Alpha Push Verts"); +				{ +					LLFastTimer t(FTM_RENDER_ALPHA_PUSH); +					gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); +					params.mVertexBuffer->setBuffer(mask); +					params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); +					gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); +				}  				// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow).  Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.  				if (current_shader &&   					draw_glow_for_this_partition &&  					params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))  				{ +					static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GLOW("Alpha Glow"); +					LLFastTimer t(FTM_RENDER_ALPHA_GLOW);  					// install glow-accumulating blend mode  					gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color  						      LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) -					emissive_shader->bind(); -					 -					// glow doesn't use vertex colors from the mesh data -					params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); +					params.mVertexBuffer->setBuffer(mask | LLVertexBuffer::MAP_EMISSIVE);  					// do the actual drawing, again  					params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  					gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); - -					// restore our alpha blend mode -					gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - -					current_shader->bind();  				}  				if (tex_setup) @@ -536,6 +540,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  		}  	} +	gGL.setSceneBlendType(LLRender::BT_ALPHA); +  	LLVertexBuffer::unbind();	  	if (!light_enabled) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 3cf96a9054..d5afa25c9c 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1505,8 +1505,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				stop_glerror(); -				static LLStaticHashedString sMatPalette("matrixPalette"); -				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv(sMatPalette,  +				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv(LLViewerShaderMgr::AVATAR_MATRIX,   					skin->mJointNames.size(),  					FALSE,  					(GLfloat*) mat[0].mMatrix); @@ -1548,6 +1547,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				buff->setBuffer(data_mask);  				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);		  			} + +			gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);  		}  	}  } diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 3805348b6b..cac862a107 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -49,9 +49,6 @@  #include "llviewershadermgr.h"  #include "llrender.h" -static LLStaticHashedString sObjectPlaneS("object_plane_s"); -static LLStaticHashedString sObjectPlaneT("object_plane_t"); -  const F32 DETAIL_SCALE = 1.f/16.f;  int DebugDetailMap = 0; @@ -355,8 +352,8 @@ void LLDrawPoolTerrain::renderFullShader()  	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;  	llassert(shader); -	shader->uniform4fv(sObjectPlaneS, 1, tp0.mV); -	shader->uniform4fv(sObjectPlaneT, 1, tp1.mV); +	shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); +	shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);  	gGL.matrixMode(LLRender::MM_TEXTURE);  	gGL.loadIdentity(); @@ -865,8 +862,8 @@ void LLDrawPoolTerrain::renderSimple()  	if (LLGLSLShader::sNoFixedFunction)  	{ -		sShader->uniform4fv(sObjectPlaneS, 1, tp0.mV); -		sShader->uniform4fv(sObjectPlaneT, 1, tp1.mV); +		sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); +		sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);  	}  	else  	{ diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index ffe438eb27..b6a4b0194c 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -1,736 +1,719 @@ -/** 
 - * @file lldrawpoolwater.cpp
 - * @brief LLDrawPoolWater class implementation
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -#include "llfeaturemanager.h"
 -#include "lldrawpoolwater.h"
 -
 -#include "llviewercontrol.h"
 -#include "lldir.h"
 -#include "llerror.h"
 -#include "m3math.h"
 -#include "llrender.h"
 -
 -#include "llagent.h"		// for gAgent for getRegion for getWaterHeight
 -#include "llcubemap.h"
 -#include "lldrawable.h"
 -#include "llface.h"
 -#include "llsky.h"
 -#include "llviewertexturelist.h"
 -#include "llviewerregion.h"
 -#include "llvosky.h"
 -#include "llvowater.h"
 -#include "llworld.h"
 -#include "pipeline.h"
 -#include "llviewershadermgr.h"
 -#include "llwaterparammanager.h"
 -
 -const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
 -const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
 -
 -static LLStaticHashedString sObjectPlaneS("object_plane_s");
 -static LLStaticHashedString sObjectPlaneT("object_plane_t");
 -static LLStaticHashedString sScreenRes("screenRes");
 -static LLStaticHashedString sNormScale("normScale");
 -static LLStaticHashedString sFresnelScale("fresnelScale");
 -static LLStaticHashedString sFresnelOffset("fresnelOffset");
 -static LLStaticHashedString sBlurMultiplier("blurMultiplier");
 -static LLStaticHashedString sSunAngle("sunAngle");
 -static LLStaticHashedString sScaledAngle("scaledAngle");
 -static LLStaticHashedString sSunAngle2("sunAngle2");
 -
 -static float sTime;
 -
 -BOOL deferred_render = FALSE;
 -
 -BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
 -BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
 -BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
 -LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);
 -F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
 -
 -LLVector3 LLDrawPoolWater::sLightDir;
 -
 -LLDrawPoolWater::LLDrawPoolWater() :
 -	LLFacePool(POOL_WATER)
 -{
 -	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
 -	gGL.getTexUnit(0)->bind(mHBTex[0]) ;
 -	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
 -
 -	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
 -	gGL.getTexUnit(0)->bind(mHBTex[1]);
 -	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
 -
 -
 -	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE);
 -	llassert(mWaterImagep);
 -	mWaterImagep->setNoDelete();
 -	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE);
 -	llassert(mOpaqueWaterImagep);
 -	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL);
 -	mWaterNormp->setNoDelete();
 -
 -	restoreGL();
 -}
 -
 -LLDrawPoolWater::~LLDrawPoolWater()
 -{
 -}
 -
 -//static
 -void LLDrawPoolWater::restoreGL()
 -{
 -	
 -}
 -
 -LLDrawPool *LLDrawPoolWater::instancePool()
 -{
 -	llerrs << "Should never be calling instancePool on a water pool!" << llendl;
 -	return NULL;
 -}
 -
 -
 -void LLDrawPoolWater::prerender()
 -{
 -	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ?
 -		LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
 -
 -	// got rid of modulation by light color since it got a little too
 -	// green at sunset and sl-57047 (underwater turns black at 8:00)
 -	sWaterFogColor = LLWaterParamManager::instance().getFogColor();
 -	sWaterFogColor.mV[3] = 0;
 -
 -}
 -
 -S32 LLDrawPoolWater::getNumPasses()
 -{
 -	if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
 -	{
 -		return 1;
 -	}
 -
 -	return 0;
 -}
 -
 -void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
 -{
 -	beginRenderPass(pass);
 -	deferred_render = TRUE;
 -}
 -
 -void LLDrawPoolWater::endPostDeferredPass(S32 pass)
 -{
 -	endRenderPass(pass);
 -	deferred_render = FALSE;
 -}
 -
 -//===============================
 -//DEFERRED IMPLEMENTATION
 -//===============================
 -void LLDrawPoolWater::renderDeferred(S32 pass)
 -{
 -	LLFastTimer t(FTM_RENDER_WATER);
 -	deferred_render = TRUE;
 -	shade();
 -	deferred_render = FALSE;
 -}
 -
 -//=========================================
 -
 -void LLDrawPoolWater::render(S32 pass)
 -{
 -	LLFastTimer ftm(FTM_RENDER_WATER);
 -	if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
 -	{
 -		return;
 -	}
 -
 -	//do a quick 'n dirty depth sort
 -	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -			 iter != mDrawFace.end(); iter++)
 -	{
 -		LLFace* facep = *iter;
 -		facep->mDistance = -facep->mCenterLocal.mV[2];
 -	}
 -
 -	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
 -
 -	// See if we are rendering water as opaque or not
 -	if (!gSavedSettings.getBOOL("RenderTransparentWater"))
 -	{
 -		// render water for low end hardware
 -		renderOpaqueLegacyWater();
 -		return;
 -	}
 -
 -	LLGLEnable blend(GL_BLEND);
 -
 -	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
 -	{
 -		shade();
 -		return;
 -	}
 -
 -	LLVOSky *voskyp = gSky.mVOSkyp;
 -
 -	stop_glerror();
 -
 -	if (!gGLManager.mHasMultitexture)
 -	{
 -		// Ack!  No multitexture!  Bail!
 -		return;
 -	}
 -
 -	LLFace* refl_face = voskyp->getReflFace();
 -
 -	gPipeline.disableLights();
 -	
 -	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 -
 -	LLGLDisable cullFace(GL_CULL_FACE);
 -	
 -	// Set up second pass first
 -	mWaterImagep->addTextureStats(1024.f*1024.f);
 -	gGL.getTexUnit(1)->activate();
 -	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
 -	gGL.getTexUnit(1)->bind(mWaterImagep) ;
 -
 -	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
 -	F32 up_dot = camera_up * LLVector3::z_axis;
 -
 -	LLColor4 water_color;
 -	if (LLViewerCamera::getInstance()->cameraUnderWater())
 -	{
 -		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
 -	}
 -	else
 -	{
 -		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
 -	}
 -
 -	gGL.diffuseColor4fv(water_color.mV);
 -
 -	// Automatically generate texture coords for detail map
 -	glEnable(GL_TEXTURE_GEN_S); //texture unit 1
 -	glEnable(GL_TEXTURE_GEN_T); //texture unit 1
 -	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
 -	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
 -
 -	// Slowly move over time.
 -	F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
 -	F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
 -	F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
 -	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
 -	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
 -
 -	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
 -	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
 -
 -	gGL.getTexUnit(0)->activate();
 -	
 -	glClearStencil(1);
 -	glClear(GL_STENCIL_BUFFER_BIT);
 -	LLGLEnable gls_stencil(GL_STENCIL_TEST);
 -	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
 -	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
 -
 -	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -		 iter != mDrawFace.end(); iter++)
 -	{
 -		LLFace *face = *iter;
 -		if (voskyp->isReflFace(face))
 -		{
 -			continue;
 -		}
 -		gGL.getTexUnit(0)->bind(face->getTexture());
 -		face->renderIndexed();
 -	}
 -
 -	// Now, disable texture coord generation on texture state 1
 -	gGL.getTexUnit(1)->activate();
 -	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 -	gGL.getTexUnit(1)->disable();
 -	glDisable(GL_TEXTURE_GEN_S); //texture unit 1
 -	glDisable(GL_TEXTURE_GEN_T); //texture unit 1
 -
 -	// Disable texture coordinate and color arrays
 -	gGL.getTexUnit(0)->activate();
 -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 -
 -	stop_glerror();
 -	
 -	if (gSky.mVOSkyp->getCubeMap())
 -	{
 -		gSky.mVOSkyp->getCubeMap()->enable(0);
 -		gSky.mVOSkyp->getCubeMap()->bind();
 -
 -		gGL.matrixMode(LLRender::MM_TEXTURE);
 -		gGL.loadIdentity();
 -		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
 -		LLMatrix4 camera_rot(camera_mat.getMat3());
 -		camera_rot.invert();
 -
 -		gGL.loadMatrix((F32 *)camera_rot.mMatrix);
 -
 -		gGL.matrixMode(LLRender::MM_MODELVIEW);
 -		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot);
 -
 -		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 -
 -		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -			 iter != mDrawFace.end(); iter++)
 -		{
 -			LLFace *face = *iter;
 -			if (voskyp->isReflFace(face))
 -			{
 -				//refl_face = face;
 -				continue;
 -			}
 -
 -			if (face->getGeomCount() > 0)
 -			{					
 -				face->renderIndexed();
 -			}
 -		}
 -
 -		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 -
 -		gSky.mVOSkyp->getCubeMap()->disable();
 -		
 -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 -		gGL.matrixMode(LLRender::MM_TEXTURE);
 -		gGL.loadIdentity();
 -		gGL.matrixMode(LLRender::MM_MODELVIEW);
 -		
 -	}
 -
 -	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 -
 -    if (refl_face)
 -	{
 -		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
 -		renderReflection(refl_face);
 -	}
 -
 -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 -}
 -
 -// for low end hardware
 -void LLDrawPoolWater::renderOpaqueLegacyWater()
 -{
 -	LLVOSky *voskyp = gSky.mVOSkyp;
 -
 -	LLGLSLShader* shader = NULL;
 -	if (LLGLSLShader::sNoFixedFunction)
 -	{
 -		if (LLPipeline::sUnderWaterRender)
 -		{
 -			shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
 -		}
 -		else
 -		{
 -			shader = &gObjectSimpleNonIndexedTexGenProgram;
 -		}
 -
 -		shader->bind();
 -	}
 -
 -	stop_glerror();
 -
 -	// Depth sorting and write to depth buffer
 -	// since this is opaque, we should see nothing
 -	// behind the water.  No blending because
 -	// of no transparency.  And no face culling so
 -	// that the underside of the water is also opaque.
 -	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
 -	LLGLDisable no_cull(GL_CULL_FACE);
 -	LLGLDisable no_blend(GL_BLEND);
 -
 -	gPipeline.disableLights();
 -
 -	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
 -
 -	// Activate the texture binding and bind one
 -	// texture since all images will have the same texture
 -	gGL.getTexUnit(0)->activate();
 -	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 -	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);
 -
 -	// Automatically generate texture coords for water texture
 -	if (!shader)
 -	{
 -		glEnable(GL_TEXTURE_GEN_S); //texture unit 0
 -		glEnable(GL_TEXTURE_GEN_T); //texture unit 0
 -		glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
 -		glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
 -	}
 -
 -	// Use the fact that we know all water faces are the same size
 -	// to save some computation
 -
 -	// Slowly move texture coordinates over time so the watter appears
 -	// to be moving.
 -	F32 movement_period_secs = 50.f;
 -
 -	F32 offset = fmod(gFrameTimeSeconds, movement_period_secs);
 -
 -	if (movement_period_secs != 0)
 -	{
 -	 	offset /= movement_period_secs;
 -	}
 -	else
 -	{
 -		offset = 0;
 -	}
 -
 -	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
 -	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };
 -
 -	if (!shader)
 -	{
 -		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
 -		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
 -	}
 -	else
 -	{
 -		shader->uniform4fv(sObjectPlaneS, 1, tp0);
 -		shader->uniform4fv(sObjectPlaneT, 1, tp1);
 -	}
 -
 -	gGL.diffuseColor3f(1.f, 1.f, 1.f);
 -
 -	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -		 iter != mDrawFace.end(); iter++)
 -	{
 -		LLFace *face = *iter;
 -		if (voskyp->isReflFace(face))
 -		{
 -			continue;
 -		}
 -
 -		face->renderIndexed();
 -	}
 -
 -	stop_glerror();
 -
 -	if (!shader)
 -	{
 -		// Reset the settings back to expected values
 -		glDisable(GL_TEXTURE_GEN_S); //texture unit 0
 -		glDisable(GL_TEXTURE_GEN_T); //texture unit 0
 -	}
 -
 -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 -}
 -
 -
 -void LLDrawPoolWater::renderReflection(LLFace* face)
 -{
 -	LLVOSky *voskyp = gSky.mVOSkyp;
 -
 -	if (!voskyp)
 -	{
 -		return;
 -	}
 -
 -	if (!face->getGeomCount())
 -	{
 -		return;
 -	}
 -	
 -	S8 dr = voskyp->getDrawRefl();
 -	if (dr < 0)
 -	{
 -		return;
 -	}
 -
 -	LLGLSNoFog noFog;
 -
 -	gGL.getTexUnit(0)->bind(mHBTex[dr]);
 -
 -	LLOverrideFaceColor override(this, face->getFaceColor().mV);
 -	face->renderIndexed();
 -}
 -
 -void LLDrawPoolWater::shade()
 -{
 -	if (!deferred_render)
 -	{
 -		gGL.setColorMask(true, true);
 -	}
 -
 -	LLVOSky *voskyp = gSky.mVOSkyp;
 -
 -	if(voskyp == NULL) 
 -	{
 -		return;
 -	}
 -
 -	LLGLDisable blend(GL_BLEND);
 -
 -	LLColor3 light_diffuse(0,0,0);
 -	F32 light_exp = 0.0f;
 -	LLVector3 light_dir;
 -	LLColor3 light_color;
 -
 -	if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	 
 -    { 	 
 -        light_dir  = gSky.getSunDirection(); 	 
 -        light_dir.normVec(); 	
 -		light_color = gSky.getSunDiffuseColor();
 -		if(gSky.mVOSkyp) {
 -	        light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); 	 
 -			light_diffuse.normVec(); 	 
 -		}
 -        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
 -        light_diffuse *= light_exp + 0.25f; 	 
 -    } 	 
 -    else  	 
 -    { 	 
 -        light_dir       = gSky.getMoonDirection(); 	 
 -        light_dir.normVec(); 	 
 -		light_color = gSky.getMoonDiffuseColor();
 -        light_diffuse   = gSky.mVOSkyp->getMoon().getColorCached(); 	 
 -        light_diffuse.normVec(); 	 
 -        light_diffuse *= 0.5f; 	 
 -        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
 -    }
 -
 -	light_exp *= light_exp;
 -	light_exp *= light_exp;
 -	light_exp *= light_exp;
 -	light_exp *= light_exp;
 -	light_exp *= 256.f;
 -	light_exp = light_exp > 32.f ? light_exp : 32.f;
 -
 -	LLGLSLShader* shader;
 -
 -	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
 -	
 -	if (deferred_render)
 -	{
 -		shader = &gDeferredWaterProgram;
 -	}
 -	else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
 -	{
 -		shader = &gUnderWaterProgram;
 -	}
 -	else
 -	{
 -		shader = &gWaterProgram;
 -	}
 -
 -	if (deferred_render)
 -	{
 -		gPipeline.bindDeferredShader(*shader);
 -	}
 -	else
 -	{
 -		shader->bind();
 -	}
 -
 -	sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
 -	
 -	S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
 -		
 -	if (reftex > -1)
 -	{
 -		gGL.getTexUnit(reftex)->activate();
 -		gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
 -		gGL.getTexUnit(0)->activate();
 -	}	
 -
 -	//bind normal map
 -	S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
 -
 -	LLWaterParamManager * param_mgr = &LLWaterParamManager::instance();
 -
 -	// change mWaterNormp if needed
 -	if (mWaterNormp->getID() != param_mgr->getNormalMapID())
 -	{
 -		mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());
 -	}
 -
 -	mWaterNormp->addTextureStats(1024.f*1024.f);
 -	gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ;
 -	if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
 -	{
 -		mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
 -	}
 -	else 
 -	{
 -		mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT);
 -	}
 -	
 -	S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
 -		
 -	if (screentex > -1)
 -	{
 -		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
 -		shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY, 
 -			param_mgr->getFogDensity());
 -		gPipeline.mWaterDis.bindTexture(0, screentex);
 -	}
 -	
 -	stop_glerror();
 -	
 -	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	
 -
 -	if (mVertexShaderLevel == 1)
 -	{
 -		sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
 -		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
 -	}
 -
 -	F32 screenRes[] = 
 -	{
 -		1.f/gGLViewport[2],
 -		1.f/gGLViewport[3]
 -	};
 -	shader->uniform2fv(sScreenRes, 1, screenRes);
 -	stop_glerror();
 -	
 -	S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 -	stop_glerror();
 -	
 -	light_dir.normVec();
 -	sLightDir = light_dir;
 -	
 -	light_diffuse *= 6.f;
 -
 -	//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
 -	shader->uniform1f(LLViewerShaderMgr::WATER_WATERHEIGHT, eyedepth);
 -	shader->uniform1f(LLViewerShaderMgr::WATER_TIME, sTime);
 -	shader->uniform3fv(LLViewerShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
 -	shader->uniform3fv(LLViewerShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
 -	shader->uniform1f(LLViewerShaderMgr::WATER_SPECULAR_EXP, light_exp);
 -	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
 -	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
 -	shader->uniform3fv(LLViewerShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
 -
 -	shader->uniform3fv(sNormScale, 1, param_mgr->getNormalScale().mV);
 -	shader->uniform1f(sFresnelScale, param_mgr->getFresnelScale());
 -	shader->uniform1f(sFresnelOffset, param_mgr->getFresnelOffset());
 -	shader->uniform1f(sBlurMultiplier, param_mgr->getBlurMultiplier());
 -
 -	F32 sunAngle = llmax(0.f, light_dir.mV[2]);
 -	F32 scaledAngle = 1.f - sunAngle;
 -
 -	shader->uniform1f(sSunAngle, sunAngle);
 -	shader->uniform1f(sScaledAngle, scaledAngle);
 -	shader->uniform1f(sSunAngle2, 0.1f + 0.2f*sunAngle);
 -
 -	LLColor4 water_color;
 -	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
 -	F32 up_dot = camera_up * LLVector3::z_axis;
 -	if (LLViewerCamera::getInstance()->cameraUnderWater())
 -	{
 -		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
 -		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
 -	}
 -	else
 -	{
 -		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
 -		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
 -	}
 -
 -	if (water_color.mV[3] > 0.9f)
 -	{
 -		water_color.mV[3] = 0.9f;
 -	}
 -
 -	{
 -		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
 -		LLGLDisable cullface(GL_CULL_FACE);
 -		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -			iter != mDrawFace.end(); iter++)
 -		{
 -			LLFace *face = *iter;
 -
 -			if (voskyp->isReflFace(face))
 -			{
 -				continue;
 -			}
 -
 -			LLVOWater* water = (LLVOWater*) face->getViewerObject();
 -			gGL.getTexUnit(diffTex)->bind(face->getTexture());
 -
 -			sNeedsReflectionUpdate = TRUE;
 -			
 -			if (water->getUseTexture() || !water->getIsEdgePatch())
 -			{
 -				sNeedsDistortionUpdate = TRUE;
 -				face->renderIndexed();
 -			}
 -			else if (gGLManager.mHasDepthClamp || deferred_render)
 -			{
 -				face->renderIndexed();
 -			}
 -			else
 -			{
 -				LLGLSquashToFarClip far_clip(glh_get_current_projection());
 -				face->renderIndexed();
 -			}
 -		}
 -	}
 -	
 -	shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 -	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
 -	shader->disableTexture(LLViewerShaderMgr::BUMP_MAP);
 -	shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 -	shader->disableTexture(LLViewerShaderMgr::WATER_REFTEX);
 -	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENDEPTH);
 -
 -	if (deferred_render)
 -	{
 -		gPipeline.unbindDeferredShader(*shader);
 -	}
 -	else
 -	{
 -		shader->unbind();
 -	}
 -
 -	gGL.getTexUnit(0)->activate();
 -	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 -	if (!deferred_render)
 -	{
 -		gGL.setColorMask(true, false);
 -	}
 -
 -}
 -
 -LLViewerTexture *LLDrawPoolWater::getDebugTexture()
 -{
 -	return LLViewerFetchedTexture::sSmokeImagep;
 -}
 -
 -LLColor3 LLDrawPoolWater::getDebugColor() const
 -{
 -	return LLColor3(0.f, 1.f, 1.f);
 -}
 +/**  + * @file lldrawpoolwater.cpp + * @brief LLDrawPoolWater class implementation + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfeaturemanager.h" +#include "lldrawpoolwater.h" + +#include "llviewercontrol.h" +#include "lldir.h" +#include "llerror.h" +#include "m3math.h" +#include "llrender.h" + +#include "llagent.h"		// for gAgent for getRegion for getWaterHeight +#include "llcubemap.h" +#include "lldrawable.h" +#include "llface.h" +#include "llsky.h" +#include "llviewertexturelist.h" +#include "llviewerregion.h" +#include "llvosky.h" +#include "llvowater.h" +#include "llworld.h" +#include "pipeline.h" +#include "llviewershadermgr.h" +#include "llwaterparammanager.h" + +const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004"); +const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055"); + +static float sTime; + +BOOL deferred_render = FALSE; + +BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE; +BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE; +BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; +LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f); +F32 LLDrawPoolWater::sWaterFogEnd = 0.f; + +LLVector3 LLDrawPoolWater::sLightDir; + +LLDrawPoolWater::LLDrawPoolWater() : +	LLFacePool(POOL_WATER) +{ +	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI); +	gGL.getTexUnit(0)->bind(mHBTex[0]) ; +	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); + +	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI); +	gGL.getTexUnit(0)->bind(mHBTex[1]); +	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); + + +	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE); +	llassert(mWaterImagep); +	mWaterImagep->setNoDelete(); +	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE); +	llassert(mOpaqueWaterImagep); +	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL); +	mWaterNormp->setNoDelete(); + +	restoreGL(); +} + +LLDrawPoolWater::~LLDrawPoolWater() +{ +} + +//static +void LLDrawPoolWater::restoreGL() +{ +	 +} + +LLDrawPool *LLDrawPoolWater::instancePool() +{ +	llerrs << "Should never be calling instancePool on a water pool!" << llendl; +	return NULL; +} + + +void LLDrawPoolWater::prerender() +{ +	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? +		LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; + +	// got rid of modulation by light color since it got a little too +	// green at sunset and sl-57047 (underwater turns black at 8:00) +	sWaterFogColor = LLWaterParamManager::instance().getFogColor(); +	sWaterFogColor.mV[3] = 0; + +} + +S32 LLDrawPoolWater::getNumPasses() +{ +	if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f) +	{ +		return 1; +	} + +	return 0; +} + +void LLDrawPoolWater::beginPostDeferredPass(S32 pass) +{ +	beginRenderPass(pass); +	deferred_render = TRUE; +} + +void LLDrawPoolWater::endPostDeferredPass(S32 pass) +{ +	endRenderPass(pass); +	deferred_render = FALSE; +} + +//=============================== +//DEFERRED IMPLEMENTATION +//=============================== +void LLDrawPoolWater::renderDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_WATER); +	deferred_render = TRUE; +	shade(); +	deferred_render = FALSE; +} + +//========================================= + +void LLDrawPoolWater::render(S32 pass) +{ +	LLFastTimer ftm(FTM_RENDER_WATER); +	if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1) +	{ +		return; +	} + +	//do a quick 'n dirty depth sort +	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +			 iter != mDrawFace.end(); iter++) +	{ +		LLFace* facep = *iter; +		facep->mDistance = -facep->mCenterLocal.mV[2]; +	} + +	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater()); + +	// See if we are rendering water as opaque or not +	if (!gSavedSettings.getBOOL("RenderTransparentWater")) +	{ +		// render water for low end hardware +		renderOpaqueLegacyWater(); +		return; +	} + +	LLGLEnable blend(GL_BLEND); + +	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy) +	{ +		shade(); +		return; +	} + +	LLVOSky *voskyp = gSky.mVOSkyp; + +	stop_glerror(); + +	if (!gGLManager.mHasMultitexture) +	{ +		// Ack!  No multitexture!  Bail! +		return; +	} + +	LLFace* refl_face = voskyp->getReflFace(); + +	gPipeline.disableLights(); +	 +	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + +	LLGLDisable cullFace(GL_CULL_FACE); +	 +	// Set up second pass first +	mWaterImagep->addTextureStats(1024.f*1024.f); +	gGL.getTexUnit(1)->activate(); +	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(1)->bind(mWaterImagep) ; + +	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); +	F32 up_dot = camera_up * LLVector3::z_axis; + +	LLColor4 water_color; +	if (LLViewerCamera::getInstance()->cameraUnderWater()) +	{ +		water_color.setVec(1.f, 1.f, 1.f, 0.4f); +	} +	else +	{ +		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); +	} + +	gGL.diffuseColor4fv(water_color.mV); + +	// Automatically generate texture coords for detail map +	glEnable(GL_TEXTURE_GEN_S); //texture unit 1 +	glEnable(GL_TEXTURE_GEN_T); //texture unit 1 +	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); +	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + +	// Slowly move over time. +	F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f); +	F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f}; +	F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f}; +	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); +	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); + +	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); +	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA); + +	gGL.getTexUnit(0)->activate(); +	 +	glClearStencil(1); +	glClear(GL_STENCIL_BUFFER_BIT); +	LLGLEnable gls_stencil(GL_STENCIL_TEST); +	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); +	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); + +	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +		 iter != mDrawFace.end(); iter++) +	{ +		LLFace *face = *iter; +		if (voskyp->isReflFace(face)) +		{ +			continue; +		} +		gGL.getTexUnit(0)->bind(face->getTexture()); +		face->renderIndexed(); +	} + +	// Now, disable texture coord generation on texture state 1 +	gGL.getTexUnit(1)->activate(); +	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(1)->disable(); +	glDisable(GL_TEXTURE_GEN_S); //texture unit 1 +	glDisable(GL_TEXTURE_GEN_T); //texture unit 1 + +	// Disable texture coordinate and color arrays +	gGL.getTexUnit(0)->activate(); +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +	stop_glerror(); +	 +	if (gSky.mVOSkyp->getCubeMap()) +	{ +		gSky.mVOSkyp->getCubeMap()->enable(0); +		gSky.mVOSkyp->getCubeMap()->bind(); + +		gGL.matrixMode(LLRender::MM_TEXTURE); +		gGL.loadIdentity(); +		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); +		LLMatrix4 camera_rot(camera_mat.getMat3()); +		camera_rot.invert(); + +		gGL.loadMatrix((F32 *)camera_rot.mMatrix); + +		gGL.matrixMode(LLRender::MM_MODELVIEW); +		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot); + +		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + +		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +			 iter != mDrawFace.end(); iter++) +		{ +			LLFace *face = *iter; +			if (voskyp->isReflFace(face)) +			{ +				//refl_face = face; +				continue; +			} + +			if (face->getGeomCount() > 0) +			{					 +				face->renderIndexed(); +			} +		} + +		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + +		gSky.mVOSkyp->getCubeMap()->disable(); +		 +		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +		gGL.matrixMode(LLRender::MM_TEXTURE); +		gGL.loadIdentity(); +		gGL.matrixMode(LLRender::MM_MODELVIEW); +		 +	} + +	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + +    if (refl_face) +	{ +		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); +		renderReflection(refl_face); +	} + +	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +} + +// for low end hardware +void LLDrawPoolWater::renderOpaqueLegacyWater() +{ +	LLVOSky *voskyp = gSky.mVOSkyp; + +	LLGLSLShader* shader = NULL; +	if (LLGLSLShader::sNoFixedFunction) +	{ +		if (LLPipeline::sUnderWaterRender) +		{ +			shader = &gObjectSimpleNonIndexedTexGenWaterProgram; +		} +		else +		{ +			shader = &gObjectSimpleNonIndexedTexGenProgram; +		} + +		shader->bind(); +	} + +	stop_glerror(); + +	// Depth sorting and write to depth buffer +	// since this is opaque, we should see nothing +	// behind the water.  No blending because +	// of no transparency.  And no face culling so +	// that the underside of the water is also opaque. +	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); +	LLGLDisable no_cull(GL_CULL_FACE); +	LLGLDisable no_blend(GL_BLEND); + +	gPipeline.disableLights(); + +	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); + +	// Activate the texture binding and bind one +	// texture since all images will have the same texture +	gGL.getTexUnit(0)->activate(); +	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep); + +	// Automatically generate texture coords for water texture +	if (!shader) +	{ +		glEnable(GL_TEXTURE_GEN_S); //texture unit 0 +		glEnable(GL_TEXTURE_GEN_T); //texture unit 0 +		glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); +		glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); +	} + +	// Use the fact that we know all water faces are the same size +	// to save some computation + +	// Slowly move texture coordinates over time so the watter appears +	// to be moving. +	F32 movement_period_secs = 50.f; + +	F32 offset = fmod(gFrameTimeSeconds, movement_period_secs); + +	if (movement_period_secs != 0) +	{ +	 	offset /= movement_period_secs; +	} +	else +	{ +		offset = 0; +	} + +	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset }; +	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset }; + +	if (!shader) +	{ +		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); +		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); +	} +	else +	{ +		shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0); +		shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1); +	} + +	gGL.diffuseColor3f(1.f, 1.f, 1.f); + +	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +		 iter != mDrawFace.end(); iter++) +	{ +		LLFace *face = *iter; +		if (voskyp->isReflFace(face)) +		{ +			continue; +		} + +		face->renderIndexed(); +	} + +	stop_glerror(); + +	if (!shader) +	{ +		// Reset the settings back to expected values +		glDisable(GL_TEXTURE_GEN_S); //texture unit 0 +		glDisable(GL_TEXTURE_GEN_T); //texture unit 0 +	} + +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +} + + +void LLDrawPoolWater::renderReflection(LLFace* face) +{ +	LLVOSky *voskyp = gSky.mVOSkyp; + +	if (!voskyp) +	{ +		return; +	} + +	if (!face->getGeomCount()) +	{ +		return; +	} +	 +	S8 dr = voskyp->getDrawRefl(); +	if (dr < 0) +	{ +		return; +	} + +	LLGLSNoFog noFog; + +	gGL.getTexUnit(0)->bind(mHBTex[dr]); + +	LLOverrideFaceColor override(this, face->getFaceColor().mV); +	face->renderIndexed(); +} + +void LLDrawPoolWater::shade() +{ +	if (!deferred_render) +	{ +		gGL.setColorMask(true, true); +	} + +	LLVOSky *voskyp = gSky.mVOSkyp; + +	if(voskyp == NULL)  +	{ +		return; +	} + +	LLGLDisable blend(GL_BLEND); + +	LLColor3 light_diffuse(0,0,0); +	F32 light_exp = 0.0f; +	LLVector3 light_dir; +	LLColor3 light_color; + +	if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	  +    { 	  +        light_dir  = gSky.getSunDirection(); 	  +        light_dir.normVec(); 	 +		light_color = gSky.getSunDiffuseColor(); +		if(gSky.mVOSkyp) { +	        light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); 	  +			light_diffuse.normVec(); 	  +		} +        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	  +        light_diffuse *= light_exp + 0.25f; 	  +    } 	  +    else  	  +    { 	  +        light_dir       = gSky.getMoonDirection(); 	  +        light_dir.normVec(); 	  +		light_color = gSky.getMoonDiffuseColor(); +        light_diffuse   = gSky.mVOSkyp->getMoon().getColorCached(); 	  +        light_diffuse.normVec(); 	  +        light_diffuse *= 0.5f; 	  +        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	  +    } + +	light_exp *= light_exp; +	light_exp *= light_exp; +	light_exp *= light_exp; +	light_exp *= light_exp; +	light_exp *= 256.f; +	light_exp = light_exp > 32.f ? light_exp : 32.f; + +	LLGLSLShader* shader; + +	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); +	 +	if (deferred_render) +	{ +		shader = &gDeferredWaterProgram; +	} +	else if (eyedepth < 0.f && LLPipeline::sWaterReflections) +	{ +		shader = &gUnderWaterProgram; +	} +	else +	{ +		shader = &gWaterProgram; +	} + +	if (deferred_render) +	{ +		gPipeline.bindDeferredShader(*shader); +	} +	else +	{ +		shader->bind(); +	} + +	sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; +	 +	S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); +		 +	if (reftex > -1) +	{ +		gGL.getTexUnit(reftex)->activate(); +		gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef); +		gGL.getTexUnit(0)->activate(); +	}	 + +	//bind normal map +	S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); + +	LLWaterParamManager * param_mgr = &LLWaterParamManager::instance(); + +	// change mWaterNormp if needed +	if (mWaterNormp->getID() != param_mgr->getNormalMapID()) +	{ +		mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID()); +	} + +	mWaterNormp->addTextureStats(1024.f*1024.f); +	gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ; +	if (gSavedSettings.getBOOL("RenderWaterMipNormal")) +	{ +		mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); +	} +	else  +	{ +		mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT); +	} +	 +	S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);	 +		 +	if (screentex > -1) +	{ +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); +		shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY,  +			param_mgr->getFogDensity()); +		gPipeline.mWaterDis.bindTexture(0, screentex); +	} +	 +	stop_glerror(); +	 +	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	 + +	if (mVertexShaderLevel == 1) +	{ +		sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue; +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); +	} + +	stop_glerror(); +	 +	S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +	stop_glerror(); +	 +	light_dir.normVec(); +	sLightDir = light_dir; +	 +	light_diffuse *= 6.f; + +	//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix); +	shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth); +	shader->uniform1f(LLShaderMgr::WATER_TIME, sTime); +	shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); +	shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); +	shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); +	shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); +	shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV); +	shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); + +	shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV); +	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale()); +	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset()); +	shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier()); + +	F32 sunAngle = llmax(0.f, light_dir.mV[2]); +	F32 scaledAngle = 1.f - sunAngle; + +	shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle); +	shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle); +	shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle); + +	LLColor4 water_color; +	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); +	F32 up_dot = camera_up * LLVector3::z_axis; +	if (LLViewerCamera::getInstance()->cameraUnderWater()) +	{ +		water_color.setVec(1.f, 1.f, 1.f, 0.4f); +		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow()); +	} +	else +	{ +		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); +		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove()); +	} + +	if (water_color.mV[3] > 0.9f) +	{ +		water_color.mV[3] = 0.9f; +	} + +	{ +		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); +		LLGLDisable cullface(GL_CULL_FACE); +		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +			iter != mDrawFace.end(); iter++) +		{ +			LLFace *face = *iter; + +			if (voskyp->isReflFace(face)) +			{ +				continue; +			} + +			LLVOWater* water = (LLVOWater*) face->getViewerObject(); +			gGL.getTexUnit(diffTex)->bind(face->getTexture()); + +			sNeedsReflectionUpdate = TRUE; +			 +			if (water->getUseTexture() || !water->getIsEdgePatch()) +			{ +				sNeedsDistortionUpdate = TRUE; +				face->renderIndexed(); +			} +			else if (gGLManager.mHasDepthClamp || deferred_render) +			{ +				face->renderIndexed(); +			} +			else +			{ +				LLGLSquashToFarClip far_clip(glh_get_current_projection()); +				face->renderIndexed(); +			} +		} +	} +	 +	shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); +	shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);	 +	shader->disableTexture(LLViewerShaderMgr::BUMP_MAP); +	shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +	shader->disableTexture(LLShaderMgr::WATER_REFTEX); +	shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH); + +	if (deferred_render) +	{ +		gPipeline.unbindDeferredShader(*shader); +	} +	else +	{ +		shader->unbind(); +	} + +	gGL.getTexUnit(0)->activate(); +	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +	if (!deferred_render) +	{ +		gGL.setColorMask(true, false); +	} + +} + +LLViewerTexture *LLDrawPoolWater::getDebugTexture() +{ +	return LLViewerFetchedTexture::sSmokeImagep; +} + +LLColor3 LLDrawPoolWater::getDebugColor() const +{ +	return LLColor3(0.f, 1.f, 1.f); +} diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 43d21137b5..c3cb914120 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -53,6 +53,12 @@  #include "llviewershadermgr.h"  #include "llvoavatar.h" +#if LL_LINUX +// Work-around spurious used before init warning on Vector4a +// +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif +  extern BOOL gGLDebugLoggingEnabled;  #define LL_MAX_INDICES_COUNT 1000000 @@ -1410,6 +1416,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	{ //use transform feedback to pack vertex buffer  		//gGLDebugLoggingEnabled = TRUE;  		LLFastTimer t(FTM_FACE_GEOM_FEEDBACK); +		LLGLEnable discard(GL_RASTERIZER_DISCARD);  		LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();  		if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices) @@ -1958,21 +1965,32 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_pos)  		{ -			LLFastTimer t(FTM_FACE_GEOM_POSITION); +			LLVector4a* src = vf.mPositions; +			 +			//_mm_prefetch((char*)src, _MM_HINT_T0); + +			LLVector4a* end = src+num_vertices; +			//LLVector4a* end_64 = end-4; + +			//LLFastTimer t(FTM_FACE_GEOM_POSITION);  			llassert(num_vertices > 0);  			mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); -  			LLMatrix4a mat_vert;  			mat_vert.loadu(mat_vert_in); +								 +			F32* dst = (F32*) vert.get(); +			F32* end_f32 = dst+mGeomCount*4; -			LLVector4a* src = vf.mPositions; -			volatile F32* dst = (volatile F32*) vert.get(); +			//_mm_prefetch((char*)dst, _MM_HINT_NTA); +			//_mm_prefetch((char*)src, _MM_HINT_NTA); +				 +			//_mm_prefetch((char*)dst, _MM_HINT_NTA); -			volatile F32* end = dst+num_vertices*4; -			LLVector4a res; +			LLVector4a res0; //,res1,res2,res3; +			  			LLVector4a texIdx;  			S32 index = mTextureIndex < 255 ? mTextureIndex : 0; @@ -1989,29 +2007,53 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			texIdx.set(0,0,0,val); +			LLVector4a tmp; +  			{ -				LLFastTimer t(FTM_FACE_POSITION_STORE); -				LLVector4a tmp; +				//LLFastTimer t2(FTM_FACE_POSITION_STORE); -				do -				{	 -					mat_vert.affineTransform(*src++, res); -					tmp.setSelectWithMask(mask, texIdx, res); +				/*if (num_vertices > 4) +				{ //more than 64 bytes +					while (src < end_64) +					{	 +						_mm_prefetch((char*)src + 64, _MM_HINT_T0); +						_mm_prefetch((char*)dst + 64, _MM_HINT_T0); + +						mat_vert.affineTransform(*src, res0); +						tmp.setSelectWithMask(mask, texIdx, res0); +						tmp.store4a((F32*) dst); + +						mat_vert.affineTransform(*(src+1), res1); +						tmp.setSelectWithMask(mask, texIdx, res1); +						tmp.store4a((F32*) dst+4); + +						mat_vert.affineTransform(*(src+2), res2); +						tmp.setSelectWithMask(mask, texIdx, res2); +						tmp.store4a((F32*) dst+8); + +						mat_vert.affineTransform(*(src+3), res3); +						tmp.setSelectWithMask(mask, texIdx, res3); +						tmp.store4a((F32*) dst+12); + +						dst += 16; +						src += 4; +					} +				}*/ + +				while (src < end) +				{ +					mat_vert.affineTransform(*src++, res0); +					tmp.setSelectWithMask(mask, texIdx, res0);  					tmp.store4a((F32*) dst);  					dst += 4;  				} -				while(dst < end);  			} - +			  			{ -				LLFastTimer t(FTM_FACE_POSITION_PAD); -				S32 aligned_pad_vertices = mGeomCount - num_vertices; -				res.set(res[0], res[1], res[2], 0.f); - -				while (aligned_pad_vertices > 0) +				//LLFastTimer t(FTM_FACE_POSITION_PAD); +				while (dst < end_f32)  				{ -					--aligned_pad_vertices; -					res.store4a((F32*) dst); +					res0.store4a((F32*) dst);  					dst += 4;  				}  			} @@ -2025,15 +2067,17 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_normal)  		{ -			LLFastTimer t(FTM_FACE_GEOM_NORMAL); +			//LLFastTimer t(FTM_FACE_GEOM_NORMAL);  			mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);  			F32* normals = (F32*) norm.get(); -			for (S32 i = 0; i < num_vertices; i++) -			{	 +			LLVector4a* src = vf.mNormals; +			LLVector4a* end = src+num_vertices; +			 +			while (src < end) +			{  				LLVector4a normal; -				mat_normal.rotate(vf.mNormals[i], normal); -				normal.normalize3fast(); +				mat_normal.rotate(*src++, normal);  				normal.store4a(normals);  				normals += 4;  			} @@ -2050,11 +2094,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);  			F32* binormals = (F32*) binorm.get(); -			for (S32 i = 0; i < num_vertices; i++) +			LLVector4a* src = vf.mBinormals; +			LLVector4a* end = vf.mBinormals+num_vertices; + +			while (src < end)  			{	  				LLVector4a binormal; -				mat_normal.rotate(vf.mBinormals[i], binormal); -				binormal.normalize3fast(); +				mat_normal.rotate(*src++, binormal);  				binormal.store4a(binormals);  				binormals += 4;  			} diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 4dfb93f1bc..643ce63f29 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -345,7 +345,7 @@ BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)  	return TRUE;  } -static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true); +static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers");  static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors; @@ -940,7 +940,7 @@ void LLFastTimerView::draw()  			}  			//interpolate towards new maximum -			last_max = (U64) lerp((F32)last_max, (F32) cur_max, LLCriticalDamp::getInterpolant(0.1f)); +			last_max = (U64) lerp((F32)last_max, (F32) cur_max, LLCriticalDamp::getInterpolant(InterpDeltaSmaller));  			if (last_max - cur_max <= 1 ||  cur_max - last_max  <= 1)  			{  				last_max = cur_max; @@ -948,7 +948,7 @@ void LLFastTimerView::draw()  			F32 alpha_target = last_max > cur_max ?  								llmin((F32) last_max/ (F32) cur_max - 1.f,1.f) :  								llmin((F32) cur_max/ (F32) last_max - 1.f,1.f); -			alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(0.1f)); +			alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(InterpDeltaSmaller));  			if (mHoverID != NULL)  			{ diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 77a0cdffce..cd4718381b 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -683,30 +683,36 @@ void LLVolumeImplFlexible::doFlexibleUpdate()  								LLVector4(z_axis, 0.f),  								LLVector4(delta_pos, 1.f)); +	LL_CHECK_MEMORY  	for (i=0; i<=num_render_sections; ++i)  	{  		new_point = &path->mPath[i];  		LLVector3 pos = newSection[i].mPosition * rel_xform;  		LLQuaternion rot = mSection[i].mAxisRotation * newSection[i].mRotation * delta_rot; -		 -		if (!mUpdated || (new_point->mPos-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f) +	 +		LLVector3 np(new_point->mPos.getF32ptr()); + +		if (!mUpdated || (np-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f)  		{ -			new_point->mPos = newSection[i].mPosition * rel_xform; +			new_point->mPos.load3((newSection[i].mPosition * rel_xform).mV);  			mUpdated = FALSE;  		} -		new_point->mRot = rot; -		new_point->mScale = newSection[i].mScale; +		new_point->mRot.loadu(LLMatrix3(rot)); +		new_point->mScale.set(newSection[i].mScale.mV[0], newSection[i].mScale.mV[1], 0,1);  		new_point->mTexT = ((F32)i)/(num_render_sections);  	} - +	LL_CHECK_MEMORY  	mLastSegmentRotation = parentSegmentRotation;  } +static LLFastTimer::DeclareTimer FTM_FLEXI_PREBUILD("Flexi Prebuild"); +  void LLVolumeImplFlexible::preRebuild()  {  	if (!mUpdated)  	{ +		LLFastTimer t(FTM_FLEXI_PREBUILD);  		doFlexibleRebuild();  	}  } diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index d6ebe44daa..10d31df22c 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -525,11 +525,11 @@ void LLFloaterColorPicker::draw()  	if (gFocusMgr.childHasMouseCapture(getDragHandle()))  	{ -		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); +		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(InterpDeltaContextFadeTime));  	}  	else  	{ -		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); +		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(InterpDeltaContextFadeTime));  	}  	mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); @@ -1113,3 +1113,4 @@ void LLFloaterColorPicker::stopUsingPipette()  		LLToolMgr::getInstance()->clearTransientTool();  	}  } + diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ea839e6f5a..07c36b9f1b 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -290,6 +290,22 @@ bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a  bool validate_face(const LLVolumeFace& face)  { + +	for (U32 v = 0; v < face.mNumVertices; v++) +	{ +		if(face.mPositions && !face.mPositions[v].isFinite3()) +		{ +			llwarns << "NaN position data in face found!" << llendl; +			return false; +		} + +		if(face.mNormals && !face.mNormals[v].isFinite3()) +		{ +			llwarns << "NaN normal data in face found!" << llendl; +			return false; +		} +	} +  	for (U32 i = 0; i < face.mNumIndices; ++i)  	{  		if (face.mIndices[i] >= face.mNumVertices) @@ -305,8 +321,10 @@ bool validate_face(const LLVolumeFace& face)  		return false;  	} +  	/*const LLVector4a scale(0.5f); +  	for (U32 i = 0; i < face.mNumIndices; i+=3)  	{  		U16 idx1 = face.mIndices[i]; @@ -323,7 +341,6 @@ bool validate_face(const LLVolumeFace& face)  			return false;  		}  	}*/ -  	return true;  } @@ -5934,3 +5951,5 @@ void LLFloaterModelPreview::setPermissonsErrorStatus(U32 status, const std::stri  	LLNotificationsUtil::add("MeshUploadPermError");  } + + diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index d8d62e5bbb..103eaace88 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -478,7 +478,7 @@ void LLSnapshotLivePreview::draw()  		{  			if (mFlashAlpha < 1.f)  			{ -				mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f)); +				mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(InterpDeltaTeenier));  			}  			else  			{ @@ -487,7 +487,7 @@ void LLSnapshotLivePreview::draw()  		}  		else  		{ -			mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f)); +			mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(InterpDeltaSmallish) * 0.5f);  		}  		// Draw shining animation if appropriate. @@ -2500,3 +2500,4 @@ BOOL LLSnapshotFloaterView::handleHover(S32 x, S32 y, MASK mask)  	}  	return TRUE;  } + diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 3aa16b4413..23241b57c4 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -1293,7 +1293,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  	// animate current height towards target height  	if (llabs(mCurHeight - mTargetHeight) > 1.f)  	{ -		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); +		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? InterpDeltaFolderOpenTime : InterpDeltaFolderCloseTime));  		requestArrange(); @@ -2538,11 +2538,11 @@ void LLFolderViewFolder::draw()  	}  	else if (mIsOpen)  	{ -		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f)); +		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(InterpDeltaTeeny));  	}  	else  	{ -		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f)); +		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(InterpDeltaTeenier));  	}  	bool possibly_has_children = false; @@ -2899,3 +2899,4 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde  		}  	}  } + diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp index b670af1782..a3c1996512 100644 --- a/indra/newview/llfollowcam.cpp +++ b/indra/newview/llfollowcam.cpp @@ -148,14 +148,16 @@ LLFollowCamParams::~LLFollowCamParams() { }  //---------------------------------------------------------  void LLFollowCamParams::setPositionLag( F32 p )   {  -	mPositionLag = llclamp(p, FOLLOW_CAM_MIN_POSITION_LAG, FOLLOW_CAM_MAX_POSITION_LAG);  +	mPositionLag = llclamp(p, FOLLOW_CAM_MIN_POSITION_LAG, FOLLOW_CAM_MAX_POSITION_LAG); +	LLCriticalDamp::setInterpolantConstant(InterpDeltaPositionLag, mPositionLag);  }  //---------------------------------------------------------  void LLFollowCamParams::setFocusLag( F32 f )   {  -	mFocusLag = llclamp(f, FOLLOW_CAM_MIN_FOCUS_LAG, FOLLOW_CAM_MAX_FOCUS_LAG);  +	mFocusLag = llclamp(f, FOLLOW_CAM_MIN_FOCUS_LAG, FOLLOW_CAM_MAX_FOCUS_LAG); +	LLCriticalDamp::setInterpolantConstant(InterpDeltaFocusLag, mFocusLag);  } @@ -184,6 +186,7 @@ void LLFollowCamParams::setPitch( F32 p )  void LLFollowCamParams::setBehindnessLag( F32 b )   {   	mBehindnessLag = llclamp(b, FOLLOW_CAM_MIN_BEHINDNESS_LAG, FOLLOW_CAM_MAX_BEHINDNESS_LAG);  +	LLCriticalDamp::setInterpolantConstant(InterpDeltaBehindnessLag, mBehindnessLag);  }  //--------------------------------------------------------- @@ -328,11 +331,11 @@ void LLFollowCam::update()  				F32 force = focusOffsetDistance - focusThresholdNormalizedByDistance;  			*/ -			F32 focusLagLerp = LLCriticalDamp::getInterpolant( mFocusLag ); +			F32 focusLagLerp = LLCriticalDamp::getInterpolant(InterpDeltaFocusLag);  			focus_pt_agent = lerp( focus_pt_agent, whereFocusWantsToBe, focusLagLerp );  			mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(focus_pt_agent);  		} -		mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f)); +		mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(InterpDeltaTeeny));  	}// if focus is not locked --------------------------------------------- @@ -415,7 +418,7 @@ void LLFollowCam::update()  		//-------------------------------------------------------------------------------------------------  		if ( distanceFromPositionToIdealPosition > mPositionThreshold )  		{ -			F32 positionPullLerp = LLCriticalDamp::getInterpolant( mPositionLag ); +			F32 positionPullLerp = LLCriticalDamp::getInterpolant(InterpDeltaPositionLag);  			simulated_pos_agent = lerp( simulated_pos_agent, whereCameraPositionWantsToBe, positionPullLerp );  		} @@ -435,7 +438,7 @@ void LLFollowCam::update()  		updateBehindnessConstraint(gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal), simulated_pos_agent);  		mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(simulated_pos_agent); -		mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f)); +		mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(InterpDeltaTeeny));  	} // if position is not locked ----------------------------------------------------------- @@ -490,7 +493,7 @@ BOOL LLFollowCam::updateBehindnessConstraint(LLVector3 focus, LLVector3& cam_pos  		if ( cameraOffsetAngle > mBehindnessMaxAngle )  		{ -			F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLCriticalDamp::getInterpolant(mBehindnessLag); +			F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLCriticalDamp::getInterpolant(InterpDeltaBehindnessLag);  			cam_position = focus + horizontalSubjectBack * (slerp(fraction, camera_offset_rotation, LLQuaternion::DEFAULT));  			cam_position.mV[VZ] = cameraZ; // clamp z value back to what it was before we started messing with it  			constraint_active = TRUE; diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 482294c8a6..b94681b340 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -980,7 +980,7 @@ void LLHUDNameTag::updateAll()  //		{  //			continue;  //		} -		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC)); +		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(InterpDeltaPositionDampingTC));  	}  } @@ -1083,3 +1083,4 @@ F32 LLHUDNameTag::LLHUDTextSegment::getWidth(const LLFontGL* font)  		return width;  	}  } + diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 826e8d560a..748ac7a16e 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -240,7 +240,7 @@ void LLManipRotate::render()  		if (mManipPart == LL_ROT_Z)  		{ -			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  			gGL.pushMatrix();  			{  				// selected part @@ -251,7 +251,7 @@ void LLManipRotate::render()  		}  		else if (mManipPart == LL_ROT_Y)  		{ -			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  			gGL.pushMatrix();  			{  				gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); @@ -262,7 +262,7 @@ void LLManipRotate::render()  		}  		else if (mManipPart == LL_ROT_X)  		{ -			mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  			gGL.pushMatrix();  			{  				gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); @@ -273,13 +273,13 @@ void LLManipRotate::render()  		}  		else if (mManipPart == LL_ROT_ROLL)  		{ -			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  		}  		else if (mManipPart == LL_NO_PART)  		{  			if (mHighlightedPart == LL_NO_PART)  			{ -				mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +				mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  			}  			LLGLEnable cull_face(GL_CULL_FACE); @@ -294,7 +294,7 @@ void LLManipRotate::render()  				{  					if (mHighlightedPart == LL_ROT_Z)  					{ -						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  						gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);  						// hovering over part  						gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f ), LLColor4( 0.f, 0.f, 1.f, 0.5f ), CIRCLE_STEPS, i); @@ -312,7 +312,7 @@ void LLManipRotate::render()  					gGL.rotatef( 90.f, 1.f, 0.f, 0.f );  					if (mHighlightedPart == LL_ROT_Y)  					{ -						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  						gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);  						// hovering over part  						gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f ), LLColor4( 0.f, 1.f, 0.f, 0.5f ), CIRCLE_STEPS, i); @@ -330,7 +330,7 @@ void LLManipRotate::render()  					gGL.rotatef( 90.f, 0.f, 1.f, 0.f );  					if (mHighlightedPart == LL_ROT_X)  					{ -						mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +						mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  						gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);  						// hovering over part @@ -346,7 +346,7 @@ void LLManipRotate::render()  				if (mHighlightedPart == LL_ROT_ROLL)  				{ -					mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +					mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  				}  			} diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 00a0bf8894..9802d5503e 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -535,11 +535,11 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)  	{  		if (mHighlightedPart == MANIPULATOR_IDS[i])  		{ -			mManipulatorScales[i] = lerp(mManipulatorScales[i], SELECTED_MANIPULATOR_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales[i] = lerp(mManipulatorScales[i], SELECTED_MANIPULATOR_SCALE, LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  		}  		else  		{ -			mManipulatorScales[i] = lerp(mManipulatorScales[i], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales[i] = lerp(mManipulatorScales[i], 1.f, LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  		}  	} @@ -2082,3 +2082,4 @@ BOOL LLManipScale::canAffectSelection()  	}  	return can_scale;  } + diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 0228807dc8..9d287e7a03 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1922,18 +1922,18 @@ void LLManipTranslate::renderTranslationHandles()  			{  				if (index == mManipPart - LL_X_ARROW || index == mHighlightedPart - LL_X_ARROW)  				{ -					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); -					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); +					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife)); +					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  				}  				else if (index == mManipPart - LL_YZ_PLANE || index == mHighlightedPart - LL_YZ_PLANE)  				{ -					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); -					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); +					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife)); +					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  				}  				else  				{ -					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); -					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); +					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife)); +					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(InterpDeltaManipulatorScaleHalfLife));  				}  			} @@ -2323,3 +2323,4 @@ BOOL LLManipTranslate::canAffectSelection()  	}  	return can_move;  } + diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 1bda7640bd..274497f2b5 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -162,7 +162,7 @@ void LLNetMap::draw()  	static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);  	if (auto_center)  	{ -		mCurPan = lerp(mCurPan, mTargetPan, LLCriticalDamp::getInterpolant(0.1f)); +		mCurPan = lerp(mCurPan, mTargetPan, LLCriticalDamp::getInterpolant(InterpDeltaSmaller));  	}  	// Prepare a scissor region @@ -987,3 +987,4 @@ void LLNetMap::handleStopTracking (const LLSD& userdata)  		LLTracker::stopTracking ((void*)LLTracker::isTracking(NULL));  	}  } + diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index 5f5258bbce..916f3d8e06 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -983,12 +983,26 @@ LLVector4a *LLPolyMesh::getScaledBinormals()  //-----------------------------------------------------------------------------  void LLPolyMesh::initializeForMorph()  { -    LLVector4a::memcpyNonAliased16((F32*) mCoords, (F32*) mSharedData->mBaseCoords, sizeof(LLVector4a) * mSharedData->mNumVertices); -	LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); -	LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); -	LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); -	LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); -	LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2)); +	// Must insure that src and dst of copies below +	// are actually 16b aligned...the 16b mod 0 size +	// is assumed from the data being LLVector4a +	// +	ll_assert_aligned(mCoords,16); +	ll_assert_aligned(mNormals,16); +	ll_assert_aligned(mScaledNormals,16); +	ll_assert_aligned(mBinormals,16); +	ll_assert_aligned(mScaledBinormals,16); +	ll_assert_aligned(mTexCoords,16); +	ll_assert_aligned(mSharedData->mBaseCoords,16); +	ll_assert_aligned(mSharedData->mBaseNormals,16); +	ll_assert_aligned(mSharedData->mTexCoords,16); + +        ll_memcpy_nonaliased_aligned_16((char*)mCoords, (char*)mSharedData->mBaseCoords, sizeof(LLVector4a) * mSharedData->mNumVertices); +	ll_memcpy_nonaliased_aligned_16((char*)mNormals, (char*)mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); +	ll_memcpy_nonaliased_aligned_16((char*)mScaledNormals, (char*)mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); +	ll_memcpy_nonaliased_aligned_16((char*)mBinormals, (char*)mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); +	ll_memcpy_nonaliased_aligned_16((char*)mScaledBinormals, (char*)mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); +	ll_memcpy_nonaliased_aligned_16((char*)mTexCoords, (char*)mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2));  	for (U32 i = 0; i < mSharedData->mNumVertices; ++i)  	{ diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 343316d30a..cf9d95455e 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6108,6 +6108,14 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)  			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  			gGL.begin(LLRender::LINES);  			{ +				// Lines require an even number of verts so repeat the first +				// vert if we don't meet that requirement +				// +				if (mSilhouetteVertices.size() & 0x1) +				{ +					mSilhouetteVertices.push_back(mSilhouetteVertices[0]); +				} +  				for(S32 i = 0; i < mSilhouetteVertices.size(); i += 2)  				{  					u_coord += u_divisor * LLSelectMgr::sHighlightUScale; @@ -7547,3 +7555,4 @@ void LLSelectMgr::sendSelectionMove()  	//saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);  } + diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index dd69172184..1ec56eb5f8 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -4654,7 +4654,9 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,  	mGroup(NULL),  	mFace(NULL),  	mDistance(0.f), -	mDrawMode(LLRender::TRIANGLES) +	mDrawMode(LLRender::TRIANGLES), +	mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA), +	mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA)  {  	mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index b1706d9d35..08e77855c4 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -119,6 +119,8 @@ public:  	LL_ALIGN_16(LLFace* mFace); //associated face  	F32 mDistance;  	U32 mDrawMode; +	U32 mBlendFuncSrc; +	U32 mBlendFuncDst;  	struct CompareTexture  	{ @@ -739,7 +741,7 @@ class LLVolumeGeometryManager: public LLGeometryManager  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group); -	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE); +	void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);  }; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index ec36cf48c2..8c5844eca7 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -549,11 +549,11 @@ void LLFloaterTexturePicker::draw()  	if (gFocusMgr.childHasMouseCapture(getDragHandle()))  	{ -		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); +		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(InterpDeltaContextFadeTime));  	}  	else  	{ -		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); +		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(InterpDeltaContextFadeTime));  	}  	updateImageStats(); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index ffeea2f4df..3f97659c66 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -212,13 +212,13 @@ void display_stats()  }  static LLFastTimer::DeclareTimer FTM_PICK("Picking"); -static LLFastTimer::DeclareTimer FTM_RENDER("Render", true); +static LLFastTimer::DeclareTimer FTM_RENDER("Render");  static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky");  static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Image Update Bump"); -static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List"); +static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List", true);  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete");  static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window");  static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("HUD Update"); @@ -1033,7 +1033,7 @@ void render_hud_attachments()  	// clamp target zoom level to reasonable values  	gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f);  	// smoothly interpolate current zoom level -	gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f)); +	gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLCriticalDamp::getInterpolant(InterpDeltaTeenier));  	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())  	{ @@ -1593,3 +1593,4 @@ void display_cleanup()  {  	gDisconnectedImagep = NULL;  } + diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b1a60197a2..09cc4a1121 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1553,6 +1553,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				dp->setPassFlags(value);  				dp->unpackUUID(owner_id, "Owner"); +				mOwnerID = owner_id; +  				if (value & 0x80)  				{  					dp->unpackVector3(new_angv, "Omega"); @@ -1626,13 +1628,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,                  retval |= checkMediaURL(media_url);  				// -				// Unpack particle system data +				// Unpack particle system data (legacy)  				//  				if (value & 0x8)  				{ -					unpackParticleSource(*dp, owner_id); +					unpackParticleSource(*dp, owner_id, true);  				} -				else +				else if (!(value & 0x400))  				{  					deleteParticleSource();  				} @@ -1697,7 +1699,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				// keep local flags and overwrite remote-controlled flags  				mFlags = (mFlags & FLAGS_LOCAL) | flags; -					// ...new objects that should come in selected need to be added to the selected list +				// ...new objects that should come in selected need to be added to the selected list  				mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);  			}  			break; @@ -4604,7 +4606,7 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own  	}  } -void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id) +void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy)  {  	if (!mPartSourcep.isNull() && mPartSourcep->isDead())  	{ @@ -4613,7 +4615,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_  	if (mPartSourcep)  	{  		// If we've got one already, just update the existing source (or remove it) -		if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp)) +		if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp, legacy))  		{  			mPartSourcep->setDead();  			mPartSourcep = NULL; @@ -4621,7 +4623,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_  	}  	else  	{ -		LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp); +		LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy);  		//If the owner is muted, don't create the system  		if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;  		// We need to be able to deal with a particle source that hasn't changed, but still got an update! @@ -5467,6 +5469,11 @@ F32 LLAlphaObject::getPartSize(S32 idx)  	return 0.f;  } +void LLAlphaObject::getBlendFunc(S32 face, U32& src, U32& dst) +{ + +} +  // virtual  void LLStaticViewerObject::updateDrawable(BOOL force_damped)  { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 97cf0a4850..cab617b745 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -584,6 +584,7 @@ public:  	} EPhysicsShapeType;  	LLUUID			mID; +	LLUUID			mOwnerID; //null if unknown  	// unique within region, not unique across regions  	// Local ID = 0 is not used @@ -662,7 +663,7 @@ protected:  	BOOL isOnMap();  	void unpackParticleSource(const S32 block_num, const LLUUID& owner_id); -	void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id); +	void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy);  	void deleteParticleSource();  	void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); @@ -826,9 +827,12 @@ public:  								LLStrider<LLVector4a>& verticesp,  								LLStrider<LLVector3>& normalsp,   								LLStrider<LLVector2>& texcoordsp, -								LLStrider<LLColor4U>& colorsp,  +								LLStrider<LLColor4U>& colorsp, +								LLStrider<LLColor4U>& emissivep,  								LLStrider<U16>& indicesp) = 0; +	virtual void getBlendFunc(S32 face, U32& src, U32& dst); +  	F32 mDepth;  }; diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 61cdfd7818..21f1d2619c 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -80,12 +80,31 @@ LLViewerPart::LLViewerPart() :  	mImagep(NULL)  {  	mPartSourcep = NULL; - +	mParent = NULL; +	mChild = NULL;  	++LLViewerPartSim::sParticleCount2 ;  }  LLViewerPart::~LLViewerPart()  { +	if (mPartSourcep.notNull() && mPartSourcep->mLastPart == this) +	{ +		mPartSourcep->mLastPart = NULL; +	} + +	//patch up holes in the ribbon +	if (mParent) +	{ +		llassert(mParent->mChild == this); +		mParent->mChild = mChild; +	} + +	if (mChild) +	{ +		llassert (mChild->mParent == this); +		mChild->mParent = mParent; +	} +  	mPartSourcep = NULL;  	--LLViewerPartSim::sParticleCount2 ; @@ -367,6 +386,9 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)  			part->mScale += frac*part->mEndScale;  		} +		// Do glow interpolation +		part->mGlow.mV[3] = (U8) (lerp(part->mStartGlow, part->mEndGlow, frac)*255.f); +  		// Set the last update time to now.  		part->mLastUpdateTime = cur_time; @@ -623,6 +645,9 @@ void LLViewerPartSim::updateSimulation()  {  	static LLFrameTimer update_timer; +	//reset VBO cursor +	LLVOPartGroup::sVBSlotCursor = 0; +  	const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f);   	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES))) diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index c91fcf0691..095de2060c 100644 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -65,15 +65,22 @@ public:  	LLVPCallback		mVPCallback;				// Callback function for more complicated behaviors  	LLPointer<LLViewerPartSource> mPartSourcep;		// Particle source used for this object -	 + +	LLViewerPart*		mParent;					// particle to connect to if this is part of a particle ribbon +	LLViewerPart*		mChild;						// child particle for clean reference destruction  	// Current particle state (possibly used for rendering)  	LLPointer<LLViewerTexture>	mImagep;  	LLVector3		mPosAgent;  	LLVector3		mVelocity;  	LLVector3		mAccel; +	LLVector3		mAxis;  	LLColor4		mColor;  	LLVector2		mScale; +	F32				mStartGlow; +	F32				mEndGlow; +	LLColor4U		mGlow; +  	static U32		sNextPartID;  }; diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index b311f659fb..8c49ce646d 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -52,6 +52,8 @@ LLViewerPartSource::LLViewerPartSource(const U32 type) :  	static U32 id_seed = 0;  	mID = ++id_seed; +	mLastPart = NULL; +  	mDelay = 0 ;  } @@ -279,6 +281,22 @@ void LLViewerPartSourceScript::update(const F32 dt)  			{  				part->mFlags |= LLPartData::LL_PART_HUD;  			} + +			if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK && mLastPart) +			{ //set previous particle's parent to this particle to chain ribbon together +				mLastPart->mParent = part; +				part->mChild = mLastPart; +				part->mAxis = LLVector3(0,0,1); + +				if (mSourceObjectp.notNull()) +				{ +					LLQuaternion rot = mSourceObjectp->getRenderRotation(); +					part->mAxis *= rot; +				} +			} + +			mLastPart = part; +  			part->mMaxAge = mPartSysData.mPartData.mMaxAge;  			part->mStartColor = mPartSysData.mPartData.mStartColor;  			part->mEndColor = mPartSysData.mPartData.mEndColor; @@ -290,6 +308,13 @@ void LLViewerPartSourceScript::update(const F32 dt)  			part->mAccel = mPartSysData.mPartAccel; +			part->mBlendFuncDest = mPartSysData.mPartData.mBlendFuncDest; +			part->mBlendFuncSource = mPartSysData.mPartData.mBlendFuncSource; + +			part->mStartGlow = mPartSysData.mPartData.mStartGlow; +			part->mEndGlow = mPartSysData.mPartData.mEndGlow; +			part->mGlow = LLColor4U(0, 0, 0, (U8) (part->mStartGlow*255.f)); +			  			if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_DROP)  			{  				part->mPosAgent = mPosAgent; @@ -430,28 +455,51 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewer  } -LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp) +LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp, bool legacy)  {  	if (!pssp)  	{  		LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp); -		if (!new_pssp->mPartSysData.unpack(dp)) +		if (legacy)  		{ -			return NULL; +			if (!new_pssp->mPartSysData.unpackLegacy(dp)) +			{ +				return NULL; +			} +		} +		else +		{ +			if (!new_pssp->mPartSysData.unpack(dp)) +			{ +				return NULL; +			}  		} +		  		if (new_pssp->mPartSysData.mTargetUUID.notNull())  		{  			LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID);  			new_pssp->setTargetObject(target_objp);  		} +		  		return new_pssp;  	}  	else  	{ -		if (!pssp->mPartSysData.unpack(dp)) +		if (legacy)  		{ -			return NULL; +			if (!pssp->mPartSysData.unpackLegacy(dp)) +			{ +				return NULL; +			}  		} +		else +		{ +			if (!pssp->mPartSysData.unpack(dp)) +			{ +				return NULL; +			} +		} +  		if (pssp->mPartSysData.mTargetUUID.notNull())  		{  			LLViewerObject *target_objp = gObjectList.findObject(pssp->mPartSysData.mTargetUUID); @@ -569,6 +617,11 @@ void LLViewerPartSourceSpiral::update(const F32 dt)  		part->mScale.mV[0] = 0.25f;  		part->mScale.mV[1] = 0.25f;  		part->mParameter = ll_frand(F_TWO_PI); +		part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; +		part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA; +		part->mStartGlow = 0.f; +		part->mEndGlow = 0.f; +		part->mGlow = LLColor4U(0, 0, 0, 0);  		LLViewerPartSim::getInstance()->addPart(part);  	} @@ -721,6 +774,12 @@ void LLViewerPartSourceBeam::update(const F32 dt)  		part->mPosAgent = mPosAgent;  		part->mVelocity = mTargetPosAgent - mPosAgent; +		part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; +		part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA; +		part->mStartGlow = 0.f; +		part->mEndGlow = 0.f; +		part->mGlow = LLColor4U(0, 0, 0, 0); +  		LLViewerPartSim::getInstance()->addPart(part);  	}  } @@ -825,6 +884,12 @@ void LLViewerPartSourceChat::update(const F32 dt)  		part->mScale.mV[0] = 0.25f;  		part->mScale.mV[1] = 0.25f;  		part->mParameter = ll_frand(F_TWO_PI); +		part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; +		part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA; +		part->mStartGlow = 0.f; +		part->mEndGlow = 0.f; +		part->mGlow = LLColor4U(0, 0, 0, 0); +  		LLViewerPartSim::getInstance()->addPart(part);  	} diff --git a/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h index 28702d36a2..12e926173b 100644 --- a/indra/newview/llviewerpartsource.h +++ b/indra/newview/llviewerpartsource.h @@ -76,6 +76,7 @@ public:  	LLVector3	mLastUpdatePosAgent;  	LLPointer<LLViewerObject>	mSourceObjectp;  	U32 mID; +	LLViewerPart* mLastPart; //last particle emitted (for making particle ribbons)  protected:  	U32			mType; @@ -85,7 +86,6 @@ protected:  	F32			mLastPartTime;  	LLUUID		mOwnerUUID;  	LLPointer<LLViewerTexture>	mImagep; -  	// Particle information  	U32			mPartFlags; // Flags for the particle  	U32         mDelay ; //delay to start particles @@ -114,7 +114,7 @@ public:  	// Returns a new particle source to attach to an object...  	static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, const S32 block_num); -	static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp); +	static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp, bool legacy);  	static LLPointer<LLViewerPartSourceScript> createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters);  	LLViewerTexture *getImage() const				{ return mImagep; } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index fc7e51d06c..7d7889845d 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -311,47 +311,6 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)  	if (mReservedAttribs.empty())  	{  		LLShaderMgr::initAttribsAndUniforms(); - -		mAvatarUniforms.push_back(LLStaticHashedString("matrixPalette")); -		mAvatarUniforms.push_back(LLStaticHashedString("gWindDir")); -		mAvatarUniforms.push_back(LLStaticHashedString("gSinWaveParams")); -		mAvatarUniforms.push_back(LLStaticHashedString("gGravity")); - -		mWLUniforms.push_back(LLStaticHashedString("camPosLocal")); - -		mTerrainUniforms.reserve(5); -		mTerrainUniforms.push_back(LLStaticHashedString("detail_0")); -		mTerrainUniforms.push_back(LLStaticHashedString("detail_1")); -		mTerrainUniforms.push_back(LLStaticHashedString("detail_2")); -		mTerrainUniforms.push_back(LLStaticHashedString("detail_3")); -		mTerrainUniforms.push_back(LLStaticHashedString("alpha_ramp")); - -		mGlowUniforms.push_back(LLStaticHashedString("glowDelta")); -		mGlowUniforms.push_back(LLStaticHashedString("glowStrength")); - -		mGlowExtractUniforms.push_back(LLStaticHashedString("minLuminance")); -		mGlowExtractUniforms.push_back(LLStaticHashedString("maxExtractAlpha")); -		mGlowExtractUniforms.push_back(LLStaticHashedString("lumWeights")); -		mGlowExtractUniforms.push_back(LLStaticHashedString("warmthWeights")); -		mGlowExtractUniforms.push_back(LLStaticHashedString("warmthAmount")); - -		mShinyUniforms.push_back(LLStaticHashedString("origin")); - -		mWaterUniforms.reserve(12); -		mWaterUniforms.push_back(LLStaticHashedString("screenTex")); -		mWaterUniforms.push_back(LLStaticHashedString("screenDepth")); -		mWaterUniforms.push_back(LLStaticHashedString("refTex")); -		mWaterUniforms.push_back(LLStaticHashedString("eyeVec")); -		mWaterUniforms.push_back(LLStaticHashedString("time")); -		mWaterUniforms.push_back(LLStaticHashedString("d1")); -		mWaterUniforms.push_back(LLStaticHashedString("d2")); -		mWaterUniforms.push_back(LLStaticHashedString("lightDir")); -		mWaterUniforms.push_back(LLStaticHashedString("specular")); -		mWaterUniforms.push_back(LLStaticHashedString("lightExp")); -		mWaterUniforms.push_back(LLStaticHashedString("fogCol")); -		mWaterUniforms.push_back(LLStaticHashedString("kd")); -		mWaterUniforms.push_back(LLStaticHashedString("refScale")); -		mWaterUniforms.push_back(LLStaticHashedString("waterHeight"));  	}	  } @@ -922,7 +881,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()  		gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));  		gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));  		gTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT]; -		success = gTerrainProgram.createShader(NULL, &mTerrainUniforms); +		success = gTerrainProgram.createShader(NULL, NULL);  	}  	if (!success) @@ -960,7 +919,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));  		gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER]; -		success = gWaterProgram.createShader(NULL, &mWaterUniforms); +		success = gWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -974,7 +933,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER];  		gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gUnderWaterProgram.createShader(NULL, &mWaterUniforms); +		success = gUnderWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -992,7 +951,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gTerrainWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT];  		gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, &mTerrainUniforms); +		terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL);  	}	  	/// Keep track of water shader levels @@ -1041,7 +1000,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  		gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB));  		gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gGlowProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; -		success = gGlowProgram.createShader(NULL, &mGlowUniforms); +		success = gGlowProgram.createShader(NULL, NULL);  		if (!success)  		{  			LLPipeline::sRenderGlow = FALSE; @@ -1055,7 +1014,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));  		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB));  		gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; -		success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms); +		success = gGlowExtractProgram.createShader(NULL, NULL);  		if (!success)  		{  			LLPipeline::sRenderGlow = FALSE; @@ -1415,7 +1374,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredWaterProgram.createShader(NULL, &mWaterUniforms); +		success = gDeferredWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1474,7 +1433,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredAvatarShadowProgram.createShader(NULL, &mAvatarUniforms); +		success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1495,7 +1454,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredTerrainProgram.createShader(NULL, &mTerrainUniforms); +		success = gDeferredTerrainProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1506,7 +1465,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredAvatarProgram.createShader(NULL, &mAvatarUniforms); +		success = gDeferredAvatarProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1526,7 +1485,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms); +		success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);  		gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;  		gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; @@ -1591,7 +1550,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gDeferredWLSkyProgram.createShader(NULL, &mWLUniforms); +		success = gDeferredWLSkyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1602,7 +1561,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gDeferredWLCloudProgram.createShader(NULL, &mWLUniforms); +		success = gDeferredWLCloudProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1613,7 +1572,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gDeferredStarProgram.createShader(NULL, &mWLUniforms); +		success = gDeferredStarProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1964,7 +1923,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		  		gObjectShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -		success = gObjectShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1981,7 +1940,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1997,7 +1956,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -		success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2015,7 +1974,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2094,7 +2053,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		success = gObjectBumpProgram.createShader(NULL, NULL); -  		if (success)  		{ //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1  			gObjectBumpProgram.bind(); @@ -2248,7 +2206,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		  		gObjectShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -		success = gObjectShinyProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectShinyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2265,7 +2223,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectShinyWaterProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectShinyWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2281,7 +2239,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -		success = gObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectFullbrightShinyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2299,7 +2257,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);  	}  	if (mVertexShaderLevel[SHADER_AVATAR] > 0) @@ -2384,7 +2342,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  			gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); +			success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL);  		}  		if (success) @@ -2401,7 +2359,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));  			gSkinnedObjectShinySimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectShinySimpleProgram.createShader(NULL, &mShinyUniforms); +			success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL);  		}  		if (success) @@ -2458,7 +2416,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); +			success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);  		}  		if (success) @@ -2477,7 +2435,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  			gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, &mShinyUniforms); +			success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL);  		}  	} @@ -2518,7 +2476,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));  		gAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; -		success = gAvatarProgram.createShader(NULL, &mAvatarUniforms); +		success = gAvatarProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -2537,7 +2495,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  			// Note: no cloth under water:  			gAvatarWaterProgram.mShaderLevel = llmin(mVertexShaderLevel[SHADER_AVATAR], 1);	  			gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;				 -			success = gAvatarWaterProgram.createShader(NULL, &mAvatarUniforms); +			success = gAvatarWaterProgram.createShader(NULL, NULL);  		}  		/// Keep track of avatar levels @@ -2556,7 +2514,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB));  		gAvatarPickProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; -		success = gAvatarPickProgram.createShader(NULL, &mAvatarUniforms); +		success = gAvatarPickProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2824,7 +2782,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  		gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT];  		gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gWLSkyProgram.createShader(NULL, &mWLUniforms); +		success = gWLSkyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2836,7 +2794,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  		gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));  		gWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT];  		gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gWLCloudProgram.createShader(NULL, &mWLUniforms); +		success = gWLCloudProgram.createShader(NULL, NULL);  	}  	return success; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 999baa0ad0..6cd52dc736 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -74,56 +74,7 @@ public:  		SHADER_COUNT  	}; -	typedef enum -	{ -		SHINY_ORIGIN = END_RESERVED_UNIFORMS -	} eShinyUniforms; - -	typedef enum -	{ -		WATER_SCREENTEX = END_RESERVED_UNIFORMS, -		WATER_SCREENDEPTH, -		WATER_REFTEX, -		WATER_EYEVEC, -		WATER_TIME, -		WATER_WAVE_DIR1, -		WATER_WAVE_DIR2, -		WATER_LIGHT_DIR, -		WATER_SPECULAR, -		WATER_SPECULAR_EXP, -		WATER_FOGCOLOR, -		WATER_FOGDENSITY, -		WATER_REFSCALE, -		WATER_WATERHEIGHT, -	} eWaterUniforms; - -	typedef enum -	{ -		WL_CAMPOSLOCAL = END_RESERVED_UNIFORMS, -		WL_WATERHEIGHT -	} eWLUniforms; - -	typedef enum -	{ -		TERRAIN_DETAIL0 = END_RESERVED_UNIFORMS, -		TERRAIN_DETAIL1, -		TERRAIN_DETAIL2, -		TERRAIN_DETAIL3, -		TERRAIN_ALPHARAMP -	} eTerrainUniforms; - -	typedef enum -	{ -		GLOW_DELTA = END_RESERVED_UNIFORMS -	} eGlowUniforms; - -	typedef enum -	{ -		AVATAR_MATRIX = END_RESERVED_UNIFORMS, -		AVATAR_WIND, -		AVATAR_SINWAVE, -		AVATAR_GRAVITY, -	} eAvatarUniforms; +	  	// simple model of forward iterator  	// http://www.sgi.com/tech/stl/ForwardIterator.html @@ -176,25 +127,6 @@ public:  	/* virtual */ void updateShaderUniforms(LLGLSLShader * shader);  private: -	 -	typedef std::vector< LLStaticHashedString > UniformVec; - -	UniformVec mShinyUniforms; - -	//water parameters -	UniformVec mWaterUniforms; - -	UniformVec mWLUniforms; - -	//terrain parameters -	UniformVec mTerrainUniforms; - -	//glow parameters -	UniformVec mGlowUniforms; - -	UniformVec mGlowExtractUniforms; - -	UniformVec mAvatarUniforms;  	// the list of shaders we need to propagate parameters to.  	std::vector<LLGLSLShader *> mShaderList; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 4efd59685e..d28da507ea 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2913,7 +2913,7 @@ void LLVOAvatar::idleUpdateWindEffect()  		LLVector3 velocity = getVelocity();  		F32 speed = velocity.length();  		//RN: velocity varies too much frame to frame for this to work -		mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLCriticalDamp::getInterpolant(0.02f)); +		mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLCriticalDamp::getInterpolant(InterpDeltaTeenier));  		mLastVel = velocity;  		LLVector4 wind;  		wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity); @@ -2934,13 +2934,10 @@ void LLVOAvatar::idleUpdateWindEffect()  		wind.mV[VW] = llmin(0.025f + (speed * 0.015f) + hover_strength, 0.5f);  		F32 interp; -		if (wind.mV[VW] > mWindVec.mV[VW]) +		interp = LLCriticalDamp::getInterpolant(InterpDeltaSmall); +		if (wind.mV[VW] <= mWindVec.mV[VW])  		{ -			interp = LLCriticalDamp::getInterpolant(0.2f); -		} -		else -		{ -			interp = LLCriticalDamp::getInterpolant(0.4f); +			interp *= 2.0f;  		}  		mWindVec = lerp(mWindVec, wind, interp); @@ -3801,7 +3798,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  			// Set the root rotation, but do so incrementally so that it  			// lags in time by some fixed amount. -			//F32 u = LLCriticalDamp::getInterpolant(PELVIS_LAG);  			F32 pelvis_lag_time = 0.f;  			if (self_in_mouselook)  			{ diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 4dca87652d..ed62abe4ef 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -476,6 +476,7 @@ void LLVOGrass::getGeometry(S32 idx,  								LLStrider<LLVector3>& normalsp,   								LLStrider<LLVector2>& texcoordsp,  								LLStrider<LLColor4U>& colorsp,  +								LLStrider<LLColor4U>& emissivep,  								LLStrider<U16>& indicesp)  {  	if(!mNumBlades)//stop rendering grass @@ -708,7 +709,11 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)  		facep->setIndicesIndex(index_count);  		facep->setVertexBuffer(buffer);  		facep->setPoolType(LLDrawPool::POOL_ALPHA); -		object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp); + +		//dummy parameter (unused by this implementation) +		LLStrider<LLColor4U> emissivep; + +		object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, emissivep, indicesp);  		vertex_count += facep->getGeomCount();  		index_count += facep->getIndicesCount(); diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index b9835b8802..1fe9990cea 100644 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -63,6 +63,7 @@ public:  								LLStrider<LLVector3>& normalsp,   								LLStrider<LLVector2>& texcoordsp,  								LLStrider<LLColor4U>& colorsp,  +								LLStrider<LLColor4U>& emissivep,  								LLStrider<U16>& indicesp);  	void updateFaceSize(S32 idx) { } diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 1a9769f09d..53d67347d1 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -49,17 +49,11 @@ const F32 MAX_PART_LIFETIME = 120.f;  extern U64 gFrameTime;  LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL; -S32 LLVOPartGroup::sVBSlotFree[]; -S32* LLVOPartGroup::sVBSlotCursor = NULL; +S32 LLVOPartGroup::sVBSlotCursor = 0;  void LLVOPartGroup::initClass()  { -	for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i) -	{ -		sVBSlotFree[i] = i; -	} - -	sVBSlotCursor = sVBSlotFree; +	  }  //static @@ -122,36 +116,33 @@ void LLVOPartGroup::destroyGL()  //static  S32 LLVOPartGroup::findAvailableVBSlot()  { -	if (sVBSlotCursor >= sVBSlotFree+LL_MAX_PARTICLE_COUNT) +	if (sVBSlotCursor >= LL_MAX_PARTICLE_COUNT)  	{ //no more available slots  		return -1;  	} -	S32 ret = *sVBSlotCursor; -	sVBSlotCursor++; - -	return ret; +	return sVBSlotCursor++;  }  bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)  { -	while (start < end) +	/*while (start < end)  	{  		if (*start == idx)  		{ //not allocated (in free list)  			return false;  		}  		++start; -	} +	}*/  	//allocated (not in free list) -	return true; +	return false;  }  //static  void LLVOPartGroup::freeVBSlot(S32 idx)  { -	llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); +	/*llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);  	llassert(sVBSlotCursor > sVBSlotFree);  	llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT)); @@ -159,7 +150,7 @@ void LLVOPartGroup::freeVBSlot(S32 idx)  	{  		sVBSlotCursor--;  		*sVBSlotCursor = idx; -	} +	}*/  }  LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -189,6 +180,7 @@ F32 LLVOPartGroup::getBinRadius()  void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)  {		  	const LLVector3& pos_agent = getPositionAgent(); +  	newMin.load3( (pos_agent - mScale).mV);  	newMax.load3( (pos_agent + mScale).mV);  	LLVector4a pos; @@ -273,6 +265,16 @@ F32 LLVOPartGroup::getPartSize(S32 idx)  	return 0.f;  } +void LLVOPartGroup::getBlendFunc(S32 idx, U32& src, U32& dst) +{ +	if (idx < (S32) mViewerPartGroupp->mParticles.size()) +	{ +		LLViewerPart* part = mViewerPartGroupp->mParticles[idx]; +		src = part->mBlendFuncSource; +		dst = part->mBlendFuncDest; +	} +} +  LLVector3 LLVOPartGroup::getCameraPosition() const  {  	return gAgentCamera.getCameraPositionAgent(); @@ -332,13 +334,42 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)  	mDepth = 0.f;  	S32 i = 0 ;  	LLVector3 camera_agent = getCameraPosition(); +	 +	F32 max_scale = 0.f; + +  	for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++)  	{  		const LLViewerPart *part = mViewerPartGroupp->mParticles[i]; + +		//remember the largest particle +		max_scale = llmax(max_scale, part->mScale.mV[0], part->mScale.mV[1]); + +		if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK) +		{ //include ribbon segment length in scale +			const LLVector3* pos_agent = NULL; +			if (part->mParent) +			{ +				pos_agent = &(part->mParent->mPosAgent); +			} +			else if (part->mPartSourcep.notNull()) +			{ +				pos_agent = &(part->mPartSourcep->mPosAgent); +			} + +			if (pos_agent) +			{ +				F32 dist = (*pos_agent-part->mPosAgent).length(); + +				max_scale = llmax(max_scale, dist); +			} +		} +  		LLVector3 part_pos_agent(part->mPosAgent);  		LLVector3 at(part_pos_agent - camera_agent); +		  		F32 camera_dist_squared = at.lengthSquared();  		F32 inv_camera_dist_squared;  		if (camera_dist_squared > 1.f) @@ -411,6 +442,9 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)  		facep->setSize(0, 0);  	} +	//record max scale (used to stretch bounding box for visibility culling) +	mScale.set(max_scale, max_scale, max_scale); +  	mDrawable->movePartition();  	LLPipeline::sCompiles++;  	return TRUE; @@ -478,74 +512,129 @@ BOOL LLVOPartGroup::lineSegmentIntersect(const LLVector3& start, const LLVector3  void LLVOPartGroup::getGeometry(const LLViewerPart& part,  								LLStrider<LLVector4a>& verticesp)  { -	LLVector4a part_pos_agent; -	part_pos_agent.load3(part.mPosAgent.mV); -	LLVector4a camera_agent; -	camera_agent.load3(getCameraPosition().mV);  -	LLVector4a at; -	at.setSub(part_pos_agent, camera_agent); -	LLVector4a up(0, 0, 1); -	LLVector4a right; - -	right.setCross3(at, up); -	right.normalize3fast(); -	up.setCross3(right, at); -	up.normalize3fast(); - -	if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK) +	if (part.mFlags & LLPartData::LL_PART_RIBBON_MASK)  	{ -		LLVector4a normvel; -		normvel.load3(part.mVelocity.mV); -		normvel.normalize3fast(); -		LLVector2 up_fracs; -		up_fracs.mV[0] = normvel.dot3(right).getF32(); -		up_fracs.mV[1] = normvel.dot3(up).getF32(); -		up_fracs.normalize(); -		LLVector4a new_up; -		LLVector4a new_right; - -		//new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up; -		LLVector4a t = right; -		t.mul(up_fracs.mV[0]); -		new_up = up; -		new_up.mul(up_fracs.mV[1]); -		new_up.add(t); - -		//new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up; -		t = right; -		t.mul(up_fracs.mV[1]); -		new_right = up; -		new_right.mul(up_fracs.mV[0]); -		t.sub(new_right); - -		up = new_up; -		right = t; -		up.normalize3fast(); -		right.normalize3fast(); +		LLVector4a axis, pos, paxis, ppos; +		F32 scale, pscale; + +		pos.load3(part.mPosAgent.mV); +		axis.load3(part.mAxis.mV); +		scale = part.mScale.mV[0]; +		 +		if (part.mParent) +		{ +			ppos.load3(part.mParent->mPosAgent.mV); +			paxis.load3(part.mParent->mAxis.mV); +			pscale = part.mParent->mScale.mV[0]; +		} +		else +		{ //use source object as position +			 +			if (part.mPartSourcep->mSourceObjectp.notNull()) +			{ +				LLVector3 v = LLVector3(0,0,1); +				v *= part.mPartSourcep->mSourceObjectp->getRenderRotation(); +				paxis.load3(v.mV); +				ppos.load3(part.mPartSourcep->mPosAgent.mV); +				pscale = part.mStartScale.mV[0]; +			} +			else +			{ //no source object, no parent, nothing to draw +				ppos = pos; +				pscale = scale; +				paxis = axis; +			} +		} + +		LLVector4a p0, p1, p2, p3; + +		scale *= 0.5f; +		pscale *= 0.5f; + +		axis.mul(scale); +		paxis.mul(pscale); + +		p0.setAdd(pos, axis); +		p1.setSub(pos,axis); +		p2.setAdd(ppos, paxis); +		p3.setSub(ppos, paxis); + +		(*verticesp++) = p2; +		(*verticesp++) = p3; +		(*verticesp++) = p0; +		(*verticesp++) = p1;  	} +	else +	{ +		LLVector4a part_pos_agent; +		part_pos_agent.load3(part.mPosAgent.mV); +		LLVector4a camera_agent; +		camera_agent.load3(getCameraPosition().mV);  +		LLVector4a at; +		at.setSub(part_pos_agent, camera_agent); +		LLVector4a up(0, 0, 1); +		LLVector4a right; + +		right.setCross3(at, up); +		right.normalize3fast(); +		up.setCross3(right, at); +		up.normalize3fast(); -	right.mul(0.5f*part.mScale.mV[0]); -	up.mul(0.5f*part.mScale.mV[1]); +		if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK) +		{ +			LLVector4a normvel; +			normvel.load3(part.mVelocity.mV); +			normvel.normalize3fast(); +			LLVector2 up_fracs; +			up_fracs.mV[0] = normvel.dot3(right).getF32(); +			up_fracs.mV[1] = normvel.dot3(up).getF32(); +			up_fracs.normalize(); +			LLVector4a new_up; +			LLVector4a new_right; + +			//new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up; +			LLVector4a t = right; +			t.mul(up_fracs.mV[0]); +			new_up = up; +			new_up.mul(up_fracs.mV[1]); +			new_up.add(t); + +			//new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up; +			t = right; +			t.mul(up_fracs.mV[1]); +			new_right = up; +			new_right.mul(up_fracs.mV[0]); +			t.sub(new_right); + +			up = new_up; +			right = t; +			up.normalize3fast(); +			right.normalize3fast(); +		} +		right.mul(0.5f*part.mScale.mV[0]); +		up.mul(0.5f*part.mScale.mV[1]); -	//HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should) -	// this works because there is actually a 4th float stored after the vertex position which is used as a texture index -	// also, somebody please VECTORIZE THIS -	LLVector4a ppapu; -	LLVector4a ppamu; +		//HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should) +		// this works because there is actually a 4th float stored after the vertex position which is used as a texture index +		// also, somebody please VECTORIZE THIS -	ppapu.setAdd(part_pos_agent, up); -	ppamu.setSub(part_pos_agent, up); +		LLVector4a ppapu; +		LLVector4a ppamu; -	verticesp->setSub(ppapu, right); -	(*verticesp++).getF32ptr()[3] = 0.f; -	verticesp->setSub(ppamu, right); -	(*verticesp++).getF32ptr()[3] = 0.f; -	verticesp->setAdd(ppapu, right); -	(*verticesp++).getF32ptr()[3] = 0.f; -	verticesp->setAdd(ppamu, right); -	(*verticesp++).getF32ptr()[3] = 0.f; +		ppapu.setAdd(part_pos_agent, up); +		ppamu.setSub(part_pos_agent, up); + +		verticesp->setSub(ppapu, right); +		(*verticesp++).getF32ptr()[3] = 0.f; +		verticesp->setSub(ppamu, right); +		(*verticesp++).getF32ptr()[3] = 0.f; +		verticesp->setAdd(ppapu, right); +		(*verticesp++).getF32ptr()[3] = 0.f; +		verticesp->setAdd(ppamu, right); +		(*verticesp++).getF32ptr()[3] = 0.f; +	}  } @@ -555,6 +644,7 @@ void LLVOPartGroup::getGeometry(S32 idx,  								LLStrider<LLVector3>& normalsp,   								LLStrider<LLVector2>& texcoordsp,  								LLStrider<LLColor4U>& colorsp,  +								LLStrider<LLColor4U>& emissivep,  								LLStrider<U16>& indicesp)  {  	if (idx >= (S32) mViewerPartGroupp->mParticles.size()) @@ -566,10 +656,40 @@ void LLVOPartGroup::getGeometry(S32 idx,  	getGeometry(part, verticesp); -	*colorsp++ = part.mColor; -	*colorsp++ = part.mColor; -	*colorsp++ = part.mColor; -	*colorsp++ = part.mColor; +	LLColor4U pcolor; +	LLColor4U color = part.mColor; + +	LLColor4U pglow; + +	if (part.mFlags & LLPartData::LL_PART_RIBBON_MASK) +	{ //make sure color blends properly +		if (part.mParent) +		{ +			pglow = part.mParent->mGlow; +			pcolor = part.mParent->mColor; +		} +		else  +		{ +			pglow = LLColor4U(0, 0, 0, (U8) (255.f*part.mStartGlow)); +			pcolor = part.mStartColor; +		} +	} +	else +	{ +		pglow = part.mGlow; +		pcolor = color; +	} + +	*colorsp++ = pcolor; +	*colorsp++ = pcolor; +	*colorsp++ = color; +	*colorsp++ = color; + +	*emissivep++ = pglow; +	*emissivep++ = pglow; +	*emissivep++ = part.mGlow; +	*emissivep++ = part.mGlow; +  	if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK))  	{ //not fullbright, needs normal @@ -712,10 +832,13 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  	LLStrider<LLVector3> normalsp;  	LLStrider<LLVector2> texcoordsp;  	LLStrider<LLColor4U> colorsp; +	LLStrider<LLColor4U> emissivep;  	buffer->getVertexStrider(verticesp);  	buffer->getNormalStrider(normalsp);  	buffer->getColorStrider(colorsp); +	buffer->getEmissiveStrider(emissivep); +  	LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];	 @@ -724,7 +847,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  		LLFace* facep = *i;  		LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); -		if (!facep->isState(LLFace::PARTICLE)) +		//if (!facep->isState(LLFace::PARTICLE))  		{ //set the indices of this face  			S32 idx = LLVOPartGroup::findAvailableVBSlot();  			if (idx >= 0) @@ -733,7 +856,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  				facep->setIndicesIndex(idx*6);  				facep->setVertexBuffer(LLVOPartGroup::sVB);  				facep->setPoolType(LLDrawPool::POOL_ALPHA); -				facep->setState(LLFace::PARTICLE); +				//facep->setState(LLFace::PARTICLE);  			}  			else  			{ @@ -748,8 +871,9 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  		LLStrider<LLVector3> cur_norm = normalsp + geom_idx;  		LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx;  		LLStrider<LLColor4U> cur_col = colorsp + geom_idx; +		LLStrider<LLColor4U> cur_glow = emissivep + geom_idx; -		object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_idx); +		object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_glow, cur_idx);  		llassert(facep->getGeomCount() == 4);  		llassert(facep->getIndicesCount() == 6); @@ -765,9 +889,16 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  		bool batched = false; +		U32 bf_src = LLRender::BF_SOURCE_ALPHA; +		U32 bf_dst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; + +		object->getBlendFunc(facep->getTEOffset(), bf_src, bf_dst); +  		if (idx >= 0 &&  			draw_vec[idx]->mTexture == facep->getTexture() && -			draw_vec[idx]->mFullbright == fullbright) +			draw_vec[idx]->mFullbright == fullbright && +			draw_vec[idx]->mBlendFuncDst == bf_dst && +			draw_vec[idx]->mBlendFuncSrc == bf_src)  		{  			if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1)  			{ @@ -799,6 +930,8 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  			info->mExtents[0] = group->mObjectExtents[0];  			info->mExtents[1] = group->mObjectExtents[1];  			info->mVSize = vsize; +			info->mBlendFuncDst = bf_dst; +			info->mBlendFuncSrc = bf_src;  			draw_vec.push_back(info);  			//for alpha sorting  			facep->setDrawInfo(info); diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index ce05a0282e..3c2e0344a2 100644 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -42,8 +42,7 @@ public:  	//vertex buffer for holding all particles  	static LLPointer<LLVertexBuffer> sVB; -	static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT]; -	static S32* sVBSlotCursor; +	static S32 sVBSlotCursor;  	static void initClass();  	static void restoreGL(); @@ -57,6 +56,7 @@ public:  							LLVertexBuffer::MAP_NORMAL |  							LLVertexBuffer::MAP_TEXCOORD0 |  							LLVertexBuffer::MAP_COLOR | +							LLVertexBuffer::MAP_EMISSIVE |  							LLVertexBuffer::MAP_TEXTURE_INDEX  	}; @@ -91,10 +91,12 @@ public:  								LLStrider<LLVector3>& normalsp,   								LLStrider<LLVector2>& texcoordsp,  								LLStrider<LLColor4U>& colorsp,  +								LLStrider<LLColor4U>& emissivep,  								LLStrider<U16>& indicesp);  	void updateFaceSize(S32 idx) { }  	F32 getPartSize(S32 idx); +	void getBlendFunc(S32 idx, U32& src, U32& dst);  	LLUUID getPartOwner(S32 idx);  	LLUUID getPartSource(S32 idx); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index db52b1bd1e..3ce32b40bb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -384,7 +384,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,  	}  	else  	{ -		// CORY TO DO: Figure out how to get the value here  		if (update_type != OUT_TERSE_IMPROVED)  		{  			LLVolumeParams volume_params; @@ -453,6 +452,11 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,  				mFaceMappingChanged = TRUE;  				mTexAnimMode = 0;  			} + +			if (value & 0x400) +			{ //particle system (new) +				unpackParticleSource(*dp, mOwnerID, false); +			}  		}  		else  		{ @@ -1051,8 +1055,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo  				}  			}  		} - - +		  		static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");  		bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject && @@ -4242,11 +4245,20 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	mFaceList.clear(); -	std::vector<LLFace*> fullbright_faces; -	std::vector<LLFace*> bump_faces; -	std::vector<LLFace*> simple_faces; +	const U32 MAX_FACE_COUNT = 4096; +	 +	static LLFace** fullbright_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); +	static LLFace** bump_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); +	static LLFace** simple_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); +	static LLFace** alpha_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); +	 +	U32 fullbright_count = 0; +	U32 bump_count = 0; +	U32 simple_count = 0; +	U32 alpha_count = 0; + -	std::vector<LLFace*> alpha_faces; +	  	U32 useage = group->mSpatialPartition->mBufferUsage;  	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); @@ -4257,6 +4269,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	bool emissive = false; +	 +  	{  		LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST); @@ -4558,7 +4572,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  					{  						if (facep->canRenderAsMask())  						{ //can be treated as alpha mask -							simple_faces.push_back(facep); +							if (simple_count < MAX_FACE_COUNT) +							{ +								simple_faces[simple_count++] = facep; +							}  						}  						else  						{ @@ -4566,7 +4583,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  							{ //only treat as alpha in the pipeline if < 100% transparent  								drawablep->setState(LLDrawable::HAS_ALPHA);  							} -							alpha_faces.push_back(facep); +							if (alpha_count < MAX_FACE_COUNT) +							{ +								alpha_faces[alpha_count++] = facep; +							}  						}  					}  					else @@ -4581,33 +4601,51 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						{  							if (te->getBumpmap())  							{ //needs normal + binormal -								bump_faces.push_back(facep); +								if (bump_count < MAX_FACE_COUNT) +								{ +									bump_faces[bump_count++] = facep; +								}  							}  							else if (te->getShiny() || !te->getFullbright())  							{ //needs normal -								simple_faces.push_back(facep); +								if (simple_count < MAX_FACE_COUNT) +								{ +									simple_faces[simple_count++] = facep; +								}  							}  							else   							{ //doesn't need normal  								facep->setState(LLFace::FULLBRIGHT); -								fullbright_faces.push_back(facep); +								if (fullbright_count < MAX_FACE_COUNT) +								{ +									fullbright_faces[fullbright_count++] = facep; +								}  							}  						}  						else  						{  							if (te->getBumpmap() && LLPipeline::sRenderBump)  							{ //needs normal + binormal -								bump_faces.push_back(facep); +								if (bump_count < MAX_FACE_COUNT) +								{ +									bump_faces[bump_count++] = facep; +								}  							}  							else if ((te->getShiny() && LLPipeline::sRenderBump) ||  								!(te->getFullbright() || bake_sunlight))  							{ //needs normal -								simple_faces.push_back(facep); +								if (simple_count < MAX_FACE_COUNT) +								{ +									simple_faces[simple_count++] = facep; +								}  							}  							else   							{ //doesn't need normal  								facep->setState(LLFace::FULLBRIGHT); -								fullbright_faces.push_back(facep); +								if (fullbright_count < MAX_FACE_COUNT) +								{ +									fullbright_faces[fullbright_count++] = facep; +								}  							}  						}  					} @@ -4657,17 +4695,17 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	if (batch_textures)  	{  		bump_mask |= LLVertexBuffer::MAP_BINORMAL; -		genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE); -		genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE); -		genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE); -		genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE); +		genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, simple_count, FALSE, TRUE); +		genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, fullbright_count, FALSE, TRUE); +		genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, bump_count, FALSE, FALSE); +		genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, alpha_count, TRUE, TRUE);  	}  	else  	{ -		genDrawInfo(group, simple_mask, simple_faces); -		genDrawInfo(group, fullbright_mask, fullbright_faces); -		genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE); -		genDrawInfo(group, alpha_mask, alpha_faces, TRUE); +		genDrawInfo(group, simple_mask, simple_faces, simple_count); +		genDrawInfo(group, fullbright_mask, fullbright_faces, fullbright_count); +		genDrawInfo(group, bump_mask, bump_faces, bump_count,  FALSE, FALSE); +		genDrawInfo(group, alpha_mask, alpha_faces, alpha_count, TRUE);  	} @@ -4699,6 +4737,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	}  } +static LLFastTimer::DeclareTimer FTM_REBUILD_MESH_FLUSH("Flush Mesh");  void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  { @@ -4708,11 +4747,14 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  		LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);  		LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers -		S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ; -  		group->mBuilt = 1.f; -		std::set<LLVertexBuffer*> mapped_buffers; +		S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; + +		const U32 MAX_BUFFER_COUNT = 4096; +		LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; + +		U32 buffer_count = 0;  		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  		{ @@ -4722,7 +4764,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  			{  				LLVOVolume* vobj = drawablep->getVOVolume();  				vobj->preRebuild(); - +				  				if (drawablep->isState(LLDrawable::ANIMATED_CHILD))  				{  					vobj->updateRelativeXform(true); @@ -4747,9 +4789,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  							} -							if (buff->isLocked()) +							if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT)  							{ -								mapped_buffers.insert(buff); +								locked_buffer[buffer_count++] = buff;  							}  						}  					} @@ -4765,21 +4807,24 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  			}  		} -		for (std::set<LLVertexBuffer*>::iterator iter = mapped_buffers.begin(); iter != mapped_buffers.end(); ++iter) -		{ -			(*iter)->flush(); -		} - -		// don't forget alpha -		if(group != NULL &&  -		   !group->mVertexBuffer.isNull() &&  -		   group->mVertexBuffer->isLocked())  		{ -			group->mVertexBuffer->flush(); +			LLFastTimer t(FTM_REBUILD_MESH_FLUSH); +			for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) +			{ +				(*iter)->flush(); +			} +		 +			// don't forget alpha +			if(group != NULL &&  +			   !group->mVertexBuffer.isNull() &&  +			   group->mVertexBuffer->isLocked()) +			{ +				group->mVertexBuffer->flush(); +			}  		}  		//if not all buffers are unmapped -		if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)  +		if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount)   		{  			llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;   			for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) @@ -4839,7 +4884,7 @@ static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures) +void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures)  {  	LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); @@ -4875,17 +4920,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		if (!distance_sort)  		{  			//sort faces by things that break batches -			std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified()); +			std::sort(faces, faces+face_count, CompareBatchBreakerModified());  		}  		else  		{  			//sort faces by distance -			std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater()); +			std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater());  		}  	}  	bool hud_group = group->isHUDGroup() ; -	std::vector<LLFace*>::iterator face_iter = faces.begin(); +	LLFace** face_iter = faces; +	LLFace** end_faces = faces+face_count;  	LLSpatialGroup::buffer_map_t buffer_map; @@ -4916,7 +4962,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  	bool flexi = false; -	while (face_iter != faces.end()) +	while (face_iter != end_faces)  	{  		//pull off next face  		LLFace* facep = *face_iter; @@ -4945,10 +4991,13 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();  		//sum up vertices needed for this render batch -		std::vector<LLFace*>::iterator i = face_iter; +		LLFace** i = face_iter;  		++i; -		std::vector<LLViewerTexture*> texture_list; +		const U32 MAX_TEXTURE_COUNT = 32; +		LLViewerTexture* texture_list[MAX_TEXTURE_COUNT]; +		 +		U32 texture_count = 0;  		{  			LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE); @@ -4956,12 +5005,15 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			{  				U8 cur_tex = 0;  				facep->setTextureIndex(cur_tex); -				texture_list.push_back(tex); - +				if (texture_count < MAX_TEXTURE_COUNT) +				{ +					texture_list[texture_count++] = tex; +				} +				  				if (can_batch_texture(facep))  				{ //populate texture_list with any textures that can be batched  				  //move i to the next unbatchable face -					while (i != faces.end()) +					while (i != end_faces)  					{  						facep = *i; @@ -4976,7 +5028,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  							if (distance_sort)  							{ //textures might be out of order, see if texture exists in current batch  								bool found = false; -								for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) +								for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx)  								{  									if (facep->getTexture() == texture_list[tex_idx])  									{ @@ -4988,7 +5040,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  								if (!found)  								{ -									cur_tex = texture_list.size(); +									cur_tex = texture_count;  								}  							}  							else @@ -5003,7 +5055,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  							tex = facep->getTexture(); -							texture_list.push_back(tex); +							if (texture_count < MAX_TEXTURE_COUNT) +							{ +								texture_list[texture_count++] = tex; +							}  						}  						if (geom_count + facep->getGeomCount() > max_vertices) @@ -5026,7 +5081,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			}  			else  			{ -				while (i != faces.end() &&  +				while (i != end_faces &&   					(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))  				{  					facep = *i; diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 376715a2d6..548890b5b5 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -57,14 +57,6 @@  #include "curl/curl.h" -static LLStaticHashedString sCamPosLocal("camPosLocal");
 -static LLStaticHashedString sWaterFogColor("waterFogColor");
 -static LLStaticHashedString sWaterFogEnd("waterFogEnd");
 -static LLStaticHashedString sWaterPlane("waterPlane");
 -static LLStaticHashedString sWaterFogDensity("waterFogDensity");
 -static LLStaticHashedString sWaterFogKS("waterFogKS");
 -static LLStaticHashedString sDistanceMultiplier("distance_multiplier"); -  LLWaterParamManager::LLWaterParamManager() :  	mFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f, 0.0f, "waterFogColor", "WaterFogColor"),  	mFogDensity(4, "waterFogDensity", 2), @@ -196,13 +188,11 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader)  	if (shader->mShaderGroup == LLGLSLShader::SG_WATER)  	{  		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV); -		shader->uniform3fv(sCamPosLocal, 1, LLViewerCamera::getInstance()->getOrigin().mV); -		shader->uniform4fv(sWaterFogColor, 1, LLDrawPoolWater::sWaterFogColor.mV); -		shader->uniform1f(sWaterFogEnd, LLDrawPoolWater::sWaterFogEnd); -		shader->uniform4fv(sWaterPlane, 1, mWaterPlane.mV); -		shader->uniform1f(sWaterFogDensity, getFogDensity()); -		shader->uniform1f(sWaterFogKS, mWaterFogKS); -		shader->uniform1f(sDistanceMultiplier, 0); +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, LLDrawPoolWater::sWaterFogColor.mV); +		shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, mWaterPlane.mV); +		shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, getFogDensity()); +		shader->uniform1f(LLShaderMgr::WATER_FOGKS, mWaterFogKS); +		shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0);  	}  } diff --git a/indra/newview/llwlanimator.h b/indra/newview/llwlanimator.h index 5223b45343..810f4cf7e5 100644 --- a/indra/newview/llwlanimator.h +++ b/indra/newview/llwlanimator.h @@ -137,3 +137,4 @@ private:  };  #endif // LL_WL_ANIMATOR_H + diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 65cb80c3e7..04d41a2512 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -61,9 +61,6 @@  #include "curl/curl.h"  #include "llstreamtools.h" -static LLStaticHashedString sCamPosLocal("camPosLocal"); -static LLStaticHashedString sSceneLightStrength("scene_light_strength"); -  LLWLParamManager::LLWLParamManager() :  	//set the defaults for the controls @@ -355,7 +352,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)  	if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)  	{  		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV); -		shader->uniform3fv(sCamPosLocal, 1, LLViewerCamera::getInstance()->getOrigin().mV); +		shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);  	}   	else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) @@ -363,7 +360,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)  		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV);  	} -	shader->uniform1f(sSceneLightStrength, mSceneLightStrength); +	shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);  } diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index 72422500fc..e13aed98ed 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -412,3 +412,4 @@ inline LLVector4 LLWLParamManager::getRotatedLightDir(void) const  }  #endif + diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index 745cdae441..b307f19e8a 100644 --- a/indra/newview/llwlparamset.cpp +++ b/indra/newview/llwlparamset.cpp @@ -406,4 +406,5 @@ void LLWLParamSet::updateHashedNames()  	{  		mParamHashedNames.push_back(LLStaticHashedString(iter->first));  	} -}
\ No newline at end of file +} + diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h index 3e9f77ba6c..6e5f1d3a4b 100644 --- a/indra/newview/llwlparamset.h +++ b/indra/newview/llwlparamset.h @@ -243,3 +243,4 @@ inline F32 LLWLParamSet::getCloudScrollY() {  #endif // LL_WLPARAM_SET_H + diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index ccc513b80d..7c3bc5988c 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -302,8 +302,8 @@ void LLWorldMapView::draw()  	mVisibleRegions.clear();  	// animate pan if necessary -	sPanX = lerp(sPanX, sTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); -	sPanY = lerp(sPanY, sTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); +	sPanX = lerp(sPanX, sTargetPanX, LLCriticalDamp::getInterpolant(InterpDeltaSmaller)); +	sPanY = lerp(sPanY, sTargetPanY, LLCriticalDamp::getInterpolant(InterpDeltaSmaller));  	const S32 width = getRect().getWidth();  	const S32 height = getRect().getHeight(); @@ -1795,3 +1795,5 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )  	}  	return FALSE;  } + + diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 690bf64798..e9cd74406d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7261,7 +7261,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  				else  				{  					//focus on alt-zoom target -					focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); +					LLViewerRegion* region = gAgent.getRegion(); +					if (region) +					{ +						focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal()); +					}  				}  			} @@ -7868,13 +7872,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n  	shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight());  	shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);  	shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); -	 -	static LLStaticHashedString sNormMat("norm_mat"); -	if (shader.getUniformLocation(sNormMat) >= 0) -	{ -		glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); -		shader.uniformMatrix4fv(sNormMat, 1, FALSE, norm_mat.m); -	}  }  static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace"); @@ -7984,8 +7981,7 @@ void LLPipeline::renderDeferredLighting()  				}  				gDeferredSunProgram.uniform3fv(sOffset, slice, offset); -				gDeferredSunProgram.uniform2f(sScreenRes, mDeferredLight.getWidth(), mDeferredLight.getHeight()); -				 +								  				{  					LLGLDisable blend(GL_BLEND);  					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); diff --git a/indra/test/io.cpp b/indra/test/io.cpp index ce747f667d..7f26ac6724 100644 --- a/indra/test/io.cpp +++ b/indra/test/io.cpp @@ -1141,6 +1141,7 @@ namespace tut  		ensure("Connected to server", connected);  		lldebugs << "connected" << llendl;  		F32 elapsed = pump_loop(mPump,0.1f); +		(void)elapsed;  		count = mPump->runningChains();  		ensure_equals("server chain onboard", count, 2);  		lldebugs << "** Client is connected." << llendl; diff --git a/indra/test/llstreamtools_tut.cpp b/indra/test/llstreamtools_tut.cpp index a93f2e8f65..68e56b5ee2 100644 --- a/indra/test/llstreamtools_tut.cpp +++ b/indra/test/llstreamtools_tut.cpp @@ -386,15 +386,17 @@ namespace tut  		std::string actual_result;  		std::istringstream is;  		bool ret; -  		is.clear();  		is.str(str = "  First Second \t \r  \n Third  Fourth-ShouldThisBePartOfFourth  Fifth\n");  		actual_result = "";  		ret = get_word(actual_result, is); // First +		(void)ret;  		actual_result = "";  		ret = get_word(actual_result, is); // Second +		(void)ret;  		actual_result = "";  		ret = get_word(actual_result, is); // Third +		(void)ret;  		// the current implementation of get_word seems inconsistent with  		// skip_to_next_word. skip_to_next_word treats any character other @@ -486,6 +488,7 @@ namespace tut  		is.str(str = "First Second \t \r\n Third  Fourth-ShouldThisBePartOfFourth  IsThisFifth\n");  		actual_result = "";  		ret = get_line(actual_result, is); +		(void)ret;  		expected_result = "First Second \t \r\n";  		ensure_equals("get_line: 1", actual_result, expected_result); @@ -551,6 +554,7 @@ namespace tut  		is.str(str = "Should not skip lone \r.\r\n");  		actual_result = "";  		ret = get_line(actual_result, is); +		(void)ret;  		expected_result = "Should not skip lone \r.\r\n";  		ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result);  	} @@ -569,6 +573,7 @@ namespace tut  		is.str(str = "\n");  		actual_result = "";  		ret = get_line(actual_result, is); +		(void)ret;  		expected_result = "\n";  		ensure_equals("get_line: Just newline", actual_result, expected_result);  	} @@ -588,6 +593,7 @@ namespace tut  		is.str(str = "First Line.\nSecond Line.\n");  		actual_result = "";  		ret = get_line(actual_result, is, 255); +		(void)ret;  		expected_result = "First Line.\n";  		ensure_equals("get_line: Basic Operation", actual_result, expected_result); diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp index 6e1c82bb24..0aad3cbc15 100644 --- a/indra/test/lltemplatemessagebuilder_tut.cpp +++ b/indra/test/lltemplatemessagebuilder_tut.cpp @@ -958,11 +958,13 @@ namespace tut  		reader->validateMessage(buffer, builtSize, LLHost());  		reader->readMessage(buffer, LLHost());  		reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue); +		(void)outValue;  		char outBuffer[bufferSize];  		memset(buffer, 0xcc, bufferSize);  		reader->getString(_PREHASH_Test1, _PREHASH_Test0, bufferSize,   						  outBuffer);  		outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1); +		(void)outValue2;  		ensure_equals("Ensure present value ", outValue, inValue);  		ensure_equals("Ensure unchanged buffer ", strlen(outBuffer), 0);  		delete reader;  | 
