diff options
Diffstat (limited to 'indra')
104 files changed, 3330 insertions, 3234 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..d0e4bc9e25 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 @@ -133,6 +182,78 @@ inline void ll_aligned_free_32(void *p) #endif } + +// Copy words 16-byte blocks from src to dst. Source and destination MUST NOT OVERLAP. +// Source and dest must be 16-byte aligned and size must be multiple of 16. +// +inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes) +{ + llassert(src != NULL); + llassert(dst != NULL); + llassert(bytes >= 16); + llassert((bytes % sizeof(F32))== 0); + llassert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src)); + llassert(bytes%16==0); + ll_assert_aligned(src,16); + ll_assert_aligned(dst,16); + + char* end = dst + bytes; + + if (bytes > 64) + { + + // Find start of 64b aligned area within block + // + void* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst); + + //at least 64 bytes before the end of the destination, switch to 16 byte copies + void* end_64 = end-64; + + // Prefetch the head of the 64b area now + // + _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); + + // Copy 16b chunks until we're 64b aligned + // + while (dst < begin_64) + { + + _mm_store_ps((F32*)dst, _mm_load_ps((F32*)src)); + dst += 16; + src += 16; + } + + // Copy 64b chunks up to your tail + // + // might be good to shmoo the 512b prefetch offset + // (characterize performance for various values) + // + while (dst < end_64) + { + _mm_prefetch((char*)src + 512, _MM_HINT_NTA); + _mm_prefetch((char*)dst + 512, _MM_HINT_NTA); + _mm_store_ps((F32*)dst, _mm_load_ps((F32*)src)); + _mm_store_ps((F32*)(dst + 16), _mm_load_ps((F32*)(src + 16))); + _mm_store_ps((F32*)(dst + 32), _mm_load_ps((F32*)(src + 32))); + _mm_store_ps((F32*)(dst + 48), _mm_load_ps((F32*)(src + 48))); + dst += 64; + src += 64; + } + } + + // Copy remainder 16b tail chunks (or ALL 16b chunks for sub-64b copies) + // + while (dst < end) + { + _mm_store_ps((F32*)dst, _mm_load_ps((F32*)src)); + dst += 16; + src += 16; + } +} + #ifndef __DEBUG_PRIVATE_MEM__ #define __DEBUG_PRIVATE_MEM__ 0 #endif @@ -541,13 +662,7 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr) // LLSingleton moved to llsingleton.h -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 #endif 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..7f221fd686 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) - { - ll_aligned_free_16(new_face.mNormals); - new_face.mNormals = NULL; - } - - if (!mTexCoords) + // disallow data amplification + // + if (new_face.mNumVertices <= mNumVertices) { - ll_aligned_free_16(new_face.mTexCoords); - new_face.mTexCoords = NULL; - } - - swapData(new_face); + llassert(new_face.mNumIndices == mNumIndices); + 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..41a0310ce0 100644 --- a/indra/llmessage/llpartdata.cpp +++ b/indra/llmessage/llpartdata.cpp @@ -37,53 +37,46 @@ -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; } -LLSD LLPartData::asLLSD() const +bool LLPartData::hasBlendFunc() const { - LLSD sd = LLSD(); - sd["pdflags"] = ll_sd_from_U32(mFlags); - sd["pdmaxage"] = mMaxAge; - sd["pdstartcolor"] = ll_sd_from_color4(mStartColor); - sd["pdendcolor"] = ll_sd_from_color4(mEndColor); - sd["pdstartscale"] = ll_sd_from_vector2(mStartScale); - sd["pdendscale"] = ll_sd_from_vector2(mEndScale); - return sd; + return mBlendFuncSource != LLPartData::LL_PART_BF_SOURCE_ALPHA || mBlendFuncDest != LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; } -bool LLPartData::fromLLSD(LLSD& sd) +S32 LLPartData::getSize() const { - mFlags = ll_U32_from_sd(sd["pdflags"]); - mMaxAge = (F32)sd["pdmaxage"].asReal(); - mStartColor = ll_color4_from_sd(sd["pdstartcolor"]); - mEndColor = ll_color4_from_sd(sd["pdendcolor"]); - mStartScale = ll_vector2_from_sd(sd["pdstartscale"]); - mEndScale = ll_vector2_from_sd(sd["pdendscale"]); - return true; + S32 size = PS_LEGACY_PART_DATA_BLOCK_SIZE; + if (hasGlow()) size += PS_PART_DATA_GLOW_SIZE; + if (hasBlendFunc()) size += PS_PART_DATA_BLEND_SIZE; + + return size; } -BOOL LLPartData::unpack(LLDataPacker &dp) +BOOL LLPartData::unpackLegacy(LLDataPacker &dp) { LLColor4U coloru; @@ -98,9 +91,70 @@ 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); + + 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 +202,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 +226,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 +245,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 +271,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 +330,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 +341,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 +372,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..ed5c1a6ac7 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,11 +88,13 @@ 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 +109,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 +155,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 +169,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 +184,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 +223,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/llmessage/tests/llpartdata_test.cpp b/indra/llmessage/tests/llpartdata_test.cpp index 9123bd06c7..de81e0bbb2 100644 --- a/indra/llmessage/tests/llpartdata_test.cpp +++ b/indra/llmessage/tests/llpartdata_test.cpp @@ -38,10 +38,34 @@ namespace tut { + + //bunch of sniffed data that *should* be a valid particle system + static U8 msg[] = { + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x80, 0x00, 0x80, + 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x5e, 0x12, 0x0b, 0xa1, 0x58, 0x05, 0xdc, 0x57, 0x66, + 0xb7, 0xf5, 0xac, 0x4b, 0xd1, 0x8f, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00, 0x00, 0x0a, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7e, 0xc6, 0x81, 0xdc, 0x7e, 0xc6, 0x81, 0xdc, 0x77, 0xcf, 0xef, 0xd4, 0xce, 0x64, 0x1a, 0x7e, + 0x26, 0x87, 0x55, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0x77, 0xcf, 0x98, 0xa3, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf2, + 0xf1, 0x65, 0x32, 0x1b, 0xef, 0x18, 0x70, 0x66, 0xba, 0x30, 0xa0, 0x11, 0xaa, 0x2f, 0xb0, 0xab, 0xd0, + 0x30, 0x7d, 0xbd, 0x01, 0x00, 0xf8, 0x0d, 0xb8, 0x30, 0x01, 0x00, 0x00, 0x00, 0xce, 0xc6, 0x81, 0xdc, + 0xce, 0xc6, 0x81, 0xdc, 0xc7, 0xcf, 0xef, 0xd4, 0x75, 0x65, 0x1a, 0x7f, 0x62, 0x6f, 0x55, 0x7f, 0x6d, + 0x65, 0x22, 0x7f, 0x6d, 0x65, 0x22, 0x7f, 0xc7, 0xcf, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf2, 0xf1, 0x62, 0x12, 0x1b, 0xef, + 0x18, 0x7e, 0xbd, 0x01, 0x00, 0x16, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xac, 0x28, 0x03, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, + 0xe0, 0xb9, 0x30, 0x03, 0xe1, 0xb9, 0x30, 0xbb, 0x00, 0x00, 0x00, 0x48, 0xe0, 0xb9, 0x30, 0x36, 0xd9, + 0x81, 0xdc, 0x36, 0xd9, 0x81, 0xdc, 0x3f, 0xd0, 0xef, 0xd4, 0xa5, 0x7a, 0x72, 0x7f, 0x26, 0x30, 0x55, + 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x3f, 0xd0, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00 }; struct partdata_test { }; + typedef test_group<partdata_test> partdata_test_t; typedef partdata_test_t::object partdata_test_object_t; tut::partdata_test_t tut_partdata_test("LLPartData"); @@ -49,168 +73,82 @@ namespace tut template<> template<> void partdata_test_object_t::test<1>() { - LLPartData llpdata,llpdata1; - U8 pkbuf[128]; - - llpdata.setFlags(LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK | - LLPartData::LL_PART_BOUNCE_MASK | LLPartData::LL_PART_WIND_MASK | LLPartData::LL_PART_FOLLOW_SRC_MASK | - LLPartData::LL_PART_FOLLOW_VELOCITY_MASK | LLPartData::LL_PART_TARGET_POS_MASK | LLPartData::LL_PART_TARGET_LINEAR_MASK | - LLPartData::LL_PART_EMISSIVE_MASK | LLPartData::LL_PART_BEAM_MASK | LLPartData::LL_PART_DEAD_MASK); - - llpdata.setMaxAge(29.3f); - - LLVector3 llvec1(1.0f, .5f, .25f); - llpdata.setStartColor(llvec1); - llpdata.setStartAlpha(.7f); - - LLVector3 llvec2(.2f, .3f, 1.0f); - llpdata.setEndColor(llvec2); - llpdata.setEndAlpha(1.0f); + LLPartSysData llpsysdata; + LLDataPackerBinaryBuffer dp1(msg, sizeof(msg)); - llpdata.setStartScale(3.23f, 4.0f); - llpdata.setEndScale(2.4678f, 1.0f); + ensure("LLPartSysData::unpack failed.", llpsysdata.unpack(dp1)); - LLDataPackerBinaryBuffer dp((U8*)pkbuf, 128); - llpdata.pack(dp); - S32 cur_size = dp.getCurrentSize(); - - LLDataPackerBinaryBuffer dp1((U8*)pkbuf, cur_size); - llpdata1.unpack(dp1); - - ensure("1.mFlags values are different after unpacking", llpdata1.mFlags == llpdata.mFlags); - ensure_approximately_equals("2.mMaxAge values are different after unpacking", llpdata1.mMaxAge, llpdata.mMaxAge, 8); - - ensure_approximately_equals("3.mStartColor[0] values are different after unpacking", llpdata1.mStartColor.mV[0], llpdata.mStartColor.mV[0], 8); - ensure_approximately_equals("4.mStartColor[1] values are different after unpacking", llpdata1.mStartColor.mV[1], llpdata.mStartColor.mV[1], 8); - ensure_approximately_equals("5.mStartColor[2] values are different after unpacking", llpdata1.mStartColor.mV[2], llpdata.mStartColor.mV[2], 8); - ensure_approximately_equals("6.mStartColor[3] values are different after unpacking", llpdata1.mStartColor.mV[3], llpdata.mStartColor.mV[3], 8); - - ensure_approximately_equals("7.mEndColor[0] values are different after unpacking", llpdata1.mEndColor.mV[0], llpdata.mEndColor.mV[0], 8); - ensure_approximately_equals("8.mEndColor[1] values are different after unpacking", llpdata1.mEndColor.mV[1], llpdata.mEndColor.mV[1], 8); - ensure_approximately_equals("9.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[2], llpdata.mEndColor.mV[2], 8); - ensure_approximately_equals("10.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[3], llpdata.mEndColor.mV[3], 8); - - ensure_approximately_equals("11.mStartScale[0] values are different after unpacking", llpdata1.mStartScale.mV[0], llpdata.mStartScale.mV[0], 5); - ensure_approximately_equals("12.mStartScale[1] values are different after unpacking", llpdata1.mStartScale.mV[1], llpdata.mStartScale.mV[1], 5); - - ensure_approximately_equals("13.mEndScale[0] values are different after unpacking", llpdata1.mEndScale.mV[0], llpdata.mEndScale.mV[0], 5); - ensure_approximately_equals("14.mEndScale[1] values are different after unpacking", llpdata1.mEndScale.mV[1], llpdata.mEndScale.mV[1], 5); - } - - - template<> template<> - void partdata_test_object_t::test<2>() - { - LLPartData llpdata,llpdata1; - - llpdata.setFlags(LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK | - LLPartData::LL_PART_BOUNCE_MASK | LLPartData::LL_PART_WIND_MASK | LLPartData::LL_PART_FOLLOW_SRC_MASK | - LLPartData::LL_PART_FOLLOW_VELOCITY_MASK | LLPartData::LL_PART_TARGET_POS_MASK | LLPartData::LL_PART_TARGET_LINEAR_MASK | - LLPartData::LL_PART_EMISSIVE_MASK | LLPartData::LL_PART_BEAM_MASK | LLPartData::LL_PART_DEAD_MASK); - - llpdata.setMaxAge(29.3f); - - LLVector3 llvec1(1.0f, .5f, .25f); - llpdata.setStartColor(llvec1); - llpdata.setStartAlpha(.7f); - - LLVector3 llvec2(.2f, .3f, 1.0f); - llpdata.setEndColor(llvec2); - llpdata.setEndAlpha(1.0f); - - llpdata.setStartScale(3.23f, 4.0f); - llpdata.setEndScale(2.4678f, 1.0f); - - LLSD llsd = llpdata.asLLSD(); - - llpdata1.fromLLSD(llsd); - - ensure("1.mFlags values are different after unpacking", llpdata1.mFlags == llpdata.mFlags); - ensure_approximately_equals("2.mMaxAge values are different after unpacking", llpdata1.mMaxAge, llpdata.mMaxAge, 8); - - ensure_approximately_equals("3.mStartColor[0] values are different after unpacking", llpdata1.mStartColor.mV[0], llpdata.mStartColor.mV[0], 8); - ensure_approximately_equals("4.mStartColor[1] values are different after unpacking", llpdata1.mStartColor.mV[1], llpdata.mStartColor.mV[1], 8); - ensure_approximately_equals("5.mStartColor[2] values are different after unpacking", llpdata1.mStartColor.mV[2], llpdata.mStartColor.mV[2], 8); - ensure_approximately_equals("6.mStartColor[3] values are different after unpacking", llpdata1.mStartColor.mV[3], llpdata.mStartColor.mV[3], 8); - - ensure_approximately_equals("7.mEndColor[0] values are different after unpacking", llpdata1.mEndColor.mV[0], llpdata.mEndColor.mV[0], 8); - ensure_approximately_equals("8.mEndColor[1] values are different after unpacking", llpdata1.mEndColor.mV[1], llpdata.mEndColor.mV[1], 8); - ensure_approximately_equals("9.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[2], llpdata.mEndColor.mV[2], 8); - ensure_approximately_equals("10.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[3], llpdata.mEndColor.mV[3], 8); - - ensure_approximately_equals("11.mStartScale[0] values are different after unpacking", llpdata1.mStartScale.mV[0], llpdata.mStartScale.mV[0], 5); - ensure_approximately_equals("12.mStartScale[1] values are different after unpacking", llpdata1.mStartScale.mV[1], llpdata.mStartScale.mV[1], 5); - - ensure_approximately_equals("13.mEndScale[0] values are different after unpacking", llpdata1.mEndScale.mV[0], llpdata.mEndScale.mV[0], 5); - ensure_approximately_equals("14.mEndScale[1] values are different after unpacking", llpdata1.mEndScale.mV[1], llpdata.mEndScale.mV[1], 5); - } - - -//*********llpartsysdata*********** - - template<> template<> - void partdata_test_object_t::test<3>() - { - LLPartSysData llpsysdata, llpsysdata1; - U8 pkbuf[256]; - llpsysdata.setBurstSpeedMin(33.33f); - ensure("1.mBurstSpeedMin coudnt be set", 33.33f == llpsysdata.mBurstSpeedMin); - - llpsysdata.setBurstSpeedMax(44.44f); - ensure("2.mBurstSpeedMax coudnt be set", 44.44f == llpsysdata.mBurstSpeedMax); - - llpsysdata.setBurstRadius(45.55f); - ensure("3.mBurstRadius coudnt be set", 45.55f == llpsysdata.mBurstRadius); - - LLVector3 llvec(44.44f, 111.11f, -40.4f); - llpsysdata.setPartAccel(llvec); - - llpsysdata.mCRC = 0xFFFFFFFF; - llpsysdata.mFlags = 0x20; - - llpsysdata.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY; - - llpsysdata.mMaxAge = 99.99f; - llpsysdata.mStartAge = 18.5f; - llpsysdata.mInnerAngle = 4.234f; - llpsysdata.mOuterAngle = 7.123f; - llpsysdata.mBurstRate = 245.53f; - llpsysdata.mBurstPartCount = 0xFF; - llpsysdata.mAngularVelocity = llvec; - - llpsysdata.mPartImageID.generate(); - llpsysdata.mTargetUUID.generate(); + //mCRC 1 unsigned int + ensure("mCRC different after unpacking", llpsysdata.mCRC == (U32) 1); + //mFlags 0 unsigned int + ensure ("mFlags different after unpacking", llpsysdata.mFlags == (U32) 0); + //mPattern 1 '' unsigned char + ensure ("mPattern different after unpacking", llpsysdata.mPattern == (U8) 1); + //mInnerAngle 0.00000000 float + ensure_approximately_equals("mInnerAngle different after unpacking", llpsysdata.mInnerAngle, 0.f, 8); + //mOuterAngle 0.00000000 float + ensure_approximately_equals("mOuterAngle different after unpacking", llpsysdata.mOuterAngle, 0.f, 8); + //mAngularVelocity 0,0,0 + ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[0], 0.f, 8); + ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[1], 0.f, 8); + ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[2], 0.f, 8); + //mBurstRate 0.097656250 float + ensure_approximately_equals("mBurstRate different after unpacking", llpsysdata.mBurstRate, 0.097656250f, 8); + //mBurstPartCount 1 '' unsigned char + ensure("mBurstPartCount different after unpacking", llpsysdata.mBurstPartCount == (U8) 1); + //mBurstRadius 0.00000000 float + ensure_approximately_equals("mBurstRadius different after unpacking", llpsysdata.mBurstRadius, 0.f, 8); + //mBurstSpeedMin 1.0000000 float + ensure_approximately_equals("mBurstSpeedMin different after unpacking", llpsysdata.mBurstSpeedMin, 1.f, 8); + //mBurstSpeedMax 1.0000000 float + ensure_approximately_equals("mBurstSpeedMax different after unpacking", llpsysdata.mBurstSpeedMax, 1.f, 8); + //mMaxAge 0.00000000 float + ensure_approximately_equals("mMaxAge different after unpacking", llpsysdata.mMaxAge, 0.f, 8); + //mStartAge 0.00000000 float + ensure_approximately_equals("mStartAge different after unpacking", llpsysdata.mStartAge, 0.f, 8); + //mPartAccel <0,0,0> + ensure_approximately_equals("mPartAccel.mV[0] different after unpacking", llpsysdata.mPartAccel.mV[0], 0.f, 7); + ensure_approximately_equals("mPartAccel.mV[1] different after unpacking", llpsysdata.mPartAccel.mV[1], 0.f, 7); + ensure_approximately_equals("mPartAccel.mV[2] different after unpacking", llpsysdata.mPartAccel.mV[2], 0.f, 7); + + //mPartData + LLPartData& data = llpsysdata.mPartData; + + //mFlags 132354 unsigned int + ensure ("mPartData.mFlags different after unpacking", data.mFlags == (U32) 132354); + //mMaxAge 10.000000 float + ensure_approximately_equals("mPartData.mMaxAge different after unpacking", data.mMaxAge, 10.f, 8); + //mStartColor <1,1,1,1> + ensure_approximately_equals("mPartData.mStartColor.mV[0] different after unpacking", data.mStartColor.mV[0], 1.f, 8); + ensure_approximately_equals("mPartData.mStartColor.mV[1] different after unpacking", data.mStartColor.mV[1], 1.f, 8); + ensure_approximately_equals("mPartData.mStartColor.mV[2] different after unpacking", data.mStartColor.mV[2], 1.f, 8); + ensure_approximately_equals("mPartData.mStartColor.mV[3] different after unpacking", data.mStartColor.mV[3], 1.f, 8); + //mEndColor <1,1,0,0> + ensure_approximately_equals("mPartData.mEndColor.mV[0] different after unpacking", data.mEndColor.mV[0], 1.f, 8); + ensure_approximately_equals("mPartData.mEndColor.mV[1] different after unpacking", data.mEndColor.mV[1], 1.f, 8); + ensure_approximately_equals("mPartData.mEndColor.mV[2] different after unpacking", data.mEndColor.mV[2], 0.f, 8); + ensure_approximately_equals("mPartData.mEndColor.mV[3] different after unpacking", data.mEndColor.mV[3], 0.f, 8); + //mStartScale <1,1> + ensure_approximately_equals("mPartData.mStartScale.mV[0] different after unpacking", data.mStartScale.mV[0], 1.f, 8); + ensure_approximately_equals("mPartData.mStartScale.mV[1] different after unpacking", data.mStartScale.mV[1], 1.f, 8); + //mEndScale <0,0> + ensure_approximately_equals("mPartData.mEndScale.mV[0] different after unpacking", data.mEndScale.mV[0], 0.f, 8); + ensure_approximately_equals("mPartData.mEndScale.mV[1] different after unpacking", data.mEndScale.mV[1], 0.f, 8); + //mPosOffset <0,0,0> + ensure_approximately_equals("mPartData.mPosOffset.mV[0] different after unpacking", data.mPosOffset.mV[0], 0.f, 8); + ensure_approximately_equals("mPartData.mPosOffset.mV[1] different after unpacking", data.mPosOffset.mV[1], 0.f, 8); + ensure_approximately_equals("mPartData.mPosOffset.mV[2] different after unpacking", data.mPosOffset.mV[2], 0.f, 8); + //mParameter 0.00000000 float + ensure_approximately_equals("mPartData.mParameter different after unpacking", data.mParameter, 0.f, 8); - LLDataPackerBinaryBuffer dp((U8*)pkbuf, 256); - llpsysdata.pack(dp); - S32 cur_size = dp.getCurrentSize(); - LLDataPackerBinaryBuffer dp1((U8*)pkbuf, cur_size); - llpsysdata1.unpack(dp1); - - ensure("1.mCRC's not equal", llpsysdata.mCRC == llpsysdata1.mCRC); - ensure("2.mFlags's not equal", llpsysdata.mFlags == llpsysdata1.mFlags); - ensure("3.mPattern's not equal", llpsysdata.mPattern == llpsysdata1.mPattern); - ensure_approximately_equals("4.mMaxAge's not equal", llpsysdata.mMaxAge , llpsysdata1.mMaxAge, 8); - ensure_approximately_equals("5.mStartAge's not equal", llpsysdata.mStartAge, llpsysdata1.mStartAge, 8); - ensure_approximately_equals("6.mOuterAngle's not equal", llpsysdata.mOuterAngle, llpsysdata1.mOuterAngle, 5); - ensure_approximately_equals("7.mInnerAngles's not equal", llpsysdata.mInnerAngle, llpsysdata1.mInnerAngle, 5); - ensure_approximately_equals("8.mBurstRate's not equal", llpsysdata.mBurstRate, llpsysdata1.mBurstRate, 8); - ensure("9.mBurstPartCount's not equal", llpsysdata.mBurstPartCount == llpsysdata1.mBurstPartCount); - - ensure_approximately_equals("10.mBurstSpeedMin's not equal", llpsysdata.mBurstSpeedMin, llpsysdata1.mBurstSpeedMin, 8); - ensure_approximately_equals("11.mBurstSpeedMax's not equal", llpsysdata.mBurstSpeedMax, llpsysdata1.mBurstSpeedMax, 8); - - ensure_approximately_equals("12.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[0], llpsysdata1.mAngularVelocity.mV[0], 7); - ensure_approximately_equals("13.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[1], llpsysdata1.mAngularVelocity.mV[1], 7); - ensure_approximately_equals("14.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[2], llpsysdata1.mAngularVelocity.mV[2], 7); - - ensure_approximately_equals("15.mPartAccel's not equal", llpsysdata.mPartAccel.mV[0], llpsysdata1.mPartAccel.mV[0], 7); - ensure_approximately_equals("16.mPartAccel's not equal", llpsysdata.mPartAccel.mV[1], llpsysdata1.mPartAccel.mV[1], 7); - ensure_approximately_equals("17.mPartAccel's not equal", llpsysdata.mPartAccel.mV[2], llpsysdata1.mPartAccel.mV[2], 7); - - ensure("18.mPartImageID's not equal", llpsysdata.mPartImageID == llpsysdata1.mPartImageID); - ensure("19.mTargetUUID's not equal", llpsysdata.mTargetUUID == llpsysdata1.mTargetUUID); - ensure_approximately_equals("20.mBurstRadius's not equal", llpsysdata.mBurstRadius, llpsysdata1.mBurstRadius, 8); + //mStartGlow 0.00000000 float + ensure_approximately_equals("mPartData.mStartGlow different after unpacking", data.mStartGlow, 0.f, 8); + //mEndGlow 0.00000000 float + ensure_approximately_equals("mPartData.mEndGlow different after unpacking", data.mEndGlow, 0.f, 8); + //mBlendFuncSource 2 '' unsigned char + ensure("mPartData.mBlendFuncSource different after unpacking", data.mBlendFuncSource == (U8) 2); + //mBlendFuncDest 1 '' unsigned char + ensure("mPartData.mBlendFuncDest different after unpacking", data.mBlendFuncDest == (U8) 1); } } 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..e39d2862fb 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 && @@ -2990,7 +2993,8 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p //transform view vector into volume space view_vector -= getRenderPosition(); - mDrawable->mDistanceWRTCamera = view_vector.length(); + // WTF...why is silhouette generation touching a variable used all over the place?! + //mDrawable->mDistanceWRTCamera = view_vector.length(); LLQuaternion worldRot = getRenderRotation(); view_vector = view_vector * ~worldRot; if (!isVolumeGlobal()) @@ -4242,11 +4246,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 +4270,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool emissive = false; + + { LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST); @@ -4558,7 +4573,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 +4584,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 +4602,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 +4696,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 +4738,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } +static LLFastTimer::DeclareTimer FTM_REBUILD_MESH_FLUSH("Flush Mesh"); void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { @@ -4708,11 +4748,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 +4765,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); - + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) { vobj->updateRelativeXform(true); @@ -4747,9 +4790,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 +4808,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 +4885,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 +4921,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 +4963,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 +4992,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 +5006,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 +5029,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 +5041,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (!found) { - cur_tex = texture_list.size(); + cur_tex = texture_count; } } else @@ -5003,7 +5056,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 +5082,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; |