diff options
-rw-r--r-- | indra/llinventory/llsettingsbase.cpp | 13 | ||||
-rw-r--r-- | indra/llinventory/llsettingsbase.h | 22 | ||||
-rw-r--r-- | indra/llinventory/llsettingsdaycycle.h | 2 | ||||
-rw-r--r-- | indra/llinventory/llsettingssky.h | 2 | ||||
-rw-r--r-- | indra/llinventory/llsettingswater.h | 2 | ||||
-rw-r--r-- | indra/newview/llagent.cpp | 14 | ||||
-rw-r--r-- | indra/newview/llagent.h | 10 | ||||
-rw-r--r-- | indra/newview/llenvironment.cpp | 126 | ||||
-rw-r--r-- | indra/newview/llenvironment.h | 9 |
9 files changed, 168 insertions, 32 deletions
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index f870ec8904..411eaff8e3 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -547,8 +547,11 @@ F64 LLSettingsBlender::setPosition(F64 blendf) } blendf = llclamp(blendf, 0.0, 1.0); - //_WARNS("LAPRAS") << "blending at " << (blendf * 100.0f) << "%" << LL_ENDL; mTarget->replaceSettings(mInitial->getSettings()); + if (mIsTrivial || (blendf == 0.0)) + { // this is a trivial blend. Results will be identical to the initial. + return blendf; + } mTarget->blend(mFinal, blendf); return blendf; @@ -562,6 +565,11 @@ void LLSettingsBlender::triggerComplete() } //------------------------------------------------------------------------- +F64 LLSettingsBlenderTimeDelta::calculateBlend(F64 spanpos, F64 spanlen) const +{ + return fmod(spanpos, spanlen) / spanlen; +} + void LLSettingsBlenderTimeDelta::update(F64 timedelta) { mTimeSpent += F64Seconds(timedelta); @@ -572,8 +580,7 @@ void LLSettingsBlenderTimeDelta::update(F64 timedelta) return; } - F64 blendf = fmod(mTimeSpent.value(), mBlendSpan.value()) / mBlendSpan.value(); - + F64 blendf = calculateBlend(mTimeSpent.value(), mBlendSpan.value()); // Note no clamp here. setPosition(blendf); diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index d00e340b4b..71358d6a49 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -166,6 +166,8 @@ public: virtual bool validate(); + virtual ptr_t buildDerivedClone() = 0; + class Validator { public: @@ -269,10 +271,15 @@ public: mOnFinished(), mTarget(target), mInitial(initsetting), - mFinal(endsetting) + mFinal(endsetting), + mIsTrivial(false) { if (mInitial) mTarget->replaceSettings(mInitial->getSettings()); + + if (!mFinal) + mFinal = mInitial; + mIsTrivial = (mFinal == mInitial); } virtual ~LLSettingsBlender() {} @@ -280,8 +287,16 @@ public: virtual void reset( LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64 /*span*/ = 1.0) { // note: the 'span' reset parameter is unused by the base class. + if (!mInitial) + LL_WARNS("BLENDER") << "Reseting blender with empty initial setting. Expect badness in the future." << LL_ENDL; + mInitial = initsetting; mFinal = endsetting; + + if (!mFinal) + mFinal = mInitial; + mIsTrivial = (mFinal == mInitial); + mTarget->replaceSettings(mInitial->getSettings()); } @@ -308,6 +323,8 @@ public: virtual void update(F64 blendf); virtual F64 setPosition(F64 blendf); + virtual void switchTrack(S32 trackno, F64 position = -1.0) { /*NoOp*/ } + protected: void triggerComplete(); @@ -316,6 +333,7 @@ protected: LLSettingsBase::ptr_t mTarget; LLSettingsBase::ptr_t mInitial; LLSettingsBase::ptr_t mFinal; + bool mIsTrivial; }; class LLSettingsBlenderTimeDelta : public LLSettingsBlender @@ -349,6 +367,8 @@ public: virtual void update(F64 timedelta) override; protected: + F64 calculateBlend(F64 spanpos, F64 spanlen) const; + F64Seconds mBlendSpan; F64Seconds mLastUpdate; F64Seconds mTimeSpent; diff --git a/indra/llinventory/llsettingsdaycycle.h b/indra/llinventory/llsettingsdaycycle.h index 9a89031aed..336a00f386 100644 --- a/indra/llinventory/llsettingsdaycycle.h +++ b/indra/llinventory/llsettingsdaycycle.h @@ -114,6 +114,8 @@ public: virtual validation_list_t getValidationList() const override; static validation_list_t validationList(); + virtual LLSettingsBase::ptr_t buildDerivedClone() override { return buildClone(); } + protected: LLSettingsDay(); diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index 59a9dc9a43..9379cd37c3 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -479,6 +479,8 @@ public: return mNextCloudTextureId; } + virtual LLSettingsBase::ptr_t buildDerivedClone() override { return buildClone(); } + protected: static const std::string SETTING_LEGACY_EAST_ANGLE; static const std::string SETTING_LEGACY_ENABLE_CLOUD_SCROLL; diff --git a/indra/llinventory/llsettingswater.h b/indra/llinventory/llsettingswater.h index 64de4486ca..acae903e92 100644 --- a/indra/llinventory/llsettingswater.h +++ b/indra/llinventory/llsettingswater.h @@ -211,6 +211,8 @@ public: static LLSD translateLegacySettings(LLSD legacy); + virtual LLSettingsBase::ptr_t buildDerivedClone() override { return buildClone(); } + protected: static const std::string SETTING_LEGACY_BLUR_MULTIPILER; static const std::string SETTING_LEGACY_FOG_COLOR; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 80e5647ace..b413c21033 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -381,6 +381,7 @@ LLAgent::LLAgent() : mAgentOriginGlobal(), mPositionGlobal(), + mLastTestGlobal(), mDistanceTraveled(0.F), mLastPositionGlobal(LLVector3d::zero), @@ -1070,6 +1071,13 @@ void LLAgent::setPositionAgent(const LLVector3 &pos_agent) pos_agent_d.setVec(pos_agent); mPositionGlobal = pos_agent_d + mAgentOriginGlobal; } + + if (((mLastTestGlobal - mPositionGlobal).lengthSquared() > 1.0) && !mOnPositionChanged.empty()) + { // If the position has changed my more than 1 meter since the last time we triggered. + // filters out some noise. + mLastTestGlobal = mPositionGlobal; + mOnPositionChanged(mFrameAgent.getOrigin(), mPositionGlobal); + } } //----------------------------------------------------------------------------- @@ -1110,6 +1118,12 @@ const LLVector3 &LLAgent::getPositionAgent() return mFrameAgent.getOrigin(); } +boost::signals2::connection LLAgent::whenPositionChanged(position_signal_t::slot_type fn) +{ + return mOnPositionChanged.connect(fn); +} + + //----------------------------------------------------------------------------- // getRegionsVisited() //----------------------------------------------------------------------------- diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 4bb4d317e8..477ec88be4 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -189,6 +189,8 @@ private: // Position //-------------------------------------------------------------------- public: + typedef boost::signals2::signal<void(const LLVector3 &position_local, const LLVector3d &position_global)> position_signal_t; + LLVector3 getPosAgentFromGlobal(const LLVector3d &pos_global) const; LLVector3d getPosGlobalFromAgent(const LLVector3 &pos_agent) const; const LLVector3d &getPositionGlobal() const; @@ -196,10 +198,16 @@ public: // Call once per frame to update position, angles (radians). void updateAgentPosition(const F32 dt, const F32 yaw, const S32 mouse_x, const S32 mouse_y); void setPositionAgent(const LLVector3 ¢er); + + boost::signals2::connection whenPositionChanged(position_signal_t::slot_type fn); + protected: void propagate(const F32 dt); // ! BUG ! Should roll into updateAgentPosition private: - mutable LLVector3d mPositionGlobal; + mutable LLVector3d mPositionGlobal; + + position_signal_t mOnPositionChanged; + LLVector3d mLastTestGlobal; //-------------------------------------------------------------------- // Velocity diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 9bc3f65c79..11347917c3 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -124,7 +124,7 @@ namespace LLTrackBlenderLoopingTime(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno, F64Seconds cyclelength, F64Seconds cycleoffset) : LLSettingsBlenderTimeDelta(target, LLSettingsBase::ptr_t(), LLSettingsBase::ptr_t(), F64Seconds(1.0)), mDay(day), - mTrackNo(trackno), + mTrackNo(0), mCycleLength(cyclelength), mCycleOffset(cycleoffset) { @@ -134,10 +134,57 @@ namespace mFinal = (*initial.second).second; mBlendSpan = getSpanTime(initial); + mTrackNo = selectTrackNumber(trackno); + setOnFinished([this](const LLSettingsBlender::ptr_t &){ onFinishedSpan(); }); } + + void switchTrack(S32 trackno, F64) override + { + S32 use_trackno = selectTrackNumber(trackno); + + if (use_trackno == mTrackNo) + { // results in no change + return; + } + + mTrackTransitionStart = mTarget->buildDerivedClone(); + mTrackNo = use_trackno; + + F64Seconds now = getAdjustedNow() + LLEnvironment::TRANSITION_ALTITUDE; + LLSettingsDay::TrackBound_t bounds = getBoundingEntries(now); + + LLSettingsBase::ptr_t pendsetting = (*bounds.first).second->buildDerivedClone(); + F64 targetpos = convertTimeToPosition(now) - (*bounds.first).first; + F64 targetspan = get_wrapping_distance((*bounds.first).first, (*bounds.second).first); + + F64 blendf = calculateBlend(targetpos, targetspan); + pendsetting->blend((*bounds.second).second, blendf); + + reset(mTrackTransitionStart, pendsetting, LLEnvironment::TRANSITION_ALTITUDE.value()); + } + + protected: + S32 selectTrackNumber(S32 trackno) + { + if (trackno == 0) + { // We are dealing with the water track. There is only ever one. + return 0; + } + + for (S32 test = trackno; test == 0; --test) + { // Find the track below the requested one with data. + LLSettingsDay::CycleTrack_t &track = mDay->getCycleTrack(mTrackNo); + + if (!track.empty()) + return test; + } + + return 1; + } + LLSettingsDay::TrackBound_t getBoundingEntries(F64Seconds time) { LLSettingsDay::CycleTrack_t &wtrack = mDay->getCycleTrack(mTrackNo); @@ -170,6 +217,7 @@ namespace S32 mTrackNo; F64Seconds mCycleLength; F64Seconds mCycleOffset; + LLSettingsBase::ptr_t mTrackTransitionStart; void onFinishedSpan() { @@ -186,6 +234,7 @@ const F32Seconds LLEnvironment::TRANSITION_INSTANT(0.0f); const F32Seconds LLEnvironment::TRANSITION_FAST(1.0f); const F32Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f); const F32Seconds LLEnvironment::TRANSITION_SLOW(10.0f); +const F32Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f); const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg const F32 LLEnvironment::NIGHTTIME_ELEVATION_COS(LLSky::NIGHTTIME_ELEVATION_COS); @@ -202,7 +251,8 @@ LLEnvironment::LLEnvironment(): mDayCycleByName(), mDayCycleById(), mUserPrefs(), - mSelectedEnvironment(LLEnvironment::ENV_LOCAL) + mSelectedEnvironment(LLEnvironment::ENV_LOCAL), + mCurrentTrack(1) { } @@ -228,11 +278,13 @@ void LLEnvironment::initSingleton() requestRegionEnvironment(); - LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLEnvironment::onParcelChange, this)); - gAgent.addParcelChangedCallback(boost::bind(&LLEnvironment::onParcelChange, this)); + LLRegionInfoModel::instance().setUpdateCallback([this]() { onParcelChange(); }); + gAgent.addParcelChangedCallback([this]() { onParcelChange(); }); //TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer. - gAgent.addRegionChangedCallback(boost::bind(&LLEnvironment::requestRegionEnvironment, this)); + gAgent.addRegionChangedCallback([this]() { requestRegionEnvironment(); }); + + gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); }); } LLEnvironment::~LLEnvironment() @@ -374,6 +426,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe environment->clear(); environment->setDay(pday, daylength, dayoffset); + environment->setSkyTrack(mCurrentTrack); environment->animate(); /*TODO: readjust environment*/ } @@ -1435,6 +1488,29 @@ void LLEnvironment::legacyLoadAllPresets() } } +void LLEnvironment::onAgentPositionHasChanged(const LLVector3 &localpos) +{ + S32 trackno = calculateSkyTrackForAltitude(localpos.mV[VZ]); + if (trackno == mCurrentTrack) + return; + + LL_WARNS("LAPRAS") << "Wants to switch to track #" << trackno << LL_ENDL; + + mCurrentTrack = trackno; + for (S32 env = ENV_LOCAL; env < ENV_DEFAULT; ++env) + { + if (mEnvironments[env]) + mEnvironments[env]->setSkyTrack(mCurrentTrack); + } +} + +S32 LLEnvironment::calculateSkyTrackForAltitude(F64 altitude) +{ + //*LAPRAS* temp base on region's response. + return llmin((static_cast<S32>(altitude) / 100) + 1, (LLSettingsDay::TRACK_MAX - 1)); +} + + //========================================================================= LLEnvironment::DayInstance::DayInstance() : mDayCycle(), @@ -1533,13 +1609,11 @@ void LLEnvironment::DayInstance::clear() void LLEnvironment::DayInstance::setSkyTrack(S32 trackno) { - /*TODO*/ -// if (trackno != mSkyTrack) -// { -// mSkyTrack = trackno; -// -// // *TODO*: Pick the sky track based on the skytrack. -// } + mSkyTrack = trackno; + if (mBlenderSky) + { + mBlenderSky->switchTrack(trackno); + } } @@ -1572,35 +1646,35 @@ void LLEnvironment::DayInstance::animate() mWater.reset(); mBlenderWater.reset(); } - else if (wtrack.size() == 1) - { - mWater = std::static_pointer_cast<LLSettingsWater>((*(wtrack.begin())).second); - mBlenderWater.reset(); - } +// else if (wtrack.size() == 1) +// { +// mWater = std::static_pointer_cast<LLSettingsWater>((*(wtrack.begin())).second); +// mBlenderWater.reset(); +// } else { mWater = LLSettingsVOWater::buildDefaultWater(); mBlenderWater = std::make_shared<LLTrackBlenderLoopingTime>(mWater, mDayCycle, 0, mDayLength, mDayOffset); } - // Day track 1 only for the moment - // sky - LLSettingsDay::CycleTrack_t &track = mDayCycle->getCycleTrack(mSkyTrack); + // sky, initalize to track 1 + LLSettingsDay::CycleTrack_t &track = mDayCycle->getCycleTrack(1); if (track.empty()) { mSky.reset(); mBlenderSky.reset(); } - else if (track.size() == 1) - { - mSky = std::static_pointer_cast<LLSettingsSky>((*(track.begin())).second); - mBlenderSky.reset(); - } +// else if (track.size() == 1) +// { +// mSky = std::static_pointer_cast<LLSettingsSky>((*(track.begin())).second); +// mBlenderSky.reset(); +// } else { mSky = LLSettingsVOSky::buildDefaultSky(); - mBlenderSky = std::make_shared<LLTrackBlenderLoopingTime>(mSky, mDayCycle, mSkyTrack, mDayLength, mDayOffset); + mBlenderSky = std::make_shared<LLTrackBlenderLoopingTime>(mSky, mDayCycle, 1, mDayLength, mDayOffset); + mBlenderSky->switchTrack(mSkyTrack); } } diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index e8e5a74196..cdfac34d90 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -53,6 +53,7 @@ public: static const F32Seconds TRANSITION_FAST; static const F32Seconds TRANSITION_DEFAULT; static const F32Seconds TRANSITION_SLOW; + static const F32Seconds TRANSITION_ALTITUDE; struct EnvironmentInfo { @@ -214,6 +215,8 @@ public: void selectAgentEnvironment(); + S32 calculateSkyTrackForAltitude(F64 altitude); + protected: virtual void initSingleton(); @@ -267,6 +270,7 @@ private: S64Seconds mDayLength; S64Seconds mDayOffset; + S32 mLastTrackAltitude; LLSettingsBlender::ptr_t mBlenderSky; LLSettingsBlender::ptr_t mBlenderWater; @@ -333,6 +337,8 @@ private: change_signal_t mWaterListChange; change_signal_t mDayCycleListChange; + S32 mCurrentTrack; + DayInstance::ptr_t getEnvironmentInstance(EnvSelection_t env, bool create = false); DayInstance::ptr_t getSelectedEnvironmentInstance(); @@ -364,6 +370,7 @@ private: void recordEnvironment(S32 parcel_id, EnvironmentInfo::ptr_t environment); + void onAgentPositionHasChanged(const LLVector3 &localpos); //========================================================================= void legacyLoadAllPresets(); static LLSD legacyLoadPreset(const std::string& path); @@ -378,7 +385,7 @@ public: LLTrackBlenderLoopingManual(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno); F64 setPosition(F64 position) override; - void switchTrack(S32 trackno, F64 position = -1.0); + virtual void switchTrack(S32 trackno, F64 position) override; S32 getTrack() const { return mTrackNo; } typedef std::shared_ptr<LLTrackBlenderLoopingManual> ptr_t; |