diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 6d2e1f5b78..e297fbd94e 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -32,8 +32,6 @@ #include "llsdserialize.h" -#pragma optimize("", off) - //========================================================================= namespace { @@ -54,8 +52,6 @@ const std::string LLSettingsBase::SETTING_NAME("name"); const std::string LLSettingsBase::SETTING_HASH("hash"); const std::string LLSettingsBase::SETTING_TYPE("type"); -const F64Seconds LLSettingsBlender::DEFAULT_THRESHOLD(0.01); - //========================================================================= LLSettingsBase::LLSettingsBase(): mSettings(LLSD::emptyMap()), @@ -541,21 +537,48 @@ bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range) } //========================================================================= -void LLSettingsBlender::update(F64Seconds timedelta) +void LLSettingsBlender::update(F64 blendf) { - mTimeSpent += timedelta; - if (mTimeSpent >= mSeconds) +} + +F64 LLSettingsBlender::setPosition(F64 blendf) +{ + if (blendf >= 1.0) { - LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon - mOnFinished(shared_from_this()); - return; + triggerComplete(); + return 1.0; } - - F64 blendf = fmod(mTimeSpent.value(), mSeconds.value()) / mSeconds.value(); + blendf = llclamp(blendf, 0.0, 1.0); //_WARNS("LAPRAS") << "blending at " << (blendf * 100.0f) << "%" << LL_ENDL; mTarget->replaceSettings(mInitial->getSettings()); mTarget->blend(mFinal, blendf); + + return blendf; } +void LLSettingsBlender::triggerComplete() +{ + mTarget->replaceSettings(mFinal->getSettings()); + LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon + mOnFinished(shared_from_this()); +} + +//------------------------------------------------------------------------- +void LLSettingsBlenderTimeDelta::update(F64 timedelta) +{ + mTimeSpent += F64Seconds(timedelta); + + if (mTimeSpent > mBlendSpan) + { + triggerComplete(); + return; + } + + F64 blendf = fmod(mTimeSpent.value(), mBlendSpan.value()) / mBlendSpan.value(); + + // Note no clamp here. + + setPosition(blendf); +} diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index 06c1e6231e..aebb3ddc5a 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -266,39 +266,24 @@ public: typedef boost::signals2::signal finish_signal_t; typedef boost::signals2::connection connection_t; - static const F64Seconds DEFAULT_THRESHOLD; - LLSettingsBlender(const LLSettingsBase::ptr_t &target, - const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64Seconds seconds) : + const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64 span = 1.0) : + mOnFinished(), mTarget(target), mInitial(initsetting), - mFinal(endsetting), - mSeconds(seconds), - mOnFinished(), - mLastUpdate(0.0f), - mTimeSpent(0.0f) + mFinal(endsetting) { + if (mInitial) mTarget->replaceSettings(mInitial->getSettings()); - mTimeStart = F64Seconds(LLDate::now().secondsSinceEpoch()); - mLastUpdate = mTimeStart; } - ~LLSettingsBlender() {} + virtual ~LLSettingsBlender() {} - void reset( LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64Seconds seconds ) + virtual void reset( LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64 span = 1.0) { mInitial = initsetting; mFinal = endsetting; - mSeconds = seconds; mTarget->replaceSettings(mInitial->getSettings()); - mTimeStart.value(LLDate::now().secondsSinceEpoch()); - mLastUpdate = mTimeStart; - mTimeSpent.value(0.0f); - } - - connection_t setOnFinished(const finish_signal_t::slot_type &onfinished) - { - return mOnFinished.connect(onfinished); } LLSettingsBase::ptr_t getTarget() const @@ -316,17 +301,60 @@ public: return mFinal; } - void update(F64Seconds time); + connection_t setOnFinished(const finish_signal_t::slot_type &onfinished) + { + return mOnFinished.connect(onfinished); + } + + virtual void update(F64 blendf); + virtual F64 setPosition(F64 blendf); + +protected: + void triggerComplete(); + + finish_signal_t mOnFinished; -private: LLSettingsBase::ptr_t mTarget; LLSettingsBase::ptr_t mInitial; LLSettingsBase::ptr_t mFinal; - F64Seconds mSeconds; - finish_signal_t mOnFinished; +}; + +class LLSettingsBlenderTimeDelta : public LLSettingsBlender +{ +public: + LLSettingsBlenderTimeDelta(const LLSettingsBase::ptr_t &target, + const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64Seconds seconds) : + LLSettingsBlender(target, initsetting, endsetting, seconds.value()), + mBlendSpan(seconds), + mLastUpdate(0.0f), + mTimeSpent(0.0f) + { + mTimeStart = F64Seconds(LLDate::now().secondsSinceEpoch()); + mLastUpdate = mTimeStart; + } + + virtual ~LLSettingsBlenderTimeDelta() + { + } + + virtual void reset(LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64 span = 1.0) override + { + LLSettingsBlender::reset(initsetting, endsetting, span); + + mBlendSpan.value(span); + mTimeStart.value(LLDate::now().secondsSinceEpoch()); + mLastUpdate = mTimeStart; + mTimeSpent.value(0.0f); + } + + virtual void update(F64 timedelta) override; + +protected: + F64Seconds mBlendSpan; F64Seconds mLastUpdate; F64Seconds mTimeSpent; F64Seconds mTimeStart; }; + #endif diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp index 3f60430715..5a6280884d 100644 --- a/indra/llinventory/llsettingsdaycycle.cpp +++ b/indra/llinventory/llsettingsdaycycle.cpp @@ -502,6 +502,53 @@ LLSettingsDay::KeyframeList_t LLSettingsDay::getTrackKeyframes(S32 trackno) return keyframes; } +bool LLSettingsDay::moveTrackKeyframe(S32 trackno, F32 old_frame, F32 new_frame) +{ + if ((trackno < 0) || (trackno >= TRACK_MAX)) + { + LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL; + return false; + } + + if (old_frame == new_frame) + { + return false; + } + + CycleTrack_t &track = mDayTracks[trackno]; + CycleTrack_t::iterator iter = track.find(old_frame); + if (iter != track.end()) + { + LLSettingsBase::ptr_t base = iter->second; + track.erase(iter); + track[llclamp(new_frame, 0.0f, 1.0f)] = base; + return true; + } + + return false; + +} + +bool LLSettingsDay::removeTrackKeyframe(S32 trackno, F32 frame) +{ + if ((trackno < 0) || (trackno >= TRACK_MAX)) + { + LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL; + return false; + } + + CycleTrack_t &track = mDayTracks[trackno]; + CycleTrack_t::iterator iter = track.find(frame); + if (iter != track.end()) + { + LLSettingsBase::ptr_t base = iter->second; + track.erase(iter); + return true; + } + + return false; +} + void LLSettingsDay::setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, F32 keyframe) { mDayTracks[TRACK_WATER][llclamp(keyframe, 0.0f, 1.0f)] = water; diff --git a/indra/llinventory/llsettingsdaycycle.h b/indra/llinventory/llsettingsdaycycle.h index 93c275bfb8..15a5b29f9f 100644 --- a/indra/llinventory/llsettingsdaycycle.h +++ b/indra/llinventory/llsettingsdaycycle.h @@ -60,7 +60,7 @@ public: typedef std::map CycleTrack_t; typedef std::vector CycleList_t; - typedef std::shared_ptr ptr_t; + typedef std::shared_ptr ptr_t; typedef std::vector KeyframeList_t; typedef std::pair TrackBound_t; @@ -86,6 +86,8 @@ public: //--------------------------------------------------------------------- KeyframeList_t getTrackKeyframes(S32 track); + bool moveTrackKeyframe(S32 track, F32 old_frame, F32 new_frame); + bool removeTrackKeyframe(S32 track, F32 frame); void setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, F32 keyframe); const LLSettingsWaterPtr_t getWaterAtKeyframe(F32 keyframe); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 90fc3854c4..d878bd9abe 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -62,6 +62,125 @@ namespace { LLTrace::BlockTimerStatHandle FTM_ENVIRONMENT_UPDATE("Update Environment Tick"); LLTrace::BlockTimerStatHandle FTM_SHADER_PARAM_UPDATE("Update Shader Parameters"); + + //--------------------------------------------------------------------- + inline F32 get_wrapping_distance(F32 begin, F32 end) + { + if (begin < end) + { + return end - begin; + } + else if (begin > end) + { + return 1.0 - (begin - end); + } + + return 0; + } + + LLSettingsDay::CycleTrack_t::iterator get_wrapping_atafter(LLSettingsDay::CycleTrack_t &collection, F32 key) + { + if (collection.empty()) + return collection.end(); + + LLSettingsDay::CycleTrack_t::iterator it = collection.upper_bound(key); + + if (it == collection.end()) + { // wrap around + it = collection.begin(); + } + + return it; + } + + LLSettingsDay::CycleTrack_t::iterator get_wrapping_atbefore(LLSettingsDay::CycleTrack_t &collection, F32 key) + { + if (collection.empty()) + return collection.end(); + + LLSettingsDay::CycleTrack_t::iterator it = collection.lower_bound(key); + + if (it == collection.end()) + { // all keyframes are lower, take the last one. + --it; // we know the range is not empty + } + else if ((*it).first > key) + { // the keyframe we are interested in is smaller than the found. + if (it == collection.begin()) + it = collection.end(); + --it; + } + + return it; + } + + LLSettingsDay::TrackBound_t get_bounding_entries(LLSettingsDay::CycleTrack_t &track, F32 keyframe) + { + return LLSettingsDay::TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe)); + } + + //--------------------------------------------------------------------- + class LLTrackBlenderLoopingTime : public LLSettingsBlenderTimeDelta + { + public: + 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), + mCycleLength(cyclelength), + mCycleOffset(cycleoffset) + { + LLSettingsDay::TrackBound_t initial = getBoundingEntries(getAdjustedNow()); + + mInitial = (*initial.first).second; + mFinal = (*initial.second).second; + mBlendSpan = getSpanTime(initial); + + setOnFinished([this](const LLSettingsBlender::ptr_t &){ onFinishedSpan(); }); + } + + protected: + LLSettingsDay::TrackBound_t getBoundingEntries(F64Seconds time) + { + LLSettingsDay::CycleTrack_t &wtrack = mDay->getCycleTrack(mTrackNo); + F64 position = convertTimeToPosition(time); + + LLSettingsDay::TrackBound_t bounds = get_bounding_entries(wtrack, position); + return bounds; + } + + F64Seconds getAdjustedNow() const + { + F64Seconds now(LLDate::now().secondsSinceEpoch()); + + return (now + mCycleOffset); + } + + F64Seconds getSpanTime(const LLSettingsDay::TrackBound_t &bounds) const + { + return mCycleLength * get_wrapping_distance((*bounds.first).first, (*bounds.second).first); + } + + F64 convertTimeToPosition(F64Seconds time) + { + F64 position = static_cast(fmod(time.value(), mCycleLength.value())) / static_cast(mCycleLength.value()); + return llclamp(position, 0.0, 1.0); + } + + private: + LLSettingsDay::ptr_t mDay; + S32 mTrackNo; + F64Seconds mCycleLength; + F64Seconds mCycleOffset; + + void onFinishedSpan() + { + LLSettingsDay::TrackBound_t next = getBoundingEntries(getAdjustedNow()); + F64Seconds nextspan = getSpanTime(next); + reset((*next.first).second, (*next.second).second, nextspan.value()); + } + }; + } //========================================================================= @@ -198,6 +317,7 @@ bool LLEnvironment::isInventoryEnabled() const !gAgent.getRegionCapability("UpdateSettingsTaskInventory").empty()); } + LLEnvironment::connection_t LLEnvironment::setSkyListChange(const LLEnvironment::change_signal_t::slot_type& cb) { return mSkyListChange.connect(cb); @@ -494,12 +614,6 @@ void LLEnvironment::updateEnvironment(F64Seconds transition, bool forced) } } -void LLEnvironment::onTransitionDone(const LLSettingsBlender::ptr_t blender, bool isSky) -{ - /*TODO: Test for both sky and water*/ - mCurrentEnvironment->animate(); -} - //------------------------------------------------------------------------- void LLEnvironment::update(const LLViewerCamera * cam) { @@ -1364,67 +1478,6 @@ void LLEnvironment::legacyLoadAllPresets() } //========================================================================= -namespace -{ - inline F32 get_wrapping_distance(F32 begin, F32 end) - { - if (begin < end) - { - return end - begin; - } - else if (begin > end) - { - return 1.0 - (begin - end); - } - - return 0; - } - - LLSettingsDay::CycleTrack_t::iterator get_wrapping_atafter(LLSettingsDay::CycleTrack_t &collection, F32 key) - { - if (collection.empty()) - return collection.end(); - - LLSettingsDay::CycleTrack_t::iterator it = collection.upper_bound(key); - - if (it == collection.end()) - { // wrap around - it = collection.begin(); - } - - return it; - } - - LLSettingsDay::CycleTrack_t::iterator get_wrapping_atbefore(LLSettingsDay::CycleTrack_t &collection, F32 key) - { - if (collection.empty()) - return collection.end(); - - LLSettingsDay::CycleTrack_t::iterator it = collection.lower_bound(key); - - if (it == collection.end()) - { // all keyframes are lower, take the last one. - --it; // we know the range is not empty - } - else if ((*it).first > key) - { // the keyframe we are interested in is smaller than the found. - if (it == collection.begin()) - it = collection.end(); - --it; - } - - return it; - } - - LLSettingsDay::TrackBound_t get_bounding_entries(LLSettingsDay::CycleTrack_t &track, F32 keyframe) - { - return LLSettingsDay::TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe)); - } - -} -//========================================================================= - - LLEnvironment::DayInstance::DayInstance() : mDayCycle(), mSky(), @@ -1434,7 +1487,8 @@ LLEnvironment::DayInstance::DayInstance() : mBlenderSky(), mBlenderWater(), mInitialized(false), - mType(TYPE_INVALID) + mType(TYPE_INVALID), + mSkyTrack(1) { } void LLEnvironment::DayInstance::update(F64Seconds delta) @@ -1443,9 +1497,9 @@ void LLEnvironment::DayInstance::update(F64Seconds delta) initialize(); if (mBlenderSky) - mBlenderSky->update(delta); + mBlenderSky->update(delta.value()); if (mBlenderWater) - mBlenderWater->update(delta); + mBlenderWater->update(delta.value()); // if (mSky) // mSky->update(); @@ -1523,8 +1577,21 @@ void LLEnvironment::DayInstance::clear() mDayOffset = LLSettingsDay::DEFAULT_DAYOFFSET; mBlenderSky.reset(); mBlenderWater.reset(); + mSkyTrack = 1; } +void LLEnvironment::DayInstance::setSkyTrack(S32 trackno) +{ + /*TODO*/ +// if (trackno != mSkyTrack) +// { +// mSkyTrack = trackno; +// +// // *TODO*: Pick the sky track based on the skytrack. +// } +} + + void LLEnvironment::DayInstance::setBlenders(const LLSettingsBlender::ptr_t &skyblend, const LLSettingsBlender::ptr_t &waterblend) { mBlenderSky = skyblend; @@ -1561,21 +1628,13 @@ void LLEnvironment::DayInstance::animate() } else { - LLSettingsDay::TrackBound_t bounds = get_bounding_entries(wtrack, secondsToKeyframe(now)); - F64Seconds timespan = mDayLength * get_wrapping_distance((*bounds.first).first, (*bounds.second).first); - - mWater = std::static_pointer_cast((*bounds.first).second)->buildClone(); - mBlenderWater = std::make_shared(mWater, - (*bounds.first).second, (*bounds.second).second, timespan); - mBlenderWater->setOnFinished( - [this](LLSettingsBlender::ptr_t blender) { onTrackTransitionDone(0, blender); }); - - + mWater = LLSettingsVOWater::buildDefaultWater(); + mBlenderWater = std::make_shared(mWater, mDayCycle, 0, mDayLength, mDayOffset); } // Day track 1 only for the moment // sky - LLSettingsDay::CycleTrack_t &track = mDayCycle->getCycleTrack(1); + LLSettingsDay::CycleTrack_t &track = mDayCycle->getCycleTrack(mSkyTrack); if (track.empty()) { @@ -1589,38 +1648,11 @@ void LLEnvironment::DayInstance::animate() } else { - LLSettingsDay::TrackBound_t bounds = get_bounding_entries(track, secondsToKeyframe(now)); - F64Seconds timespan = mDayLength * get_wrapping_distance((*bounds.first).first, (*bounds.second).first); - - mSky = std::static_pointer_cast((*bounds.first).second)->buildClone(); - mBlenderSky = std::make_shared(mSky, - (*bounds.first).second, (*bounds.second).second, timespan); - mBlenderSky->setOnFinished( - [this](LLSettingsBlender::ptr_t blender) { onTrackTransitionDone(1, blender); }); + mSky = LLSettingsVOSky::buildDefaultSky(); + mBlenderSky = std::make_shared(mSky, mDayCycle, mSkyTrack, mDayLength, mDayOffset); } } -void LLEnvironment::DayInstance::onTrackTransitionDone(S32 trackno, const LLSettingsBlender::ptr_t blender) -{ - LL_WARNS("LAPRAS") << "onTrackTransitionDone for " << trackno << LL_ENDL; - F64Seconds now(LLDate::now().secondsSinceEpoch()); - - now += mDayOffset; - - LLSettingsDay::CycleTrack_t &track = mDayCycle->getCycleTrack(trackno); - - LLSettingsDay::TrackBound_t bounds = get_bounding_entries(track, secondsToKeyframe(now)); - - F32 distance = get_wrapping_distance((*bounds.first).first, (*bounds.second).first); - F64Seconds timespan = mDayLength * distance; - - LL_WARNS("LAPRAS") << "New sky blender. now=" << now << - " start=" << (*bounds.first).first << " end=" << (*bounds.second).first << - " span=" << timespan << LL_ENDL; - - blender->reset((*bounds.first).second, (*bounds.second).second, timespan); -} - //------------------------------------------------------------------------- LLEnvironment::DayTransition::DayTransition(const LLSettingsSky::ptr_t &skystart, const LLSettingsWater::ptr_t &waterstart, LLEnvironment::DayInstance::ptr_t &end, S64Seconds time) : @@ -1644,7 +1676,7 @@ void LLEnvironment::DayTransition::animate() mNextInstance->animate(); mWater = mStartWater->buildClone(); - mBlenderWater = std::make_shared(mWater, mStartWater, mNextInstance->getWater(), mTransitionTime); + mBlenderWater = std::make_shared(mWater, mStartWater, mNextInstance->getWater(), mTransitionTime); mBlenderWater->setOnFinished( [this](LLSettingsBlender::ptr_t blender) { mBlenderWater.reset(); @@ -1654,7 +1686,7 @@ void LLEnvironment::DayTransition::animate() }); mSky = mStartSky->buildClone(); - mBlenderSky = std::make_shared(mSky, mStartSky, mNextInstance->getSky(), mTransitionTime); + mBlenderSky = std::make_shared(mSky, mStartSky, mNextInstance->getSky(), mTransitionTime); mBlenderSky->setOnFinished( [this](LLSettingsBlender::ptr_t blender) { mBlenderSky.reset(); diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 417e6d35c1..30286d54fd 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -243,11 +243,14 @@ private: void clear(); + void setSkyTrack(S32 trackno); + LLSettingsDay::ptr_t getDayCycle() const { return mDayCycle; } LLSettingsSky::ptr_t getSky() const { return mSky; } LLSettingsWater::ptr_t getWater() const { return mWater; } S64Seconds getDayLength() const { return mDayLength; } S64Seconds getDayOffset() const { return mDayOffset; } + S32 getSkyTrack() const { return mSkyTrack; } virtual void animate(); @@ -257,6 +260,7 @@ private: LLSettingsDay::ptr_t mDayCycle; LLSettingsSky::ptr_t mSky; LLSettingsWater::ptr_t mWater; + S32 mSkyTrack; InstanceType_t mType; bool mInitialized; @@ -268,8 +272,6 @@ private: LLSettingsBlender::ptr_t mBlenderWater; F64 secondsToKeyframe(S64Seconds seconds); - - void onTrackTransitionDone(S32 trackno, const LLSettingsBlender::ptr_t blender); }; typedef std::array InstanceArray_t; @@ -362,7 +364,6 @@ private: void recordEnvironment(S32 parcel_id, EnvironmentInfo::ptr_t environment); - void onTransitionDone(const LLSettingsBlender::ptr_t, bool isSky); //========================================================================= void legacyLoadAllPresets(); static LLSD legacyLoadPreset(const std::string& path); diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index e41259feb3..c57add32fe 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -52,22 +52,24 @@ #include "lltrans.h" static const std::string track_tabs[] = { - "water_track", - "sky4_track", - "sky3_track", - "sky2_track", - "sky1_track", - }; + "water_track", + "sky1_track", + "sky2_track", + "sky3_track", + "sky4_track", +}; LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key): LLFloater(key), mSaveButton(NULL), mCancelButton(NULL), - mCurrentTrack(1) -// mDayCyclesCombo(NULL) -// , mTimeSlider(NULL) -// , mKeysSlider(NULL) + mDayLength(0), + mDayOffset(0), + mCurrentTrack(4), + mTimeSlider(NULL), + mFramesSlider(NULL), + mCurrentTimeLabel(NULL) // , mTimeCtrl(NULL) // , mMakeDefaultCheckBox(NULL) // , @@ -82,24 +84,24 @@ BOOL LLFloaterEditExtDayCycle::postBuild() getChild("delete_frame")->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onRemoveTrack, this)); getChild("day_cycle_name")->setKeystrokeCallback(boost::bind(&LLFloaterEditExtDayCycle::onCommitName, this, _1, _2), NULL); -// mDayCyclesCombo = getChild("day_cycle_preset_combo"); - -// mTimeSlider = getChild("WLTimeSlider"); -// mKeysSlider = getChild("WLDayCycleKeys"); -// mTimeCtrl = getChild("time"); mSaveButton = getChild("save_btn", true); mCancelButton = getChild("cancel_btn", true); mUploadButton = getChild("upload_btn", true); - mKeysSlider = getChild("WLDayCycleKeys"); - mSkyTabContainer = getChild("frame_settings_sky", true); - mWaterTabContainer = getChild("frame_settings_water", true); -// mMakeDefaultCheckBox = getChild("make_default_cb"); + mTimeSlider = getChild("WLTimeSlider"); + mFramesSlider = getChild("WLDayCycleFrames"); + mSkyTabLayoutContainer = getChild("frame_settings_sky", true); + mWaterTabLayoutContainer = getChild("frame_settings_water", true); + mCurrentTimeLabel = getChild("current_time", true); //initCallbacks(); mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onBtnSave, this)); mCancelButton->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onBtnCancel, this)); mUploadButton->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onUpload, this)); + mTimeSlider->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onTimeSliderMoved, this)); + mFramesSlider->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onFrameSliderCallback, this)); + + mTimeSlider->addSlider(0); getChild("sky4_track", true)->setToggleState(true); @@ -115,8 +117,14 @@ void LLFloaterEditExtDayCycle::onOpen(const LLSD& key) { // TODO/TEMP - LLSettingsDay::ptr_t pday = LLEnvironment::instance().getEnvironmentDay(LLEnvironment::ENV_REGION); + LLEnvironment::EnvSelection_t env = LLEnvironment::ENV_REGION; // should not be used + LLSettingsDay::ptr_t pday = LLEnvironment::instance().getEnvironmentDay(env); mEditDay = pday->buildClone(); // pday should be passed as parameter + + S64Seconds daylength = LLEnvironment::instance().getEnvironmentDayLength(env); + S64Seconds dayoffset = LLEnvironment::instance().getEnvironmentDayOffset(env); + mDayLength = daylength; // should be passed as parameter + mDayOffset = dayoffset; // should be passed as parameter } LLLineEditor* name_field = getChild("day_cycle_name"); @@ -124,35 +132,34 @@ void LLFloaterEditExtDayCycle::onOpen(const LLSD& key) selectTrack(mCurrentTrack); - /* TODO - if (mEditDay->hasSetting("cycle length")) // todo: figure out name + // time labels + mCurrentTimeLabel->setTextArg("[PRCNT]", std::string("0")); + const S32 max_elm = 5; + if (mDayLength.value() != 0) { - // extract setting - S32 extracted_time = - std::string time = LLTrans::getString("time_label", LLSD("TIME",(extracted_time * 0..100%) + offset)); - std::string descr = LLTrans::getString("0_label", LLSD("DSC",time)); - getChild("p0")->setLabel(descr); - ... - - getChild("p1")->setLabel(descr); - time = - descr = - getChild("p2")->setLabel(descr); - time = - descr = - getChild("p3")->setLabel(descr); - time = - descr = - getChild("p4")->setLabel(descr); + F32Hours hrs; + LLUIString formatted_label = getString("time_label"); + for (int i = 0; i < max_elm; i++) + { + // Todo: if possible, find a better way, both to get string and child names + hrs = ((mDayLength / (max_elm - 1)) * i) + mDayOffset; + formatted_label.setArg("[TIME]", llformat("%.1f", hrs.value())); + getChild("p" + llformat("%d", i), true)->setTextArg("[DSC]", formatted_label.getString()); + } + hrs = mDayOffset; + formatted_label.setArg("[TIME]", llformat("%.1f", hrs.value())); + mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString()); } else { - std::string descr = LLTrans::getString("0_label", LLSD()); - getChild("p0")->setLabel(descr); - + for (int i = 0; i < max_elm; i++) + { + getChild("p" + llformat("%d", i), true)->setTextArg("[DSC]", std::string()); + } + mCurrentTimeLabel->setTextArg("[DSC]", std::string()); } - */ + //todo: add time slider setting /*list_name_id_t getSkyList() const; list_name_id_t getWaterList() const; @@ -257,21 +264,33 @@ void LLFloaterEditExtDayCycle::onBtnCancel() void LLFloaterEditExtDayCycle::onAddTrack() { - F32 frame = 0; // temp? - mKeysSlider->addSlider(frame); + F32 frame = mTimeSlider->getCurSliderValue(); + LLSettingsBase::ptr_t setting; + // todo: expand to generate from panels instead of using defaults + if (mEditDay->getSettingsAtKeyframe(frame, mCurrentTrack).get() != NULL) //temp check? todo: disable button in such cases + { + return; + } if (mCurrentTrack == 0) { - mEditDay->setWaterAtKeyframe(LLSettingsVOWater::buildDefaultWater(), frame); + setting = LLSettingsVOWater::buildDefaultWater(); + mEditDay->setWaterAtKeyframe(std::dynamic_pointer_cast(setting), frame); } else { - mEditDay->setSkyAtKeyframe(LLSettingsVOSky::buildDefaultSky(), frame, mCurrentTrack); + setting = LLSettingsVOSky::buildDefaultSky(); + mEditDay->setSkyAtKeyframe(std::dynamic_pointer_cast(setting), frame, mCurrentTrack); } + addSliderFrame(frame, setting); + updateTabs(); } void LLFloaterEditExtDayCycle::onRemoveTrack() { - //mKeysSlider->deleteCurSlider(); + F32 frame = mTimeSlider->getCurSliderValue(); + mEditDay->removeTrackKeyframe(mCurrentTrack, frame); + removeCurrentSliderFrame(); + //mFramesSlider->deleteCurSlider(); } void LLFloaterEditExtDayCycle::onCommitName(class LLLineEditor* caller, void* user_data) @@ -285,8 +304,68 @@ void LLFloaterEditExtDayCycle::onTrackSelectionCallback(const LLSD& user_data) selectTrack(track_index); } +void LLFloaterEditExtDayCycle::onFrameSliderCallback() +{ + if (mFramesSlider->getValue().size() == 0) + { + mLastFrameSlider.clear(); + return; + } + // make sure we have a slider + const std::string& cur_sldr = mFramesSlider->getCurSlider(); + if (cur_sldr == "") + { + mLastFrameSlider.clear(); + return; + } + + F32 new_frame = mFramesSlider->getCurSliderValue(); + // todo: add safety checks, user shouldn't be capable of moving one frame over another or move missing frame + keymap_t::iterator iter = mSliderKeyMap.find(cur_sldr); + if (iter != mSliderKeyMap.end() && /*temp? until disabling mechanics*/ mEditDay->getSettingsAtKeyframe(new_frame, mCurrentTrack).get() == NULL) + { + LL_DEBUGS() << "Moving frame from " << iter->second.first << " to " << new_frame << LL_ENDL; + if (mEditDay->moveTrackKeyframe(mCurrentTrack, iter->second.first, new_frame)) + { + iter->second.first = new_frame; + } + } + + if (mLastFrameSlider != cur_sldr) + { + // technically should not be possible for both frame and slider to change + // but for safety, assume that they can change independently and both + mLastFrameSlider = cur_sldr; + updateTabs(); + } + // updateTrack(); + // reset last known position +} + +void LLFloaterEditExtDayCycle::onTimeSliderMoved() +{ + // Todo: safety checks + // Update label + F32 time = mTimeSlider->getCurSliderValue(); + mCurrentTimeLabel->setTextArg("[PRCNT]", llformat("%.0f", time * 100)); + if (mDayLength.value() != 0) + { + F32Hours hrs = (mDayLength * time) + mDayOffset; + LLUIString formatted_label = getString("time_label"); + formatted_label.setArg("[TIME]", llformat("%.1f", hrs.value())); + mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString()); + } + else + { + mCurrentTimeLabel->setTextArg("[DSC]", std::string()); + } + + //Todo: update something related to time/play? +} + void LLFloaterEditExtDayCycle::selectTrack(U32 track_index) { + // todo: safety checks mCurrentTrack = track_index; LLButton* button = getChild(track_tabs[track_index], true); if (button->getToggleState()) @@ -294,24 +373,22 @@ void LLFloaterEditExtDayCycle::selectTrack(U32 track_index) return; } - for (int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) // yse max value { getChild(track_tabs[i], true)->setToggleState(false); } button->setToggleState(true); - updateTabs(); + bool show_water = mCurrentTrack == 0; + mSkyTabLayoutContainer->setVisible(!show_water); + mWaterTabLayoutContainer->setVisible(show_water); updateSlider(); } void LLFloaterEditExtDayCycle::updateTabs() { - bool show_water = mCurrentTrack == 0; - mSkyTabContainer->setVisible(!show_water); - mWaterTabContainer->setVisible(show_water); - - if (show_water) + if (mCurrentTrack == 0) { updateWaterTabs(); } @@ -323,11 +400,13 @@ void LLFloaterEditExtDayCycle::updateTabs() void LLFloaterEditExtDayCycle::updateWaterTabs() { - const LLSettingsWaterPtr_t p_water = mEditDay->getWaterAtKeyframe(mKeysSlider->getCurSliderValue()); + // todo: substitute with mSliderKeyMap? + const LLSettingsWaterPtr_t p_water = mEditDay->getWaterAtKeyframe(mFramesSlider->getCurSliderValue()); // Compiler warnings from getChild about LLPanelSettingsWaterMainTab not being complete/missing params constructor... - // Todo: fix class to work with getChild() - LLPanelSettingsWaterMainTab* panel = mWaterTabContainer->findChild("water_panel", true); + // Todo: fix class to work with getChild()? + LLView* tab_container = mWaterTabLayoutContainer->getChild("water_tabs"); //can't extract panels directly, since they are in 'tuple' + LLPanelSettingsWaterMainTab* panel = dynamic_cast(tab_container->getChildView("water_panel")); if (panel) { panel->setWater(p_water); // todo: Null disables @@ -336,22 +415,25 @@ void LLFloaterEditExtDayCycle::updateWaterTabs() void LLFloaterEditExtDayCycle::updateSkyTabs() { - const LLSettingsSkyPtr_t p_sky = mEditDay->getSkyAtKeyframe(mKeysSlider->getCurSliderValue(), mCurrentTrack); + // todo: substitute with mSliderKeyMap? + const LLSettingsSkyPtr_t p_sky = mEditDay->getSkyAtKeyframe(mFramesSlider->getCurSliderValue(), mCurrentTrack); + + LLView* tab_container = mSkyTabLayoutContainer->getChild("sky_tabs"); //can't extract panels directly, since they are in 'tuple' // Compiler warnings from getChild about tabs... // Todo: fix class LLPanelSettingsSky* panel; - panel = mSkyTabContainer->findChild("atmosphere_panel", true); + panel = dynamic_cast(tab_container->getChildView("atmosphere_panel")); if (panel) { panel->setSky(p_sky); // todo: Null disables } - panel = mSkyTabContainer->findChild("clouds_panel", true); + panel = dynamic_cast(tab_container->getChildView("clouds_panel")); if (panel) { panel->setSky(p_sky); } - panel = mSkyTabContainer->findChild("moon_panel", true); + panel = dynamic_cast(tab_container->getChildView("moon_panel")); if (panel) { panel->setSky(p_sky); @@ -360,19 +442,41 @@ void LLFloaterEditExtDayCycle::updateSkyTabs() void LLFloaterEditExtDayCycle::updateSlider() { - mKeysSlider->clear(); + mFramesSlider->clear(); + mSliderKeyMap.clear(); - LLSettingsDay::KeyframeList_t keyframes = mEditDay->getTrackKeyframes(mCurrentTrack); - LLSettingsDay::KeyframeList_t::iterator iter = keyframes.begin(); - LLSettingsDay::KeyframeList_t::iterator end = keyframes.end(); - - while (iter != end) + LLSettingsDay::CycleTrack_t track = mEditDay->getCycleTrack(mCurrentTrack); + for (auto &frame : track) { - mKeysSlider->addSlider(*iter); - iter++; + addSliderFrame(frame.first, frame.second); } } +void LLFloaterEditExtDayCycle::addSliderFrame(const F32 frame, LLSettingsBase::ptr_t setting) +{ + // multi slider distinguishes elements by key/name in string format + // store names to map to be able to recal dependencies + std::string new_slider = mFramesSlider->addSlider(frame); + mSliderKeyMap[new_slider] = framedata_t(frame, setting); + mLastFrameSlider = new_slider; + + updateTabs(); +} + +void LLFloaterEditExtDayCycle::removeCurrentSliderFrame() +{ + std::string sldr = mFramesSlider->getCurSlider(); + mFramesSlider->deleteCurSlider(); + keymap_t::iterator iter = mSliderKeyMap.find(sldr); + if (iter != mSliderKeyMap.end()) + { + LL_DEBUGS() << "Removing frame from " << iter->second.first << LL_ENDL; + mSliderKeyMap.erase(iter); + } + + updateTabs(); +} + /*void LLFloaterEditExtDayCycle::updateTrack() { LLMultiSliderCtrl* slider = getChild("WLDayCycleKeys"); @@ -540,52 +644,7 @@ LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSi // #endif // } // -// void LLFloaterEditExtDayCycle::onTimeSliderMoved() -// { -// #if 0 -// /// get the slider value -// F32 val = mTimeSlider->getCurSliderValue() / sHoursPerDay; // -// // set the value, turn off animation -// LLWLParamManager::getInstance()->mAnimator.setDayTime((F64)val); -// LLWLParamManager::getInstance()->mAnimator.deactivate(); -// -// // then call update once -// LLWLParamManager::getInstance()->mAnimator.update( -// LLWLParamManager::getInstance()->mCurParams); -// #endif -// } -// -// void LLFloaterEditExtDayCycle::onKeyTimeMoved() -// { -// #if 0 -// if (mKeysSlider->getValue().size() == 0) -// { -// return; -// } -// -// // make sure we have a slider -// const std::string& cur_sldr = mKeysSlider->getCurSlider(); -// if (cur_sldr == "") -// { -// return; -// } -// -// F32 time24 = mKeysSlider->getCurSliderValue(); -// -// // check to see if a key exists -// LLWLParamKey key = mSliderToKey[cur_sldr].keyframe; -// LL_DEBUGS() << "Setting key time: " << time24 << LL_ENDL; -// mSliderToKey[cur_sldr].time = time24; -// -// // if it exists, turn on check box -// mSkyPresetsCombo->selectByValue(key.toStringVal()); -// -// mTimeCtrl->setTime24(time24); -// -// applyTrack(); -// #endif -// } // // void LLFloaterEditExtDayCycle::onKeyTimeChanged() // { @@ -655,25 +714,6 @@ LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSi // #endif // } // -void LLFloaterEditExtDayCycle::addSliderKey(F32 time, const std::shared_ptr keyframe) -{ - // make a slider - const std::string& sldr_name = mKeysSlider->addSlider(time); - if (sldr_name.empty()) - { - return; - } - - // set the key - SliderKey newKey(keyframe, mKeysSlider->getCurSliderValue()); - - llassert_always(sldr_name != LLStringUtil::null); - - // add to map - mSliderToKey.insert(std::pair(sldr_name, newKey)); - - llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size()); -} // #if 0 // LLWLParamKey LLFloaterEditExtDayCycle::getSelectedDayCycle() diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h index a9004087c9..c67cfdd274 100644 --- a/indra/newview/llfloatereditextdaycycle.h +++ b/indra/newview/llfloatereditextdaycycle.h @@ -35,20 +35,11 @@ class LLCheckBoxCtrl; class LLComboBox; class LLLineEditor; class LLMultiSliderCtrl; +class LLTextBox; class LLTimeCtrl; typedef std::shared_ptr LLSettingsBasePtr_t; -class SliderKey -{ -public: - SliderKey(LLSettingsBasePtr_t kf, F32 t) : keyframe(kf), time(t) {} - - LLSettingsBasePtr_t keyframe; - F32 time; -}; - - /** * Floater for creating or editing a day cycle. */ @@ -94,19 +85,22 @@ private: void onRemoveTrack(); void onCommitName(class LLLineEditor* caller, void* user_data); void onTrackSelectionCallback(const LLSD& user_data); + void onTimeSliderMoved(); /// time slider moved + void onFrameSliderCallback(); /// a frame moved or frame selection changed void selectTrack(U32 track_index); void updateTabs(); void updateSkyTabs(); void updateWaterTabs(); - void updateSlider(); //track->slider + void updateSlider(); //track to slider + void addSliderFrame(const F32 frame, LLSettingsBase::ptr_t setting); + void removeCurrentSliderFrame(); //void updateTrack(); // slider->track, todo: better name // /// refresh the day cycle combobox // void refreshDayCyclesList(); // // /// add a slider to the track - void addSliderKey(F32 time, const LLSettingsBasePtr_t key); // // void initCallbacks(); // // LLWLParamKey getSelectedDayCycle(); @@ -119,8 +113,6 @@ private: // void setApplyProgress(bool started); // bool getApplyProgress() const; // -// void onTimeSliderMoved(); /// time slider moved -// void onKeyTimeMoved(); /// a key frame moved // void onKeyTimeChanged(); /// a key frame's time changed // void onAddKey(); /// new key added on slider // void onDeleteKey(); /// a key frame deleted @@ -143,7 +135,10 @@ private: LLSettingsDay::ptr_t mSavedDay; LLSettingsDay::ptr_t mEditDay; - U32 mCurrentTrack; + S64Seconds mDayLength; + S64Seconds mDayOffset; + U32 mCurrentTrack; + std::string mLastFrameSlider; LLButton* mSaveButton; LLButton* mCancelButton; @@ -151,16 +146,16 @@ private: edit_commit_signal_t mCommitSignal; -// LLComboBox* mDayCyclesCombo; -// LLMultiSliderCtrl* mTimeSlider; - LLMultiSliderCtrl* mKeysSlider; - LLView* mSkyTabContainer; - LLView* mWaterTabContainer; - // LLTimeCtrl* mTimeCtrl; -// LLCheckBoxCtrl* mMakeDefaultCheckBox; + LLMultiSliderCtrl* mTimeSlider; + LLMultiSliderCtrl* mFramesSlider; + LLView* mSkyTabLayoutContainer; + LLView* mWaterTabLayoutContainer; + LLTextBox* mCurrentTimeLabel; - // map of sliders to parameters - std::map mSliderToKey; + // map of sliders to parameters + typedef std::pair framedata_t; + typedef std::map keymap_t; + keymap_t mSliderKeyMap; }; #endif // LL_LLFloaterEditExtDayCycle_H diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp index e10af29e82..e5c6116c4f 100644 --- a/indra/newview/llpaneleditsky.cpp +++ b/indra/newview/llpaneleditsky.cpp @@ -74,6 +74,10 @@ namespace const F32 SLIDER_SCALE_GLOW_B(-5.0f); } +static LLPanelInjector t_settings_atmos("panel_settings_atmos"); +static LLPanelInjector t_settings_cloud("panel_settings_cloud"); +static LLPanelInjector t_settings_sunmoon("panel_settings_sunmoon"); + //========================================================================== LLPanelSettingsSky::LLPanelSettingsSky() : LLSettingsEditPanel(), diff --git a/indra/newview/llpaneleditwater.cpp b/indra/newview/llpaneleditwater.cpp index 2864a4858b..940b171dfe 100644 --- a/indra/newview/llpaneleditwater.cpp +++ b/indra/newview/llpaneleditwater.cpp @@ -57,6 +57,8 @@ namespace const std::string FIELD_WATER_BLUR_MULTIP("water_blur_multip"); } +static LLPanelInjector t_settings_water("panel_settings_water"); + //========================================================================== LLPanelSettingsWater::LLPanelSettingsWater() : LLSettingsEditPanel(), diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml index 70f5e21327..3b63d0018c 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml @@ -8,17 +8,13 @@ title="Edit Day Cycle" width="705"> + Create a New Day Cycle Edit Day Cycle Name your day cycle, adjust the controls to create it, and click "Save". To edit your day cycle, adjust the controls below and click "Save". - - - 0%[DSC] - 25%[DSC] - 50%[DSC] - 75%[DSC] - 100%[DSC] + + ([TIME] hr) + parameter="4" />