diff options
author | Nyx (Neal Orman) <nyx@lindenlab.com> | 2010-09-27 22:56:08 -0400 |
---|---|---|
committer | Nyx (Neal Orman) <nyx@lindenlab.com> | 2010-09-27 22:56:08 -0400 |
commit | e045d212d35354d679c2d2e05c6d4689f9f8ac95 (patch) | |
tree | 20ba9f542316816d82dbc092d52a63fccde3d7e7 | |
parent | e6688f993f82d2683e3eadce96c893959c94be2d (diff) |
STORM-1126 WIP Windlight Estate Settings port from 1.23: first pass at merging in windlight estate settings to viewer-dev codebase.
not built, not tested. Probably needs a bunch of fixes to be able
to be integrated.
(resubmitted by Vadim ProductEngine)
53 files changed, 3854 insertions, 1204 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1f4302d870..533eea7420 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -139,6 +139,7 @@ set(viewer_SOURCE_FILES lldrawpoolwlsky.cpp lldriverparam.cpp lldynamictexture.cpp + llenvmanager.cpp llemote.cpp lleventinfo.cpp lleventnotifier.cpp @@ -562,6 +563,7 @@ set(viewer_SOURCE_FILES llwind.cpp llwlanimator.cpp llwldaycycle.cpp + llwlhandlers.cpp llwlparammanager.cpp llwlparamset.cpp llworld.cpp @@ -670,6 +672,7 @@ set(viewer_HEADER_FILES lldriverparam.h lldynamictexture.h llemote.h + llenvmanager.h lleventinfo.h lleventnotifier.h lleventpoll.h @@ -1088,6 +1091,7 @@ set(viewer_HEADER_FILES llwind.h llwlanimator.h llwldaycycle.h + llwlhandlers.h llwlparammanager.h llwlparamset.h llworld.h @@ -1933,6 +1937,23 @@ if (LL_TESTS) #ADD_VIEWER_BUILD_TEST(lltextureinfodetails viewer) #ADD_VIEWER_BUILD_TEST(lltexturestatsuploader viewer) +include(LLAddBuildTest) +SET(viewer_TEST_SOURCE_FILES + llagentaccess.cpp + llwlparammanager.cpp + # Not *actually* a unit test, it's an integration test. + # Because it won't work in the new unit test iface, i've commented out + # and notified Nat. Delete this when it's replaced! + # + poppy & brad 2009-06-05 + # llcapabilitylistener.cpp + ) +set_source_files_properties( + ${viewer_TEST_SOURCE_FILES} + PROPERTIES + LL_TEST_ADDITIONAL_SOURCE_FILES llviewerprecompiledheaders.cpp + ) +LL_ADD_PROJECT_UNIT_TESTS(${VIEWER_BINARY_NAME} "${viewer_TEST_SOURCE_FILES}") + endif (LL_TESTS) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 742a20a849..d21e978ca5 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11046,6 +11046,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>UseEnvironmentFromRegion</key> + <map> + <key>Comment</key> + <string>Choose whether to use the region's environment settings, or override them with the local settings.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>UseExternalBrowser</key> <map> <key>Comment</key> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 721fe81a3c..173e81733c 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 23 +version 24 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 1bad7e5260..602f62cf69 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 22 +version 23 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 4fba47e3df..bbe63be5ae 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 22 +version 23 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index c9bd7851ed..56d2c76dc7 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -36,8 +36,10 @@ #include "llanimationstates.h" #include "llbottomtray.h" #include "llcallingcard.h" +#include "llcapabilitylistener.h" #include "llchannelmanager.h" #include "llconsole.h" +#include "llenvmanager.h" #include "llfirstuse.h" #include "llfloatercamera.h" #include "llfloaterreg.h" @@ -76,6 +78,7 @@ #include "llwindow.h" #include "llworld.h" #include "llworldmap.h" +#include "stringize.h" using namespace LLVOAvatarDefines; @@ -620,6 +623,16 @@ void LLAgent::setRegion(LLViewerRegion *regionp) gSky.mVOGroundp->setRegion(regionp); } + // Notify windlight managers + bool teleport = (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE); + if (teleport) + { + LLEnvManager::getInstance()->notifyTP(); + } + else + { + LLEnvManager::getInstance()->notifyCrossing(); + } } else { @@ -636,6 +649,9 @@ void LLAgent::setRegion(LLViewerRegion *regionp) // Update all of the regions. LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal); + + // Notify windlight managers about login + LLEnvManager::getInstance()->notifyLogin(); } } mRegionp = regionp; @@ -653,6 +669,9 @@ void LLAgent::setRegion(LLViewerRegion *regionp) LLSelectMgr::getInstance()->updateSelectionCenter(); LLFloaterMove::sUpdateFlyingStatus(); + + // notify EnvManager that a refresh is needed + LLEnvManager::instance().refreshFromStorage(LLEnvKey::SCOPE_REGION); } diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 41a299151e..0910d920f2 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -34,6 +34,8 @@ #include "llviewercamera.h" #include "llimage.h" #include "llwlparammanager.h" +#include "llviewershadermgr.h" +#include "llglslshader.h" #include "llsky.h" #include "llvowlsky.h" #include "llviewerregion.h" @@ -66,7 +68,7 @@ LLDrawPoolWLSky::LLDrawPoolWLSky(void) : sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE); - LLWLParamManager::instance()->propagateParameters(); + LLWLParamManager::getInstance()->propagateParameters(); } LLDrawPoolWLSky::~LLDrawPoolWLSky() @@ -161,7 +163,7 @@ void LLDrawPoolWLSky::renderStars(void) const // clamping and allow the star_alpha param to brighten the stars. bool error; LLColor4 star_alpha(LLColor4::black); - star_alpha.mV[3] = LLWLParamManager::instance()->mCurParams.getFloat("star_brightness", error) / 2.f; + star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f; llassert_always(!error); gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex()); @@ -254,7 +256,7 @@ void LLDrawPoolWLSky::render(S32 pass) } LLFastTimer ftm(FTM_RENDER_WL_SKY); - const F32 camHeightLocal = LLWLParamManager::instance()->getDomeOffset() * LLWLParamManager::instance()->getDomeRadius(); + const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius(); LLGLSNoFog disableFog; LLGLDepthTest depth(GL_TRUE, GL_FALSE); diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp new file mode 100644 index 0000000000..f551aa6c8a --- /dev/null +++ b/indra/newview/llenvmanager.cpp @@ -0,0 +1,474 @@ +/** + * @file llenvmanager.cpp + * @brief Implementation of classes managing WindLight and water settings. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llenvmanager.h" + +#include "llagent.h" +#include "llviewerregion.h" + +#include "llfloaterwindlight.h" +#include "llfloaterwater.h" +#include "llfloaterenvsettings.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llfloaterregioninfo.h" +#include "llwindlightscrubbers.h" +#include "llwlhandlers.h" + +extern LLControlGroup gSavedSettings; + +/*virtual*/ void LLEnvManager::initSingleton() +{ + mOrigSettingStore[LLEnvKey::SCOPE_LOCAL] = lindenDefaults(); + mCurNormalScope = (gSavedSettings.getBOOL("UseEnvironmentFromRegion") ? LLEnvKey::SCOPE_REGION : LLEnvKey::SCOPE_LOCAL); + mInterpNextChangeMessage = true; + mPendingOutgoingMessage = false; + mIsEditing = false; +} + +/******* + * Region Changes + *******/ + +void LLEnvManager::notifyLogin() +{ + changedRegion(false); +} +void LLEnvManager::notifyCrossing() +{ + changedRegion(true); +} +void LLEnvManager::notifyTP() +{ + changedRegion(false); +} +void LLEnvManager::changedRegion(bool interp) +{ + mInterpNextChangeMessage = interp; + mPendingOutgoingMessage = false; + + LLFloaterEnvSettings::instance()->close(); + + resetInternalsToDefault(LLEnvKey::SCOPE_REGION); + + maybeClearEditingScope(LLEnvKey::SCOPE_REGION, true, false); +} + +/******* + * Editing settings / UI mode + *******/ + +void LLEnvManager::startEditingScope(LLEnvKey::EScope scope) +{ + if (mIsEditing) + { + LL_WARNS("Windlight") << "Tried to start editing windlight settings while already editing some settings (possibly others)! Ignoring..." << LL_ENDL; + return; + } + if (!canEdit(scope)) + { + LL_WARNS("Windlight") << "Tried to start editing windlight settings while not allowed to! Ignoring..." << LL_ENDL; + return; + } + + mIsEditing = true; + mCurEditingScope = scope; + + // show scope being edited + loadSettingsIntoManagers(scope, false); + + switch (scope) + { + case LLEnvKey::SCOPE_LOCAL: + // not implemented here (yet) + return; + case LLEnvKey::SCOPE_REGION: + LLPanelRegionTerrainInfo::instance()->setCommitControls(true); + break; + default: + return; + } +} + +void LLEnvManager::maybeClearEditingScope(LLEnvKey::EScope scope, bool user_initiated, bool was_commit) +{ + if (mIsEditing && mCurEditingScope == scope) + { + maybeClearEditingScope(user_initiated, was_commit); // handles UI, updating managers, etc. + } +} + +void LLEnvManager::maybeClearEditingScope(bool user_initiated, bool was_commit) +{ + bool clear_now = true; + if (mIsEditing && !was_commit) + { + if(user_initiated) + { + LLSD args; + args["SCOPE"] = getScopeString(mCurEditingScope); + LLNotifications::instance().add("EnvEditUnsavedChangesCancel", args, LLSD(), + boost::bind(&LLEnvManager::clearEditingScope, this, _1, _2)); + clear_now = false; + } + else + { + LLNotifications::instance().add("EnvEditExternalCancel", LLSD()); + } + } + + if(clear_now) + { + clearEditingScope(LLSD(), LLSD()); + } +} + +void LLEnvManager::clearEditingScope(const LLSD& notification, const LLSD& response) +{ + if(notification.isDefined() && response.isDefined() && LLNotification::getSelectedOption(notification, response) != 0) + { + // *TODO: select terrain panel here + mIsEditing = false; + LLFloaterRegionInfo::showInstance(); + return; + } + + mIsEditing = false; + + updateUIFromEditability(); + LLPanelRegionTerrainInfo::instance()->cancelChanges(); + + loadSettingsIntoManagers(mCurNormalScope, true); +} + +void LLEnvManager::updateUIFromEditability() +{ + // *TODO When the checkbox from LLFloaterEnvSettings is moved elsewhere, opening the local environment settings window should auto-display local settings + // Currently, disable all editing to ensure region settings are hidden from those that can't edit them (to preserve possibility of future tradable assets) + // Remove "!gSavedSettings.getBOOL(...)" when the desired behavior is implemented + LLFloaterEnvSettings::instance()->setControlsEnabled(canEdit(LLEnvKey::SCOPE_LOCAL) && !gSavedSettings.getBOOL("UseEnvironmentFromRegion")); + LLPanelRegionTerrainInfo::instance()->setEnvControls(canEdit(LLEnvKey::SCOPE_REGION)); + // enable estate UI iff canEdit(LLEnvKey::SCOPE_ESTATE), etc. +} + +bool LLEnvManager::regionCapable() +{ + return !gAgent.getRegion()->getCapability("EnvironmentSettings").empty(); +} + +const std::string LLEnvManager::getScopeString(LLEnvKey::EScope scope) +{ + switch(scope) + { + case LLEnvKey::SCOPE_LOCAL: + return LLTrans::getString("LocalSettings"); + case LLEnvKey::SCOPE_REGION: + return LLTrans::getString("RegionSettings"); + default: + return " (?)"; + } +} + +bool LLEnvManager::canEdit(LLEnvKey::EScope scope) +{ + // can't edit while a message is being sent or if already editing + if (mPendingOutgoingMessage || mIsEditing) + { + return false; + } + + // check permissions and caps + switch (scope) + { + case LLEnvKey::SCOPE_LOCAL: + return true; // always permitted to edit local + case LLEnvKey::SCOPE_REGION: + bool owner_or_god_or_manager; + { + LLViewerRegion* region = gAgent.getRegion(); + if (NULL == region || region->getCapability("EnvironmentSettings").empty()) + { + // not a windlight-aware region + return false; + } + owner_or_god_or_manager = gAgent.isGodlike() + || (region && (region->getOwner() == gAgent.getID())) + || (region && region->isEstateManager()); + } + return owner_or_god_or_manager; + default: + return false; + } +} + +/******* + * Incoming Messaging + *******/ + +void LLEnvManager::refreshFromStorage(LLEnvKey::EScope scope) +{ + switch (scope) + { + case LLEnvKey::SCOPE_LOCAL: + break; + case LLEnvKey::SCOPE_REGION: + if (!LLEnvironmentRequestResponder::initiateRequest()) + { + // don't have a cap for this, presume invalid response + processIncomingMessage(LLSD(), scope); + } + break; + default: + processIncomingMessage(LLSD(), scope); + break; + } +} + +bool LLEnvManager::processIncomingMessage(const LLSD& unvalidated_content, const LLEnvKey::EScope scope) +{ + if (scope != LLEnvKey::SCOPE_REGION) + { + return false; + } + + // Start out with defaults + resetInternalsToDefault(scope); + updateUIFromEditability(); + + // Validate + std::set<std::string> empty_set; + LLWLPacketScrubber scrubber(scope, empty_set); + LLSD windlight_llsd = scrubber.scrub(unvalidated_content); + + bool valid = windlight_llsd.isDefined(); // successful scrub + + mLastReceivedID = unvalidated_content[0]["messageID"].asUUID(); // if the message was valid, grab the UUID from it and save it for next outbound update message + + if (valid) + { + F32 sun_hour = LLPanelRegionTerrainInfo::instance()->getSunHour(); // this slider is kept up to date + LLWLParamManager::getInstance()->addAllSkies(scope, windlight_llsd[2]); + LLEnvironmentSettings newSettings(windlight_llsd[1], windlight_llsd[2], windlight_llsd[3], sun_hour); + mOrigSettingStore[scope] = newSettings; + } + else + { + LL_WARNS("Windlight Sync") << "Failed to parse windlight settings!" << LL_ENDL; + // presume defaults (already reset above) + } + + maybeClearEditingScope(scope, false, false); + + // refresh display with new settings, if applicable + if (mCurNormalScope == scope && !mIsEditing) // if mIsEditing still, must be editing some other scope, so don't load + { + loadSettingsIntoManagers(scope, mInterpNextChangeMessage); + } + + mInterpNextChangeMessage = true; // reset flag + + return valid; +} + + +/******* + * Outgoing Messaging + *******/ + +void LLEnvManager::commitSettings(LLEnvKey::EScope scope) +{ + bool success = true; + switch (scope) + { + case (LLEnvKey::SCOPE_LOCAL): + // not implemented - LLWLParamManager and LLWaterParamManager currently manage local storage themselves + break; + case (LLEnvKey::SCOPE_REGION): + mPendingOutgoingMessage = true; + LLSD metadata(LLSD::emptyMap()); + metadata["regionID"] = gAgent.getRegion()->getRegionID(); + metadata["messageID"] = mLastReceivedID; // add last received update ID to outbound message so simulator can handle concurrent updates + + saveSettingsFromManagers(scope); // save current settings into settings store before grabbing from settings store and sending + success = LLEnvironmentApplyResponder::initiateRequest(makePacket(LLEnvKey::SCOPE_REGION, metadata)); + if(success) + { + // while waiting for the return message, render old settings + // (as of Aug 09, we should get an updated RegionInfo packet, which triggers a re-request of Windlight data, which causes us to show new settings) + loadSettingsIntoManagers(LLEnvKey::SCOPE_REGION, true); + } + break; + } + + if(success) + { + // with mPendingOutgoingMessage = true, nothing is editable + updateUIFromEditability(); + maybeClearEditingScope(true, true); + } + else + { + mPendingOutgoingMessage = false; + } +} + +LLSD LLEnvManager::makePacket(LLEnvKey::EScope scope, const LLSD& metadata) +{ + return mOrigSettingStore[scope].makePacket(metadata); +} + +void LLEnvManager::commitSettingsFinished(LLEnvKey::EScope scope) +{ + mPendingOutgoingMessage = false; + + updateUIFromEditability(); +} + +/******* + * Loading defaults + *******/ + +void LLEnvManager::resetInternalsToDefault(LLEnvKey::EScope scope) +{ + if (LLEnvKey::SCOPE_LOCAL != scope) + { + LLWLParamManager::getInstance()->clearParamSetsOfScope(scope); + } + + mOrigSettingStore[scope] = lindenDefaults(); + LLWLParamManager::getInstance()->mAnimator.setTimeType(LLWLAnimator::TIME_LINDEN); +} + +const LLEnvironmentSettings& LLEnvManager::lindenDefaults() +{ + static bool loaded = false; + static LLEnvironmentSettings defSettings; + + if (!loaded) + { + LLWaterParamSet defaultWater; + LLWaterParamManager::instance().getParamSet("default", defaultWater); + + // *TODO save default skies (remove hack in LLWLDayCycle::loadDayCycle when this is done) + + defSettings.saveParams( + LLWLDayCycle::loadCycleDataFromFile("default.xml"), // frames will refer to local presets, which is okay + LLSD(LLSD::emptyMap()), // should never lose the default sky presets (read-only) + defaultWater.getAll(), + 0.0); + + loaded = true; + } + + return defSettings; +} + +/******* + * Manipulation of Param Managers + *******/ + +void LLEnvManager::loadSettingsIntoManagers(LLEnvKey::EScope scope, bool interpolate) +{ + LLEnvironmentSettings settings = mOrigSettingStore[scope]; + + if(interpolate) + { + LLWLParamManager::getInstance()->mAnimator.startInterpolation(settings.getWaterParams()); + } + + LLWLParamManager::getInstance()->addAllSkies(scope, settings.getSkyMap()); + LLWLParamManager::getInstance()->mDay.loadDayCycle(settings.getWLDayCycle(), scope); + LLWLParamManager::getInstance()->resetAnimator(settings.getDayTime(), true); + + LLWaterParamManager::getInstance()->mCurParams.setAll(settings.getWaterParams()); +} + +void LLEnvManager::saveSettingsFromManagers(LLEnvKey::EScope scope) +{ + switch (scope) + { + case LLEnvKey::SCOPE_LOCAL: + mOrigSettingStore[scope].saveParams( + LLWLParamManager::getInstance()->mDay.asLLSD(), + LLSD(LLSD::emptyMap()), // never overwrite + LLWaterParamManager::getInstance()->mCurParams.getAll(), + LLWLParamManager::getInstance()->mAnimator.mDayTime); + break; + case LLEnvKey::SCOPE_REGION: + { + // ensure only referenced region-scope skies are saved, resolve naming collisions, etc. + std::map<LLWLParamKey, LLWLParamSet> final_references = LLWLParamManager::getInstance()->finalizeFromDayCycle(scope); + LLSD referenced_skies = LLWLParamManager::getInstance()->createSkyMap(final_references); + mOrigSettingStore[scope].saveParams( + LLWLParamManager::getInstance()->mDay.asLLSD(), + referenced_skies, + LLWaterParamManager::getInstance()->mCurParams.getAll(), + LLWLParamManager::getInstance()->mAnimator.mDayTime); + } + break; + default: + return; + } +} + +/******* + * Setting desired display level + *******/ + +void LLEnvManager::setNormallyDisplayedScope(LLEnvKey::EScope new_scope) +{ + // temp, just save the scope directly as a value in the future when there's more than two + bool want_region = (LLEnvKey::SCOPE_REGION == new_scope); + gSavedSettings.setBOOL("UseEnvironmentFromRegion", want_region); + + if (mCurNormalScope != new_scope) + { + mCurNormalScope = new_scope; + notifyOptInChange(); + } +} + +void LLEnvManager::notifyOptInChange() +{ + bool opt_in = gSavedSettings.getBOOL("UseEnvironmentFromRegion"); + + // Save local settings if switching to region + if(opt_in) + { + LL_INFOS("Windlight") << "Saving currently-displayed settings as current local settings..." << LL_ENDL; + saveSettingsFromManagers(LLEnvKey::SCOPE_LOCAL); + } + + maybeClearEditingScope(true, false); +} diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h new file mode 100644 index 0000000000..1ff4654003 --- /dev/null +++ b/indra/newview/llenvmanager.h @@ -0,0 +1,214 @@ +/** + * @file llenvmanager.h + * @brief Declaration of classes managing WindLight and water settings. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLENVMANAGER_H +#define LL_LLENVMANAGER_H + +#include "llmemory.h" +#include "llsd.h" + +class LLWLParamManager; +class LLWaterParamManager; +class LLWLAnimator; + +// generic key +struct LLEnvKey +{ +public: + // Note: enum ordering is important; for example, a region-level floater (1) will see local and region (all values that are <=) + typedef enum e_scope + { + SCOPE_LOCAL, // 0 + SCOPE_REGION//, // 1 + // SCOPE_ESTATE, // 2 + // etc. + } EScope; +}; + +class LLEnvironmentSettings +{ +public: + LLEnvironmentSettings() : + mWLDayCycle(LLSD::emptyMap()), + mSkyMap(LLSD::emptyMap()), + mWaterParams(LLSD::emptyMap()), + mDayTime(0.f) + {} + LLEnvironmentSettings(const LLSD& dayCycle, const LLSD& skyMap, const LLSD& waterParams, F64 dayTime) : + mWLDayCycle(dayCycle), + mSkyMap(skyMap), + mWaterParams(waterParams), + mDayTime(dayTime) + {} + ~LLEnvironmentSettings() {} + + void saveParams(const LLSD& dayCycle, const LLSD& skyMap, const LLSD& waterParams, F64 dayTime) + { + mWLDayCycle = dayCycle; + mSkyMap = skyMap; + mWaterParams = waterParams; + mDayTime = dayTime; + } + + LLSD& getWLDayCycle() + { + return mWLDayCycle; + } + + LLSD& getWaterParams() + { + return mWaterParams; + } + + LLSD& getSkyMap() + { + return mSkyMap; + } + + F64 getDayTime() + { + return mDayTime; + } + + LLSD makePacket(const LLSD& metadata) + { + LLSD full_packet = LLSD::emptyArray(); + + // 0: metadata + full_packet.append(metadata); + + // 1: day cycle + full_packet.append(mWLDayCycle); + + // 2: map of sky setting names to sky settings (as LLSD) + full_packet.append(mSkyMap); + + // 3: water params + full_packet.append(mWaterParams); + + return full_packet; + } + +private: + LLSD mWLDayCycle, mWaterParams, mSkyMap; + F64 mDayTime; +}; + +// not thread-safe +class LLEnvManager : public LLSingleton<LLEnvManager> +{ +public: + // sets scopes (currently, only region-scope) to startup states + // delay calling these until as close as possible to knowing whether the remote service is capable of holding windlight settings + void notifyCrossing(); + // these avoid interpolation on the next incoming message (if it comes) + void notifyLogin(); + void notifyTP(); + + // request settings again from remote storage (currently implemented only for region) + void refreshFromStorage(LLEnvKey::EScope scope); + // stores settings and starts transitions (as necessary) + // validates packet and returns whether it was valid + // loads defaults if not valid + // returns whether or not arguments were valid + bool processIncomingMessage(const LLSD& packet, LLEnvKey::EScope scope); + // saves settings in the given scope to persistent storage appropriate for that scope + void commitSettings(LLEnvKey::EScope scope); + // called back when the commit finishes + void commitSettingsFinished(LLEnvKey::EScope scope); + + /* + * notify of changes in god/not-god mode, estate ownership, etc. + * should be called every time after entering new region (after receiving new caps) + */ + void notifyPermissionChange(); + + bool regionCapable(); + static const std::string getScopeString(LLEnvKey::EScope scope); + bool canEdit(LLEnvKey::EScope scope); + // enables and populates UI + // populates display (param managers) with scope's settings + // silently fails if canEdit(scope) is false! + void startEditingScope(LLEnvKey::EScope scope); + // cancel and close UI as necessary + // reapplies unedited settings + // displays the settings from the scope that user has set (i.e. opt-in setting for now) + void maybeClearEditingScope(bool user_initiated, bool was_commit); + // clear the scope only if was editing that scope + void maybeClearEditingScope(LLEnvKey::EScope scope, bool user_initiated, bool was_commit); + // actually do the clearing + void clearEditingScope(const LLSD& notification, const LLSD& response); + + // clear and reload defaults into scope + void resetInternalsToDefault(LLEnvKey::EScope scope); + + // sets which scope is to be displayed + // fix me if/when adding more levels of scope + void setNormallyDisplayedScope(LLEnvKey::EScope scope); + +private: + // overriden initializer + friend class LLSingleton<LLEnvManager>; + virtual void initSingleton(); + // helper function (when region changes, but before caps are received) + void changedRegion(bool interpolate); + // apply to current display and UI + void loadSettingsIntoManagers(LLEnvKey::EScope scope, bool interpolate); + // save from current display and UI into memory (mOrigSettingStore) + void saveSettingsFromManagers(LLEnvKey::EScope scope); + + // Save copy of settings from the current ones in the param managers + LLEnvironmentSettings collateFromParamManagers(); + // bundle settings (already committed from UI) into an LLSD + LLSD makePacket(LLEnvKey::EScope scope, const LLSD& metadata); + + void updateUIFromEditability(); + + // only call when setting *changes*, not just when it might have changed + // saves local settings into mOrigSettingStore when necessary + void notifyOptInChange(); + + // calculate Linden default settings + static const LLEnvironmentSettings& lindenDefaults(); + + std::map<LLEnvKey::EScope, LLEnvironmentSettings> mOrigSettingStore; // settings which have been committed from UI + + bool mInterpNextChangeMessage; + bool mPendingOutgoingMessage; + bool mIsEditing; + LLEnvKey::EScope mCurNormalScope; // scope being displayed when not editing (i.e. most of the time) + LLEnvKey::EScope mCurEditingScope; + LLUUID mLastReceivedID; +}; + +#endif // LL_LLENVMANAGER_H + diff --git a/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp index 22816ee802..efaac5cfc5 100644 --- a/indra/newview/llfloaterdaycycle.cpp +++ b/indra/newview/llfloaterdaycycle.cpp @@ -2,25 +2,31 @@ * @file llfloaterdaycycle.cpp * @brief LLFloaterDayCycle class definition * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, 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. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * 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. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * 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 + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -51,34 +57,23 @@ #include "llwlparammanager.h" #include "llpostprocess.h" #include "llfloaterwindlight.h" +#include "llwindlightscrubbers.h" +#include "llenvmanager.h" - -std::map<std::string, LLWLSkyKey> LLFloaterDayCycle::sSliderToKey; +LLFloaterDayCycle* LLFloaterDayCycle::sDayCycle = NULL; const F32 LLFloaterDayCycle::sHoursPerDay = 24.0f; +std::map<std::string, LLWLCycleSliderKey> LLFloaterDayCycle::sSliderToKey; +LLEnvKey::EScope LLFloaterDayCycle::sScope; +std::string LLFloaterDayCycle::sOriginalTitle; +LLWLAnimator::ETime LLFloaterDayCycle::sPreviousTimeType = LLWLAnimator::TIME_LINDEN; -LLFloaterDayCycle::LLFloaterDayCycle(const LLSD& key) -: LLFloater(key) +LLFloaterDayCycle::LLFloaterDayCycle() : LLFloater(std::string("Day Cycle Floater")) { -} + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_day_cycle_options.xml", NULL, FALSE); + sOriginalTitle = getTitle(); -BOOL LLFloaterDayCycle::postBuild() -{ - // add the combo boxes - LLComboBox* keyCombo = getChild<LLComboBox>("WLKeyPresets"); - - if(keyCombo != NULL) - { - keyCombo->removeall(); - std::map<std::string, LLWLParamSet>::iterator mIt = - LLWLParamManager::instance()->mParamList.begin(); - for(; mIt != LLWLParamManager::instance()->mParamList.end(); mIt++) - { - keyCombo->add(std::string(mIt->first)); - } - - // set defaults on combo boxes - keyCombo->selectFirstItem(); - } + llassert(MAX_LOCAL_KEY_FRAMES <= getChild<LLMultiSliderCtrl>("WLDayCycleKeys")->getMaxSliderCount() && + MAX_REGION_KEYFRAMES <= getChild<LLMultiSliderCtrl>("WLDayCycleKeys")->getMaxSliderCount()); // add the time slider LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLTimeSlider"); @@ -87,57 +82,67 @@ BOOL LLFloaterDayCycle::postBuild() // load it up initCallbacks(); - - syncMenu(); - syncSliderTrack(); - - return TRUE; } LLFloaterDayCycle::~LLFloaterDayCycle() { } +void LLFloaterDayCycle::onClickHelp(void* data) +{ + LLFloaterDayCycle* self = LLFloaterDayCycle::instance(); + + std::string xml_alert = *(std::string *) data; + LLNotifications::instance().add(self->contextualNotification(xml_alert)); +} + +void LLFloaterDayCycle::initHelpBtn(const std::string& name, const std::string& xml_alert) +{ + childSetAction(name, onClickHelp, new std::string(xml_alert)); +} + void LLFloaterDayCycle::initCallbacks(void) { + initHelpBtn("WLDayCycleHelp", "HelpDayCycle"); + // WL Day Cycle - getChild<LLUICtrl>("WLTimeSlider")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeSliderMoved, this, _1)); - getChild<LLUICtrl>("WLDayCycleKeys")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyTimeMoved, this, _1)); - getChild<LLUICtrl>("WLCurKeyHour")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyTimeChanged, this, _1)); - getChild<LLUICtrl>("WLCurKeyMin")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyTimeChanged, this, _1)); - getChild<LLUICtrl>("WLKeyPresets")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyPresetChanged, this, _1)); - - getChild<LLUICtrl>("WLLengthOfDayHour")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeRateChanged, this, _1)); - getChild<LLUICtrl>("WLLengthOfDayMin")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeRateChanged, this, _1)); - getChild<LLUICtrl>("WLLengthOfDaySec")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeRateChanged, this, _1)); - getChild<LLUICtrl>("WLUseLindenTime")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onUseLindenTime, this, _1)); - getChild<LLUICtrl>("WLAnimSky")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onRunAnimSky, this, _1)); - getChild<LLUICtrl>("WLStopAnimSky")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onStopAnimSky, this, _1)); - - getChild<LLUICtrl>("WLLoadDayCycle")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onLoadDayCycle, this, _1)); - getChild<LLUICtrl>("WLSaveDayCycle")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onSaveDayCycle, this, _1)); - - getChild<LLUICtrl>("WLAddKey")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onAddKey, this, _1)); - getChild<LLUICtrl>("WLDeleteKey")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onDeleteKey, this, _1)); + childSetCommitCallback("WLTimeSlider", onTimeSliderMoved, NULL); + childSetCommitCallback("WLDayCycleKeys", onKeyTimeMoved, NULL); + childSetCommitCallback("WLCurKeyHour", onKeyTimeChanged, NULL); + childSetCommitCallback("WLCurKeyMin", onKeyTimeChanged, NULL); + childSetCommitCallback("WLKeyPresets", onKeyPresetChanged, NULL); + + childSetCommitCallback("WLLengthOfDayHour", onTimeRateChanged, NULL); + childSetCommitCallback("WLLengthOfDayMin", onTimeRateChanged, NULL); + childSetCommitCallback("WLLengthOfDaySec", onTimeRateChanged, NULL); + childSetAction("WLUseLindenTime", onUseLindenTime, NULL); + childSetAction("WLAnimSky", onRunAnimSky, NULL); + childSetAction("WLStopAnimSky", onStopAnimSky, NULL); + + childSetAction("WLLoadDayCycle", onLoadDayCycle, NULL); + childSetAction("WLSaveDayCycle", onSaveDayCycle, NULL); + + childSetAction("WLAddKey", onAddKey, NULL); + childSetAction("WLDeleteKey", onDeleteKey, NULL); } void LLFloaterDayCycle::syncMenu() { -// std::map<std::string, LLVector4> & currentParams = LLWLParamManager::instance()->mCurParams.mParamValues; +// std::map<std::string, LLVector4> & currentParams = LLWLParamManager::getInstance()->mCurParams.mParamValues; // set time - LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLTimeSlider"); - sldr->setCurSliderValue((F32)LLWLParamManager::instance()->mAnimator.getDayTime() * sHoursPerDay); + LLMultiSliderCtrl* sldr = LLFloaterDayCycle::sDayCycle->getChild<LLMultiSliderCtrl>("WLTimeSlider"); + sldr->setCurSliderValue((F32)LLWLParamManager::getInstance()->mAnimator.getDayTime() * sHoursPerDay); - LLSpinCtrl* secSpin = getChild<LLSpinCtrl>("WLLengthOfDaySec"); - LLSpinCtrl* minSpin = getChild<LLSpinCtrl>("WLLengthOfDayMin"); - LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>("WLLengthOfDayHour"); + LLSpinCtrl* secSpin = sDayCycle->getChild<LLSpinCtrl>("WLLengthOfDaySec"); + LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>("WLLengthOfDayMin"); + LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>("WLLengthOfDayHour"); F32 curRate; F32 hours, min, sec; // get the current rate - curRate = LLWLParamManager::instance()->mDay.mDayRate; + curRate = LLWLParamManager::getInstance()->mDay.mDayRate; hours = (F32)((int)(curRate / 60 / 60)); curRate -= (hours * 60 * 60); min = (F32)((int)(curRate / 60)); @@ -149,28 +154,28 @@ void LLFloaterDayCycle::syncMenu() secSpin->setValue(sec); // turn off Use Estate Time button if it's already being used - if( LLWLParamManager::instance()->mAnimator.mUseLindenTime == true) + if( LLWLParamManager::getInstance()->mAnimator.getUseLindenTime()) { - getChildView("WLUseLindenTime")->setEnabled(FALSE); + LLFloaterDayCycle::sDayCycle->childDisable("WLUseLindenTime"); } else { - getChildView("WLUseLindenTime")->setEnabled(TRUE); + LLFloaterDayCycle::sDayCycle->childEnable("WLUseLindenTime"); } } void LLFloaterDayCycle::syncSliderTrack() { // clear the slider - LLMultiSliderCtrl* kSldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); + LLMultiSliderCtrl* kSldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); kSldr->clear(); sSliderToKey.clear(); // add sliders - std::map<F32, std::string>::iterator mIt = - LLWLParamManager::instance()->mDay.mTimeMap.begin(); - for(; mIt != LLWLParamManager::instance()->mDay.mTimeMap.end(); mIt++) + std::map<F32, LLWLParamKey>::iterator mIt = + LLWLParamManager::getInstance()->mDay.mTimeMap.begin(); + for(; mIt != LLWLParamManager::getInstance()->mDay.mTimeMap.end(); mIt++) { addSliderKey(mIt->first * sHoursPerDay, mIt->second); } @@ -185,34 +190,115 @@ void LLFloaterDayCycle::syncTrack() } LLMultiSliderCtrl* sldr; - sldr = getChild<LLMultiSliderCtrl>( + sldr = sDayCycle->getChild<LLMultiSliderCtrl>( "WLDayCycleKeys"); llassert_always(sSliderToKey.size() == sldr->getValue().size()); LLMultiSliderCtrl* tSldr; - tSldr = getChild<LLMultiSliderCtrl>( + tSldr = sDayCycle->getChild<LLMultiSliderCtrl>( "WLTimeSlider"); // create a new animation track - LLWLParamManager::instance()->mDay.clearKeys(); + LLWLParamManager::getInstance()->mDay.clearKeyframes(); // add the keys one by one - std::map<std::string, LLWLSkyKey>::iterator mIt = sSliderToKey.begin(); + std::map<std::string, LLWLCycleSliderKey>::iterator mIt = sSliderToKey.begin(); for(; mIt != sSliderToKey.end(); mIt++) { - LLWLParamManager::instance()->mDay.addKey(mIt->second.time / sHoursPerDay, - mIt->second.presetName); + LLWLParamManager::getInstance()->mDay.addKeyframe(mIt->second.time / sHoursPerDay, + mIt->second.keyframe); } // set the param manager's track to the new one - LLWLParamManager::instance()->resetAnimator( + LLWLParamManager::getInstance()->resetAnimator( tSldr->getCurSliderValue() / sHoursPerDay, false); - LLWLParamManager::instance()->mAnimator.update( - LLWLParamManager::instance()->mCurParams); + LLWLParamManager::getInstance()->mAnimator.update( + LLWLParamManager::getInstance()->mCurParams); +} + +void LLFloaterDayCycle::refreshPresetsFromParamManager() +{ + LLComboBox* keyCombo = sDayCycle->getChild<LLComboBox>("WLKeyPresets"); + + if(keyCombo != NULL) + { + std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = + LLWLParamManager::getInstance()->mParamList.begin(); + for(; mIt != LLWLParamManager::getInstance()->mParamList.end(); mIt++) + { + if(mIt->first.scope <= sScope) + { + llinfos << "Adding key: " << mIt->first.toString() << llendl; + keyCombo->add(mIt->first.toString(), LLSD(mIt->first.toStringVal())); + } + } + + // set defaults on combo boxes + keyCombo->selectFirstItem(); + } } -void LLFloaterDayCycle::onRunAnimSky(LLUICtrl* ctrl) +// static +LLFloaterDayCycle* LLFloaterDayCycle::instance() +{ + if (!sDayCycle) + { + sDayCycle = new LLFloaterDayCycle(); + // sDayCycle->open(); + // sDayCycle->setFocus(TRUE); + } + return sDayCycle; +} + +bool LLFloaterDayCycle::isOpen() +{ + if (sDayCycle != NULL) + { + return true; + } + return false; +} + +void LLFloaterDayCycle::show(LLEnvKey::EScope scope) +{ + LLFloaterDayCycle* dayCycle = instance(); + if(scope != sScope && ((LLView*)dayCycle)->getVisible()) + { + LLNotifications::instance().add("EnvOtherScopeAlreadyOpen", LLSD()); + return; + } + sScope = scope; + std::string title = sOriginalTitle + " (" + LLEnvManager::getScopeString(sScope) + ")"; + dayCycle->setTitle(title); + refreshPresetsFromParamManager(); + dayCycle->syncMenu(); + syncSliderTrack(); + + // set drop-down menu to match preset of currently-selected keyframe (one is automatically selected initially) + const std::string& curSldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys")->getCurSlider(); + if(strlen(curSldr.c_str()) > 0) // only do this if there is a curSldr, otherwise we put an invalid entry into the map + { + sDayCycle->getChild<LLComboBox>("WLKeyPresets")->selectByValue(sSliderToKey[curSldr].keyframe.toStringVal()); + } + + // comment in if you want the menu to rebuild each time + //LLUICtrlFactory::getInstance()->buildFloater(dayCycle, "floater_day_cycle_options.xml"); + //dayCycle->initCallbacks(); + + dayCycle->open(); +} + +// virtual +void LLFloaterDayCycle::onClose(bool app_quitting) +{ + if (sDayCycle) + { + sDayCycle->setVisible(FALSE); + } +} + +void LLFloaterDayCycle::onRunAnimSky(void* userData) { // if no keys, do nothing if(sSliderToKey.size() == 0) @@ -221,46 +307,47 @@ void LLFloaterDayCycle::onRunAnimSky(LLUICtrl* ctrl) } LLMultiSliderCtrl* sldr; - sldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); + sldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); llassert_always(sSliderToKey.size() == sldr->getValue().size()); - LLMultiSliderCtrl* tSldr; - tSldr = getChild<LLMultiSliderCtrl>("WLTimeSlider"); + LLMultiSliderCtrl* tSldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLTimeSlider"); + + sPreviousTimeType = LLWLParamManager::getInstance()->mAnimator.getTimeType(); // turn off linden time - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.setTimeType(LLWLAnimator::TIME_CUSTOM); // set the param manager's track to the new one - LLWLParamManager::instance()->resetAnimator( - tSldr->getCurSliderValue() / sHoursPerDay, true); + LLWLParamManager::getInstance()->resetAnimator(tSldr->getCurSliderValue() / sHoursPerDay, true); - llassert_always(LLWLParamManager::instance()->mAnimator.mTimeTrack.size() == sldr->getValue().size()); + llassert_always(LLWLParamManager::getInstance()->mAnimator.mTimeTrack.size() == sldr->getValue().size()); } -void LLFloaterDayCycle::onStopAnimSky(LLUICtrl* ctrl) +void LLFloaterDayCycle::onStopAnimSky(void* userData) { // if no keys, do nothing if(sSliderToKey.size() == 0) { return; } - // turn off animation and using linden time - LLWLParamManager::instance()->mAnimator.mIsRunning = false; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.deactivate(); // turn off animation and using linden time + LLMultiSliderCtrl* tSldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLTimeSlider"); + LLWLParamManager::getInstance()->resetAnimator(tSldr->getCurSliderValue() / sHoursPerDay, false); + LLWLParamManager::getInstance()->mAnimator.setTimeType(sPreviousTimeType); } -void LLFloaterDayCycle::onUseLindenTime(LLUICtrl* ctrl) +void LLFloaterDayCycle::onUseLindenTime(void* userData) { - LLComboBox* box = getChild<LLComboBox>("WLPresetsCombo"); + LLFloaterWindLight* wl = LLFloaterWindLight::instance(); + LLComboBox* box = wl->getChild<LLComboBox>("WLPresetsCombo"); box->selectByValue(""); - LLWLParamManager::instance()->mAnimator.mIsRunning = true; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = true; + LLWLParamManager::getInstance()->mAnimator.deactivate(); } -void LLFloaterDayCycle::onLoadDayCycle(LLUICtrl* ctrl) +void LLFloaterDayCycle::onLoadDayCycle(void* userData) { - LLWLParamManager::instance()->mDay.loadDayCycle("Default.xml"); + LLWLParamManager::getInstance()->mDay.loadDayCycleFromFile("Default.xml"); // sync it all up syncSliderTrack(); @@ -268,46 +355,45 @@ void LLFloaterDayCycle::onLoadDayCycle(LLUICtrl* ctrl) // set the param manager's track to the new one LLMultiSliderCtrl* tSldr; - tSldr = getChild<LLMultiSliderCtrl>( + tSldr = sDayCycle->getChild<LLMultiSliderCtrl>( "WLTimeSlider"); - LLWLParamManager::instance()->resetAnimator( + LLWLParamManager::getInstance()->resetAnimator( tSldr->getCurSliderValue() / sHoursPerDay, false); // and draw it - LLWLParamManager::instance()->mAnimator.update( - LLWLParamManager::instance()->mCurParams); + LLWLParamManager::getInstance()->mAnimator.update( + LLWLParamManager::getInstance()->mCurParams); } -void LLFloaterDayCycle::onSaveDayCycle(LLUICtrl* ctrl) +void LLFloaterDayCycle::onSaveDayCycle(void* userData) { - LLWLParamManager::instance()->mDay.saveDayCycle("Default.xml"); + LLWLParamManager::getInstance()->mDay.saveDayCycle("Default.xml"); } -void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl) +void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl, void* userData) { - LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>( + LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>( "WLTimeSlider"); /// get the slider value F32 val = sldr->getCurSliderValue() / sHoursPerDay; // set the value, turn off animation - LLWLParamManager::instance()->mAnimator.setDayTime((F64)val); - LLWLParamManager::instance()->mAnimator.mIsRunning = false; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.setDayTime((F64)val); + LLWLParamManager::getInstance()->mAnimator.deactivate(); // then call update once - LLWLParamManager::instance()->mAnimator.update( - LLWLParamManager::instance()->mCurParams); + LLWLParamManager::getInstance()->mAnimator.update( + LLWLParamManager::getInstance()->mCurParams); } -void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl) +void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl, void* userData) { - LLComboBox* comboBox = getChild<LLComboBox>("WLKeyPresets"); - LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); - LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>("WLCurKeyHour"); - LLSpinCtrl* minSpin = getChild<LLSpinCtrl>("WLCurKeyMin"); + LLComboBox* comboBox = sDayCycle->getChild<LLComboBox>("WLKeyPresets"); + LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); + LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>("WLCurKeyHour"); + LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>("WLCurKeyMin"); if(sldr->getValue().size() == 0) { return; @@ -322,11 +408,11 @@ void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl) F32 time = sldr->getCurSliderValue(); // check to see if a key exists - std::string presetName = sSliderToKey[curSldr].presetName; + LLWLParamKey key = sSliderToKey[curSldr].keyframe; sSliderToKey[curSldr].time = time; // if it exists, turn on check box - comboBox->selectByValue(presetName); + comboBox->selectByValue(key.toStringVal()); // now set the spinners F32 hour = (F32)((S32)time); @@ -345,18 +431,18 @@ void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl) } -void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl) +void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl, void* userData) { // if no keys, skipped if(sSliderToKey.size() == 0) { return; } - LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>( + LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>( "WLDayCycleKeys"); - LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>( + LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>( "WLCurKeyHour"); - LLSpinCtrl* minSpin = getChild<LLSpinCtrl>( + LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>( "WLCurKeyMin"); F32 hour = hourSpin->get(); @@ -368,18 +454,17 @@ void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl) F32 time = sldr->getCurSliderValue() / sHoursPerDay; // now set the key's time in the sliderToKey map - std::string presetName = sSliderToKey[curSldr].presetName; sSliderToKey[curSldr].time = time; syncTrack(); } -void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl) +void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl, void* userData) { // get the time - LLComboBox* comboBox = getChild<LLComboBox>( + LLComboBox* comboBox = sDayCycle->getChild<LLComboBox>( "WLKeyPresets"); - LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>( + LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>( "WLDayCycleKeys"); // do nothing if no sliders @@ -388,7 +473,9 @@ void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl) } // change the map - std::string newPreset(comboBox->getSelectedValue().asString()); + + std::string stringVal = comboBox->getSelectedValue().asString(); + LLWLParamKey newKey(stringVal); const std::string& curSldr = sldr->getCurSlider(); // if null, don't use @@ -396,21 +483,21 @@ void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl) return; } - sSliderToKey[curSldr].presetName = newPreset; + sSliderToKey[curSldr].keyframe = newKey; syncTrack(); } -void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl) +void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl, void* userData) { // get the time - LLSpinCtrl* secSpin = getChild<LLSpinCtrl>( + LLSpinCtrl* secSpin = sDayCycle->getChild<LLSpinCtrl>( "WLLengthOfDaySec"); - LLSpinCtrl* minSpin = getChild<LLSpinCtrl>( + LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>( "WLLengthOfDayMin"); - LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>( + LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>( "WLLengthOfDayHour"); F32 hour; @@ -424,34 +511,57 @@ void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl) if(time <= 0) { time = 1; } - LLWLParamManager::instance()->mDay.mDayRate = time; + LLWLParamManager::getInstance()->mDay.mDayRate = time; syncTrack(); } -void LLFloaterDayCycle::onAddKey(LLUICtrl* ctrl) +void LLFloaterDayCycle::onAddKey(void* userData) { - LLComboBox* comboBox = getChild<LLComboBox>( + LLComboBox* comboBox = sDayCycle->getChild<LLComboBox>( "WLKeyPresets"); - LLMultiSliderCtrl* kSldr = getChild<LLMultiSliderCtrl>( + LLMultiSliderCtrl* kSldr = sDayCycle->getChild<LLMultiSliderCtrl>( "WLDayCycleKeys"); - LLMultiSliderCtrl* tSldr = getChild<LLMultiSliderCtrl>( + LLMultiSliderCtrl* tSldr = sDayCycle->getChild<LLMultiSliderCtrl>( "WLTimeSlider"); llassert_always(sSliderToKey.size() == kSldr->getValue().size()); + S32 max_sliders; + switch(sScope) + { + case LLEnvKey::SCOPE_LOCAL: + max_sliders = LLWLPacketScrubber::MAX_LOCAL_KEY_FRAMES; + break; + case LLEnvKey::SCOPE_REGION: + max_sliders = LLWLPacketScrubber::MAX_REGION_KEY_FRAMES; + break; + default: + max_sliders = kSldr->getMaxSliderCount(); + break; + } + + if(kSldr->getSliderCount() >= max_sliders) + { + LLSD args; + args["SCOPE"] = LLEnvManager::getScopeString(sScope); + args["MAX"] = max_sliders; + LLNotifications::instance().add("DayCycleTooManyKeyframes", args); + return; + } + // get the values - std::string newPreset(comboBox->getSelectedValue().asString()); + LLWLParamKey newKeyframe(comboBox->getSelectedValue()); // add the slider key - addSliderKey(tSldr->getCurSliderValue(), newPreset); + addSliderKey(tSldr->getCurSliderValue(), newKeyframe); syncTrack(); } -void LLFloaterDayCycle::addSliderKey(F32 time, const std::string & presetName) +void LLFloaterDayCycle::addSliderKey(F32 time, LLWLParamKey keyframe) { - LLMultiSliderCtrl* kSldr = getChild<LLMultiSliderCtrl>( + LLMultiSliderCtrl* kSldr = sDayCycle->getChild<LLMultiSliderCtrl>( "WLDayCycleKeys"); // make a slider @@ -461,30 +571,28 @@ void LLFloaterDayCycle::addSliderKey(F32 time, const std::string & presetName) } // set the key - LLWLSkyKey newKey; - newKey.presetName = presetName; - newKey.time = kSldr->getCurSliderValue(); + LLWLCycleSliderKey newKey(keyframe, kSldr->getCurSliderValue()); llassert_always(sldrName != LLStringUtil::null); // add to map - sSliderToKey.insert(std::pair<std::string, LLWLSkyKey>(sldrName, newKey)); + sSliderToKey.insert(std::pair<std::string, LLWLCycleSliderKey>(sldrName, newKey)); llassert_always(sSliderToKey.size() == kSldr->getValue().size()); } -void LLFloaterDayCycle::deletePreset(std::string& presetName) +void LLFloaterDayCycle::deletePreset(LLWLParamKey keyframe) { - LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); + LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); /// delete any reference - std::map<std::string, LLWLSkyKey>::iterator curr_preset, next_preset; + std::map<std::string, LLWLCycleSliderKey>::iterator curr_preset, next_preset; for(curr_preset = sSliderToKey.begin(); curr_preset != sSliderToKey.end(); curr_preset = next_preset) { next_preset = curr_preset; ++next_preset; - if (curr_preset->second.presetName == presetName) + if (curr_preset->second.keyframe == keyframe) { sldr->deleteSlider(curr_preset->first); sSliderToKey.erase(curr_preset); @@ -492,19 +600,25 @@ void LLFloaterDayCycle::deletePreset(std::string& presetName) } } -void LLFloaterDayCycle::onDeleteKey(LLUICtrl* ctrl) +void LLFloaterDayCycle::onDeleteKey(void* userData) { - if(sSliderToKey.size() == 0) { + if(sSliderToKey.size() == 0) + { + return; + } + else if(sSliderToKey.size() == 1) + { + LLNotifications::instance().add("EnvCannotDeleteLastDayCycleKey", LLSD()); return; } - LLComboBox* comboBox = getChild<LLComboBox>( + LLComboBox* comboBox = sDayCycle->getChild<LLComboBox>( "WLKeyPresets"); - LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); + LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); // delete from map const std::string& sldrName = sldr->getCurSlider(); - std::map<std::string, LLWLSkyKey>::iterator mIt = sSliderToKey.find(sldrName); + std::map<std::string, LLWLCycleSliderKey>::iterator mIt = sSliderToKey.find(sldrName); sSliderToKey.erase(mIt); sldr->deleteCurSlider(); @@ -514,11 +628,11 @@ void LLFloaterDayCycle::onDeleteKey(LLUICtrl* ctrl) } const std::string& name = sldr->getCurSlider(); - comboBox->selectByValue(sSliderToKey[name].presetName); + comboBox->selectByValue(sSliderToKey[name].keyframe.toLLSD()); F32 time = sSliderToKey[name].time; - LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>("WLCurKeyHour"); - LLSpinCtrl* minSpin = getChild<LLSpinCtrl>("WLCurKeyMin"); + LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>("WLCurKeyHour"); + LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>("WLCurKeyMin"); // now set the spinners F32 hour = (F32)((S32)time); diff --git a/indra/newview/llfloaterdaycycle.h b/indra/newview/llfloaterdaycycle.h index 993ddb8f07..1c021f0c6a 100644 --- a/indra/newview/llfloaterdaycycle.h +++ b/indra/newview/llfloaterdaycycle.h @@ -2,25 +2,31 @@ * @file llfloaterdaycycle.h * @brief LLFloaterDayCycle class definition * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, 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. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * 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. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * 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 + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -32,15 +38,19 @@ #include <vector> #include "llwlparamset.h" #include "llwlanimator.h" +#include "llwlparammanager.h" struct WLColorControl; struct WLFloatControl; -/// convenience class for holding keys mapped to sliders -struct LLWLSkyKey +/// convenience class for holding keyframes mapped to sliders +struct LLWLCycleSliderKey { public: - std::string presetName; + LLWLCycleSliderKey(LLWLParamKey kf, F32 t) : keyframe(kf), time(t) {} + LLWLCycleSliderKey() : keyframe(), time(0.f) {} // Don't use this default constructor + + LLWLParamKey keyframe; F32 time; }; @@ -49,71 +59,94 @@ public: class LLFloaterDayCycle : public LLFloater { public: - - LLFloaterDayCycle(const LLSD& key); + LLFloaterDayCycle(); virtual ~LLFloaterDayCycle(); - /*virtual*/ BOOL postBuild(); + + // map of sliders to parameters + static std::map<std::string, LLWLCycleSliderKey> sSliderToKey; + + /// help button stuff + static void onClickHelp(void* data); + void initHelpBtn(const std::string& name, const std::string& xml_alert); /// initialize all void initCallbacks(void); + /// one and one instance only + static LLFloaterDayCycle* instance(); + /// on time slider moved - void onTimeSliderMoved(LLUICtrl* ctrl); + static void onTimeSliderMoved(LLUICtrl* ctrl, void* userData); /// what happens when you move the key frame - void onKeyTimeMoved(LLUICtrl* ctrl); + static void onKeyTimeMoved(LLUICtrl* ctrl, void* userData); /// what happens when you change the key frame's time - void onKeyTimeChanged(LLUICtrl* ctrl); + static void onKeyTimeChanged(LLUICtrl* ctrl, void* userData); /// if you change the combo box, change the frame - void onKeyPresetChanged(LLUICtrl* ctrl); + static void onKeyPresetChanged(LLUICtrl* ctrl, void* userData); /// run this when user says to run the sky animation - void onRunAnimSky(LLUICtrl* ctrl); + static void onRunAnimSky(void* userData); /// run this when user says to stop the sky animation - void onStopAnimSky(LLUICtrl* ctrl); + static void onStopAnimSky(void* userData); /// if you change the combo box, change the frame - void onTimeRateChanged(LLUICtrl* ctrl); + static void onTimeRateChanged(LLUICtrl* ctrl, void* userData); /// add a new key on slider - void onAddKey(LLUICtrl* ctrl); + static void onAddKey(void* userData); /// delete any and all reference to a preset - void deletePreset(std::string& presetName); + void deletePreset(LLWLParamKey keyframe); /// delete a key frame - void onDeleteKey(LLUICtrl* ctrl); + static void onDeleteKey(void* userData); /// button to load day - void onLoadDayCycle(LLUICtrl* ctrl); + static void onLoadDayCycle(void* userData); /// button to save day - void onSaveDayCycle(LLUICtrl* ctrl); + static void onSaveDayCycle(void* userData); /// toggle for Linden time - void onUseLindenTime(LLUICtrl* ctrl); + static void onUseLindenTime(void* userData); + + + //// menu management + + /// show off our menu + static void show(LLEnvKey::EScope scope = LLEnvKey::SCOPE_LOCAL); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); /// sync up sliders with day cycle structure - void syncMenu(); + static void syncMenu(); // makes sure key slider has what's in day cycle - void syncSliderTrack(); + static void syncSliderTrack(); /// makes sure day cycle data structure has what's in menu - void syncTrack(); + static void syncTrack(); + + /// refresh combox box from param manager + static void refreshPresetsFromParamManager(); /// add a slider to the track - void addSliderKey(F32 time, const std::string& presetName); + static void addSliderKey(F32 time, LLWLParamKey keyframe); private: - - // map of sliders to parameters - static std::map<std::string, LLWLSkyKey> sSliderToKey; - + static LLFloaterDayCycle* sDayCycle; // one instance on the inside static const F32 sHoursPerDay; + static LLEnvKey::EScope sScope; + static std::string sOriginalTitle; + static LLWLAnimator::ETime sPreviousTimeType; }; diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp index fcaef1f34b..6d1b27db07 100644 --- a/indra/newview/llfloaterenvsettings.cpp +++ b/indra/newview/llfloaterenvsettings.cpp @@ -2,25 +2,31 @@ * @file llfloaterenvsettings.cpp * @brief LLFloaterEnvSettings class definition * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, 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. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * 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. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * 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 + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -28,9 +34,10 @@ #include "llfloaterenvsettings.h" -#include "llfloaterreg.h" #include "llfloaterwindlight.h" #include "llfloaterwater.h" +#include "llfloaterdaycycle.h" +#include "llfloaterregioninfo.h" #include "lluictrlfactory.h" #include "llsliderctrl.h" #include "llcombobox.h" @@ -42,57 +49,89 @@ #include "llwaterparammanager.h" #include "llmath.h" #include "llviewerwindow.h" +#include "llviewercontrol.h" + +#include "llcheckboxctrl.h" #include "pipeline.h" #include <sstream> -LLFloaterEnvSettings::LLFloaterEnvSettings(const LLSD& key) - : LLFloater(key) +LLFloaterEnvSettings* LLFloaterEnvSettings::sEnvSettings = NULL; + +LLFloaterEnvSettings::LLFloaterEnvSettings() : LLFloater(std::string("Environment Settings Floater")) { + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_env_settings.xml", NULL, FALSE); + + // load it up + initCallbacks(); } -// virtual + LLFloaterEnvSettings::~LLFloaterEnvSettings() { } -// virtual -BOOL LLFloaterEnvSettings::postBuild() -{ - // load it up - initCallbacks(); - syncMenu(); - return TRUE; + +void LLFloaterEnvSettings::onClickHelp(void* data) +{ + LLFloaterEnvSettings* self = (LLFloaterEnvSettings*)data; + LLNotifications::instance().add(self->contextualNotification("EnvSettingsHelpButton")); +} + +void LLFloaterEnvSettings::onUseRegionEnvironment(LLUICtrl* ctrl, void* data) +{ + LLFloaterEnvSettings* self = (LLFloaterEnvSettings*)data; + LLCheckBoxCtrl* checkbox = (LLCheckBoxCtrl*)self->getChildView("RegionWLOptIn"); + setOptIn(checkbox->getValue().asBoolean()); +} + +void LLFloaterEnvSettings::setOptIn(bool opt_in) +{ + if (opt_in) + { + LLEnvManager::getInstance()->setNormallyDisplayedScope(LLEnvKey::SCOPE_REGION); + } + else + { + LLEnvManager::getInstance()->setNormallyDisplayedScope(LLEnvKey::SCOPE_LOCAL); + } } void LLFloaterEnvSettings::initCallbacks(void) { // our three sliders - getChild<LLUICtrl>("EnvTimeSlider")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeDayTime, this, _1)); - getChild<LLUICtrl>("EnvCloudSlider")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeCloudCoverage, this, _1)); - getChild<LLUICtrl>("EnvWaterFogSlider")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeWaterFogDensity, this, _1, &LLWaterParamManager::instance()->mFogDensity)); + childSetCommitCallback("EnvTimeSlider", onChangeDayTime, NULL); + childSetCommitCallback("EnvCloudSlider", onChangeCloudCoverage, NULL); + childSetCommitCallback("EnvWaterFogSlider", onChangeWaterFogDensity, + &LLWaterParamManager::getInstance()->mFogDensity); // color picker - getChild<LLUICtrl>("EnvWaterColor")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeWaterColor, this, _1, &LLWaterParamManager::instance()->mFogColor)); + childSetCommitCallback("EnvWaterColor", onChangeWaterColor, + &LLWaterParamManager::getInstance()->mFogColor); // WL Top - getChild<LLUICtrl>("EnvAdvancedSkyButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onOpenAdvancedSky, this)); - getChild<LLUICtrl>("EnvAdvancedWaterButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onOpenAdvancedWater, this)); - getChild<LLUICtrl>("EnvUseEstateTimeButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onUseEstateTime, this)); + childSetAction("EnvAdvancedSkyButton", onOpenAdvancedSky, NULL); + childSetAction("EnvAdvancedWaterButton", onOpenAdvancedWater, NULL); + childSetAction("EnvUseEstateTimeButton", onUseEstateTime, NULL); + childSetAction("EnvUseLocalTimeButton", onUseLocalTime, NULL); + childSetAction("EnvSettingsHelpButton", onClickHelp, this); + + childSetCommitCallback("RegionWLOptIn", onUseRegionEnvironment, this); } + // menu maintenance functions void LLFloaterEnvSettings::syncMenu() { LLSliderCtrl* sldr; - sldr = getChild<LLSliderCtrl>("EnvTimeSlider"); + sldr = sEnvSettings->getChild<LLSliderCtrl>("EnvTimeSlider"); // sync the clock - F32 val = (F32)LLWLParamManager::instance()->mAnimator.getDayTime(); - std::string timeStr = timeToString(val); + F32 val = (F32)LLWLParamManager::getInstance()->mAnimator.getDayTime(); + std::string timeStr = LLWLAnimator::timeToString(val); LLTextBox* textBox; - textBox = getChild<LLTextBox>("EnvTimeText"); + textBox = sEnvSettings->getChild<LLTextBox>("EnvTimeText"); textBox->setValue(timeStr); @@ -106,62 +145,159 @@ void LLFloaterEnvSettings::syncMenu() // sync cloud coverage bool err; - getChild<LLUICtrl>("EnvCloudSlider")->setValue(LLWLParamManager::instance()->mCurParams.getFloat("cloud_shadow", err)); + childSetValue("EnvCloudSlider", LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_shadow", err)); - LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); // sync water params LLColor4 col = param_mgr->getFogColor(); - LLColorSwatchCtrl* colCtrl = getChild<LLColorSwatchCtrl>("EnvWaterColor"); + LLColorSwatchCtrl* colCtrl = sEnvSettings->getChild<LLColorSwatchCtrl>("EnvWaterColor"); col.mV[3] = 1.0f; colCtrl->set(col); - getChild<LLUICtrl>("EnvWaterFogSlider")->setValue(param_mgr->mFogDensity.mExp); + childSetValue("EnvWaterFogSlider", param_mgr->mFogDensity.mExp); param_mgr->setDensitySliderValue(param_mgr->mFogDensity.mExp); - // turn off Use Estate Time button if it's already being used - if(LLWLParamManager::instance()->mAnimator.mUseLindenTime) + // turn off Use Estate/Local Time buttons if already being used + + if(LLWLParamManager::getInstance()->mAnimator.getUseLindenTime()) { - getChildView("EnvUseEstateTimeButton")->setEnabled(FALSE); - } else { - getChildView("EnvUseEstateTimeButton")->setEnabled(TRUE); + childDisable("EnvUseEstateTimeButton"); + } + else + { + childEnable("EnvUseEstateTimeButton"); + } + + if(LLWLParamManager::getInstance()->mAnimator.getUseLocalTime()) + { + childDisable("EnvUseLocalTimeButton"); + } + else + { + childEnable("EnvUseLocalTimeButton"); } if(!gPipeline.canUseVertexShaders()) { - getChildView("EnvWaterColor")->setEnabled(FALSE); - getChildView("EnvWaterColorText")->setEnabled(FALSE); - //getChildView("EnvAdvancedWaterButton")->setEnabled(FALSE); + childDisable("EnvWaterColor"); + childDisable("EnvWaterColorText"); + //childDisable("EnvAdvancedWaterButton"); } else { - getChildView("EnvWaterColor")->setEnabled(TRUE); - getChildView("EnvWaterColorText")->setEnabled(TRUE); - //getChildView("EnvAdvancedWaterButton")->setEnabled(TRUE); + childEnable("EnvWaterColor"); + childEnable("EnvWaterColorText"); + //childEnable("EnvAdvancedWaterButton"); } // only allow access to these if they are using windlight if(!gPipeline.canUseWindLightShaders()) { - getChildView("EnvCloudSlider")->setEnabled(FALSE); - getChildView("EnvCloudText")->setEnabled(FALSE); - //getChildView("EnvAdvancedSkyButton")->setEnabled(FALSE); + childDisable("EnvCloudSlider"); + childDisable("EnvCloudText"); + //childDisable("EnvAdvancedSkyButton"); + } + else + { + childEnable("EnvCloudSlider"); + childEnable("EnvCloudText"); + //childEnable("EnvAdvancedSkyButton"); + } +} + + +// static instance of it +LLFloaterEnvSettings* LLFloaterEnvSettings::instance() +{ + if (!sEnvSettings) + { + sEnvSettings = new LLFloaterEnvSettings(); + // sEnvSettings->open(); + // sEnvSettings->setFocus(TRUE); + } + return sEnvSettings; +} + +void LLFloaterEnvSettings::setControlsEnabled(bool enable) +{ + if(enable) + { + // reenable UI elements, resync sliders, and reload saved settings + childEnable("EnvAdvancedSkyButton"); + childEnable("EnvAdvancedWaterButton"); + childEnable("EnvUseEstateTimeButton"); + childShow("EnvTimeText"); + childShow("EnvWaterColor"); + childShow("EnvTimeSlider"); + childShow("EnvCloudSlider"); + childShow("EnvWaterFogSlider"); + syncMenu(); } else { - getChildView("EnvCloudSlider")->setEnabled(TRUE); - getChildView("EnvCloudText")->setEnabled(TRUE); - //getChildView("EnvAdvancedSkyButton")->setEnabled(TRUE); + // disable UI elements the user shouldn't be able to see to protect potentially proprietary WL region settings from being visible + LLFloaterWindLight::instance()->close(); + LLFloaterWater::instance()->close(); + LLFloaterDayCycle::instance()->close(); + childDisable("EnvAdvancedSkyButton"); + childDisable("EnvAdvancedWaterButton"); + childDisable("EnvUseEstateTimeButton"); + childHide("EnvTimeText"); + childHide("EnvWaterColor"); + childHide("EnvTimeSlider"); + childHide("EnvCloudSlider"); + childHide("EnvWaterFogSlider"); } } -void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl) + +void LLFloaterEnvSettings::show() +{ + LLFloaterEnvSettings* envSettings = instance(); + envSettings->syncMenu(); + + // comment in if you want the menu to rebuild each time + //LLUICtrlFactory::getInstance()->buildFloater(envSettings, "floater_env_settings.xml"); + //envSettings->initCallbacks(); + + // Set environment opt-in checkbox based on saved value -- only need to do once, not every time syncMenu is called + + bool opt_in = gSavedSettings.getBOOL("UseEnvironmentFromRegion"); + + sEnvSettings->childSetVisible("RegionWLOptIn", LLEnvManager::getInstance()->regionCapable()); + sEnvSettings->setOptIn(opt_in); + sEnvSettings->getChildView("RegionWLOptIn")->setValue(LLSD::Boolean(opt_in)); + sEnvSettings->getChildView("RegionWLOptIn")->setToolTip(sEnvSettings->getString("region_environment_tooltip")); + envSettings->open(); +} + +bool LLFloaterEnvSettings::isOpen() { - LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl); + if (sEnvSettings != NULL) + { + return true; + } + return false; +} + +// virtual +void LLFloaterEnvSettings::onClose(bool app_quitting) +{ + if (sEnvSettings) + { + sEnvSettings->setVisible(FALSE); + } +} + + +void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldr; + sldr = sEnvSettings->getChild<LLSliderCtrl>("EnvTimeSlider"); // deactivate animator - LLWLParamManager::instance()->mAnimator.mIsRunning = false; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.deactivate(); F32 val = sldr->getValueF32() + 0.25f; if(val > 1.0) @@ -169,100 +305,81 @@ void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl) val--; } - LLWLParamManager::instance()->mAnimator.setDayTime((F64)val); - LLWLParamManager::instance()->mAnimator.update( - LLWLParamManager::instance()->mCurParams); + LLWLParamManager::getInstance()->mAnimator.setDayTime((F64)val); + LLWLParamManager::getInstance()->mAnimator.update( + LLWLParamManager::getInstance()->mCurParams); } -void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl) +void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl, void* userData) { - LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl); + LLSliderCtrl* sldr; + sldr = sEnvSettings->getChild<LLSliderCtrl>("EnvCloudSlider"); // deactivate animator - //LLWLParamManager::instance()->mAnimator.mIsRunning = false; - //LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + //LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; + //LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; F32 val = sldr->getValueF32(); - LLWLParamManager::instance()->mCurParams.set("cloud_shadow", val); + LLWLParamManager::getInstance()->mCurParams.set("cloud_shadow", val); } -void LLFloaterEnvSettings::onChangeWaterFogDensity(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl) +void LLFloaterEnvSettings::onChangeWaterFogDensity(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldr; - sldr = getChild<LLSliderCtrl>("EnvWaterFogSlider"); + sldr = sEnvSettings->getChild<LLSliderCtrl>("EnvWaterFogSlider"); + + if(NULL == userData) + { + return; + } + + WaterExpFloatControl * expFloatControl = static_cast<WaterExpFloatControl *>(userData); F32 val = sldr->getValueF32(); expFloatControl->mExp = val; - LLWaterParamManager::instance()->setDensitySliderValue(val); + LLWaterParamManager::getInstance()->setDensitySliderValue(val); - expFloatControl->update(LLWaterParamManager::instance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + expFloatControl->update(LLWaterParamManager::getInstance()->mCurParams); + LLWaterParamManager::getInstance()->propagateParameters(); } -void LLFloaterEnvSettings::onChangeWaterColor(LLUICtrl* ctrl, WaterColorControl* colorControl) +void LLFloaterEnvSettings::onChangeWaterColor(LLUICtrl* ctrl, void* userData) { LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl); + WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData); *colorControl = swatch->get(); - colorControl->update(LLWaterParamManager::instance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + colorControl->update(LLWaterParamManager::getInstance()->mCurParams); + LLWaterParamManager::getInstance()->propagateParameters(); } -void LLFloaterEnvSettings::onOpenAdvancedSky() +void LLFloaterEnvSettings::onOpenAdvancedSky(void* userData) { - LLFloaterReg::showInstance("env_windlight"); + LLFloaterWindLight::show(); } -void LLFloaterEnvSettings::onOpenAdvancedWater() +void LLFloaterEnvSettings::onOpenAdvancedWater(void* userData) { - LLFloaterReg::showInstance("env_water"); + LLFloaterWater::show(); } -void LLFloaterEnvSettings::onUseEstateTime() +void LLFloaterEnvSettings::onUseEstateTime(void* userData) { - LLFloaterWindLight* wl = LLFloaterReg::findTypedInstance<LLFloaterWindLight>("env_windlight"); - if(wl) + if(LLFloaterWindLight::isOpen()) { + // select the blank value in + LLFloaterWindLight* wl = LLFloaterWindLight::instance(); LLComboBox* box = wl->getChild<LLComboBox>("WLPresetsCombo"); box->selectByValue(""); } - LLWLParamManager::instance()->mAnimator.mIsRunning = true; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = true; + LLWLParamManager::getInstance()->mAnimator.activate(LLWLAnimator::TIME_LINDEN); } -std::string LLFloaterEnvSettings::timeToString(F32 curTime) +void LLFloaterEnvSettings::onUseLocalTime(void* userData) { - S32 hours; - S32 min; - - // get hours and minutes - hours = (S32) (24.0 * curTime); - curTime -= ((F32) hours / 24.0f); - min = llround(24.0f * 60.0f * curTime); - - // handle case where it's 60 - if(min == 60) - { - hours++; - min = 0; - } - - std::string newTime = getString("timeStr"); - struct tm * timeT; - time_t secT = time(0); - timeT = gmtime (&secT); - - timeT->tm_hour = hours; - timeT->tm_min = min; - secT = mktime (timeT); - secT -= LLStringOps::getLocalTimeOffset (); - - LLSD substitution; - substitution["datetime"] = (S32) secT; - - LLStringUtil::format (newTime, substitution); - return newTime; + LLWLParamManager::getInstance()->mAnimator.setDayTime(LLWLAnimator::getLocalTime()); + LLWLParamManager::getInstance()->mAnimator.activate(LLWLAnimator::TIME_LOCAL); } diff --git a/indra/newview/llfloaterenvsettings.h b/indra/newview/llfloaterenvsettings.h index a6280cfb97..0bf3e48676 100644 --- a/indra/newview/llfloaterenvsettings.h +++ b/indra/newview/llfloaterenvsettings.h @@ -2,25 +2,31 @@ * @file llfloaterskysettings.h * @brief LLFloaterEnvSettings class definition * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, 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. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * 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. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * 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 + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -33,50 +39,77 @@ #include "llfloater.h" -struct WaterColorControl; -struct WaterExpFloatControl; /// Menuing system for all of windlight's functionality class LLFloaterEnvSettings : public LLFloater { public: - LLFloaterEnvSettings(const LLSD& key); - /*virtual*/ ~LLFloaterEnvSettings(); - /*virtual*/ BOOL postBuild(); + LLFloaterEnvSettings(); + virtual ~LLFloaterEnvSettings(); + /// initialize all the callbacks for the menu void initCallbacks(void); + /// one and one instance only + static LLFloaterEnvSettings* instance(); + + /// callback for the menus help button + static void onClickHelp(void* data); + /// handle if time of day is changed - void onChangeDayTime(LLUICtrl* ctrl); + static void onChangeDayTime(LLUICtrl* ctrl, void* userData); /// handle if cloud coverage is changed - void onChangeCloudCoverage(LLUICtrl* ctrl); + static void onChangeCloudCoverage(LLUICtrl* ctrl, void* userData); /// handle change in water fog density - void onChangeWaterFogDensity(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl); + static void onChangeWaterFogDensity(LLUICtrl* ctrl, void* userData); + + /// handle change in under water fog density + static void onChangeUnderWaterFogMod(LLUICtrl* ctrl, void* userData); /// handle change in water fog color - void onChangeWaterColor(LLUICtrl* ctrl, WaterColorControl* colorControl); + static void onChangeWaterColor(LLUICtrl* ctrl, void* userData); /// open the advanced sky settings menu - void onOpenAdvancedSky(); + static void onOpenAdvancedSky(void* userData); /// open the advanced water settings menu - void onOpenAdvancedWater(); + static void onOpenAdvancedWater(void* userData); /// sync time with the server - void onUseEstateTime(); + static void onUseEstateTime(void* userData); + + /// sync time with local clock + static void onUseLocalTime(void* userData); + + // opt-in for region Windlight settings + //static void onUseRegionEnvironment(LLUICtrl* ctrl, void* userData); + static void onUseRegionEnvironment(LLUICtrl*, void*); //// menu management + /// enables or disable all controls + void setControlsEnabled(bool enable); + + /// show off our menu + static void show(); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); + /// sync up sliders with parameters void syncMenu(); - /// convert the present time to a digital clock time - std::string timeToString(F32 curTime); - private: + // one instance on the inside + static LLFloaterEnvSettings* sEnvSettings; + + static void setOptIn(bool opt_in); }; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index ed81fdec16..f6377d50fa 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -40,6 +40,8 @@ #include "llxfermanager.h" #include "indra_constants.h" #include "message.h" +#include "llsd.h" +#include "llsdserialize.h" #include "llagent.h" #include "llappviewer.h" @@ -47,6 +49,7 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" +#include "llenvmanager.h" #include "llfilepicker.h" #include "llfloatergodtools.h" // for send_sim_wide_deletes() #include "llfloatertopobjects.h" // added to fix SL-32336 @@ -81,6 +84,9 @@ #include "lltrans.h" #include "llagentui.h" +// contains includes needed for WL estate settings +#include "llfloaterwater.h" + const S32 TERRAIN_TEXTURE_COUNT = 4; const S32 CORNER_COUNT = 4; @@ -287,6 +293,10 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) return; } + + // currently, region can send this message when its windlight settings change + LLEnvManager::instance().refreshFromStorage(LLEnvKey::SCOPE_REGION); + LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); LLViewerRegion* region = gAgent.getRegion(); @@ -1144,9 +1154,32 @@ void LLPanelRegionTextureInfo::onClickDump(void* data) ///////////////////////////////////////////////////////////////////////////// // LLPanelRegionTerrainInfo ///////////////////////////////////////////////////////////////////////////// +// Initialize statics +LLPanelRegionTerrainInfo* LLPanelRegionTerrainInfo::sPanelRegionTerrainInfo = NULL; + +LLPanelRegionTerrainInfo* LLPanelRegionTerrainInfo::instance() +{ + if (!sPanelRegionTerrainInfo) + { + sPanelRegionTerrainInfo = new LLPanelRegionTerrainInfo(); + } + return sPanelRegionTerrainInfo; +} + +// virtual +void LLPanelRegionTerrainInfo::close(bool app_quitting) +{ + if (sPanelRegionTerrainInfo) + { + sPanelRegionTerrainInfo = NULL; + } +} + BOOL LLPanelRegionTerrainInfo::postBuild() { LLPanelRegionInfo::postBuild(); + + sPanelRegionTerrainInfo = this; // singleton instance pointer initCtrl("water_height_spin"); initCtrl("terrain_raise_spin"); @@ -1161,20 +1194,42 @@ BOOL LLPanelRegionTerrainInfo::postBuild() childSetAction("upload_raw_btn", onClickUploadRaw, this); childSetAction("bake_terrain_btn", onClickBakeTerrain, this); + // WL advanced buttons + childSetAction("EnvAdvancedSkyButton", onOpenAdvancedSky, this); + childSetAction("EnvAdvancedWaterButton", onOpenAdvancedWater, this); + childSetAction("EnvUseEstateTimeButton", onUseEstateTime, this); + + // Commit, cancel, and default + childSetAction("WLRegionApply", onCommitRegionWL, this); + childSetAction("WLRegionCancel", onCancelRegionWL, this); + childSetAction("WLRegionDefault", onSetRegionToDefaultWL, this); + return TRUE; } +F32 LLPanelRegionTerrainInfo::getSunHour() +{ + if (childIsEnabled("sun_hour_slider")) + { + return (F32)childGetValue("sun_hour_slider").asReal(); + } + return 0.f; +} + // virtual bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { - llinfos << "LLPanelRegionTerrainInfo::refreshFromRegion" << llendl; - BOOL owner_or_god = gAgent.isGodlike() || (region && (region->getOwner() == gAgent.getID())); BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager()); setCtrlsEnabled(owner_or_god_or_manager); + + // Disable select children + LLPanelRegionTerrainInfo::instance()->setCommitControls(false); + LLPanelRegionTerrainInfo::instance()->setEnvControls(LLEnvManager::getInstance()->regionCapable()); getChildView("apply_btn")->setEnabled(FALSE); + LLEnvManager::instance().maybeClearEditingScope(LLEnvKey::SCOPE_REGION, false, false); getChildView("download_raw_btn")->setEnabled(owner_or_god); getChildView("upload_raw_btn")->setEnabled(owner_or_god); @@ -1183,6 +1238,24 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) return LLPanelRegionInfo::refreshFromRegion(region); } +void LLPanelRegionTerrainInfo::setEnvControls(bool available) +{ + getChildView("EnvUseEstateTimeButton")->setVisible(available); + getChildView("EnvAdvancedSkyButton")->setVisible(available); + getChildView("EnvAdvancedWaterButton")->setVisible(available); + getChildView("WLRegionApply")->setVisible(available); + getChildView("WLRegionCancel")->setVisible(available); + getChildView("WLRegionDefault")->setVisible(available); + getChildView("wl_settings_unavailable")->setVisible(!available); +} + +void LLPanelRegionTerrainInfo::setCommitControls(bool available) +{ + getChildView("WLRegionApply")->setEnabled(available); + getChildView("WLRegionCancel")->setEnabled(available); + refresh(); +} + // virtual BOOL LLPanelRegionTerrainInfo::sendUpdate() { @@ -1320,9 +1393,70 @@ bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, con strings.push_back("bake"); LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); + return false; } +/////////////////////////////////////////////////////////////// +// Callbacks for WindLight additions to Region terrain panel + +void LLPanelRegionTerrainInfo::onOpenAdvancedSky(void* userData) +{ + LLFloaterWindLight::show(LLEnvKey::SCOPE_REGION); +} + +void LLPanelRegionTerrainInfo::onOpenAdvancedWater(void* userData) +{ + LLFloaterWater::show(LLEnvKey::SCOPE_REGION); +} + + +void LLPanelRegionTerrainInfo::onUseEstateTime(void* userData) +{ + if(LLFloaterWindLight::isOpen()) + { + // select the blank value in + LLFloaterWindLight* wl = LLFloaterWindLight::instance(); + LLComboBox* box = wl->getChild<LLComboBox>("WLPresetsCombo"); + box->selectByValue(""); + } + + LLWLParamManager::getInstance()->mAnimator.activate(LLWLAnimator::TIME_LINDEN); +} + +/////////////////////////////////////////////////////// +// Advanced handling for WL region estate integration + +// Handle commit of WL settings to region +void LLPanelRegionTerrainInfo::onCommitRegionWL(void* userData) +{ + LLEnvManager::getInstance()->commitSettings(LLEnvKey::SCOPE_REGION); + LLEnvManager::getInstance()->maybeClearEditingScope(LLEnvKey::SCOPE_REGION, true, false); +} + +// Handle cancel of WL settings for region +void LLPanelRegionTerrainInfo::onCancelRegionWL(void* userData) +{ + LLEnvManager::getInstance()->maybeClearEditingScope(LLEnvKey::SCOPE_REGION, true, false); +} + +// Handle reversion of region WL settings to default +void LLPanelRegionTerrainInfo::onSetRegionToDefaultWL(void* userData) +{ + LLEnvManager::instance().resetInternalsToDefault(LLEnvKey::SCOPE_REGION); + LLEnvManager::instance().startEditingScope(LLEnvKey::SCOPE_REGION); +} + +void LLPanelRegionTerrainInfo::cancelChanges() +{ + LLFloaterWindLight::instance()->close(); + LLFloaterWater::instance()->close(); + LLFloaterDayCycle::instance()->close(); + + // disable commmit and cancel + LLPanelRegionTerrainInfo::instance()->setCommitControls(false); +} + ///////////////////////////////////////////////////////////////////////////// // LLPanelEstateInfo // @@ -1996,6 +2130,16 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) return rv; } +void LLFloaterRegionInfo::close(bool app_quitting) +{ + if(!app_quitting) + { + LLEnvManager::getInstance()->maybeClearEditingScope(true, false); + LLPanelRegionTerrainInfo::close(app_quitting); + } + LLFloater::close(app_quitting); +} + void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl) { if (checkRemovalButton(child_ctrl->getName())) diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 2393c74c45..2fdec5a944 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -57,6 +57,13 @@ class LLPanelRegionTerrainInfo; class LLPanelEstateInfo; class LLPanelEstateCovenant; +class LLEventTimer; +class LLEnvironmentSettings; +class LLWLParamManager; +class LLWaterParamManager; +class LLWLParamSet; +class LLWaterParamSet; + class LLFloaterRegionInfo : public LLFloater { friend class LLFloaterReg; @@ -221,19 +228,27 @@ protected: }; ///////////////////////////////////////////////////////////////////////////// - class LLPanelRegionTerrainInfo : public LLPanelRegionInfo { public: - LLPanelRegionTerrainInfo() - : LLPanelRegionInfo() {} + LLPanelRegionTerrainInfo() : LLPanelRegionInfo() {} ~LLPanelRegionTerrainInfo() {} - // LLPanel - virtual BOOL postBuild(); - virtual bool refreshFromRegion(LLViewerRegion* region); + static LLPanelRegionTerrainInfo* instance(); + virtual BOOL postBuild(); // LLPanel + static void close(bool app_quitting); + + F32 getSunHour(); + virtual bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator + void setEnvControls(bool available); // Whether environment settings are available for this region + void setCommitControls(bool available); // Whether user can currently commit (whether they changed anything) + void cancelChanges(); // cancels changes, reverts local settings, and resyncs UI + + //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button protected: + static LLPanelRegionTerrainInfo* sPanelRegionTerrainInfo; // static instance pointer for singleton + virtual BOOL sendUpdate(); void onChangeUseEstateTime(); @@ -244,6 +259,13 @@ protected: static void onClickUploadRaw(void*); static void onClickBakeTerrain(void*); bool callbackBakeTerrain(const LLSD& notification, const LLSD& response); + + static void onOpenAdvancedSky(void* userData); // open the advanced sky settings menu + static void onOpenAdvancedWater(void* userData); // open the advanced water settings menu + static void onUseEstateTime(void* userData); // sync time with the server + static void onCommitRegionWL(void* userData); // commit region information to server + static void onCancelRegionWL(void* userData); // cancel changes to region + static void onSetRegionToDefaultWL(void* userData); // revert region WL settings to default }; ///////////////////////////////////////////////////////////////////////////// @@ -332,6 +354,7 @@ public: // are ignored, so must disable UI. void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban); + virtual void close(bool app_quitting = false); protected: virtual BOOL sendUpdate(); // confirmation dialog callback diff --git a/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp index be4b144f41..a443b788fb 100644 --- a/indra/newview/llfloaterwater.cpp +++ b/indra/newview/llfloaterwater.cpp @@ -59,6 +59,8 @@ #undef max std::set<std::string> LLFloaterWater::sDefaultPresets; +LLEnvKey::EScope LLFloaterWater::sScope; +std::string LLFloaterWater::sOriginalTitle; LLFloaterWater::LLFloaterWater(const LLSD& key) : LLFloater(key) @@ -70,7 +72,7 @@ LLFloaterWater::~LLFloaterWater() } BOOL LLFloaterWater::postBuild() { - + sOriginalTitle=getTitle(); std::string def_water = getString("WLDefaultWaterNames"); // no editing or deleting of the blank string @@ -88,8 +90,8 @@ BOOL LLFloaterWater::postBuild() if(comboBox != NULL) { std::map<std::string, LLWaterParamSet>::iterator mIt = - LLWaterParamManager::instance()->mParamList.begin(); - for(; mIt != LLWaterParamManager::instance()->mParamList.end(); mIt++) + LLWaterParamManager::getInstance()->mParamList.begin(); + for(; mIt != LLWaterParamManager::getInstance()->mParamList.end(); mIt++) { comboBox->add(mIt->first); } @@ -104,7 +106,7 @@ BOOL LLFloaterWater::postBuild() } void LLFloaterWater::initCallbacks(void) { - LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); getChild<LLUICtrl>("WaterFogColor")->setCommitCallback(boost::bind(&LLFloaterWater::onWaterFogColorMoved, this, _1, ¶m_mgr->mFogColor)); @@ -163,7 +165,7 @@ bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& res if(option == 0) { LLComboBox* comboBox = getChild<LLComboBox>( "WaterPresetsCombo"); - LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); // add the current parameters to the list // see if it's there first @@ -195,7 +197,7 @@ void LLFloaterWater::syncMenu() { bool err; - LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); LLWaterParamSet & current_params = param_mgr->mCurParams; @@ -262,9 +264,9 @@ void LLFloaterWater::onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl->mX = sldrCtrl->getValueF32(); - vectorControl->update(LLWaterParamManager::instance()->mCurParams); + vectorControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + LLWaterParamManager::getInstance()->propagateParameters(); } // vector control callbacks @@ -274,9 +276,9 @@ void LLFloaterWater::onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl->mY = sldrCtrl->getValueF32(); - vectorControl->update(LLWaterParamManager::instance()->mCurParams); + vectorControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + LLWaterParamManager::getInstance()->propagateParameters(); } // vector control callbacks @@ -286,9 +288,9 @@ void LLFloaterWater::onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl->mZ = sldrCtrl->getValueF32(); - vectorControl->update(LLWaterParamManager::instance()->mCurParams); + vectorControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + LLWaterParamManager::getInstance()->propagateParameters(); } @@ -299,9 +301,9 @@ void LLFloaterWater::onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl->mX = sldrCtrl->getValueF32(); - vectorControl->update(LLWaterParamManager::instance()->mCurParams); + vectorControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + LLWaterParamManager::getInstance()->propagateParameters(); } // vector control callbacks @@ -311,9 +313,9 @@ void LLFloaterWater::onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl->mY = sldrCtrl->getValueF32(); - vectorControl->update(LLWaterParamManager::instance()->mCurParams); + vectorControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + LLWaterParamManager::getInstance()->propagateParameters(); } // color control callbacks @@ -335,9 +337,9 @@ void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* col getChild<LLUICtrl>(name)->setValue(colorControl->mR); } - colorControl->update(LLWaterParamManager::instance()->mCurParams); + colorControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + LLWaterParamManager::getInstance()->propagateParameters(); } void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) @@ -359,9 +361,9 @@ void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* col } - colorControl->update(LLWaterParamManager::instance()->mCurParams); + colorControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + LLWaterParamManager::getInstance()->propagateParameters(); } void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) @@ -382,9 +384,9 @@ void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* col getChild<LLUICtrl>(name)->setValue(colorControl->mB); } - colorControl->update(LLWaterParamManager::instance()->mCurParams); + colorControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + LLWaterParamManager::getInstance()->propagateParameters(); } void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) @@ -393,9 +395,9 @@ void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* col colorControl->mA = sldrCtrl->getValueF32(); - colorControl->update(LLWaterParamManager::instance()->mCurParams); + colorControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + LLWaterParamManager::getInstance()->propagateParameters(); } @@ -454,8 +456,8 @@ void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* col } // now update the current parameters and send them to shaders - colorControl->update(LLWaterParamManager::instance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + colorControl->update(LLWaterParamManager::getInstance()->mCurParams); + LLWaterParamManager::getInstance()->propagateParameters(); } void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl) @@ -464,10 +466,10 @@ void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl F32 val = sldrCtrl->getValueF32(); expFloatControl->mExp = val; - LLWaterParamManager::instance()->setDensitySliderValue(val); + LLWaterParamManager::getInstance()->setDensitySliderValue(val); - expFloatControl->update(LLWaterParamManager::instance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + expFloatControl->update(LLWaterParamManager::getInstance()->mCurParams); + LLWaterParamManager::getInstance()->propagateParameters(); } void LLFloaterWater::onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl) @@ -476,23 +478,23 @@ void LLFloaterWater::onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floa floatControl->mX = sldrCtrl->getValueF32() / floatControl->mMult; - floatControl->update(LLWaterParamManager::instance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + floatControl->update(LLWaterParamManager::getInstance()->mCurParams); + LLWaterParamManager::getInstance()->propagateParameters(); } void LLFloaterWater::onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) { LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl); *colorControl = swatch->get(); - colorControl->update(LLWaterParamManager::instance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + colorControl->update(LLWaterParamManager::getInstance()->mCurParams); + LLWaterParamManager::getInstance()->propagateParameters(); } void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl) { LLTextureCtrl* textCtrl = static_cast<LLTextureCtrl*>(ctrl); LLUUID textID = textCtrl->getImageAssetID(); - LLWaterParamManager::instance()->setNormalMapID(textID); + LLWaterParamManager::getInstance()->setNormalMapID(textID); } void LLFloaterWater::onNewPreset() @@ -511,7 +513,7 @@ void LLFloaterWater::onSavePreset() return; } - LLWaterParamManager::instance()->mCurParams.mName = + LLWaterParamManager::getInstance()->mCurParams.mName = comboBox->getSelectedItemLabel(); // check to see if it's a default and shouldn't be overwritten @@ -532,7 +534,7 @@ bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& res // if they choose save, do it. Otherwise, don't do anything if(option == 0) { - LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); param_mgr->setParamSet( param_mgr->mCurParams.mName, @@ -583,7 +585,7 @@ bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& r return false; } - LLWaterParamManager::instance()->removeParamSet(name, true); + LLWaterParamManager::getInstance()->removeParamSet(name, true); // remove and choose another S32 new_index = combo_box->getCurrentIndex(); @@ -594,8 +596,8 @@ bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& r { key_combo->remove(name); - // remove from slider, as well - day_cycle->deletePreset(name); + // water is not part of day cycles, yet + //day_cycle->deletePreset(name); } // pick the previously selected index after delete diff --git a/indra/newview/llfloaterwater.h b/indra/newview/llfloaterwater.h index e3db91e80d..57fb9745b1 100644 --- a/indra/newview/llfloaterwater.h +++ b/indra/newview/llfloaterwater.h @@ -101,6 +101,8 @@ public: private: static std::set<std::string> sDefaultPresets; + static LLEnvKey::EScope sScope; + static std::string sOriginalTitle; }; diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp index ae98b2cf99..960a552b3d 100644 --- a/indra/newview/llfloaterwindlight.cpp +++ b/indra/newview/llfloaterwindlight.cpp @@ -2,25 +2,31 @@ * @file llfloaterwindlight.cpp * @brief LLFloaterWindLight class definition * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, 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. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * 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. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * 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 + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -31,11 +37,9 @@ #include "pipeline.h" #include "llsky.h" -#include "llfloaterreg.h" #include "llsliderctrl.h" #include "llmultislider.h" #include "llmultisliderctrl.h" -#include "llnotificationsutil.h" #include "llspinctrl.h" #include "llcheckboxctrl.h" #include "lluictrlfactory.h" @@ -54,48 +58,31 @@ #include "llwlparamset.h" #include "llwlparammanager.h" #include "llpostprocess.h" -#include "lltabcontainer.h" - #undef max -std::set<std::string> LLFloaterWindLight::sDefaultPresets; +LLFloaterWindLight* LLFloaterWindLight::sWindLight = NULL; +std::set<LLWLParamKey> LLFloaterWindLight::sDefaultPresets; +LLEnvKey::EScope LLFloaterWindLight::sScope; +std::string LLFloaterWindLight::sOriginalTitle; static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f; -LLFloaterWindLight::LLFloaterWindLight(const LLSD& key) - : LLFloater(key) +LLFloaterWindLight::LLFloaterWindLight() : LLFloater(std::string("windlight floater")) { -} - -LLFloaterWindLight::~LLFloaterWindLight() -{ -} - -BOOL LLFloaterWindLight::postBuild() -{ - // add the list of presets - std::string def_days = getString("WLDefaultSkyNames"); - - // no editing or deleting of the blank string - sDefaultPresets.insert(""); - boost_tokenizer tokens(def_days, boost::char_separator<char>(":")); - for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) - { - std::string tok(*token_iter); - sDefaultPresets.insert(tok); - } - + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_windlight_options.xml", NULL, FALSE); + sOriginalTitle = getTitle(); + // add the combo boxes LLComboBox* comboBox = getChild<LLComboBox>("WLPresetsCombo"); if(comboBox != NULL) { - - std::map<std::string, LLWLParamSet>::iterator mIt = - LLWLParamManager::instance()->mParamList.begin(); - for(; mIt != LLWLParamManager::instance()->mParamList.end(); mIt++) + + std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = + LLWLParamManager::getInstance()->mParamList.begin(); + for(; mIt != LLWLParamManager::getInstance()->mParamList.end(); mIt++) { - comboBox->add(mIt->first); + comboBox->add(mIt->first.toString(), mIt->first.toLLSD()); } // entry for when we're in estate time @@ -104,107 +91,167 @@ BOOL LLFloaterWindLight::postBuild() // set defaults on combo boxes comboBox->selectByValue(LLSD("Default")); } + + // add the list of presets + std::string def_days = getString("WLDefaultSkyNames"); + + // no editing or deleting of the blank string + LLWLParamKey blank("", LLEnvKey::SCOPE_LOCAL); + sDefaultPresets.insert(blank); + boost_tokenizer tokens(def_days, boost::char_separator<char>(":")); + for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) + { + std::string tok(*token_iter); + LLWLParamKey key(tok, LLEnvKey::SCOPE_LOCAL); + sDefaultPresets.insert(key); + } + // load it up initCallbacks(); +} - syncMenu(); - - return TRUE; +LLFloaterWindLight::~LLFloaterWindLight() +{ } + void LLFloaterWindLight::initCallbacks(void) { - LLWLParamManager * param_mgr = LLWLParamManager::instance(); + // help buttons + initHelpBtn("WLBlueHorizonHelp", "HelpBlueHorizon"); + initHelpBtn("WLHazeHorizonHelp", "HelpHazeHorizon"); + initHelpBtn("WLBlueDensityHelp", "HelpBlueDensity"); + initHelpBtn("WLHazeDensityHelp", "HelpHazeDensity"); + + initHelpBtn("WLDensityMultHelp", "HelpDensityMult"); + initHelpBtn("WLDistanceMultHelp", "HelpDistanceMult"); + initHelpBtn("WLMaxAltitudeHelp", "HelpMaxAltitude"); + + initHelpBtn("WLSunlightColorHelp", "HelpSunlightColor"); + initHelpBtn("WLAmbientHelp", "HelpSunAmbient"); + initHelpBtn("WLSunGlowHelp", "HelpSunGlow"); + initHelpBtn("WLTimeOfDayHelp", "HelpTimeOfDay"); + initHelpBtn("WLEastAngleHelp", "HelpEastAngle"); + + initHelpBtn("WLSceneGammaHelp", "HelpSceneGamma"); + initHelpBtn("WLStarBrightnessHelp", "HelpStarBrightness"); + + initHelpBtn("WLCloudColorHelp", "HelpCloudColor"); + initHelpBtn("WLCloudDetailHelp", "HelpCloudDetail"); + initHelpBtn("WLCloudDensityHelp", "HelpCloudDensity"); + initHelpBtn("WLCloudCoverageHelp", "HelpCloudCoverage"); + + initHelpBtn("WLCloudScaleHelp", "HelpCloudScale"); + initHelpBtn("WLCloudScrollXHelp", "HelpCloudScrollX"); + initHelpBtn("WLCloudScrollYHelp", "HelpCloudScrollY"); + + initHelpBtn("WLClassicCloudsHelp", "HelpClassicClouds"); + + LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); // blue horizon - getChild<LLUICtrl>("WLBlueHorizonR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mBlueHorizon)); - getChild<LLUICtrl>("WLBlueHorizonG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mBlueHorizon)); - getChild<LLUICtrl>("WLBlueHorizonB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mBlueHorizon)); - getChild<LLUICtrl>("WLBlueHorizonI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mBlueHorizon)); + childSetCommitCallback("WLBlueHorizonR", onColorControlRMoved, ¶m_mgr->mBlueHorizon); + childSetCommitCallback("WLBlueHorizonG", onColorControlGMoved, ¶m_mgr->mBlueHorizon); + childSetCommitCallback("WLBlueHorizonB", onColorControlBMoved, ¶m_mgr->mBlueHorizon); + childSetCommitCallback("WLBlueHorizonI", onColorControlIMoved, ¶m_mgr->mBlueHorizon); // haze density, horizon, mult, and altitude - getChild<LLUICtrl>("WLHazeDensity")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mHazeDensity)); - getChild<LLUICtrl>("WLHazeHorizon")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mHazeHorizon)); - getChild<LLUICtrl>("WLDensityMult")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mDensityMult)); - getChild<LLUICtrl>("WLMaxAltitude")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mMaxAlt)); + childSetCommitCallback("WLHazeDensity", onColorControlRMoved, ¶m_mgr->mHazeDensity); + childSetCommitCallback("WLHazeHorizon", onColorControlRMoved, ¶m_mgr->mHazeHorizon); + childSetCommitCallback("WLDensityMult", onFloatControlMoved, ¶m_mgr->mDensityMult); + childSetCommitCallback("WLMaxAltitude", onFloatControlMoved, ¶m_mgr->mMaxAlt); // blue density - getChild<LLUICtrl>("WLBlueDensityR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mBlueDensity)); - getChild<LLUICtrl>("WLBlueDensityG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mBlueDensity)); - getChild<LLUICtrl>("WLBlueDensityB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mBlueDensity)); - getChild<LLUICtrl>("WLBlueDensityI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mBlueDensity)); + childSetCommitCallback("WLBlueDensityR", onColorControlRMoved, ¶m_mgr->mBlueDensity); + childSetCommitCallback("WLBlueDensityG", onColorControlGMoved, ¶m_mgr->mBlueDensity); + childSetCommitCallback("WLBlueDensityB", onColorControlBMoved, ¶m_mgr->mBlueDensity); + childSetCommitCallback("WLBlueDensityI", onColorControlIMoved, ¶m_mgr->mBlueDensity); // Lighting // sunlight - getChild<LLUICtrl>("WLSunlightR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mSunlight)); - getChild<LLUICtrl>("WLSunlightG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mSunlight)); - getChild<LLUICtrl>("WLSunlightB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mSunlight)); - getChild<LLUICtrl>("WLSunlightI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mSunlight)); + childSetCommitCallback("WLSunlightR", onColorControlRMoved, ¶m_mgr->mSunlight); + childSetCommitCallback("WLSunlightG", onColorControlGMoved, ¶m_mgr->mSunlight); + childSetCommitCallback("WLSunlightB", onColorControlBMoved, ¶m_mgr->mSunlight); + childSetCommitCallback("WLSunlightI", onColorControlIMoved, ¶m_mgr->mSunlight); // glow - getChild<LLUICtrl>("WLGlowR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onGlowRMoved, this, _1, ¶m_mgr->mGlow)); - getChild<LLUICtrl>("WLGlowB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onGlowBMoved, this, _1, ¶m_mgr->mGlow)); + childSetCommitCallback("WLGlowR", onGlowRMoved, ¶m_mgr->mGlow); + childSetCommitCallback("WLGlowB", onGlowBMoved, ¶m_mgr->mGlow); // ambient - getChild<LLUICtrl>("WLAmbientR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mAmbient)); - getChild<LLUICtrl>("WLAmbientG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mAmbient)); - getChild<LLUICtrl>("WLAmbientB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mAmbient)); - getChild<LLUICtrl>("WLAmbientI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mAmbient)); + childSetCommitCallback("WLAmbientR", onColorControlRMoved, ¶m_mgr->mAmbient); + childSetCommitCallback("WLAmbientG", onColorControlGMoved, ¶m_mgr->mAmbient); + childSetCommitCallback("WLAmbientB", onColorControlBMoved, ¶m_mgr->mAmbient); + childSetCommitCallback("WLAmbientI", onColorControlIMoved, ¶m_mgr->mAmbient); // time of day - getChild<LLUICtrl>("WLSunAngle")->setCommitCallback(boost::bind(&LLFloaterWindLight::onSunMoved, this, _1, ¶m_mgr->mLightnorm)); - getChild<LLUICtrl>("WLEastAngle")->setCommitCallback(boost::bind(&LLFloaterWindLight::onSunMoved, this, _1, ¶m_mgr->mLightnorm)); + childSetCommitCallback("WLSunAngle", onSunMoved, ¶m_mgr->mLightnorm); + childSetCommitCallback("WLEastAngle", onSunMoved, ¶m_mgr->mLightnorm); // Clouds // Cloud Color - getChild<LLUICtrl>("WLCloudColorR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mCloudColor)); - getChild<LLUICtrl>("WLCloudColorG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mCloudColor)); - getChild<LLUICtrl>("WLCloudColorB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mCloudColor)); - getChild<LLUICtrl>("WLCloudColorI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mCloudColor)); + childSetCommitCallback("WLCloudColorR", onColorControlRMoved, ¶m_mgr->mCloudColor); + childSetCommitCallback("WLCloudColorG", onColorControlGMoved, ¶m_mgr->mCloudColor); + childSetCommitCallback("WLCloudColorB", onColorControlBMoved, ¶m_mgr->mCloudColor); + childSetCommitCallback("WLCloudColorI", onColorControlIMoved, ¶m_mgr->mCloudColor); // Cloud - getChild<LLUICtrl>("WLCloudX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mCloudMain)); - getChild<LLUICtrl>("WLCloudY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mCloudMain)); - getChild<LLUICtrl>("WLCloudDensity")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mCloudMain)); + childSetCommitCallback("WLCloudX", onColorControlRMoved, ¶m_mgr->mCloudMain); + childSetCommitCallback("WLCloudY", onColorControlGMoved, ¶m_mgr->mCloudMain); + childSetCommitCallback("WLCloudDensity", onColorControlBMoved, ¶m_mgr->mCloudMain); // Cloud Detail - getChild<LLUICtrl>("WLCloudDetailX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mCloudDetail)); - getChild<LLUICtrl>("WLCloudDetailY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mCloudDetail)); - getChild<LLUICtrl>("WLCloudDetailDensity")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mCloudDetail)); + childSetCommitCallback("WLCloudDetailX", onColorControlRMoved, ¶m_mgr->mCloudDetail); + childSetCommitCallback("WLCloudDetailY", onColorControlGMoved, ¶m_mgr->mCloudDetail); + childSetCommitCallback("WLCloudDetailDensity", onColorControlBMoved, ¶m_mgr->mCloudDetail); // Cloud extras - getChild<LLUICtrl>("WLCloudCoverage")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mCloudCoverage)); - getChild<LLUICtrl>("WLCloudScale")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mCloudScale)); - getChild<LLUICtrl>("WLCloudLockX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollXToggled, this, _1)); - getChild<LLUICtrl>("WLCloudLockY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollYToggled, this, _1)); - getChild<LLUICtrl>("WLCloudScrollX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollXMoved, this, _1)); - getChild<LLUICtrl>("WLCloudScrollY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollYMoved, this, _1)); - getChild<LLUICtrl>("WLDistanceMult")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mDistanceMult)); - getChild<LLUICtrl>("DrawClassicClouds")->setCommitCallback(boost::bind(LLSavedSettingsGlue::setBOOL, _1, "SkyUseClassicClouds")); + childSetCommitCallback("WLCloudCoverage", onFloatControlMoved, ¶m_mgr->mCloudCoverage); + childSetCommitCallback("WLCloudScale", onFloatControlMoved, ¶m_mgr->mCloudScale); + childSetCommitCallback("WLCloudLockX", onCloudScrollXToggled, NULL); + childSetCommitCallback("WLCloudLockY", onCloudScrollYToggled, NULL); + childSetCommitCallback("WLCloudScrollX", onCloudScrollXMoved, NULL); + childSetCommitCallback("WLCloudScrollY", onCloudScrollYMoved, NULL); + childSetCommitCallback("WLDistanceMult", onFloatControlMoved, ¶m_mgr->mDistanceMult); + childSetCommitCallback("DrawClassicClouds", LLSavedSettingsGlue::setBOOL, (void*)"SkyUseClassicClouds"); // WL Top - getChild<LLUICtrl>("WLDayCycleMenuButton")->setCommitCallback(boost::bind(&LLFloaterWindLight::onOpenDayCycle, this)); + childSetAction("WLDayCycleMenuButton", onOpenDayCycle, NULL); // Load/save LLComboBox* comboBox = getChild<LLComboBox>("WLPresetsCombo"); //childSetAction("WLLoadPreset", onLoadPreset, comboBox); - getChild<LLUICtrl>("WLNewPreset")->setCommitCallback(boost::bind(&LLFloaterWindLight::onNewPreset, this)); - getChild<LLUICtrl>("WLSavePreset")->setCommitCallback(boost::bind(&LLFloaterWindLight::onSavePreset, this)); - getChild<LLUICtrl>("WLDeletePreset")->setCommitCallback(boost::bind(&LLFloaterWindLight::onDeletePreset, this)); + childSetAction("WLNewPreset", onNewPreset, comboBox); + childSetAction("WLSavePreset", onSavePreset, comboBox); + childSetAction("WLDeletePreset", onDeletePreset, comboBox); - comboBox->setCommitCallback(boost::bind(&LLFloaterWindLight::onChangePresetName, this, _1)); + comboBox->setCommitCallback(onChangePresetName); // Dome - getChild<LLUICtrl>("WLGamma")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mWLGamma)); - getChild<LLUICtrl>("WLStarAlpha")->setCommitCallback(boost::bind(&LLFloaterWindLight::onStarAlphaMoved, this, _1)); + childSetCommitCallback("WLGamma", onFloatControlMoved, ¶m_mgr->mWLGamma); + childSetCommitCallback("WLStarAlpha", onStarAlphaMoved, NULL); +} + +void LLFloaterWindLight::onClickHelp(void* data) +{ + LLFloaterWindLight* self = LLFloaterWindLight::instance(); + + const std::string xml_alert = *(std::string*)data; + LLNotifications::instance().add(self->contextualNotification(xml_alert)); +} + +void LLFloaterWindLight::initHelpBtn(const std::string& name, const std::string& xml_alert) +{ + childSetAction(name, onClickHelp, new std::string(xml_alert)); } bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& response) { std::string text = response["message"].asString(); - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLWLParamKey newKey(text, LLEnvKey::SCOPE_LOCAL); + S32 option = LLNotification::getSelectedOption(notification, response); if(text == "") { @@ -212,26 +259,29 @@ bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& } if(option == 0) { - LLComboBox* comboBox = getChild<LLComboBox>("WLPresetsCombo"); + LLComboBox* comboBox = sWindLight->getChild<LLComboBox>( + "WLPresetsCombo"); - LLFloaterDayCycle* day_cycle = LLFloaterReg::findTypedInstance<LLFloaterDayCycle>("env_day_cycle"); + LLFloaterDayCycle* sDayCycle = NULL; LLComboBox* keyCombo = NULL; - if(day_cycle) + if(LLFloaterDayCycle::isOpen()) { - keyCombo = day_cycle->getChild<LLComboBox>("WLKeyPresets"); + sDayCycle = LLFloaterDayCycle::instance(); + keyCombo = sDayCycle->getChild<LLComboBox>( + "WLKeyPresets"); } // add the current parameters to the list // see if it's there first - std::map<std::string, LLWLParamSet>::iterator mIt = - LLWLParamManager::instance()->mParamList.find(text); + std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = + LLWLParamManager::getInstance()->mParamList.find(newKey); // if not there, add a new one - if(mIt == LLWLParamManager::instance()->mParamList.end()) + if(mIt == LLWLParamManager::getInstance()->mParamList.end()) { - LLWLParamManager::instance()->addParamSet(text, - LLWLParamManager::instance()->mCurParams); - comboBox->add(text); + LLWLParamManager::getInstance()->addParamSet(newKey, + LLWLParamManager::getInstance()->mCurParams); + comboBox->add(newKey.toString(), newKey.toLLSD()); comboBox->sortByName(); // add a blank to the bottom @@ -243,18 +293,18 @@ bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& comboBox->add(LLStringUtil::null); comboBox->setSelectedByValue(text, true); - if(keyCombo) + if(LLFloaterDayCycle::isOpen()) { keyCombo->add(text); keyCombo->sortByName(); } - LLWLParamManager::instance()->savePreset(text); + LLWLParamManager::getInstance()->savePreset(newKey); // otherwise, send a message to the user } else { - LLNotificationsUtil::add("ExistsSkyPresetAlert"); + LLNotifications::instance().add("ExistsSkyPresetAlert"); } } return false; @@ -264,38 +314,38 @@ void LLFloaterWindLight::syncMenu() { bool err; - LLWLParamManager * param_mgr = LLWLParamManager::instance(); + LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); LLWLParamSet& currentParams = param_mgr->mCurParams; //std::map<std::string, LLVector4> & currentParams = param_mgr->mCurParams.mParamValues; // blue horizon param_mgr->mBlueHorizon = currentParams.getVector(param_mgr->mBlueHorizon.mName, err); - getChild<LLUICtrl>("WLBlueHorizonR")->setValue(param_mgr->mBlueHorizon.r / 2.0); - getChild<LLUICtrl>("WLBlueHorizonG")->setValue(param_mgr->mBlueHorizon.g / 2.0); - getChild<LLUICtrl>("WLBlueHorizonB")->setValue(param_mgr->mBlueHorizon.b / 2.0); - getChild<LLUICtrl>("WLBlueHorizonI")->setValue( + childSetValue("WLBlueHorizonR", param_mgr->mBlueHorizon.r / 2.0); + childSetValue("WLBlueHorizonG", param_mgr->mBlueHorizon.g / 2.0); + childSetValue("WLBlueHorizonB", param_mgr->mBlueHorizon.b / 2.0); + childSetValue("WLBlueHorizonI", std::max(param_mgr->mBlueHorizon.r / 2.0, std::max(param_mgr->mBlueHorizon.g / 2.0, param_mgr->mBlueHorizon.b / 2.0))); // haze density, horizon, mult, and altitude param_mgr->mHazeDensity = currentParams.getVector(param_mgr->mHazeDensity.mName, err); - getChild<LLUICtrl>("WLHazeDensity")->setValue(param_mgr->mHazeDensity.r); + childSetValue("WLHazeDensity", param_mgr->mHazeDensity.r); param_mgr->mHazeHorizon = currentParams.getVector(param_mgr->mHazeHorizon.mName, err); - getChild<LLUICtrl>("WLHazeHorizon")->setValue(param_mgr->mHazeHorizon.r); + childSetValue("WLHazeHorizon", param_mgr->mHazeHorizon.r); param_mgr->mDensityMult = currentParams.getVector(param_mgr->mDensityMult.mName, err); - getChild<LLUICtrl>("WLDensityMult")->setValue(param_mgr->mDensityMult.x * + childSetValue("WLDensityMult", param_mgr->mDensityMult.x * param_mgr->mDensityMult.mult); param_mgr->mMaxAlt = currentParams.getVector(param_mgr->mMaxAlt.mName, err); - getChild<LLUICtrl>("WLMaxAltitude")->setValue(param_mgr->mMaxAlt.x); + childSetValue("WLMaxAltitude", param_mgr->mMaxAlt.x); // blue density param_mgr->mBlueDensity = currentParams.getVector(param_mgr->mBlueDensity.mName, err); - getChild<LLUICtrl>("WLBlueDensityR")->setValue(param_mgr->mBlueDensity.r / 2.0); - getChild<LLUICtrl>("WLBlueDensityG")->setValue(param_mgr->mBlueDensity.g / 2.0); - getChild<LLUICtrl>("WLBlueDensityB")->setValue(param_mgr->mBlueDensity.b / 2.0); - getChild<LLUICtrl>("WLBlueDensityI")->setValue( + childSetValue("WLBlueDensityR", param_mgr->mBlueDensity.r / 2.0); + childSetValue("WLBlueDensityG", param_mgr->mBlueDensity.g / 2.0); + childSetValue("WLBlueDensityB", param_mgr->mBlueDensity.b / 2.0); + childSetValue("WLBlueDensityI", std::max(param_mgr->mBlueDensity.r / 2.0, std::max(param_mgr->mBlueDensity.g / 2.0, param_mgr->mBlueDensity.b / 2.0))); @@ -303,107 +353,161 @@ void LLFloaterWindLight::syncMenu() // sunlight param_mgr->mSunlight = currentParams.getVector(param_mgr->mSunlight.mName, err); - getChild<LLUICtrl>("WLSunlightR")->setValue(param_mgr->mSunlight.r / WL_SUN_AMBIENT_SLIDER_SCALE); - getChild<LLUICtrl>("WLSunlightG")->setValue(param_mgr->mSunlight.g / WL_SUN_AMBIENT_SLIDER_SCALE); - getChild<LLUICtrl>("WLSunlightB")->setValue(param_mgr->mSunlight.b / WL_SUN_AMBIENT_SLIDER_SCALE); - getChild<LLUICtrl>("WLSunlightI")->setValue( + childSetValue("WLSunlightR", param_mgr->mSunlight.r / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLSunlightG", param_mgr->mSunlight.g / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLSunlightB", param_mgr->mSunlight.b / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLSunlightI", std::max(param_mgr->mSunlight.r / WL_SUN_AMBIENT_SLIDER_SCALE, std::max(param_mgr->mSunlight.g / WL_SUN_AMBIENT_SLIDER_SCALE, param_mgr->mSunlight.b / WL_SUN_AMBIENT_SLIDER_SCALE))); // glow param_mgr->mGlow = currentParams.getVector(param_mgr->mGlow.mName, err); - getChild<LLUICtrl>("WLGlowR")->setValue(2 - param_mgr->mGlow.r / 20.0f); - getChild<LLUICtrl>("WLGlowB")->setValue(-param_mgr->mGlow.b / 5.0f); + childSetValue("WLGlowR", 2 - param_mgr->mGlow.r / 20.0f); + childSetValue("WLGlowB", -param_mgr->mGlow.b / 5.0f); // ambient param_mgr->mAmbient = currentParams.getVector(param_mgr->mAmbient.mName, err); - getChild<LLUICtrl>("WLAmbientR")->setValue(param_mgr->mAmbient.r / WL_SUN_AMBIENT_SLIDER_SCALE); - getChild<LLUICtrl>("WLAmbientG")->setValue(param_mgr->mAmbient.g / WL_SUN_AMBIENT_SLIDER_SCALE); - getChild<LLUICtrl>("WLAmbientB")->setValue(param_mgr->mAmbient.b / WL_SUN_AMBIENT_SLIDER_SCALE); - getChild<LLUICtrl>("WLAmbientI")->setValue( + childSetValue("WLAmbientR", param_mgr->mAmbient.r / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLAmbientG", param_mgr->mAmbient.g / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLAmbientB", param_mgr->mAmbient.b / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLAmbientI", std::max(param_mgr->mAmbient.r / WL_SUN_AMBIENT_SLIDER_SCALE, std::max(param_mgr->mAmbient.g / WL_SUN_AMBIENT_SLIDER_SCALE, param_mgr->mAmbient.b / WL_SUN_AMBIENT_SLIDER_SCALE))); - getChild<LLUICtrl>("WLSunAngle")->setValue(param_mgr->mCurParams.getFloat("sun_angle",err) / F_TWO_PI); - getChild<LLUICtrl>("WLEastAngle")->setValue(param_mgr->mCurParams.getFloat("east_angle",err) / F_TWO_PI); + childSetValue("WLSunAngle", param_mgr->mCurParams.getFloat("sun_angle",err) / F_TWO_PI); + childSetValue("WLEastAngle", param_mgr->mCurParams.getFloat("east_angle",err) / F_TWO_PI); // Clouds // Cloud Color param_mgr->mCloudColor = currentParams.getVector(param_mgr->mCloudColor.mName, err); - getChild<LLUICtrl>("WLCloudColorR")->setValue(param_mgr->mCloudColor.r); - getChild<LLUICtrl>("WLCloudColorG")->setValue(param_mgr->mCloudColor.g); - getChild<LLUICtrl>("WLCloudColorB")->setValue(param_mgr->mCloudColor.b); - getChild<LLUICtrl>("WLCloudColorI")->setValue( + childSetValue("WLCloudColorR", param_mgr->mCloudColor.r); + childSetValue("WLCloudColorG", param_mgr->mCloudColor.g); + childSetValue("WLCloudColorB", param_mgr->mCloudColor.b); + childSetValue("WLCloudColorI", std::max(param_mgr->mCloudColor.r, std::max(param_mgr->mCloudColor.g, param_mgr->mCloudColor.b))); // Cloud param_mgr->mCloudMain = currentParams.getVector(param_mgr->mCloudMain.mName, err); - getChild<LLUICtrl>("WLCloudX")->setValue(param_mgr->mCloudMain.r); - getChild<LLUICtrl>("WLCloudY")->setValue(param_mgr->mCloudMain.g); - getChild<LLUICtrl>("WLCloudDensity")->setValue(param_mgr->mCloudMain.b); + childSetValue("WLCloudX", param_mgr->mCloudMain.r); + childSetValue("WLCloudY", param_mgr->mCloudMain.g); + childSetValue("WLCloudDensity", param_mgr->mCloudMain.b); // Cloud Detail param_mgr->mCloudDetail = currentParams.getVector(param_mgr->mCloudDetail.mName, err); - getChild<LLUICtrl>("WLCloudDetailX")->setValue(param_mgr->mCloudDetail.r); - getChild<LLUICtrl>("WLCloudDetailY")->setValue(param_mgr->mCloudDetail.g); - getChild<LLUICtrl>("WLCloudDetailDensity")->setValue(param_mgr->mCloudDetail.b); + childSetValue("WLCloudDetailX", param_mgr->mCloudDetail.r); + childSetValue("WLCloudDetailY", param_mgr->mCloudDetail.g); + childSetValue("WLCloudDetailDensity", param_mgr->mCloudDetail.b); // Cloud extras param_mgr->mCloudCoverage = currentParams.getVector(param_mgr->mCloudCoverage.mName, err); param_mgr->mCloudScale = currentParams.getVector(param_mgr->mCloudScale.mName, err); - getChild<LLUICtrl>("WLCloudCoverage")->setValue(param_mgr->mCloudCoverage.x); - getChild<LLUICtrl>("WLCloudScale")->setValue(param_mgr->mCloudScale.x); + childSetValue("WLCloudCoverage", param_mgr->mCloudCoverage.x); + childSetValue("WLCloudScale", param_mgr->mCloudScale.x); // cloud scrolling bool lockX = !param_mgr->mCurParams.getEnableCloudScrollX(); bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY(); - getChild<LLUICtrl>("WLCloudLockX")->setValue(lockX); - getChild<LLUICtrl>("WLCloudLockY")->setValue(lockY); - getChild<LLUICtrl>("DrawClassicClouds")->setValue(gSavedSettings.getBOOL("SkyUseClassicClouds")); + childSetValue("WLCloudLockX", lockX); + childSetValue("WLCloudLockY", lockY); + childSetValue("DrawClassicClouds", gSavedSettings.getBOOL("SkyUseClassicClouds")); // disable if locked, enable if not if(lockX) { - getChildView("WLCloudScrollX")->setEnabled(FALSE); + childDisable("WLCloudScrollX"); } else { - getChildView("WLCloudScrollX")->setEnabled(TRUE); + childEnable("WLCloudScrollX"); } if(lockY) { - getChildView("WLCloudScrollY")->setEnabled(FALSE); + childDisable("WLCloudScrollY"); } else { - getChildView("WLCloudScrollY")->setEnabled(TRUE); + childEnable("WLCloudScrollY"); } // *HACK cloud scrolling is off my an additive of 10 - getChild<LLUICtrl>("WLCloudScrollX")->setValue(param_mgr->mCurParams.getCloudScrollX() - 10.0f); - getChild<LLUICtrl>("WLCloudScrollY")->setValue(param_mgr->mCurParams.getCloudScrollY() - 10.0f); + childSetValue("WLCloudScrollX", param_mgr->mCurParams.getCloudScrollX() - 10.0f); + childSetValue("WLCloudScrollY", param_mgr->mCurParams.getCloudScrollY() - 10.0f); param_mgr->mDistanceMult = currentParams.getVector(param_mgr->mDistanceMult.mName, err); - getChild<LLUICtrl>("WLDistanceMult")->setValue(param_mgr->mDistanceMult.x); + childSetValue("WLDistanceMult", param_mgr->mDistanceMult.x); // Tweak extras param_mgr->mWLGamma = currentParams.getVector(param_mgr->mWLGamma.mName, err); - getChild<LLUICtrl>("WLGamma")->setValue(param_mgr->mWLGamma.x); + childSetValue("WLGamma", param_mgr->mWLGamma.x); - getChild<LLUICtrl>("WLStarAlpha")->setValue(param_mgr->mCurParams.getStarBrightness()); + childSetValue("WLStarAlpha", param_mgr->mCurParams.getStarBrightness()); +} - LLTabContainer* tab = getChild<LLTabContainer>("WindLight Tabs"); - LLPanel* panel = getChild<LLPanel>("Scattering"); - tab->enableTabButton(tab->getIndexForPanel(panel), gSavedSettings.getBOOL("RenderDeferredGI")); +// static +LLFloaterWindLight* LLFloaterWindLight::instance() +{ + if (!sWindLight) + { + sWindLight = new LLFloaterWindLight(); + } + return sWindLight; +} +void LLFloaterWindLight::show(LLEnvKey::EScope scope) +{ + LLFloaterWindLight* windLight = instance(); + if(scope != sScope && ((LLView*)windLight)->getVisible()) + { + LLNotifications::instance().add("EnvOtherScopeAlreadyOpen", LLSD()); + return; + } + sScope = scope; + std::string scope_str = ""; + switch(sScope) + { + case LLEnvKey::SCOPE_LOCAL: + scope_str = LLTrans::getString("LocalSettings"); + break; + case LLEnvKey::SCOPE_REGION: + scope_str = LLTrans::getString("RegionSettings"); + break; + } + std::string title = sOriginalTitle + " (" + scope_str + ")"; + windLight->setTitle(title); + windLight->syncMenu(); + + LLEnvManager::instance().startEditingScope(scope); + + // comment in if you want the menu to rebuild each time + //LLUICtrlFactory::getInstance()->buildFloater(windLight, "floater_windlight_options.xml"); + //windLight->initCallbacks(); + + windLight->open(); } +bool LLFloaterWindLight::isOpen() +{ + if (sWindLight != NULL) { + return true; + } + return false; +} + +// virtual +void LLFloaterWindLight::onClose(bool app_quitting) +{ + if (sWindLight) + { + sWindLight->setVisible(FALSE); + } +} // color control callbacks -void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, WLColorControl* colorControl) +void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl * colorControl = static_cast<WLColorControl *>(userData); colorControl->r = sldrCtrl->getValueF32(); if(colorControl->isSunOrAmbientColor) { @@ -421,24 +525,25 @@ void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, WLColorControl* co name.append("I"); if(colorControl->isSunOrAmbientColor) { - getChild<LLUICtrl>(name)->setValue(colorControl->r / 3); + sWindLight->childSetValue(name, colorControl->r / 3); } else if(colorControl->isBlueHorizonOrDensity) { - getChild<LLUICtrl>(name)->setValue(colorControl->r / 2); + sWindLight->childSetValue(name, colorControl->r / 2); } else { - getChild<LLUICtrl>(name)->setValue(colorControl->r); + sWindLight->childSetValue(name, colorControl->r); } } - colorControl->update(LLWLParamManager::instance()->mCurParams); + colorControl->update(LLWLParamManager::getInstance()->mCurParams); - LLWLParamManager::instance()->propagateParameters(); + LLWLParamManager::getInstance()->propagateParameters(); } -void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, WLColorControl* colorControl) +void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl * colorControl = static_cast<WLColorControl *>(userData); colorControl->g = sldrCtrl->getValueF32(); if(colorControl->isSunOrAmbientColor) { @@ -456,24 +561,25 @@ void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, WLColorControl* co name.append("I"); if(colorControl->isSunOrAmbientColor) { - getChild<LLUICtrl>(name)->setValue(colorControl->g / 3); + sWindLight->childSetValue(name, colorControl->g / 3); } else if(colorControl->isBlueHorizonOrDensity) { - getChild<LLUICtrl>(name)->setValue(colorControl->g / 2); + sWindLight->childSetValue(name, colorControl->g / 2); } else { - getChild<LLUICtrl>(name)->setValue(colorControl->g); + sWindLight->childSetValue(name, colorControl->g); } } - colorControl->update(LLWLParamManager::instance()->mCurParams); + colorControl->update(LLWLParamManager::getInstance()->mCurParams); - LLWLParamManager::instance()->propagateParameters(); + LLWLParamManager::getInstance()->propagateParameters(); } -void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, WLColorControl* colorControl) +void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl * colorControl = static_cast<WLColorControl *>(userData); colorControl->b = sldrCtrl->getValueF32(); if(colorControl->isSunOrAmbientColor) { @@ -491,24 +597,25 @@ void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, WLColorControl* co name.append("I"); if(colorControl->isSunOrAmbientColor) { - getChild<LLUICtrl>(name)->setValue(colorControl->b / 3); + sWindLight->childSetValue(name, colorControl->b / 3); } else if(colorControl->isBlueHorizonOrDensity) { - getChild<LLUICtrl>(name)->setValue(colorControl->b / 2); + sWindLight->childSetValue(name, colorControl->b / 2); } else { - getChild<LLUICtrl>(name)->setValue(colorControl->b); + sWindLight->childSetValue(name, colorControl->b); } } - colorControl->update(LLWLParamManager::instance()->mCurParams); + colorControl->update(LLWLParamManager::getInstance()->mCurParams); - LLWLParamManager::instance()->propagateParameters(); + LLWLParamManager::getInstance()->propagateParameters(); } -void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, WLColorControl* colorControl) +void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl * colorControl = static_cast<WLColorControl *>(userData); colorControl->i = sldrCtrl->getValueF32(); @@ -565,84 +672,100 @@ void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, WLColorControl* co // divide sun color vals by three if(colorControl->isSunOrAmbientColor) { - getChild<LLUICtrl>(rName)->setValue(colorControl->r/3); - getChild<LLUICtrl>(gName)->setValue(colorControl->g/3); - getChild<LLUICtrl>(bName)->setValue(colorControl->b/3); + sWindLight->childSetValue(rName, colorControl->r/3); + sWindLight->childSetValue(gName, colorControl->g/3); + sWindLight->childSetValue(bName, colorControl->b/3); } else if(colorControl->isBlueHorizonOrDensity) { - getChild<LLUICtrl>(rName)->setValue(colorControl->r/2); - getChild<LLUICtrl>(gName)->setValue(colorControl->g/2); - getChild<LLUICtrl>(bName)->setValue(colorControl->b/2); + sWindLight->childSetValue(rName, colorControl->r/2); + sWindLight->childSetValue(gName, colorControl->g/2); + sWindLight->childSetValue(bName, colorControl->b/2); } else { // set the sliders to the new vals - getChild<LLUICtrl>(rName)->setValue(colorControl->r); - getChild<LLUICtrl>(gName)->setValue(colorControl->g); - getChild<LLUICtrl>(bName)->setValue(colorControl->b); + sWindLight->childSetValue(rName, colorControl->r); + sWindLight->childSetValue(gName, colorControl->g); + sWindLight->childSetValue(bName, colorControl->b); } } // now update the current parameters and send them to shaders - colorControl->update(LLWLParamManager::instance()->mCurParams); - LLWLParamManager::instance()->propagateParameters(); + colorControl->update(LLWLParamManager::getInstance()->mCurParams); + LLWLParamManager::getInstance()->propagateParameters(); } /// GLOW SPECIFIC CODE -void LLFloaterWindLight::onGlowRMoved(LLUICtrl* ctrl, WLColorControl* colorControl) +void LLFloaterWindLight::onGlowRMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl * colorControl = static_cast<WLColorControl *>(userData); // scaled by 20 colorControl->r = (2 - sldrCtrl->getValueF32()) * 20; - colorControl->update(LLWLParamManager::instance()->mCurParams); - LLWLParamManager::instance()->propagateParameters(); + colorControl->update(LLWLParamManager::getInstance()->mCurParams); + LLWLParamManager::getInstance()->propagateParameters(); } /// \NOTE that we want NEGATIVE (-) B -void LLFloaterWindLight::onGlowBMoved(LLUICtrl* ctrl, WLColorControl* colorControl) +void LLFloaterWindLight::onGlowBMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl * colorControl = static_cast<WLColorControl *>(userData); /// \NOTE that we want NEGATIVE (-) B and NOT by 20 as 20 is too big colorControl->b = -sldrCtrl->getValueF32() * 5; - colorControl->update(LLWLParamManager::instance()->mCurParams); - LLWLParamManager::instance()->propagateParameters(); + colorControl->update(LLWLParamManager::getInstance()->mCurParams); + LLWLParamManager::getInstance()->propagateParameters(); } -void LLFloaterWindLight::onFloatControlMoved(LLUICtrl* ctrl, WLFloatControl* floatControl) +void LLFloaterWindLight::onFloatControlMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + WLFloatControl * floatControl = static_cast<WLFloatControl *>(userData); floatControl->x = sldrCtrl->getValueF32() / floatControl->mult; - floatControl->update(LLWLParamManager::instance()->mCurParams); - LLWLParamManager::instance()->propagateParameters(); + floatControl->update(LLWLParamManager::getInstance()->mCurParams); + LLWLParamManager::getInstance()->propagateParameters(); +} + +void LLFloaterWindLight::onBoolToggle(LLUICtrl* ctrl, void* userData) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl); + + bool value = cbCtrl->get(); + (*(static_cast<BOOL *>(userData))) = value; } + // Lighting callbacks // time of day -void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, WLColorControl* colorControl) +void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); - LLSliderCtrl* sunSldr = getChild<LLSliderCtrl>("WLSunAngle"); - LLSliderCtrl* eastSldr = getChild<LLSliderCtrl>("WLEastAngle"); + LLSliderCtrl* sunSldr = sWindLight->getChild<LLSliderCtrl>("WLSunAngle"); + LLSliderCtrl* eastSldr = sWindLight->getChild<LLSliderCtrl>("WLEastAngle"); + WLColorControl * colorControl = static_cast<WLColorControl *>(userData); + // get the two angles - LLWLParamManager * param_mgr = LLWLParamManager::instance(); + LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); param_mgr->mCurParams.setSunAngle(F_TWO_PI * sunSldr->getValueF32()); param_mgr->mCurParams.setEastAngle(F_TWO_PI * eastSldr->getValueF32()); @@ -659,24 +782,35 @@ void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, WLColorControl* colorControl param_mgr->propagateParameters(); } -void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl) +void LLFloaterWindLight::onFloatTweakMoved(LLUICtrl* ctrl, void* userData) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + F32 * tweak = static_cast<F32 *>(userData); + + (*tweak) = sldrCtrl->getValueF32(); + LLWLParamManager::getInstance()->propagateParameters(); +} + +void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); - LLWLParamManager::instance()->mCurParams.setStarBrightness(sldrCtrl->getValueF32()); + LLWLParamManager::getInstance()->mCurParams.setStarBrightness(sldrCtrl->getValueF32()); } -void LLFloaterWindLight::onNewPreset() +void LLFloaterWindLight::onNewPreset(void* userData) { - LLNotificationsUtil::add("NewSkyPreset", LLSD(), LLSD(), boost::bind(&LLFloaterWindLight::newPromptCallback, this, _1, _2)); + LLNotifications::instance().add("NewSkyPreset", LLSD(), LLSD(), newPromptCallback); } -void LLFloaterWindLight::onSavePreset() +void LLFloaterWindLight::onSavePreset(void* userData) { // get the name - LLComboBox* comboBox = getChild<LLComboBox>( + LLComboBox* comboBox = sWindLight->getChild<LLComboBox>( "WLPresetsCombo"); // don't save the empty name @@ -686,90 +820,98 @@ void LLFloaterWindLight::onSavePreset() } // check to see if it's a default and shouldn't be overwritten - std::set<std::string>::iterator sIt = sDefaultPresets.find( - comboBox->getSelectedItemLabel()); + std::set<LLWLParamKey>::iterator sIt = sDefaultPresets.find( + LLWLParamKey(comboBox->getSelectedValue())); if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("SkyEditPresets")) { - LLNotificationsUtil::add("WLNoEditDefault"); + LLNotifications::instance().add("WLNoEditDefault"); return; } - LLWLParamManager::instance()->mCurParams.mName = + LLWLParamManager::getInstance()->mCurParams.mName = comboBox->getSelectedItemLabel(); - LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterWindLight::saveAlertCallback, this, _1, _2)); + LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback); } bool LLFloaterWindLight::saveAlertCallback(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + S32 option = LLNotification::getSelectedOption(notification, response); // if they choose save, do it. Otherwise, don't do anything if(option == 0) { - LLWLParamManager * param_mgr = LLWLParamManager::instance(); + LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); + + // we should only "save" local presets; those with other scopes should be "save as" + LLWLParamKey key(param_mgr->mCurParams.mName, LLEnvKey::SCOPE_LOCAL); - param_mgr->setParamSet(param_mgr->mCurParams.mName, param_mgr->mCurParams); + param_mgr->setParamSet(key, param_mgr->mCurParams); // comment this back in to save to file - param_mgr->savePreset(param_mgr->mCurParams.mName); + param_mgr->savePreset(key); } return false; } -void LLFloaterWindLight::onDeletePreset() +void LLFloaterWindLight::onDeletePreset(void* userData) { - LLComboBox* combo_box = getChild<LLComboBox>( + LLComboBox* combo_box = sWindLight->getChild<LLComboBox>( "WLPresetsCombo"); - if(combo_box->getSelectedValue().asString() == "") + if(combo_box->getSelectedValue().isUndefined()) { return; } LLSD args; - args["SKY"] = combo_box->getSelectedValue().asString(); - LLNotificationsUtil::add("WLDeletePresetAlert", args, LLSD(), - boost::bind(&LLFloaterWindLight::deleteAlertCallback, this, _1, _2)); + args["SKY"] = combo_box->getSelectedValue()[0].asString(); + LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), + boost::bind(&LLFloaterWindLight::deleteAlertCallback, sWindLight, _1, _2)); } bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + S32 option = LLNotification::getSelectedOption(notification, response); // if they choose delete, do it. Otherwise, don't do anything if(option == 0) { - LLComboBox* combo_box = getChild<LLComboBox>("WLPresetsCombo"); - LLFloaterDayCycle* day_cycle = LLFloaterReg::findTypedInstance<LLFloaterDayCycle>("env_day_cycle"); + LLComboBox* combo_box = getChild<LLComboBox>( + "WLPresetsCombo"); + LLFloaterDayCycle* day_cycle = NULL; LLComboBox* key_combo = NULL; + LLMultiSliderCtrl* mult_sldr = NULL; - if (day_cycle) + if(LLFloaterDayCycle::isOpen()) { - key_combo = day_cycle->getChild<LLComboBox>("WLKeyPresets"); + day_cycle = LLFloaterDayCycle::instance(); + key_combo = day_cycle->getChild<LLComboBox>( + "WLKeyPresets"); + mult_sldr = day_cycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); } - std::string name(combo_box->getSelectedValue().asString()); + LLWLParamKey key(combo_box->getSelectedValue()); // check to see if it's a default and shouldn't be deleted - std::set<std::string>::iterator sIt = sDefaultPresets.find(name); + std::set<LLWLParamKey>::iterator sIt = sDefaultPresets.find(key); if(sIt != sDefaultPresets.end()) { - LLNotificationsUtil::add("WLNoEditDefault"); + LLNotifications::instance().add("WLNoEditDefault"); return false; } - LLWLParamManager::instance()->removeParamSet(name, true); + LLWLParamManager::getInstance()->removeParamSet(key, true); // remove and choose another S32 new_index = combo_box->getCurrentIndex(); - combo_box->remove(name); + combo_box->remove(key.toString()); if(key_combo != NULL) { - key_combo->remove(name); + key_combo->remove(key.toString()); // remove from slider, as well - day_cycle->deletePreset(name); + day_cycle->deletePreset(key); } // pick the previously selected index after delete @@ -787,53 +929,56 @@ bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLS } -void LLFloaterWindLight::onChangePresetName(LLUICtrl* ctrl) +void LLFloaterWindLight::onChangePresetName(LLUICtrl* ctrl, void * userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); - std::string data = ctrl->getValue().asString(); - if(!data.empty()) + LLComboBox * combo_box = static_cast<LLComboBox*>(ctrl); + + if(combo_box->getSimple() == "") { - LLWLParamManager::instance()->loadPreset( data); - syncMenu(); + return; } + + LLWLParamManager::getInstance()->loadPreset(LLWLParamKey(combo_box->getSelectedValue())); + sWindLight->syncMenu(); } -void LLFloaterWindLight::onOpenDayCycle() +void LLFloaterWindLight::onOpenDayCycle(void* userData) { - LLFloaterReg::showInstance("env_day_cycle"); + LLFloaterDayCycle::show(sScope); } // Clouds -void LLFloaterWindLight::onCloudScrollXMoved(LLUICtrl* ctrl) +void LLFloaterWindLight::onCloudScrollXMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); // *HACK all cloud scrolling is off by an additive of 10. - LLWLParamManager::instance()->mCurParams.setCloudScrollX(sldrCtrl->getValueF32() + 10.0f); + LLWLParamManager::getInstance()->mCurParams.setCloudScrollX(sldrCtrl->getValueF32() + 10.0f); } -void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl) +void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); // *HACK all cloud scrolling is off by an additive of 10. - LLWLParamManager::instance()->mCurParams.setCloudScrollY(sldrCtrl->getValueF32() + 10.0f); + LLWLParamManager::getInstance()->mCurParams.setCloudScrollY(sldrCtrl->getValueF32() + 10.0f); } -void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl) +void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl); bool lock = cbCtrl->get(); - LLWLParamManager::instance()->mCurParams.setEnableCloudScrollX(!lock); + LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollX(!lock); - LLSliderCtrl* sldr = getChild<LLSliderCtrl>( + LLSliderCtrl* sldr = sWindLight->getChild<LLSliderCtrl>( "WLCloudScrollX"); if(cbCtrl->get()) @@ -847,15 +992,15 @@ void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl) } -void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl) +void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl); bool lock = cbCtrl->get(); - LLWLParamManager::instance()->mCurParams.setEnableCloudScrollY(!lock); + LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollY(!lock); - LLSliderCtrl* sldr = getChild<LLSliderCtrl>( + LLSliderCtrl* sldr = sWindLight->getChild<LLSliderCtrl>( "WLCloudScrollY"); if(cbCtrl->get()) @@ -867,9 +1012,3 @@ void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl) sldr->setEnabled(true); } } - -void LLFloaterWindLight::deactivateAnimator() -{ - LLWLParamManager::instance()->mAnimator.mIsRunning = false; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; -} diff --git a/indra/newview/llfloaterwindlight.h b/indra/newview/llfloaterwindlight.h index b43edc2c11..c0fea2558c 100644 --- a/indra/newview/llfloaterwindlight.h +++ b/indra/newview/llfloaterwindlight.h @@ -2,25 +2,31 @@ * @file llfloaterwindlight.h * @brief LLFloaterWindLight class definition * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, 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. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * 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. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * 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 + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -35,77 +41,98 @@ #include <vector> #include "llwlparamset.h" +#include "llwlparammanager.h" struct WLColorControl; struct WLFloatControl; - /// Menuing system for all of windlight's functionality class LLFloaterWindLight : public LLFloater { public: - - LLFloaterWindLight(const LLSD& key); + LLFloaterWindLight(); virtual ~LLFloaterWindLight(); - /*virtual*/ BOOL postBuild(); + /// initialize all void initCallbacks(void); - bool newPromptCallback(const LLSD& notification, const LLSD& response); + /// one and one instance only + static LLFloaterWindLight* instance(); + + // help button stuff + static void onClickHelp(void* data); + void initHelpBtn(const std::string& name, const std::string& xml_alert); + + static bool newPromptCallback(const LLSD& notification, const LLSD& response); /// general purpose callbacks for dealing with color controllers - void onColorControlRMoved(LLUICtrl* ctrl, WLColorControl* userData); - void onColorControlGMoved(LLUICtrl* ctrl, WLColorControl* userData); - void onColorControlBMoved(LLUICtrl* ctrl, WLColorControl* userData); - void onColorControlIMoved(LLUICtrl* ctrl, WLColorControl* userData); - void onFloatControlMoved(LLUICtrl* ctrl, WLFloatControl* userData); + static void onColorControlRMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlGMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlBMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlIMoved(LLUICtrl* ctrl, void* userData); + static void onFloatControlMoved(LLUICtrl* ctrl, void* userData); + static void onBoolToggle(LLUICtrl* ctrl, void* userData); /// lighting callbacks for glow - void onGlowRMoved(LLUICtrl* ctrl, WLColorControl* userData); + static void onGlowRMoved(LLUICtrl* ctrl, void* userData); //static void onGlowGMoved(LLUICtrl* ctrl, void* userData); - void onGlowBMoved(LLUICtrl* ctrl, WLColorControl* userData); + static void onGlowBMoved(LLUICtrl* ctrl, void* userData); /// lighting callbacks for sun - void onSunMoved(LLUICtrl* ctrl, WLColorControl* userData); + static void onSunMoved(LLUICtrl* ctrl, void* userData); + + /// handle if float is changed + static void onFloatTweakMoved(LLUICtrl* ctrl, void* userData); /// for handling when the star slider is moved to adjust the alpha - void onStarAlphaMoved(LLUICtrl* ctrl); + static void onStarAlphaMoved(LLUICtrl* ctrl, void* userData); /// when user hits the load preset button - void onNewPreset(); + static void onNewPreset(void* userData); /// when user hits the save preset button - void onSavePreset(); + static void onSavePreset(void* userData); /// prompts a user when overwriting a preset - bool saveAlertCallback(const LLSD& notification, const LLSD& response); + static bool saveAlertCallback(const LLSD& notification, const LLSD& response); /// when user hits the save preset button - void onDeletePreset(); + static void onDeletePreset(void* userData); /// prompts a user when overwriting a preset bool deleteAlertCallback(const LLSD& notification, const LLSD& response); /// what to do when you change the preset name - void onChangePresetName(LLUICtrl* ctrl); + static void onChangePresetName(LLUICtrl* ctrl, void* userData); /// when user hits the save preset button - void onOpenDayCycle(); + static void onOpenDayCycle(void* userData); /// handle cloud scrolling - void onCloudScrollXMoved(LLUICtrl* ctrl); - void onCloudScrollYMoved(LLUICtrl* ctrl); - void onCloudScrollXToggled(LLUICtrl* ctrl); - void onCloudScrollYToggled(LLUICtrl* ctrl); + static void onCloudScrollXMoved(LLUICtrl* ctrl, void* userData); + static void onCloudScrollYMoved(LLUICtrl* ctrl, void* userData); + static void onCloudScrollXToggled(LLUICtrl* ctrl, void* userData); + static void onCloudScrollYToggled(LLUICtrl* ctrl, void* userData); + + //// menu management + + /// show off our menu + static void show(LLEnvKey::EScope scope = LLEnvKey::SCOPE_LOCAL); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); /// sync up sliders with parameters void syncMenu(); - /// turn off animated skies - static void deactivateAnimator(); - private: - static std::set<std::string> sDefaultPresets; + static LLFloaterWindLight* sWindLight; // one instance on the inside + static std::set<LLWLParamKey> sDefaultPresets; + static LLEnvKey::EScope sScope; + static std::string sOriginalTitle; }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index c56cacd12b..7fa78ab386 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1153,8 +1153,6 @@ bool idle_startup() // init the shader managers LLPostProcess::initClass(); - LLWLParamManager::initClass(); - LLWaterParamManager::initClass(); LLViewerObject::initVOClasses(); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 916cbe2267..5b0cf72ac5 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -178,8 +178,8 @@ void display_update_camera() gViewerWindow->setup3DRender(); // update all the sky/atmospheric/water settings - LLWLParamManager::instance()->update(LLViewerCamera::getInstance()); - LLWaterParamManager::instance()->update(LLViewerCamera::getInstance()); + LLWLParamManager::getInstance()->update(LLViewerCamera::getInstance()); + LLWaterParamManager::getInstance()->update(LLViewerCamera::getInstance()); // Update land visibility too LLWorld::getInstance()->setLandFarClip(final_far); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index d4af5048c3..614eb6ed88 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7628,55 +7628,56 @@ class LLWorldEnvSettings : public view_listener_t LLFloaterReg::toggleInstance("env_settings"); return true; } - + else if(gSavedSettings.getBOOL("UseEnvironmentFromRegion")) + { + LLNotifications::instance().add("EnvLockedUsingRegion", LLSD()); + } + else + { if (tod == "sunrise") { // set the value, turn off animation - LLWLParamManager::instance()->mAnimator.setDayTime(0.25); - LLWLParamManager::instance()->mAnimator.mIsRunning = false; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.setDayTime(0.25); + LLWLParamManager::getInstance()->mAnimator.deactivate(); // then call update once - LLWLParamManager::instance()->mAnimator.update( - LLWLParamManager::instance()->mCurParams); + LLWLParamManager::getInstance()->mAnimator.update( + LLWLParamManager::getInstance()->mCurParams); } else if (tod == "noon") { // set the value, turn off animation - LLWLParamManager::instance()->mAnimator.setDayTime(0.567); - LLWLParamManager::instance()->mAnimator.mIsRunning = false; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.setDayTime(0.567); + LLWLParamManager::getInstance()->mAnimator.deactivate(); // then call update once - LLWLParamManager::instance()->mAnimator.update( - LLWLParamManager::instance()->mCurParams); + LLWLParamManager::getInstance()->mAnimator.update( + LLWLParamManager::getInstance()->mCurParams); } else if (tod == "sunset") { // set the value, turn off animation - LLWLParamManager::instance()->mAnimator.setDayTime(0.75); - LLWLParamManager::instance()->mAnimator.mIsRunning = false; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.setDayTime(0.75); + LLWLParamManager::getInstance()->mAnimator.deactivate(); // then call update once - LLWLParamManager::instance()->mAnimator.update( - LLWLParamManager::instance()->mCurParams); + LLWLParamManager::getInstance()->mAnimator.update( + LLWLParamManager::getInstance()->mCurParams); } else if (tod == "midnight") { // set the value, turn off animation - LLWLParamManager::instance()->mAnimator.setDayTime(0.0); - LLWLParamManager::instance()->mAnimator.mIsRunning = false; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.setDayTime(0.0); + LLWLParamManager::getInstance()->mAnimator.deactivate(); // then call update once - LLWLParamManager::instance()->mAnimator.update( - LLWLParamManager::instance()->mCurParams); + LLWLParamManager::getInstance()->mAnimator.update( + LLWLParamManager::getInstance()->mCurParams); } else { - LLWLParamManager::instance()->mAnimator.mIsRunning = true; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = true; + LLWLParamManager::getInstance()->mAnimator.activate(LLWLAnimator::TIME_LINDEN); + } } return true; } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 98f16757b2..0ed254bbc5 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1365,6 +1365,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); + capabilityNames.append("EnvironmentSettings"); capabilityNames.append("FetchInventory"); capabilityNames.append("ObjectMedia"); capabilityNames.append("ObjectMediaNavigate"); @@ -1494,3 +1495,8 @@ std::string LLViewerRegion::getDescription() const { return stringize(*this); } + +std::string LLViewerRegion::getDescription() const +{ + return stringize(*this); +} diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 038c831e59..307e2cf3a2 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -405,6 +405,11 @@ private: /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities) LLCapabilityListener mCapabilityListener; + /// Post an event to this LLCapabilityListener to invoke a capability message on + /// this LLViewerRegion's server + /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities) + LLCapabilityListener mCapabilityListener; + private: bool mAlive; // can become false if circuit disconnects diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index d078c15316..fa30c1ae9e 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1492,6 +1492,16 @@ std::string LLViewerShaderMgr::getShaderDirPrefix(void) void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader) { - LLWLParamManager::instance()->updateShaderUniforms(shader); - LLWaterParamManager::instance()->updateShaderUniforms(shader); + LLWLParamManager::getInstance()->updateShaderUniforms(shader); + LLWaterParamManager::getInstance()->updateShaderUniforms(shader); +} + +LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const +{ + return mShaderList.begin(); +} + +LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const +{ + return mShaderList.end(); } diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index db880fded6..e958cf1172 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -240,20 +240,12 @@ public: base_iter_t mIter; }; - shader_iter beginShaders() const - { - return mShaderList.begin(); - } - - shader_iter endShaders() const - { - return mShaderList.end(); - } - + shader_iter beginShaders() const; + shader_iter endShaders() const; - /* virtual */ std::string getShaderDirPrefix(void); // Virtual + /* virtual */ std::string getShaderDirPrefix(void); - /* virtual */ void updateShaderUniforms(LLGLSLShader * shader); // Virtual + /* virtual */ void updateShaderUniforms(LLGLSLShader * shader); private: diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 7ae8c2c07d..a6465f1c4f 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -356,7 +356,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mAtmHeight = ATM_HEIGHT; mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS); - mSunDefaultPosition = LLVector3(LLWLParamManager::instance()->mCurParams.getVector("lightnorm", error)); + mSunDefaultPosition = LLVector3(LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error)); if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition")) { initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0)); @@ -638,24 +638,24 @@ void LLVOSky::initAtmospherics(void) bool error; // uniform parameters for convenience - dome_radius = LLWLParamManager::instance()->getDomeRadius(); - dome_offset_ratio = LLWLParamManager::instance()->getDomeOffset(); - sunlight_color = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("sunlight_color", error)); - ambient = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("ambient", error)); - //lightnorm = LLWLParamManager::instance()->mCurParams.getVector("lightnorm", error); - gamma = LLWLParamManager::instance()->mCurParams.getVector("gamma", error)[0]; - blue_density = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("blue_density", error)); - blue_horizon = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("blue_horizon", error)); - haze_density = LLWLParamManager::instance()->mCurParams.getVector("haze_density", error)[0]; - haze_horizon = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("haze_horizon", error)); - density_multiplier = LLWLParamManager::instance()->mCurParams.getVector("density_multiplier", error)[0]; - max_y = LLWLParamManager::instance()->mCurParams.getVector("max_y", error)[0]; - glow = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("glow", error)); - cloud_shadow = LLWLParamManager::instance()->mCurParams.getVector("cloud_shadow", error)[0]; - cloud_color = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("cloud_color", error)); - cloud_scale = LLWLParamManager::instance()->mCurParams.getVector("cloud_scale", error)[0]; - cloud_pos_density1 = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("cloud_pos_density1", error)); - cloud_pos_density2 = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("cloud_pos_density2", error)); + dome_radius = LLWLParamManager::getInstance()->getDomeRadius(); + dome_offset_ratio = LLWLParamManager::getInstance()->getDomeOffset(); + sunlight_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("sunlight_color", error)); + ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("ambient", error)); + //lightnorm = LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error); + gamma = LLWLParamManager::getInstance()->mCurParams.getVector("gamma", error)[0]; + blue_density = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_density", error)); + blue_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_horizon", error)); + haze_density = LLWLParamManager::getInstance()->mCurParams.getVector("haze_density", error)[0]; + haze_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("haze_horizon", error)); + density_multiplier = LLWLParamManager::getInstance()->mCurParams.getVector("density_multiplier", error)[0]; + max_y = LLWLParamManager::getInstance()->mCurParams.getVector("max_y", error)[0]; + glow = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("glow", error)); + cloud_shadow = LLWLParamManager::getInstance()->mCurParams.getVector("cloud_shadow", error)[0]; + cloud_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_color", error)); + cloud_scale = LLWLParamManager::getInstance()->mCurParams.getVector("cloud_scale", error)[0]; + cloud_pos_density1 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density1", error)); + cloud_pos_density2 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density2", error)); // light norm is different. We need the sun's direction, not the light direction // which could be from the moon. And we need to clamp it @@ -1025,7 +1025,7 @@ void LLVOSky::calcAtmospherics(void) // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio // between sunlight and point lights in windlight to normalize point lights. F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); - LLWLParamManager::instance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp); + LLWLParamManager::getInstance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp); mSunDiffuse = vary_SunlightColor; mSunAmbient = vary_AmbientColor; @@ -2115,7 +2115,7 @@ void LLVOSky::updateFog(const F32 distance) F32 depth = water_height - camera_height; // get the water param manager variables - float water_fog_density = LLWaterParamManager::instance()->getFogDensity(); + float water_fog_density = LLWaterParamManager::getInstance()->getFogDensity(); LLColor4 water_fog_color = LLDrawPoolWater::sWaterFogColor.mV; // adjust the color based on depth. We're doing linear approximations diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index ca57c0144b..5cb61b8734 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -568,7 +568,7 @@ void LLVOWLSky::buildFanBuffer(LLStrider<LLVector3> & vertices, LLStrider<LLVector2> & texCoords, LLStrider<U16> & indices) { - const F32 RADIUS = LLWLParamManager::instance()->getDomeRadius(); + const F32 RADIUS = LLWLParamManager::getInstance()->getDomeRadius(); U32 i, num_slices; F32 phi0, theta, x0, y0, z0; @@ -629,7 +629,7 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack, LLStrider<LLVector2> & texCoords, LLStrider<U16> & indices) { - const F32 RADIUS = LLWLParamManager::instance()->getDomeRadius(); + const F32 RADIUS = LLWLParamManager::getInstance()->getDomeRadius(); U32 i, j, num_slices, num_stacks; F32 phi0, theta, x0, y0, z0; diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 7314894c2e..c984938303 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -57,8 +57,6 @@ #include "curl/curl.h" -LLWaterParamManager * LLWaterParamManager::sInstance = NULL; - 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), @@ -246,7 +244,7 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader) { if (shader->mShaderGroup == LLGLSLShader::SG_WATER) { - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::instance()->getRotatedLightDir().mV); + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV); shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV); shader->uniform4fv("waterFogColor", 1, LLDrawPoolWater::sWaterFogColor.mV); shader->uniform4fv("waterPlane", 1, mWaterPlane.mV); @@ -320,19 +318,6 @@ void LLWaterParamManager::update(LLViewerCamera * cam) } } -// static -void LLWaterParamManager::initClass(void) -{ - instance(); -} - -// static -void LLWaterParamManager::cleanupClass(void) -{ - delete sInstance; - sInstance = NULL; -} - bool LLWaterParamManager::addParamSet(const std::string& name, LLWaterParamSet& param) { // add a new one if not one there already @@ -439,17 +424,9 @@ F32 LLWaterParamManager::getFogDensity(void) return fogDensity; } -// static -LLWaterParamManager * LLWaterParamManager::instance() +// virtual static +void LLWaterParamManager::initSingleton() { - if(NULL == sInstance) - { - sInstance = new LLWaterParamManager(); - - sInstance->loadAllPresets(LLStringUtil::null); - - sInstance->getParamSet("Default", sInstance->mCurParams); - } - - return sInstance; + loadAllPresets(LLStringUtil::null); + getParamSet("Default", mCurParams); } diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h index c479f1861c..d5919bbf68 100644 --- a/indra/newview/llwaterparammanager.h +++ b/indra/newview/llwaterparammanager.h @@ -212,13 +212,10 @@ struct WaterExpFloatControl /// WindLight parameter manager class - what controls all the wind light shaders -class LLWaterParamManager +class LLWaterParamManager : public LLSingleton<LLWaterParamManager> { public: - LLWaterParamManager(); - ~LLWaterParamManager(); - /// load a preset file void loadAllPresets(const std::string & fileName); @@ -238,9 +235,6 @@ public: /// Update shader uniforms that have changed. void updateShaderUniforms(LLGLSLShader * shader); - /// Perform global initialization for this class. - static void initClass(void); - // Cleanup of global data that's only inited once per class. static void cleanupClass(); @@ -281,9 +275,6 @@ public: F32 getFogDensity(void); LLColor4 getFogColor(void); - // singleton pattern implementation - static LLWaterParamManager * instance(); - public: LLWaterParamSet mCurParams; @@ -311,11 +302,13 @@ public: F32 mDensitySliderValue; private: + friend class LLSingleton<LLWaterParamManager>; + /*virtual*/ void initSingleton(); + LLWaterParamManager(); + ~LLWaterParamManager(); + LLVector4 mWaterPlane; F32 mWaterFogKS; - - // our parameter manager singleton instance - static LLWaterParamManager * sInstance; }; inline void LLWaterParamManager::setDensitySliderValue(F32 val) diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp index 9457d631be..488b189e94 100644 --- a/indra/newview/llwaterparamset.cpp +++ b/indra/newview/llwaterparamset.cpp @@ -224,3 +224,46 @@ F32 LLWaterParamSet::getFloat(const std::string& paramName, bool& error) return 0; } +// Added for interpolation effect in DEV-33645 +// Based on LLWLParamSet::mix, but written by Jacob without an intimate knowledge of how WindLight works. +// The function definition existed in the header but was never implemented. If you think there is something +// wrong with this, you're probably right. Ask Jacob, Q, or a member of the original WindLight team. +void LLWaterParamSet::mix(LLWaterParamSet& src, LLWaterParamSet& dest, F32 weight) +{ + // Setup + LLSD srcVal, destVal; // LLSD holders for get/set calls, reusable + + // Iterate through values + for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter) + { + // If param exists in both src and dest, set the holder variables, otherwise skip + if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first)) + { + srcVal = src.mParamValues[iter->first]; + destVal = dest.mParamValues[iter->first]; + } + else + { + continue; + } + + if(iter->second.isReal()) // If it's a real, interpolate directly + { + iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight); + } + else if(iter->second.isArray() && iter->second[0].isReal() // If it's an array of reals, loop through the reals and interpolate on those + && iter->second.size() == srcVal.size() && iter->second.size() == destVal.size()) + { + // Actually do interpolation: old value + (difference in values * factor) + for(int i=0; i < iter->second.size(); ++i) + { + // iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal(); // old way of doing it -- equivalent but one more operation + iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight); + } + } + else // Else, skip + { + continue; + } + } +} diff --git a/indra/newview/llwlanimator.cpp b/indra/newview/llwlanimator.cpp index a94a2e41aa..2e249b9701 100644 --- a/indra/newview/llwlanimator.cpp +++ b/indra/newview/llwlanimator.cpp @@ -30,20 +30,31 @@ #include "llsky.h" #include "pipeline.h" #include "llwlparammanager.h" +#include "llwaterparammanager.h" -LLWLAnimator::LLWLAnimator() : mStartTime(0), mDayRate(1), mDayTime(0), - mIsRunning(FALSE), mUseLindenTime(false) +extern LLControlGroup gSavedSettings; + +F64 LLWLAnimator::INTERP_TOTAL_SECONDS = 3.f; + +LLWLAnimator::LLWLAnimator() : mStartTime(0.f), mDayRate(1.f), mDayTime(0.f), + mIsRunning(FALSE), mIsInterpolating(FALSE), mTimeType(TIME_LINDEN), + mInterpStartTime(), mInterpEndTime() { - mDayTime = 0; + mInterpBeginWL = new LLWLParamSet(); + mInterpBeginWater = new LLWaterParamSet(); + mInterpEndWater = new LLWaterParamSet(); } void LLWLAnimator::update(LLWLParamSet& curParams) { + llassert(mUseLindenTime != mUseLocalTime); + F64 curTime; curTime = getDayTime(); // don't do anything if empty - if(mTimeTrack.size() == 0) { + if(mTimeTrack.size() == 0) + { return; } @@ -53,13 +64,15 @@ void LLWLAnimator::update(LLWLParamSet& curParams) mSecondIt++; // grab the two tween iterators - while(mSecondIt != mTimeTrack.end() && curTime > mSecondIt->first) { + while(mSecondIt != mTimeTrack.end() && curTime > mSecondIt->first) + { mFirstIt++; mSecondIt++; } // scroll it around when you get to the end - if(mSecondIt == mTimeTrack.end() || mFirstIt->first > curTime) { + if(mSecondIt == mTimeTrack.end() || mFirstIt->first > curTime) + { mSecondIt = mTimeTrack.begin(); mFirstIt = mTimeTrack.end(); mFirstIt--; @@ -67,70 +80,109 @@ void LLWLAnimator::update(LLWLParamSet& curParams) F32 weight = 0; - if(mFirstIt->first < mSecondIt->first) { + if(mFirstIt->first < mSecondIt->first) + { // get the delta time and the proper weight weight = F32 (curTime - mFirstIt->first) / (mSecondIt->first - mFirstIt->first); // handle the ends - } else if(mFirstIt->first > mSecondIt->first) { + } + else if(mFirstIt->first > mSecondIt->first) + { // right edge of time line - if(curTime >= mFirstIt->first) { + if(curTime >= mFirstIt->first) + { weight = F32 (curTime - mFirstIt->first) / ((1 + mSecondIt->first) - mFirstIt->first); - // left edge of time line - } else { + } + else + { weight = F32 ((1 + curTime) - mFirstIt->first) / ((1 + mSecondIt->first) - mFirstIt->first); } - // handle same as whatever the last one is - } else { + } + else + { weight = 1; } + if(mIsInterpolating) + { + // *TODO_JACOB: this is kind of laggy. Not sure why. The part that lags is the curParams.mix call, and none of the other mixes. It works, though. + clock_t current = clock(); + if(current >= mInterpEndTime) + { + mIsInterpolating = false; + return; + } + + // determine moving target for final interpolation value + LLWLParamSet buf = LLWLParamSet(); + buf.setAll(LLWLParamManager::getInstance()->mParamList[mFirstIt->second].getAll()); // just give it some values, otherwise it has no params to begin with (see comment in constructor) + buf.mix(LLWLParamManager::getInstance()->mParamList[mFirstIt->second], LLWLParamManager::getInstance()->mParamList[mSecondIt->second], weight); // mix to determine moving target for interpolation finish (as below) + + // mix from previous value to moving target + weight = (current - mInterpStartTime) / (INTERP_TOTAL_SECONDS * CLOCKS_PER_SEC); + curParams.mix(*mInterpBeginWL, buf, weight); + + // mix water + LLWaterParamManager::getInstance()->mCurParams.mix(*mInterpBeginWater, *mInterpEndWater, weight); + } + else + { // do the interpolation and set the parameters - curParams.mix(LLWLParamManager::instance()->mParamList[mFirstIt->second], - LLWLParamManager::instance()->mParamList[mSecondIt->second], weight); + curParams.mix(LLWLParamManager::getInstance()->mParamList[mFirstIt->second], LLWLParamManager::getInstance()->mParamList[mSecondIt->second], weight); + } } F64 LLWLAnimator::getDayTime() { - if(!mIsRunning) { + if(!mIsRunning) + { return mDayTime; } - - if(mUseLindenTime) { - + else if(mTimeType == TIME_LINDEN) + { F32 phase = gSky.getSunPhase() / F_PI; // we're not solving the non-linear equation that determines sun phase // we're just linearly interpolating between the major points if (phase <= 5.0 / 4.0) { mDayTime = (1.0 / 3.0) * phase + (1.0 / 3.0); - } else { + } + else + { mDayTime = phase - (1.0 / 2.0); } - if(mDayTime > 1) { + if(mDayTime > 1) + { mDayTime--; } return mDayTime; } + else if(mTimeType == TIME_LOCAL) + { + return getLocalTime(); + } // get the time; mDayTime = (LLTimer::getElapsedSeconds() - mStartTime) / mDayRate; // clamp it - if(mDayTime < 0) { + if(mDayTime < 0) + { mDayTime = 0; } - while(mDayTime > 1) { + while(mDayTime > 1) + { mDayTime--; } @@ -144,15 +196,18 @@ void LLWLAnimator::setDayTime(F64 dayTime) mDayTime = dayTime; // clamp it - if(mDayTime < 0) { + if(mDayTime < 0) + { mDayTime = 0; - } else if(mDayTime > 1) { + } + else if(mDayTime > 1) + { mDayTime = 1; } } -void LLWLAnimator::setTrack(std::map<F32, std::string>& curTrack, +void LLWLAnimator::setTrack(std::map<F32, LLWLParamKey>& curTrack, F32 dayRate, F64 dayTime, bool run) { mTimeTrack = curTrack; @@ -161,3 +216,96 @@ void LLWLAnimator::setTrack(std::map<F32, std::string>& curTrack, mIsRunning = run; } + +void LLWLAnimator::startInterpolation(LLSD& targetWater) +{ + mInterpBeginWL->setAll(LLWLParamManager::getInstance()->mCurParams.getAll()); + mInterpBeginWater->setAll(LLWaterParamManager::getInstance()->mCurParams.getAll()); + + mInterpStartTime = clock(); + mInterpEndTime = mInterpStartTime + clock_t(INTERP_TOTAL_SECONDS) * CLOCKS_PER_SEC; + + // Don't set any ending WL -- this is continuously calculated as the animator updates since it's a moving target + mInterpEndWater->setAll(targetWater); + + mIsInterpolating = true; +} + +std::string LLWLAnimator::timeToString(F32 curTime) +{ + S32 hours; + S32 min; + bool isPM = false; + + // get hours and minutes + hours = (S32) (24.0 * curTime); + curTime -= ((F32) hours / 24.0f); + min = llround(24.0f * 60.0f * curTime); + + // handle case where it's 60 + if(min == 60) + { + hours++; + min = 0; + } + + // set for PM + if(hours >= 12 && hours < 24) + { + isPM = true; + } + + // convert to non-military notation + if(hours >= 24) + { + hours = 12; + } + else if(hours > 12) + { + hours -= 12; + } + else if(hours == 0) + { + hours = 12; + } + + // make the string + std::stringstream newTime; + newTime << hours << ":"; + + // double 0 + if(min < 10) + { + newTime << 0; + } + + // finish it + newTime << min << " "; + if(isPM) + { + newTime << "PM"; + } + else + { + newTime << "AM"; + } + + return newTime.str(); +} + +F64 LLWLAnimator::getLocalTime() +{ + char buffer[9]; + time_t rawtime; + struct tm* timeinfo; + + time(&rawtime); + timeinfo = localtime(&rawtime); + strftime(buffer, 9, "%H:%M:%S", timeinfo); + std::string timeStr(buffer); + + F64 tod = ((F64)atoi(timeStr.substr(0,2).c_str())) / 24.f + + ((F64)atoi(timeStr.substr(3,2).c_str())) / 1440.f + + ((F64)atoi(timeStr.substr(6,2).c_str())) / 86400.f; + return tod; +} diff --git a/indra/newview/llwlanimator.h b/indra/newview/llwlanimator.h index 5677290213..07c2fa2328 100644 --- a/indra/newview/llwlanimator.h +++ b/indra/newview/llwlanimator.h @@ -28,28 +28,39 @@ #define LL_WL_ANIMATOR_H #include "llwlparamset.h" +#include "llwaterparamset.h" #include <string> #include <map> +struct LLWLParamKey; + class LLWLAnimator { public: + typedef enum e_time + { + TIME_LINDEN, + TIME_LOCAL, + TIME_CUSTOM + } ETime; + F64 mStartTime; F32 mDayRate; F64 mDayTime; // track to play - std::map<F32, std::string> mTimeTrack; - std::map<F32, std::string>::iterator mFirstIt, mSecondIt; - - // params to use - //std::map<std::string, LLWLParamSet> mParamList; - - bool mIsRunning; - bool mUseLindenTime; + std::map<F32, LLWLParamKey> mTimeTrack; + std::map<F32, LLWLParamKey>::iterator mFirstIt, mSecondIt; // simple constructor LLWLAnimator(); + ~LLWLAnimator() + { + delete mInterpBeginWL; + delete mInterpBeginWater; + delete mInterpEndWater; + } + // update the parameters void update(LLWLParamSet& curParams); @@ -63,9 +74,66 @@ public: void setDayTime(F64 dayTime); // set an animation track - void setTrack(std::map<F32, std::string>& track, + void setTrack(std::map<F32, LLWLParamKey>& track, F32 dayRate, F64 dayTime = 0, bool run = true); + void deactivate() + { + mIsRunning = false; + } + + void activate(ETime time) + { + mIsRunning = true; + mTimeType = time; + } + + void startInterpolation(LLSD& targetWater); + + bool getIsRunning() + { + return mIsRunning; + } + + bool getUseCustomTime() + { + return mTimeType == TIME_CUSTOM; + } + + bool getUseLocalTime() + { + return mTimeType == TIME_LOCAL; + } + + bool getUseLindenTime() + { + return mTimeType == TIME_LINDEN; + } + + void setTimeType(ETime time) + { + mTimeType = time; + } + + ETime getTimeType() + { + return mTimeType; + } + + /// convert the present time to a digital clock time + static std::string timeToString(F32 curTime); + + /// get local time between 0 and 1 + static F64 getLocalTime(); + +private: + ETime mTimeType; + bool mIsRunning, mIsInterpolating; + LLWLParamSet *mInterpBeginWL; + LLWaterParamSet *mInterpBeginWater, *mInterpEndWater; + clock_t mInterpStartTime, mInterpEndTime; + + static F64 INTERP_TOTAL_SECONDS; }; #endif // LL_WL_ANIMATOR_H diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp index 85b3d62a49..52bbb4b5fc 100644 --- a/indra/newview/llwldaycycle.cpp +++ b/indra/newview/llwldaycycle.cpp @@ -2,37 +2,42 @@ * @file llwldaycycle.cpp * @brief Implementation for the LLWLDayCycle class. * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, 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. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * 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. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * 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 + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llwldaycycle.h" - -#include "llnotificationsutil.h" #include "llsdserialize.h" -#include "llxmlnode.h" - #include "llwlparammanager.h" +#include "llfloaterdaycycle.h" + +#include "llviewerwindow.h" #include <map> @@ -45,85 +50,111 @@ LLWLDayCycle::~LLWLDayCycle() { } -void LLWLDayCycle::loadDayCycle(const std::string & fileName) +void LLWLDayCycle::loadDayCycle(const LLSD& day_data, LLWLParamKey::EScope scope) { - // clear the first few things mTimeMap.clear(); - // now load the file - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, - "windlight/days", fileName)); - llinfos << "Loading DayCycle settings from " << pathName << llendl; - - llifstream day_cycle_xml(pathName); - if (day_cycle_xml.is_open()) + // add each key frame + for(S32 i = 0; i < day_data.size(); ++i) { - // load and parse it - LLSD day_data(LLSD::emptyArray()); - LLPointer<LLSDParser> parser = new LLSDXMLParser(); - parser->parse(day_cycle_xml, day_data, LLSDSerialize::SIZE_UNLIMITED); - - // add each key - for(S32 i = 0; i < day_data.size(); ++i) + // make sure it's a two array + if(day_data[i].size() != 2) + { + continue; + } + + // check each param key exists in param manager + bool success; + LLWLParamSet pset; + LLWLParamKey frame = LLWLParamKey(day_data[i][1].asString(), scope); + success = + LLWLParamManager::getInstance()->getParamSet(frame, pset); + if(!success) { - // make sure it's a two array - if(day_data[i].size() != 2) + // *HACK try the local-scope ones for "A-something" defaults + // (because our envManager.lindenDefault() doesn't have the skies yet) + if (frame.name.find("A-") == 0) { - continue; + frame.scope = LLEnvKey::SCOPE_LOCAL; + success = LLWLParamManager::getInstance()->getParamSet(frame, pset); } - - // check each param name exists in param manager - bool success; - LLWLParamSet pset; - success = LLWLParamManager::instance()->getParamSet(day_data[i][1].asString(), pset); - if(!success) + + if (!success) { // alert the user LLSD args; args["SKY"] = day_data[i][1].asString(); - LLNotificationsUtil::add("WLMissingSky", args); + LLNotifications::instance().add("WLMissingSky", args); continue; } - - // then add the key - addKey((F32)day_data[i][0].asReal(), day_data[i][1].asString()); } + + // then add the keyframe + addKeyframe((F32)day_data[i][0].asReal(), frame); + } +} + +void LLWLDayCycle::loadDayCycleFromFile(const std::string & fileName) +{ + loadDayCycle(loadCycleDataFromFile(fileName), LLWLParamKey::SCOPE_LOCAL); +} +/*static*/ LLSD LLWLDayCycle::loadCycleDataFromFile(const std::string & fileName) +{ + // now load the file + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, + "windlight/days", fileName)); + llinfos << "Loading DayCycle settings from " << pathName << llendl; + + llifstream day_cycle_xml(pathName); + if (day_cycle_xml.is_open()) + { + // load and parse it + LLSD day_data(LLSD::emptyArray()); + LLPointer<LLSDParser> parser = new LLSDXMLParser(); + parser->parse(day_cycle_xml, day_data, LLSDSerialize::SIZE_UNLIMITED); day_cycle_xml.close(); + return day_data; + } + else + { + return LLSD(); } } void LLWLDayCycle::saveDayCycle(const std::string & fileName) { - LLSD day_data(LLSD::emptyArray()); + LLSD day_data = asLLSD(); std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", fileName)); //llinfos << "Saving WindLight settings to " << pathName << llendl; - for(std::map<F32, std::string>::const_iterator mIt = mTimeMap.begin(); - mIt != mTimeMap.end(); - ++mIt) - { - LLSD key(LLSD::emptyArray()); - key.append(mIt->first); - key.append(mIt->second); - day_data.append(key); - } - llofstream day_cycle_xml(pathName); LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter(); formatter->format(day_data, day_cycle_xml, LLSDFormatter::OPTIONS_PRETTY); day_cycle_xml.close(); } +LLSD LLWLDayCycle::asLLSD() +{ + LLSD day_data(LLSD::emptyArray()); + for(std::map<F32, LLWLParamKey>::const_iterator mIt = mTimeMap.begin(); mIt != mTimeMap.end(); ++mIt) + { + LLSD key(LLSD::emptyArray()); + key.append(mIt->first); + key.append(mIt->second.name); + day_data.append(key); + } + return day_data; +} -void LLWLDayCycle::clearKeys() +void LLWLDayCycle::clearKeyframes() { mTimeMap.clear(); } -bool LLWLDayCycle::addKey(F32 newTime, const std::string & paramName) +bool LLWLDayCycle::addKeyframe(F32 newTime, LLWLParamKey frame) { // no adding negative time if(newTime < 0) @@ -134,7 +165,7 @@ bool LLWLDayCycle::addKey(F32 newTime, const std::string & paramName) // if time not being used, add it and return true if(mTimeMap.find(newTime) == mTimeMap.end()) { - mTimeMap.insert(std::pair<F32, std::string>(newTime, paramName)); + mTimeMap.insert(std::pair<F32, LLWLParamKey>(newTime, frame)); return true; } @@ -142,40 +173,40 @@ bool LLWLDayCycle::addKey(F32 newTime, const std::string & paramName) return false; } -bool LLWLDayCycle::changeKeyTime(F32 oldTime, F32 newTime) +bool LLWLDayCycle::changeKeyframeTime(F32 oldTime, F32 newTime) { // just remove and add back - std::string name = mTimeMap[oldTime]; + LLWLParamKey frame = mTimeMap[oldTime]; - bool stat = removeKey(oldTime); + bool stat = removeKeyframe(oldTime); if(stat == false) { return stat; } - return addKey(newTime, name); + return addKeyframe(newTime, frame); } -bool LLWLDayCycle::changeKeyParam(F32 time, const std::string & name) +bool LLWLDayCycle::changeKeyframeParam(F32 time, LLWLParamKey key) { // just remove and add back // make sure param exists LLWLParamSet tmp; - bool stat = LLWLParamManager::instance()->getParamSet(name, tmp); + bool stat = LLWLParamManager::getInstance()->getParamSet(key, tmp); if(stat == false) { return stat; } - mTimeMap[time] = name; + mTimeMap[time] = key; return true; } -bool LLWLDayCycle::removeKey(F32 time) +bool LLWLDayCycle::removeKeyframe(F32 time) { // look for the time. If there, erase it - std::map<F32, std::string>::iterator mIt = mTimeMap.find(time); + std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time); if(mIt != mTimeMap.end()) { mTimeMap.erase(mIt); @@ -185,15 +216,15 @@ bool LLWLDayCycle::removeKey(F32 time) return false; } -bool LLWLDayCycle::getKey(const std::string & name, F32& key) +bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) { - // scroll through till we find the - std::map<F32, std::string>::iterator mIt = mTimeMap.begin(); + // scroll through till we find the correct value in the map + std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.begin(); for(; mIt != mTimeMap.end(); ++mIt) { - if(name == mIt->second) + if(frame == mIt->second) { - key = mIt->first; + key_time = mIt->first; return true; } } @@ -204,10 +235,10 @@ bool LLWLDayCycle::getKey(const std::string & name, F32& key) bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param) { // just scroll on through till you find it - std::map<F32, std::string>::iterator mIt = mTimeMap.find(time); - if(mIt != mTimeMap.end()) + std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time); + if(mIt != mTimeMap.end()) { - return LLWLParamManager::instance()->getParamSet(mIt->second, param); + return LLWLParamManager::getInstance()->getParamSet(mIt->second, param); } // return error if not found @@ -217,13 +248,30 @@ bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param) bool LLWLDayCycle::getKeyedParamName(F32 time, std::string & name) { // just scroll on through till you find it - std::map<F32, std::string>::iterator mIt = mTimeMap.find(time); + std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time); if(mIt != mTimeMap.end()) { - name = mTimeMap[time]; + name = mTimeMap[time].name; return true; } // return error if not found return false; } + +void LLWLDayCycle::removeReferencesTo(const LLWLParamKey& keyframe) +{ + F32 keytime; + bool might_exist; + do + { + // look for it + might_exist = getKeytime(keyframe, keytime); + if(!might_exist) + { + return; + } + might_exist = removeKeyframe(keytime); + + } while(might_exist); // might be another one +} diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h index 5cbf72191d..d56194a74a 100644 --- a/indra/newview/llwldaycycle.h +++ b/indra/newview/llwldaycycle.h @@ -34,13 +34,15 @@ class LLWLDayCycle; #include <string> #include "llwlparamset.h" #include "llwlanimator.h" +struct LLWLParamKey; +#include "llenvmanager.h" // for LLEnvKey::EScope class LLWLDayCycle { public: // lists what param sets are used when during the day - std::map<F32, std::string> mTimeMap; + std::map<F32, LLWLParamKey> mTimeMap; // how long is my day F32 mDayRate; @@ -54,35 +56,44 @@ public: ~LLWLDayCycle(); /// load a day cycle - void loadDayCycle(const std::string & fileName); + void loadDayCycle(const LLSD& llsd, LLEnvKey::EScope scope); + + /// load a day cycle + void loadDayCycleFromFile(const std::string & fileName); /// load a day cycle void saveDayCycle(const std::string & fileName); - /// clear keys - void clearKeys(); + /// load the LLSD data from a file (returns the undefined LLSD if not found) + static LLSD loadCycleDataFromFile(const std::string & fileName); + + /// get the LLSD data for this day cycle + LLSD asLLSD(); + + /// clear keyframes + void clearKeyframes(); /// Getters and Setters /// add a new key frame to the day cycle /// returns true if successful /// no negative time - bool addKey(F32 newTime, const std::string & paramName); + bool addKeyframe(F32 newTime, LLWLParamKey key); - /// adjust a key's placement in the day cycle + /// adjust a keyframe's placement in the day cycle /// returns true if successful - bool changeKeyTime(F32 oldTime, F32 newTime); + bool changeKeyframeTime(F32 oldTime, F32 newTime); - /// adjust a key's parameter used + /// adjust a keyframe's parameter used /// returns true if successful - bool changeKeyParam(F32 time, const std::string & paramName); + bool changeKeyframeParam(F32 time, LLWLParamKey key); - /// remove a key from the day cycle + /// remove a key frame from the day cycle /// returns true if successful - bool removeKey(F32 time); + bool removeKeyframe(F32 time); /// get the first key time for a parameter /// returns false if not there - bool getKey(const std::string & name, F32& key); + bool getKeytime(LLWLParamKey keyFrame, F32& keyTime); /// get the param set at a given time /// returns true if found one @@ -92,6 +103,9 @@ public: /// returns true if it found one bool getKeyedParamName(F32 time, std::string & name); + /// removes all references to the sky (paramkey) + /// does nothing if the sky doesn't exist in the day + void removeReferencesTo(const LLWLParamKey& keyframe); }; diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp new file mode 100644 index 0000000000..c4f11cf00a --- /dev/null +++ b/indra/newview/llwlhandlers.cpp @@ -0,0 +1,159 @@ +/** + * @file llwlhandlers.cpp + * @brief Various classes which handle Windlight-related messaging + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwlhandlers.h" + +#include "llagent.h" +#include "llviewerregion.h" +#include "llenvmanager.h" + +/**** + * LLEnvironmentRequestResponder + ****/ +int LLEnvironmentRequestResponder::sCount = 0; // init to 0 + +/*static*/ bool LLEnvironmentRequestResponder::initiateRequest() +{ + std::string url = gAgent.getRegion()->getCapability("EnvironmentSettings"); + if (url.empty()) + { + LL_INFOS("WindlightCaps") << "Skipping windlight setting request - we don't have this capability" << LL_ENDL; + // region is apparently not capable of this; don't respond at all + return false; + } + else + { + LL_DEBUGS("WindlightCaps") << "Requesting windlight settings via " << url << LL_ENDL; + LLHTTPClient::get(url, new LLEnvironmentRequestResponder()); + return true; + } +} +LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() +{ + mID = ++sCount; +} +/*virtual*/ void LLEnvironmentRequestResponder::result(const LLSD& unvalidated_content) +{ + LL_DEBUGS("WindlightCaps") << "Receiving windlight settings..." << LL_ENDL; + + if (mID != sCount) + { + LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL; + return; + } + + if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + { + LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting " + << gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID() + << ") - ignoring..." << LL_ENDL; + return; + } + + LLEnvManager::getInstance()->processIncomingMessage(unvalidated_content, LLEnvKey::SCOPE_REGION); +} +/*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason) +{ + LL_INFOS("WindlightCaps") << "Got an error, not using region windlight..." << LL_ENDL; + // notify manager that region settings are undefined + LLEnvManager::getInstance()->processIncomingMessage(LLSD(), LLEnvKey::SCOPE_REGION); +} + + +/**** + * LLEnvironmentApplyResponder + ****/ +clock_t LLEnvironmentApplyResponder::UPDATE_WAIT_SECONDS = clock_t(3.f); +clock_t LLEnvironmentApplyResponder::sLastUpdate = clock_t(0.f); + +bool LLEnvironmentApplyResponder::initiateRequest(const LLSD& content) +{ + clock_t current = clock(); + if(current >= sLastUpdate + (UPDATE_WAIT_SECONDS * CLOCKS_PER_SEC)) + { + sLastUpdate = current; + } + else + { + LLSD args(LLSD::emptyMap()); + args["WAIT"] = (F64)UPDATE_WAIT_SECONDS; + LLNotifications::instance().add("EnvUpdateRate", args); + return false; + } + + std::string url = gAgent.getRegion()->getCapability("EnvironmentSettings"); + if (!url.empty()) + { + LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL; + LLHTTPClient::post(url, content, new LLEnvironmentApplyResponder()); + return true; + } + return false; +} +/*virtual*/ void LLEnvironmentApplyResponder::result(const LLSD& content) +{ + if (content["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + { + LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently " + << gAgent.getRegion()->getRegionID() << ", reply is from " << content["regionID"].asUUID() + << "); ignoring..." << LL_ENDL; + return; + } + else if (content["success"].asBoolean()) + { + LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << content["regionID"].asUUID() << LL_ENDL; + } + else + { + LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings! Reason from sim: " << content["fail_reason"].asString() << LL_ENDL; + LLSD args(LLSD::emptyMap()); + args["FAIL_REASON"] = content["fail_reason"].asString(); + LLNotifications::instance().add("WLRegionApplyFail", args); + } + + LLEnvManager::getInstance()->commitSettingsFinished(LLEnvKey::SCOPE_REGION); +} +/*virtual*/ void LLEnvironmentApplyResponder::error(U32 status, const std::string& reason) +{ + std::stringstream msg; + msg << reason << " (Code " << status << ")"; + + LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! Reason: " << msg << LL_ENDL; + + LLSD args(LLSD::emptyMap()); + args["FAIL_REASON"] = msg.str(); + LLNotifications::instance().add("WLRegionApplyFail", args); + + LLEnvManager::getInstance()->commitSettingsFinished(LLEnvKey::SCOPE_REGION); +} diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h new file mode 100644 index 0000000000..a50404f2e1 --- /dev/null +++ b/indra/newview/llwlhandlers.h @@ -0,0 +1,89 @@ +/** + * @file llwlhandlers.h + * @brief Headers for classes in llwlhandlers.cpp + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLWLHANDLERS_H +#define LL_LLWLHANDLERS_H + +#include "llviewerprecompiledheaders.h" + +class LLEnvManager; + +class LLEnvironmentRequestResponder: public LLHTTPClient::Responder +{ +public: + virtual void result(const LLSD& content); + virtual void error(U32 status, const std::string& reason); + +private: + friend class LLEnvManager; + // returns true if request was sucessfully sent + static bool initiateRequest(); + + LLEnvironmentRequestResponder(); + static int sCount; + int mID; +}; + +class LLEnvironmentApplyResponder: public LLHTTPClient::Responder +{ +public: + /* + * Expecting reply from sim in form of: + * { + * regionID : uuid, + * messageID: uuid, + * success : true + * } + * or + * { + * regionID : uuid, + * success : false, + * fail_reason : string + * } + */ + virtual void result(const LLSD& content); + + virtual void error(U32 status, const std::string& reason); // non-200 errors only + +private: + friend class LLEnvManager; + + static clock_t sLastUpdate; + static clock_t UPDATE_WAIT_SECONDS; + + // for format of packet expected, see llwlscrubbers.cpp in llmessage + static bool initiateRequest(const LLSD& packet); + + LLEnvironmentApplyResponder() {} +}; + +#endif // LL_LLWLHANDLERS_H diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 9b6047395a..493d066942 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -2,25 +2,31 @@ * @file llwlparammanager.cpp * @brief Implementation for the LLWLParamManager class. * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, 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. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * 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. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * 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 + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -31,28 +37,34 @@ #include "pipeline.h" #include "llsky.h" -#include "llfloaterreg.h" #include "llsliderctrl.h" #include "llspinctrl.h" #include "llcheckboxctrl.h" #include "lluictrlfactory.h" +#include "llviewercamera.h" #include "llcombobox.h" #include "lllineeditor.h" #include "llsdserialize.h" #include "v4math.h" +#include "llviewerdisplay.h" #include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "lldrawpoolwater.h" +#include "llagent.h" +#include "llviewerregion.h" +#include "llenvmanager.h" #include "llwlparamset.h" #include "llpostprocess.h" #include "llfloaterwindlight.h" #include "llfloaterdaycycle.h" #include "llfloaterenvsettings.h" +#include "llviewershadermgr.h" +#include "llglslshader.h" #include "curl/curl.h" - -LLWLParamManager * LLWLParamManager::sInstance = NULL; -static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params"); +#include "llstreamtools.h" LLWLParamManager::LLWLParamManager() : @@ -95,19 +107,150 @@ LLWLParamManager::~LLWLParamManager() { } +void LLWLParamManager::clearParamSetsOfScope(LLWLParamKey::EScope scope) +{ + if (LLWLParamKey::SCOPE_LOCAL == scope) + { + LL_WARNS("Windlight") << "Tried to clear windlight sky presets from local system! This shouldn't be called..." << LL_ENDL; + return; + } + + std::set<LLWLParamKey> to_remove; + for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = mParamList.begin(); iter != mParamList.end(); ++iter) + { + if(iter->first.scope == scope) + { + to_remove.insert(iter->first); + } + } + + for(std::set<LLWLParamKey>::iterator iter = to_remove.begin(); iter != to_remove.end(); ++iter) + { + mParamList.erase(*iter); + } +} + +// returns all skies referenced by the day cycle, with their final names +// side effect: applies changes to all internal structures! +std::map<LLWLParamKey, LLWLParamSet> LLWLParamManager::finalizeFromDayCycle(LLWLParamKey::EScope scope) +{ + std::map<LLWLParamKey, LLWLParamSet> final_references; + + // Move all referenced to desired scope, renaming if necessary + // First, save skies referenced + std::map<LLWLParamKey, LLWLParamSet> current_references; // all skies referenced by the day cycle, with their current names + // guard against skies with same name and different scopes + std::set<std::string> inserted_names; + std::map<std::string, unsigned int> conflicted_names; // integer later used as a count, for uniquely renaming conflicts + + LLWLDayCycle& cycle = mDay; + for(std::map<F32, LLWLParamKey>::iterator iter = cycle.mTimeMap.begin(); + iter != cycle.mTimeMap.end(); + ++iter) + { + LLWLParamKey& key = iter->second; + std::string desired_name = key.name; + replace_newlines_with_whitespace(desired_name); // already shouldn't have newlines, but just in case + if(inserted_names.find(desired_name) == inserted_names.end()) + { + inserted_names.insert(desired_name); + } + else + { + // make exist in map + conflicted_names[desired_name] = 0; + } + current_references[key] = mParamList[key]; + } + + // forget all old skies in target scope, and rebuild, renaming as needed + clearParamSetsOfScope(scope); + for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = current_references.begin(); iter != current_references.end(); ++iter) + { + const LLWLParamKey& old_key = iter->first; + + std::string desired_name(old_key.name); + replace_newlines_with_whitespace(desired_name); + + LLWLParamKey new_key(desired_name, scope); // name will be replaced later if necessary + + // if this sky is one with a non-unique name, rename via appending a number + // an existing preset of the target scope gets to keep its name + if (scope != old_key.scope && conflicted_names.find(desired_name) != conflicted_names.end()) + { + std::string& new_name = new_key.name; + + do + { + // if this executes more than once, this is an absurdly pathological case + // (e.g. "x" repeated twice, but "x 1" already exists, so need to use "x 2") + std::stringstream temp; + temp << desired_name << " " << (++conflicted_names[desired_name]); + new_name = temp.str(); + } while (inserted_names.find(new_name) != inserted_names.end()); + + // yay, found one that works + inserted_names.insert(new_name); // track names we consume here; shouldn't be necessary due to ++int? but just in case + + // *TODO factor out below into a rename()? + + LL_INFOS("Windlight") << "Renamed " << old_key.name << " (scope" << old_key.scope << ") to " + << new_key.name << " (scope " << new_key.scope << ")" << LL_ENDL; + + // update name in sky + iter->second.mName = new_name; + + // update keys in day cycle + for(std::map<F32, LLWLParamKey>::iterator frame = cycle.mTimeMap.begin(); frame != cycle.mTimeMap.end(); ++frame) + { + if (frame->second == old_key) + { + frame->second = new_key; + } + } + + // add to master sky map + mParamList[new_key] = iter->second; + } + + final_references[new_key] = iter->second; + } + + return final_references; +} + +LLSD LLWLParamManager::createSkyMap(std::map<LLWLParamKey, LLWLParamSet> refs) +{ + LLSD skies = LLSD::emptyMap(); + for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = refs.begin(); iter != refs.end(); ++iter) + { + skies.insert(iter->first.name, iter->second.getAll()); + } + return skies; +} + +void LLWLParamManager::addAllSkies(const LLWLParamKey::EScope scope, const LLSD& sky_presets) +{ + for(LLSD::map_const_iterator iter = sky_presets.beginMap(); iter != sky_presets.endMap(); ++iter) + { + LLWLParamSet set; + set.setAll(iter->second); + mParamList[LLWLParamKey(iter->first, scope)] = set; + } +} + void LLWLParamManager::loadPresets(const std::string& file_name) { std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", "")); - LL_DEBUGS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL; - - bool found = true; + LL_INFOS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL; + + bool found = true; while(found) { std::string name; found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false); if(found) { - name=name.erase(name.length()-4); // bugfix for SL-46920: preventing filenames that break stuff. @@ -117,16 +260,16 @@ void LLWLParamManager::loadPresets(const std::string& file_name) curl_str = NULL; LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(unescaped_name,FALSE); + loadPreset(LLWLParamKey(unescaped_name, LLWLParamKey::SCOPE_LOCAL),FALSE); } } // And repeat for user presets, note the user presets will modify any system presets already loaded std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", "")); - LL_DEBUGS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL; - - found = true; + LL_INFOS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL; + + found = true; while(found) { std::string name; @@ -142,12 +285,14 @@ void LLWLParamManager::loadPresets(const std::string& file_name) curl_str = NULL; LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(unescaped_name,FALSE); + loadPreset(LLWLParamKey(unescaped_name,LLWLParamKey::SCOPE_LOCAL),FALSE); } } } +// untested and unmaintained! sanity-check me before using +/* void LLWLParamManager::savePresets(const std::string & fileName) { //Nobody currently calls me, but if they did, then its reasonable to write the data out to the user's folder @@ -157,11 +302,11 @@ void LLWLParamManager::savePresets(const std::string & fileName) std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", fileName)); - for(std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.begin(); + for(std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.begin(); mIt != mParamList.end(); ++mIt) { - paramsData[mIt->first] = mIt->second.getAll(); + paramsData[mIt->first.name] = mIt->second.getAll(); } llofstream presetsXML(pathName); @@ -172,70 +317,78 @@ void LLWLParamManager::savePresets(const std::string & fileName) presetsXML.close(); } +*/ -void LLWLParamManager::loadPreset(const std::string & name,bool propagate) +void LLWLParamManager::loadPreset(const LLWLParamKey key, bool propagate) { - - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_escape(name.c_str(), name.size()); - std::string escaped_filename(curl_str); - curl_free(curl_str); - curl_str = NULL; - - escaped_filename += ".xml"; - - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename)); - LL_DEBUGS2("AppInit", "Shaders") << "Loading WindLight sky setting from " << pathName << LL_ENDL; - - llifstream presetsXML; - presetsXML.open(pathName.c_str()); - - // That failed, try loading from the users area instead. - if(!presetsXML) + if(mParamList.find(key) == mParamList.end()) // key does not already exist in mapping { - pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename); - LL_DEBUGS2("AppInit", "Shaders") << "Loading User WindLight sky setting from " << pathName << LL_ENDL; - presetsXML.clear(); - presetsXML.open(pathName.c_str()); - } + if(key.scope == LLWLParamKey::SCOPE_LOCAL) // local scope, so try to load from file + { + // bugfix for SL-46920: preventing filenames that break stuff. + char * curl_str = curl_escape(key.name.c_str(), key.name.size()); + std::string escaped_filename(curl_str); + curl_free(curl_str); + curl_str = NULL; - if (presetsXML) - { - LLSD paramsData(LLSD::emptyMap()); + escaped_filename += ".xml"; - LLPointer<LLSDParser> parser = new LLSDXMLParser(); + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename)); + llinfos << "Loading WindLight sky setting from " << pathName << llendl; - parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED); + llifstream presetsXML; + presetsXML.open(pathName.c_str()); - std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name); - if(mIt == mParamList.end()) - { - addParamSet(name, paramsData); + // That failed, try loading from the users area instead. + if(!presetsXML) + { + pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename); + llinfos << "Loading User WindLight sky setting from " << pathName << llendl; + presetsXML.open(pathName.c_str()); + } + + if (presetsXML) + { + loadPresetFromXML(key, presetsXML); + presetsXML.close(); + } + else + { + llwarns << "Could not load local WindLight sky setting " << key.toString() << llendl; + return; + } } - else + else { - setParamSet(name, paramsData); - } - presetsXML.close(); - } - else - { - llwarns << "Can't find " << name << llendl; - return; + llwarns << "Attempted to load non-local WindLight sky settings " << key.toString() << "; not found in parameter mapping." << llendl; + return; + } } - if(propagate) { - getParamSet(name, mCurParams); + getParamSet(key, mCurParams); propagateParameters(); } -} +} -void LLWLParamManager::savePreset(const std::string & name) +void LLWLParamManager::loadPresetFromXML(LLWLParamKey key, std::istream & presetsXML) +{ + LLSD paramsData(LLSD::emptyMap()); + LLPointer<LLSDParser> parser = new LLSDXMLParser(); + + parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED); + + std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); + + if(mIt == mParamList.end()) addParamSet(key, paramsData); + else setParamSet(key, paramsData); +} + +void LLWLParamManager::savePreset(LLWLParamKey key) { // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_escape(name.c_str(), name.size()); + char * curl_str = curl_escape(key.name.c_str(), key.name.size()); std::string escaped_filename(curl_str); curl_free(curl_str); curl_str = NULL; @@ -247,7 +400,7 @@ void LLWLParamManager::savePreset(const std::string & name) std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename)); // fill it with LLSD windlight params - paramsData = mParamList[name].getAll(); + paramsData = mParamList[key].getAll(); // write to file llofstream presetsXML(pathName); @@ -282,7 +435,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader) void LLWLParamManager::propagateParameters(void) { - LLFastTimer ftm(FTM_UPDATE_WLPARAM); + LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); LLVector4 sunDir; LLVector4 moonDir; @@ -306,7 +459,7 @@ void LLWLParamManager::propagateParameters(void) { mLightDir = sunDir; } - else if(sunDir.mV[1] < 0 && sunDir.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS) + else if(sunDir.mV[1] < 0 && sunDir.mV[1] > NIGHTTIME_ELEVATION_COS) { // clamp v1 to 0 so sun never points up and causes weirdness on some machines LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]); @@ -353,13 +506,13 @@ void LLWLParamManager::propagateParameters(void) void LLWLParamManager::update(LLViewerCamera * cam) { - LLFastTimer ftm(FTM_UPDATE_WLPARAM); + LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); // update clouds, sun, and general mCurParams.updateCloudScrolling(); // update only if running - if(mAnimator.mIsRunning) + if(mAnimator.getIsRunning()) { mAnimator.update(mCurParams); } @@ -368,30 +521,29 @@ void LLWLParamManager::update(LLViewerCamera * cam) propagateParameters(); // sync menus if they exist - LLFloaterWindLight* wlfloater = LLFloaterReg::findTypedInstance<LLFloaterWindLight>("env_windlight"); - if (wlfloater) + if(LLFloaterWindLight::isOpen()) { - wlfloater->syncMenu(); + LLFloaterWindLight::instance()->syncMenu(); } - LLFloaterDayCycle* dlfloater = LLFloaterReg::findTypedInstance<LLFloaterDayCycle>("env_day_cycle"); - if (dlfloater) + if(LLFloaterDayCycle::isOpen()) { - dlfloater->syncMenu(); + LLFloaterDayCycle::instance()->syncMenu(); } - LLFloaterEnvSettings* envfloater = LLFloaterReg::findTypedInstance<LLFloaterEnvSettings>("env_settings"); - if (envfloater) + if(LLFloaterEnvSettings::isOpen()) { - envfloater->syncMenu(); + LLFloaterEnvSettings::instance()->syncMenu(); } F32 camYaw = cam->getYaw(); + stop_glerror(); + // *TODO: potential optimization - this block may only need to be // executed some of the time. For example for water shaders only. { F32 camYawDelta = mSunDeltaYaw * DEG_TO_RAD; - LLVector3 lightNorm3(mLightDir); + LLVector3 lightNorm3(mLightDir); lightNorm3 *= LLQuaternion(-(camYaw + camYawDelta), LLVector3(0.f, 1.f, 0.f)); mRotatedLightDir = LLVector4(lightNorm3, 0.f); @@ -409,19 +561,6 @@ void LLWLParamManager::update(LLViewerCamera * cam) } } -// static -void LLWLParamManager::initClass(void) -{ - instance(); -} - -// static -void LLWLParamManager::cleanupClass() -{ - delete sInstance; - sInstance = NULL; -} - void LLWLParamManager::resetAnimator(F32 curTime, bool run) { mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate, @@ -429,26 +568,27 @@ void LLWLParamManager::resetAnimator(F32 curTime, bool run) return; } -bool LLWLParamManager::addParamSet(const std::string& name, LLWLParamSet& param) + +bool LLWLParamManager::addParamSet(const LLWLParamKey& key, LLWLParamSet& param) { // add a new one if not one there already - std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name); + std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); if(mIt == mParamList.end()) { - mParamList[name] = param; + mParamList[key] = param; return true; } return false; } -BOOL LLWLParamManager::addParamSet(const std::string& name, LLSD const & param) +BOOL LLWLParamManager::addParamSet(const LLWLParamKey& key, LLSD const & param) { // add a new one if not one there already - std::map<std::string, LLWLParamSet>::const_iterator finder = mParamList.find(name); + std::map<LLWLParamKey, LLWLParamSet>::const_iterator finder = mParamList.find(key); if(finder == mParamList.end()) { - mParamList[name].setAll(param); + mParamList[key].setAll(param); return TRUE; } else @@ -457,105 +597,88 @@ BOOL LLWLParamManager::addParamSet(const std::string& name, LLSD const & param) } } -bool LLWLParamManager::getParamSet(const std::string& name, LLWLParamSet& param) +bool LLWLParamManager::getParamSet(const LLWLParamKey& key, LLWLParamSet& param) { // find it and set it - std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name); + std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); if(mIt != mParamList.end()) { - param = mParamList[name]; - param.mName = name; + param = mParamList[key]; + param.mName = key.name; return true; } return false; } -bool LLWLParamManager::setParamSet(const std::string& name, LLWLParamSet& param) +bool LLWLParamManager::setParamSet(const LLWLParamKey& key, LLWLParamSet& param) { - mParamList[name] = param; + mParamList[key] = param; return true; } -bool LLWLParamManager::setParamSet(const std::string& name, const LLSD & param) +bool LLWLParamManager::setParamSet(const LLWLParamKey& key, const LLSD & param) { // quick, non robust (we won't be working with files, but assets) check + // this might not actually be true anymore.... if(!param.isMap()) { return false; } - mParamList[name].setAll(param); + mParamList[key].setAll(param); return true; } -bool LLWLParamManager::removeParamSet(const std::string& name, bool delete_from_disk) +void LLWLParamManager::removeParamSet(const LLWLParamKey& key, bool delete_from_disk) { // remove from param list - std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name); + std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); if(mIt != mParamList.end()) { mParamList.erase(mIt); } - - F32 key; - - // remove all references - bool stat = true; - do + else { - // get it - stat = mDay.getKey(name, key); - if(stat == false) - { - break; - } + LL_WARNS("WindLight") << "Unable to delete key " << key.toString() << "; not found." << LL_ENDL; + } - // and remove - stat = mDay.removeKey(key); + mDay.removeReferencesTo(key); - } while(stat == true); - - if(delete_from_disk) + if(delete_from_disk && key.scope == LLWLParamKey::SCOPE_LOCAL) { std::string path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", "")); // use full curl escaped name - char * curl_str = curl_escape(name.c_str(), name.size()); + char * curl_str = curl_escape(key.name.c_str(), key.name.size()); std::string escaped_name(curl_str); curl_free(curl_str); curl_str = NULL; - gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml"); + if(gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml") < 1) + { + LL_WARNS("WindLight") << "Unable to delete key " << key.toString() << " from disk; not found." << LL_ENDL; + } } - - return true; } -// static -LLWLParamManager * LLWLParamManager::instance() +// virtual static +void LLWLParamManager::initSingleton() { - if(NULL == sInstance) - { - sInstance = new LLWLParamManager(); + loadPresets(LLStringUtil::null); - sInstance->loadPresets(LLStringUtil::null); + // load the day + mDay.loadDayCycleFromFile(std::string("Default.xml")); - // load the day - sInstance->mDay.loadDayCycle(std::string("Default.xml")); + // *HACK - sets cloud scrolling to what we want... fix this better in the future + getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), mCurParams); - // *HACK - sets cloud scrolling to what we want... fix this better in the future - sInstance->getParamSet("Default", sInstance->mCurParams); - - // set it to noon - sInstance->resetAnimator(0.5, true); - - // but use linden time sets it to what the estate is - sInstance->mAnimator.mUseLindenTime = true; - } + // set it to noon + resetAnimator(0.5, true); - return sInstance; + // but use linden time sets it to what the estate is + mAnimator.setTimeType(LLWLAnimator::TIME_LINDEN); } diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index 8c6329e769..1951366939 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -2,25 +2,31 @@ * @file llwlparammanager.h * @brief Implementation for the LLWLParamManager class. * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, 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. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * 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. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * 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 + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -29,10 +35,12 @@ #include <vector> #include <map> +#include "llenvmanager.h" #include "llwlparamset.h" #include "llwlanimator.h" #include "llwldaycycle.h" #include "llviewercamera.h" +#include "lltrans.h" class LLGLSLShader; @@ -72,7 +80,7 @@ struct WLColorControl { r = val.mV[0]; g = val.mV[1]; b = val.mV[2]; - i = val.mV[3]; + i = val.mV[3]; return *this; } @@ -115,25 +123,110 @@ struct WLFloatControl { } }; -/// WindLight parameter manager class - what controls all the wind light shaders -class LLWLParamManager +struct LLWLParamKey : LLEnvKey { public: + // scope and source of a param set (WL sky preset) + std::string name; + EScope scope; - LLWLParamManager(); - ~LLWLParamManager(); + // for conversion from LLSD + static const int NAME_IDX = 0; + static const int SCOPE_IDX = 1; + + inline LLWLParamKey(const std::string& n, EScope s) + : name(n), scope(s) + { + } + inline LLWLParamKey(LLSD llsd) + : name(llsd[NAME_IDX].asString()), scope(EScope(llsd[SCOPE_IDX].asInteger())) + { + } + + inline LLWLParamKey() // NOT really valid, just so std::maps can return a default of some sort + : name(NULL), scope(SCOPE_LOCAL) + { + } + + inline LLWLParamKey(std::string& stringVal) + : name(stringVal.substr(0, stringVal.length()-1)), + scope((EScope)atoi(stringVal.substr(stringVal.length()-1, stringVal.length()).c_str())) + { + } + + inline std::string toStringVal() const + { + std::stringstream str; + str << name << scope; + return str.str(); + } + + inline LLSD toLLSD() const + { + LLSD llsd = LLSD::emptyArray(); + llsd.append(LLSD(name)); + llsd.append(LLSD(scope)); + return llsd; + } + + inline bool operator <(const LLWLParamKey other) const + { + if (name < other.name) + { + return true; + } + else if (name > other.name) + { + return false; + } + else + { + return scope < other.scope; + } + } + + inline bool operator ==(const LLWLParamKey other) const + { + return (name == other.name) && (scope == other.scope); + } + + inline std::string toString() const + { + switch (scope) + { + case SCOPE_LOCAL: + return name + std::string(" (") + LLTrans::getString("Local") + std::string(")"); + break; + case SCOPE_REGION: + return name + std::string(" (") + LLTrans::getString("Region") + std::string(")"); + break; + default: + return name + " (?)"; + } + } +}; + +/// WindLight parameter manager class - what controls all the wind light shaders +class LLWLParamManager : public LLSingleton<LLWLParamManager> +{ +public: /// load a preset file void loadPresets(const std::string & fileName); /// save the preset file + // the implementation of this method was unmaintained and is commented out + // *NOTE test and sanity-check before uncommenting and using! void savePresets(const std::string & fileName); /// load an individual preset into the sky - void loadPreset(const std::string & name,bool propogate=true); + void loadPreset(const LLWLParamKey key, bool propogate=true); + + /// load an individual preset from a stream of XML + void loadPresetFromXML(const LLWLParamKey key, std::istream & presetXML); /// save the parameter presets to file - void savePreset(const std::string & name); + void savePreset(const LLWLParamKey key); /// Set shader uniforms dirty, so they'll update automatically. void propagateParameters(void); @@ -161,36 +254,38 @@ public: /// get the radius of the dome inline F32 getDomeRadius(void) const; - - /// Perform global initialization for this class. - static void initClass(void); - - // Cleanup of global data that's only inited once per class. - static void cleanupClass(); - /// add a param to the list - bool addParamSet(const std::string& name, LLWLParamSet& param); + /// add a param set (preset) to the list + bool addParamSet(const LLWLParamKey& key, LLWLParamSet& param); - /// add a param to the list - BOOL addParamSet(const std::string& name, LLSD const & param); + /// add a param set (preset) to the list + BOOL addParamSet(const LLWLParamKey& key, LLSD const & param); - /// get a param from the list - bool getParamSet(const std::string& name, LLWLParamSet& param); + /// get a param set (preset) from the list + bool getParamSet(const LLWLParamKey& key, LLWLParamSet& param); /// set the param in the list with a new param - bool setParamSet(const std::string& name, LLWLParamSet& param); + bool setParamSet(const LLWLParamKey& key, LLWLParamSet& param); /// set the param in the list with a new param - bool setParamSet(const std::string& name, LLSD const & param); - + bool setParamSet(const LLWLParamKey& key, LLSD const & param); + /// gets rid of a parameter and any references to it - /// returns true if successful - bool removeParamSet(const std::string& name, bool delete_from_disk); + /// ignores "delete_from_disk" if the scope is not local + void removeParamSet(const LLWLParamKey& key, bool delete_from_disk); - // singleton pattern implementation - static LLWLParamManager * instance(); + /// clear parameter mapping of a given scope + void clearParamSetsOfScope(LLEnvKey::EScope scope); -public: + /// add all skies in LLSD using the given scope + void addAllSkies(LLEnvKey::EScope scope, const LLSD& preset_map); + + // returns all skies referenced by the current day cycle (in mDay), with their final names + // side effect: applies changes to all internal structures! (trashes all unreferenced skies in scope, keys in day cycle rescoped to scope, etc.) + std::map<LLWLParamKey, LLWLParamSet> finalizeFromDayCycle(LLWLParamKey::EScope scope); + + // returns all skies in map (intended to be called with output from a finalize) + LLSD createSkyMap(std::map<LLWLParamKey, LLWLParamSet> map); // helper variables LLWLAnimator mAnimator; @@ -244,13 +339,13 @@ public: F32 mDomeRadius; // list of all the parameters, listed by name - std::map<std::string, LLWLParamSet> mParamList; - + std::map<LLWLParamKey, LLWLParamSet> mParamList; private: - // our parameter manager singleton instance - static LLWLParamManager * sInstance; - + friend class LLSingleton<LLWLParamManager>; + /*virtual*/ void initSingleton(); + LLWLParamManager(); + ~LLWLParamManager(); }; inline F32 LLWLParamManager::getDomeOffset(void) const diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index cf06766d73..a027d635e6 100644 --- a/indra/newview/llwlparamset.cpp +++ b/indra/newview/llwlparamset.cpp @@ -31,6 +31,7 @@ #include "llfloaterwindlight.h" #include "llwlparammanager.h" +#include "llglslshader.h" #include "lluictrlfactory.h" #include "llsliderctrl.h" @@ -94,7 +95,7 @@ void LLWLParamSet::update(LLGLSLShader * shader) const shader->uniform4fv(param, 1, val.mV); } - else + else // param is the uniform name { LLVector4 val; @@ -119,7 +120,6 @@ void LLWLParamSet::update(LLGLSLShader * shader) const val.mV[0] = i->second.asBoolean(); } - shader->uniform4fv(param, 1, val.mV); } } @@ -260,7 +260,6 @@ void LLWLParamSet::setEastAngle(float val) void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) { // set up the iterators - LLSD::map_iterator cIt = mParamValues.beginMap(); // keep cloud positions and coverage the same /// TODO masking will do this later @@ -273,55 +272,39 @@ void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) LLSD srcVal; LLSD destVal; - // do the interpolation for all the ones saved as vectors - // skip the weird ones - for(; cIt != mParamValues.endMap(); cIt++) { + // Iterate through values + for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter) + { - // check params to make sure they're actually there - if(src.mParamValues.has(cIt->first)) + // If param exists in both src and dest, set the holder variables, otherwise skip + if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first)) { - srcVal = src.mParamValues[cIt->first]; + srcVal = src.mParamValues[iter->first]; + destVal = dest.mParamValues[iter->first]; } else { continue; } - if(dest.mParamValues.has(cIt->first)) + if(iter->second.isReal()) // If it's a real, interpolate directly { - destVal = dest.mParamValues[cIt->first]; + iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight); } - else - { - continue; - } - - // skip if not a vector - if(!cIt->second.isArray()) - { - continue; - } - - // only Real vectors allowed - if(!cIt->second[0].isReal()) + else if(iter->second.isArray() && iter->second[0].isReal() // If it's an array of reals, loop through the reals and interpolate on those + && iter->second.size() == srcVal.size() && iter->second.size() == destVal.size()) { - continue; + // Actually do interpolation: old value + (difference in values * factor) + for(int i=0; i < iter->second.size(); ++i) + { + // iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal(); // old way of doing it -- equivalent but one more operation + iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight); + } } - - // make sure all the same size - if( cIt->second.size() != srcVal.size() || - cIt->second.size() != destVal.size()) + else // Else, skip { continue; - } - - // more error checking might be necessary; - - for(int i=0; i < cIt->second.size(); ++i) - { - cIt->second[i] = (1.0f - weight) * (F32) srcVal[i].asReal() + - weight * (F32) destVal[i].asReal(); - } + } } // now mix the extra parameters diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h index 487e2bf922..1358502032 100644 --- a/indra/newview/llwlparamset.h +++ b/indra/newview/llwlparamset.h @@ -32,10 +32,10 @@ #include "v4math.h" #include "v4color.h" -#include "llviewershadermgr.h" class LLFloaterWindLight; class LLWLParamSet; +class LLGLSLShader; /// A class representing a set of parameter values for the WindLight shaders. class LLWLParamSet { diff --git a/indra/newview/tests/lldir_stub.cpp b/indra/newview/tests/lldir_stub.cpp new file mode 100644 index 0000000000..6646860b5e --- /dev/null +++ b/indra/newview/tests/lldir_stub.cpp @@ -0,0 +1,45 @@ +/** + * @file lldir_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Use me only if you need to stub out some helper functions, not if you e.g. need sane numbers from countFilesInDir + +LLDir::LLDir() {} +LLDir::~LLDir() {} +BOOL LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) { return true; } +void LLDir::setChatLogsDir(const std::string &path) {} +void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last) {} +void LLDir::setLindenUserDir(const std::string &first, const std::string &last) {} +void LLDir::setSkinFolder(const std::string &skin_folder) {} +bool LLDir::setCacheDir(const std::string &path) { return true; } +void LLDir::dumpCurrentDirectories() {} + +class LLDir_stub : public LLDir +{ +public: + LLDir_stub() {} + ~LLDir_stub() {} + + /*virtual*/ void initAppDirs(const std::string &app_name) {} + + /*virtual*/ std::string getCurPath() { return "CUR_PATH_FROM_LLDIR"; } + /*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask) { return 42; } + /*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) { fname = fname + "_NEXT"; return false; } + /*virtual*/ void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) { fname = "RANDOM_FILE"; } + /*virtual*/ BOOL fileExists(const std::string &filename) const { return false; } +}; + +LLDir_stub gDirUtil; + +LLDir* gDirUtilp = &gDirUtil; + +std::string LLDir::getExpandedFilename(ELLPath loc, const std::string& subdir, const std::string& filename) const +{ + return subdir + " --- " + filename + " --- expanded!"; +} + diff --git a/indra/newview/tests/llfloaterdaycycle_stub.cpp b/indra/newview/tests/llfloaterdaycycle_stub.cpp new file mode 100644 index 0000000000..e6b145bcfc --- /dev/null +++ b/indra/newview/tests/llfloaterdaycycle_stub.cpp @@ -0,0 +1,20 @@ +/** + * @file llfloaterdaycycle_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +class LLFloaterDayCycle +{ +public: + static bool isOpen(void); + static LLFloaterDayCycle* instance(void); + static void syncMenu(void); +}; + +bool LLFloaterDayCycle::isOpen() { return true; } +LLFloaterDayCycle* LLFloaterDayCycle::instance() { return NULL; } +void LLFloaterDayCycle::syncMenu(void) {} diff --git a/indra/newview/tests/llfloaterenvsettings_stub.cpp b/indra/newview/tests/llfloaterenvsettings_stub.cpp new file mode 100644 index 0000000000..e9e792521f --- /dev/null +++ b/indra/newview/tests/llfloaterenvsettings_stub.cpp @@ -0,0 +1,20 @@ +/** + * @file llfloaterenvsettings_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +class LLFloaterEnvSettings +{ +public: + static bool isOpen(void); + static LLFloaterEnvSettings* instance(void); + void syncMenu(void); +}; + +bool LLFloaterEnvSettings::isOpen() { return true; } +LLFloaterEnvSettings* LLFloaterEnvSettings::instance() { return NULL; } +void LLFloaterEnvSettings::syncMenu(void) {} diff --git a/indra/newview/tests/llfloaterwindlight_stub.cpp b/indra/newview/tests/llfloaterwindlight_stub.cpp new file mode 100644 index 0000000000..f1891eaf21 --- /dev/null +++ b/indra/newview/tests/llfloaterwindlight_stub.cpp @@ -0,0 +1,20 @@ +/** + * @file llfloaterwindlight_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +class LLFloaterWindLight +{ +public: + static bool isOpen(void); + static LLFloaterWindLight* instance(void); + void syncMenu(void); +}; + +bool LLFloaterWindLight::isOpen() { return true; } +LLFloaterWindLight* LLFloaterWindLight::instance() { return NULL; } +void LLFloaterWindLight::syncMenu(void) {} diff --git a/indra/newview/tests/llglslshader_stub.cpp b/indra/newview/tests/llglslshader_stub.cpp new file mode 100644 index 0000000000..5333c8a361 --- /dev/null +++ b/indra/newview/tests/llglslshader_stub.cpp @@ -0,0 +1,22 @@ +/** + * @file llglslshader_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#include "llglslshader.h" + +void LLGLSLShader::uniform1f(const std::string& uniform, F32 num) +{ +} + +void LLGLSLShader::uniform3fv(const std::string& uniform, U32 count, const GLfloat *v) +{ +} + +void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v) +{ +} diff --git a/indra/newview/tests/llpipeline_stub.cpp b/indra/newview/tests/llpipeline_stub.cpp new file mode 100644 index 0000000000..85bf0ae3fb --- /dev/null +++ b/indra/newview/tests/llpipeline_stub.cpp @@ -0,0 +1,15 @@ +/** + * @file llpipeline_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +class LLPipeline +{ +public: BOOL canUseWindLightShaders() const; +}; +BOOL LLPipeline::canUseWindLightShaders() const {return TRUE;} +LLPipeline gPipeline; diff --git a/indra/newview/tests/llsky_stub.cpp b/indra/newview/tests/llsky_stub.cpp new file mode 100644 index 0000000000..35f4944a95 --- /dev/null +++ b/indra/newview/tests/llsky_stub.cpp @@ -0,0 +1,20 @@ +/** + * @file llsky_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +class LLSky +{ +public: + void setOverrideSun(BOOL override); + void setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity); +}; + +void LLSky::setOverrideSun(BOOL override) {} +void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity) {} + +LLSky gSky; diff --git a/indra/newview/tests/llviewershadermgr_stub.cpp b/indra/newview/tests/llviewershadermgr_stub.cpp new file mode 100644 index 0000000000..0dae527035 --- /dev/null +++ b/indra/newview/tests/llviewershadermgr_stub.cpp @@ -0,0 +1,33 @@ +/** + * @file llglslshader_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#include "../llviewershadermgr.h" + +LLShaderMgr::LLShaderMgr() {} +LLShaderMgr::~LLShaderMgr() {} + +LLViewerShaderMgr::LLViewerShaderMgr() {} +LLViewerShaderMgr::~LLViewerShaderMgr() {} + +LLViewerShaderMgr* stub_instance = NULL; + +LLViewerShaderMgr* LLViewerShaderMgr::instance() { + if(NULL == stub_instance) + { + stub_instance = new LLViewerShaderMgr(); + } + + return stub_instance; +} +LLViewerShaderMgr::shader_iter fake_iter; +LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const {return fake_iter;} +LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const {return fake_iter;} + +void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader* shader) {return;} +std::string LLViewerShaderMgr::getShaderDirPrefix() {return "SHADER_DIR_PREFIX-";} diff --git a/indra/newview/tests/llwlanimator_stub.cpp b/indra/newview/tests/llwlanimator_stub.cpp new file mode 100644 index 0000000000..4d1bb85544 --- /dev/null +++ b/indra/newview/tests/llwlanimator_stub.cpp @@ -0,0 +1,12 @@ +/** + * @file llwlanimator_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +LLWLAnimator::LLWLAnimator(void) {} +void LLWLAnimator::update(LLWLParamSet& set) {} +void LLWLAnimator::setTrack(std::map<F32, LLWLParamKey>& track, F32 dayRate, F64 dayTime, bool run) {} diff --git a/indra/newview/tests/llwldaycycle_stub.cpp b/indra/newview/tests/llwldaycycle_stub.cpp new file mode 100644 index 0000000000..d98c9614b4 --- /dev/null +++ b/indra/newview/tests/llwldaycycle_stub.cpp @@ -0,0 +1,35 @@ +/** + * @file llwldaycycle_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +LLWLDayCycle::LLWLDayCycle(void) +{ +} + +LLWLDayCycle::~LLWLDayCycle(void) +{ +} + +bool LLWLDayCycle::getKeytime(LLWLParamKey keyFrame, F32& keyTime) +{ + keyTime = 0.5; + return true; +} + +bool LLWLDayCycle::removeKeyframe(F32 time) +{ + return true; +} + +void LLWLDayCycle::loadDayCycleFromFile(const std::string& fileName) +{ +} + +void LLWLDayCycle::removeReferencesTo(const LLWLParamKey &keyframe) +{ +} diff --git a/indra/newview/tests/llwlparammanager_test.cpp b/indra/newview/tests/llwlparammanager_test.cpp new file mode 100644 index 0000000000..3d31567335 --- /dev/null +++ b/indra/newview/tests/llwlparammanager_test.cpp @@ -0,0 +1,257 @@ +/** + * @file llwlparammanager_test.cpp + * @brief LLWLParamManager tests + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled headers +#include "../llviewerprecompiledheaders.h" + +// Class to test +#include "../llwlparammanager.h" + +// Dependencies +#include "linden_common.h" + +// TUT header +#include "lltut.h" + +// Stubs +#include "llwldaycycle_stub.cpp" +#include "llwlparamset_stub.cpp" +#include "llwlanimator_stub.cpp" +#include "llglslshader_stub.cpp" +#include "lldir_stub.cpp" +#include "llsky_stub.cpp" +#include "llfloaterdaycycle_stub.cpp" +#include "llfloaterenvsettings_stub.cpp" +#include "llfloaterwindlight_stub.cpp" +#include "llpipeline_stub.cpp" +#include "llviewershadermgr_stub.cpp" + +void assert_glerror(void) {} +LLViewerCamera::LLViewerCamera() {} +void LLViewerCamera::setView(F32 vertical_fov_rads) {} +std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) { return std::string(""); } + +char* curl_unescape(const char* c_str, int length) +{ + char* copy = new char[length+4]; + memcpy(copy, c_str, length); + copy[length+0] = 'E'; + copy[length+1] = 'S'; + copy[length+2] = 'C'; + copy[length+3] = '\0'; + return copy; +} +void curl_free(void* p) {delete[] ((char*)p);} +char* curl_escape(const char* c_str, int length) { + char* copy = new char[length+6]; + memcpy(copy, c_str, length); + copy[length+0] = 'U'; + copy[length+1] = 'N'; + copy[length+2] = 'E'; + copy[length+3] = 'S'; + copy[length+4] = 'C'; + copy[length+5] = '\0'; + return copy; +} + +namespace tut +{ + // Main Setup + struct LLWLParamManagerFixture + { + class LLWLParamManagerTest + { + }; + + LLWLParamManager* mTestManager; + + LLWLParamManagerFixture() + : mTestManager(LLWLParamManager::getInstance()) + { + } + + ~LLWLParamManagerFixture() + { + } + }; + typedef test_group<LLWLParamManagerFixture> factory; + typedef factory::object object; + factory tf("LLWLParamManager test"); + + // Tests + template<> template<> + void object::test<1>() + { + try + { + std::string preset = + "<llsd>\ + <map>\ + <key>ambient</key>\ + <array>\ + <real>1.0499999523162842</real>\ + <real>1.0499999523162842</real>\ + <real>1.0499999523162842</real>\ + <real>0.34999999403953552</real>\ + </array>\ + <key>blue_density</key>\ + <array>\ + <real>0.2447581488182351</real>\ + <real>0.44872328639030457</real>\ + <real>0.75999999046325684</real>\ + <real>0.38000004053115788</real>\ + </array>\ + <key>blue_horizon</key>\ + <array>\ + <real>0.49548382097675159</real>\ + <real>0.49548381382419748</real>\ + <real>0.63999999284744291</real>\ + <real>0.31999999642372146</real>\ + </array>\ + <key>cloud_color</key>\ + <array>\ + <real>0.40999999165535073</real>\ + <real>0.40999999165535073</real>\ + <real>0.40999999165535073</real>\ + <real>0.40999999165535073</real>\ + </array>\ + <key>cloud_pos_density1</key>\ + <array>\ + <real>1.6884100437164307</real>\ + <real>0.52609699964523315</real>\ + <real>0.99999999999999289</real>\ + <real>1</real>\ + </array>\ + <key>cloud_pos_density2</key>\ + <array>\ + <real>1.6884100437164307</real>\ + <real>0.52609699964523315</real>\ + <real>0.125</real>\ + <real>1</real>\ + </array>\ + <key>cloud_scale</key>\ + <array>\ + <real>0.4199999868869746</real>\ + <real>0</real>\ + <real>0</real>\ + <real>1</real>\ + </array>\ + <key>cloud_scroll_rate</key>\ + <array>\ + <real>10.199999809265137</real>\ + <real>10.01099967956543</real>\ + </array>\ + <key>cloud_shadow</key>\ + <array>\ + <real>0.26999998092651367</real>\ + <real>0</real>\ + <real>0</real>\ + <real>1</real>\ + </array>\ + <key>density_multiplier</key>\ + <array>\ + <real>0.00017999998817685818</real>\ + <real>0</real>\ + <real>0</real>\ + <real>1</real>\ + </array>\ + <key>distance_multiplier</key>\ + <array>\ + <real>0.80000001192093606</real>\ + <real>0</real>\ + <real>0</real>\ + <real>1</real>\ + </array>\ + <key>east_angle</key>\ + <real>0</real>\ + <key>enable_cloud_scroll</key>\ + <array>\ + <boolean>1</boolean>\ + <boolean>1</boolean>\ + </array>\ + <key>gamma</key>\ + <array>\ + <real>1</real>\ + <real>0</real>\ + <real>0</real>\ + <real>1</real>\ + </array>\ + <key>glow</key>\ + <array>\ + <real>5</real>\ + <real>0.0010000000474974513</real>\ + <real>-0.47999998927116394</real>\ + <real>1</real>\ + </array>\ + <key>haze_density</key>\ + <array>\ + <real>0.69999998807907104</real>\ + <real>0</real>\ + <real>0</real>\ + <real>1</real>\ + </array>\ + <key>haze_horizon</key>\ + <array>\ + <real>0.18999999761581243</real>\ + <real>0.19915600121021271</real>\ + <real>0.19915600121021271</real>\ + <real>1</real>\ + </array>\ + <key>lightnorm</key>\ + <array>\ + <real>0</real>\ + <real>0.70710659027099609</real>\ + <real>-0.70710694789886475</real>\ + <real>0</real>\ + </array>\ + <key>max_y</key>\ + <array>\ + <real>1605</real>\ + <real>0</real>\ + <real>0</real>\ + <real>1</real>\ + </array>\ + <key>preset_num</key>\ + <integer>22</integer>\ + <key>star_brightness</key>\ + <real>0</real>\ + <key>sun_angle</key>\ + <real>2.3561947345733643</real>\ + <key>sunlight_color</key>\ + <array>\ + <real>0.73421055078505759</real>\ + <real>0.78157895803450828</real>\ + <real>0.89999997615813498</real>\ + <real>0.29999998211860301</real>\ + </array>\ + </map>\ + </llsd>"; + + std::stringstream preset_stream(preset); + mTestManager->loadPresetFromXML(LLWLParamKey("test1", LLWLParamKey::SCOPE_LOCAL), preset_stream); + LLWLParamSet dummy; + ensure("Couldn't get ParamSet after loading it", mTestManager->getParamSet(LLWLParamKey("test1", LLWLParamKey::SCOPE_LOCAL), dummy)); + } + catch (...) + { + fail("loadPresetFromXML test crashed!"); + } + } + + template<> template<> + void object::test<2>() + { + mTestManager->propagateParameters(); + ensure_equals("Wrong value from getDomeOffset()", mTestManager->getDomeOffset(), 0.96f); + ensure_equals("Wrong value from getDomeRadius()", mTestManager->getDomeRadius(), 15000.f); + ensure_equals("Wrong value from getLightDir()", mTestManager->getLightDir(), LLVector4(-0,0,1,0)); + ensure_equals("Wrong value from getClampedLightDir()", mTestManager->getClampedLightDir(), LLVector4(-0,0,1,0)); + ensure_equals("Wrong value from getRotatedLightDir()", mTestManager->getRotatedLightDir(), LLVector4(0,0,0,1)); + } +} diff --git a/indra/newview/tests/llwlparamset_stub.cpp b/indra/newview/tests/llwlparamset_stub.cpp new file mode 100644 index 0000000000..6ce4b5827d --- /dev/null +++ b/indra/newview/tests/llwlparamset_stub.cpp @@ -0,0 +1,24 @@ +/** + * @file llwlparamset_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +LLWLParamSet::LLWLParamSet(void) +{ +} + +void LLWLParamSet::updateCloudScrolling() +{ +} + +void LLWLParamSet::set(const std::string& name, const LLVector4& val) +{ +} + +void LLWLParamSet::update(LLGLSLShader *shader) const +{ +} |