diff options
author | Oz Linden <oz@lindenlab.com> | 2011-04-22 18:25:57 -0400 |
---|---|---|
committer | Oz Linden <oz@lindenlab.com> | 2011-04-22 18:25:57 -0400 |
commit | c3df5f5d675abd107e1f0b4e3fb262226978ddb5 (patch) | |
tree | b89e53c972d8db034d74e1dbc55bf27ab82d3b88 | |
parent | 391bef0df021dd3a56c262087ba977ab9f2bb662 (diff) | |
parent | 95847fc2061e9b71a4d2ce078b525c047fc4ad36 (diff) |
merge up latest viewer-development
59 files changed, 4026 insertions, 1149 deletions
diff --git a/BuildParams b/BuildParams index 2cb58755e5..8cfa2e295e 100644 --- a/BuildParams +++ b/BuildParams @@ -156,11 +156,21 @@ media.build_viewer_update_version_manager = false # oz # ================ +snowstorm_project-windlight.build_debug_release_separately = true +snowstorm_project-windlight.viewer_channel = "Second Life Project Windlight Estate" +snowstorm_project-windlight.login_channel = "Second Life Project Windlight Estate" + oz_viewer-devreview.build_debug_release_separately = true + +viewer-devreview.build_debug_release_separately = true + +oz_viewer-poreview.build_debug_release_separately = true + oz_project-1.build_debug_release_separately = true + oz_project-2.build_debug_release_separately = true -oz-project-3.build_debug_release_separately = true +oz_project-3.build_debug_release_separately = true oz_viewer-beta-review.build_debug_release_separately = true # ======================================== diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b1cb10665b..0537b0e9fc 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -142,6 +142,7 @@ set(viewer_SOURCE_FILES lldrawpoolwlsky.cpp lldriverparam.cpp lldynamictexture.cpp + llenvmanager.cpp llemote.cpp lleventnotifier.cpp lleventpoll.cpp @@ -579,6 +580,7 @@ set(viewer_SOURCE_FILES llwind.cpp llwlanimator.cpp llwldaycycle.cpp + llwlhandlers.cpp llwlparammanager.cpp llwlparamset.cpp llworld.cpp @@ -687,6 +689,7 @@ set(viewer_HEADER_FILES lldriverparam.h lldynamictexture.h llemote.h + llenvmanager.h lleventnotifier.h lleventpoll.h llexpandabletextbox.h @@ -1117,6 +1120,7 @@ set(viewer_HEADER_FILES llwind.h llwlanimator.h llwldaycycle.h + llwlhandlers.h llwlparammanager.h llwlparamset.h llworld.h @@ -1993,6 +1997,22 @@ 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 + ) + endif (LL_TESTS) check_message_template(${VIEWER_BINARY_NAME}) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4e666952ce..d247ed4dc9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11322,6 +11322,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>1</integer> + </map> <key>UseExternalBrowser</key> <map> <key>Comment</key> @@ -11915,33 +11926,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>WaterFogColor</key> - <map> - <key>Comment</key> - <string>Water fog color</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Color4</string> - <key>Value</key> - <array> - <real>0.0863</real> - <real>0.168</real> - <real>0.212</real> - <real>0</real> - </array> - </map> - <key>WaterFogDensity</key> - <map> - <key>Comment</key> - <string>Water fog density</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>16.0</real> - </map> <key>WaterGLFogDensityScale</key> <map> <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7d491a7774..d011fe9044 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" @@ -77,6 +79,7 @@ #include "llwindow.h" #include "llworld.h" #include "llworldmap.h" +#include "stringize.h" using namespace LLVOAvatarDefines; @@ -627,6 +630,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 { @@ -643,6 +656,9 @@ void LLAgent::setRegion(LLViewerRegion *regionp) // Update all of the regions. LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal); + + // Notify windlight managers about login + LLEnvManager::getInstance()->notifyLogin(); } // Pass new region along to metrics components that care about this level of detail. @@ -667,6 +683,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/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9de2941c4a..ace3af3987 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1591,9 +1591,7 @@ bool LLAppViewer::cleanup() llinfos << "Cleaning up Objects" << llendflush; LLViewerObject::cleanupVOClasses(); - - LLWaterParamManager::cleanupClass(); - LLWLParamManager::cleanupClass(); + LLPostProcess::cleanupClass(); LLTracker::cleanupInstance(); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index dc94924da4..31c14361b5 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -108,7 +108,7 @@ void LLDrawPoolWater::prerender() // got rid of modulation by light color since it got a little too // green at sunset and sl-57047 (underwater turns black at 8:00) - sWaterFogColor = LLWaterParamManager::instance()->getFogColor(); + sWaterFogColor = LLWaterParamManager::instance().getFogColor(); sWaterFogColor.mV[3] = 0; } @@ -527,7 +527,7 @@ void LLDrawPoolWater::shade() //bind normal map S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); - LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + LLWaterParamManager * param_mgr = &LLWaterParamManager::instance(); // change mWaterNormp if needed if (mWaterNormp->getID() != param_mgr->getNormalMapID()) diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index eaa6aa7e37..92ad404ca0 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..c855d8597c --- /dev/null +++ b/indra/newview/llenvmanager.cpp @@ -0,0 +1,559 @@ +/** + * @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 "llfloaterreg.h" +#include "llfloaterwindlight.h" +#include "llfloaterwater.h" +#include "llfloaterenvsettings.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llfloaterregioninfo.h" +//#include "llwindlightscrubbers.h" // *HACK commented out since this code isn't released (yet) +#include "llwlhandlers.h" +#include "llnotifications.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; + + LLFloaterReg::hideInstance("env_settings"); + + resetInternalsToDefault(LLEnvKey::SCOPE_REGION); + + maybeClearEditingScope(LLEnvKey::SCOPE_REGION, true, false); +} + +/******* + * Editing settings / UI mode + *******/ + +void LLEnvManager::startEditingScope(LLEnvKey::EScope scope) +{ + LL_DEBUGS("Windlight") << "Starting editing scope " << scope << LL_ENDL; + + 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; + + // Back up local settings so that we can switch back to them later. + if (scope != LLEnvKey::SCOPE_LOCAL) + { + backUpLocalSettingsIfNeeded(); + } + + // 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(), 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) + { +#if 0 + // *TODO: select terrain panel here + mIsEditing = false; + LLFloaterReg::showTypedInstance<LLFloaterRegionInfo>("regioninfo"); +#endif + 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) +{ + // Back up local env. settings so that we can switch to them later. + if (scope != LLEnvKey::SCOPE_LOCAL) + { + backUpLocalSettingsIfNeeded(); + } + + switch (scope) + { + case LLEnvKey::SCOPE_LOCAL: + break; + case LLEnvKey::SCOPE_REGION: + if (!LLEnvironmentRequest::initiate()) + { + // 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 + + // *HACK - Don't have the validator, so just use content without validating. Should validate here for third-party grids. + LLSD windlight_llsd(unvalidated_content); + bool valid = true; + // end HACK + + mLastReceivedID = unvalidated_content[0]["messageID"].asUUID(); // if the message was valid, grab the UUID from it and save it for next outbound update message + LL_DEBUGS("Windlight Sync") << "mLastReceivedID: " << mLastReceivedID << LL_ENDL; + LL_DEBUGS("Windlight Sync") << "windlight_llsd: " << windlight_llsd << LL_ENDL; + + if (valid) + { + F32 sun_hour = 0; + LLPanelRegionTerrainInfo* terrain_panel = LLPanelRegionTerrainInfo::instance(); + + if (terrain_panel) + { + sun_hour = terrain_panel->getSunHour(); // this slider is kept up to date + } + else + { + llwarns << "Cannot instantiate the terrain panel (exiting?)" << llendl; + } + + 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); + } + else + { + LL_DEBUGS("Windlight Sync") << "Not loading settings (mCurNormalScope=" << mCurNormalScope << ", scope=" << scope << ", mIsEditing=" << mIsEditing << ")" << LL_ENDL; + } + + mInterpNextChangeMessage = true; // reset flag + + return valid; +} + + +/******* + * Outgoing Messaging + *******/ + +void LLEnvManager::commitSettings(LLEnvKey::EScope scope) +{ + LL_DEBUGS("Windlight Sync") << "commitSettings(scope = " << scope << ")" << LL_ENDL; + + 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(); +} + +void LLEnvManager::applyLocalSettingsToRegion() +{ + // Immediately apply current environment settings to region. + LLEnvManager::instance().commitSettings(LLEnvKey::SCOPE_REGION); +} + +/******* + * 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) +{ + LL_DEBUGS("Windlight Sync") << "Loading settings (scope = " << scope << ")" << LL_ENDL; + + 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) +{ + LL_DEBUGS("Windlight Sync") << "Saving settings (scope = " << scope << ")" << LL_ENDL; + 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); + + LL_DEBUGS("Windlight Sync") << "Dumping referenced skies (" << final_references.size() << ") to LLSD: " << referenced_skies << LL_ENDL; + + mOrigSettingStore[scope].saveParams( + LLWLParamManager::getInstance()->mDay.asLLSD(), + referenced_skies, + LLWaterParamManager::getInstance()->mCurParams.getAll(), + LLWLParamManager::getInstance()->mAnimator.mDayTime); + } + break; + default: + return; + } +} + +void LLEnvManager::backUpLocalSettingsIfNeeded() +{ + // *HACK: Back up local env. settings so that we can switch to them later. + // Otherwise local day cycle is likely to be reset. + static bool sSavedLocalSettings = false; + + if (!sSavedLocalSettings) + { + LL_DEBUGS("Windlight") << "Backing up local environment settings" << LL_ENDL; + saveSettingsFromManagers(LLEnvKey::SCOPE_LOCAL); + sSavedLocalSettings = true; + } +} + +/******* + * 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) + { + LL_INFOS("Windlight") << "Switching to scope " << new_scope << LL_ENDL; + mCurNormalScope = new_scope; + notifyOptInChange(); + } +} + +LLEnvKey::EScope LLEnvManager::getNormallyDisplayedScope() const +{ + return mCurNormalScope; +} + +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); +} + +void LLEnvManager::dumpScopes() +{ + LLSD scope_dump; + + scope_dump = makePacket(LLEnvKey::SCOPE_LOCAL, LLSD()); + LL_DEBUGS("Windlight") << "Local scope:" << scope_dump << LL_ENDL; + + scope_dump = makePacket(LLEnvKey::SCOPE_REGION, LLSD()); + LL_DEBUGS("Windlight") << "Region scope:" << scope_dump << LL_ENDL; +} diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h new file mode 100644 index 0000000000..438fe4590d --- /dev/null +++ b/indra/newview/llenvmanager.h @@ -0,0 +1,223 @@ +/** + * @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); + // Immediately apply current settings from managers to region. + void applyLocalSettingsToRegion(); + + /* + * 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); + // gets normally displayed scope + LLEnvKey::EScope getNormallyDisplayedScope() const; + + // for debugging purposes + void dumpScopes(); + +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); + // If not done already, save current local environment settings, so that we can switch to them later. + void backUpLocalSettingsIfNeeded(); + + // 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..eb429d7803 100644 --- a/indra/newview/llfloaterdaycycle.cpp +++ b/indra/newview/llfloaterdaycycle.cpp @@ -41,6 +41,8 @@ #include "llcombobox.h" #include "lllineeditor.h" #include "llwlanimator.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" #include "v4math.h" #include "llviewerdisplay.h" @@ -51,34 +53,29 @@ #include "llwlparammanager.h" #include "llpostprocess.h" #include "llfloaterwindlight.h" +//#include "llwindlightscrubbers.h" // *HACK commented out since this code isn't released (yet) +#include "llenvmanager.h" +#include "llfloaterreg.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(const LLSD &key) : LLFloater(key) { } +// virtual 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)); - } + sOriginalTitle = getTitle(); - // set defaults on combo boxes - keyCombo->selectFirstItem(); - } + // *HACK commented out since this code isn't released (yet) + //llassert(LLWLPacketScrubber::MAX_LOCAL_KEY_FRAMES <= getChild<LLMultiSliderCtrl>("WLDayCycleKeys")->getMaxValue() && + // LLWLPacketScrubber::MAX_REGION_KEY_FRAMES <= getChild<LLMultiSliderCtrl>("WLDayCycleKeys")->getMaxValue()); // add the time slider LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLTimeSlider"); @@ -88,9 +85,6 @@ BOOL LLFloaterDayCycle::postBuild() // load it up initCallbacks(); - syncMenu(); - syncSliderTrack(); - return TRUE; } @@ -98,46 +92,59 @@ LLFloaterDayCycle::~LLFloaterDayCycle() { } +void LLFloaterDayCycle::onClickHelp(void* data) +{ + std::string xml_alert = *(std::string *) data; + LLNotifications::instance().add(xml_alert, LLSD(), LLSD()); +} + +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 +156,31 @@ 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++) + + lldebugs << "Adding " << LLWLParamManager::getInstance()->mDay.mTimeMap.size() << " keys to slider" << llendl; + + 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); } @@ -178,41 +188,128 @@ void LLFloaterDayCycle::syncSliderTrack() void LLFloaterDayCycle::syncTrack() { + lldebugs << "Syncing track (" << sSliderToKey.size() << ")" << llendl; + // if no keys, do nothing if(sSliderToKey.size() == 0) { + lldebugs << "No keys, not syncing" << llendl; return; } 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(); + } +} + +// static +LLFloaterDayCycle* LLFloaterDayCycle::instance() +{ + if (!sDayCycle) + { + lldebugs << "Instantiating Day Cycle floater" << llendl; + sDayCycle = LLFloaterReg::getTypedInstance<LLFloaterDayCycle>("env_day_cycle"); + llassert(sDayCycle); + // sDayCycle->open(); + // sDayCycle->setFocus(TRUE); + } + return sDayCycle; } -void LLFloaterDayCycle::onRunAnimSky(LLUICtrl* ctrl) +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(), 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->openFloater(); +} + +// virtual +void LLFloaterDayCycle::onClose(bool app_quitting) +{ + if (sDayCycle) + { + lldebugs << "Destorying Day Cycle floater" << llendl; + sDayCycle = NULL; + } +} + +void LLFloaterDayCycle::onRunAnimSky(void* userData) { // if no keys, do nothing if(sSliderToKey.size() == 0) @@ -221,46 +318,49 @@ 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"); - box->selectByValue(""); - - LLWLParamManager::instance()->mAnimator.mIsRunning = true; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = true; + LLFloaterWindLight* wlfloater = LLFloaterReg::findTypedInstance<LLFloaterWindLight>("env_windlight"); + if (wlfloater) + { + LLComboBox* box = wlfloater->getChild<LLComboBox>("WLPresetsCombo"); + box->selectByValue(""); + } + 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 +368,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 +421,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 +444,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 +467,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 +486,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 +496,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 +524,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 = 20; // *HACK this should be LLWLPacketScrubber::MAX_LOCAL_KEY_FRAMES; + break; + case LLEnvKey::SCOPE_REGION: + max_sliders = 12; // *HACK this should be LLWLPacketScrubber::MAX_REGION_KEY_FRAMES; + break; + default: + max_sliders = (S32)kSldr->getMaxValue(); + break; + } + + if ((S32)sSliderToKey.size() >= max_sliders) + { + LLSD args; + args["SCOPE"] = LLEnvManager::getScopeString(sScope); + args["MAX"] = max_sliders; + LLNotificationsUtil::add("DayCycleTooManyKeyframes", args, LLSD(), LLNotificationFunctorRegistry::instance().DONOTHING); + 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 +584,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 +613,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(), 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 +641,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..b09d1d5bf4 100644 --- a/indra/newview/llfloaterdaycycle.h +++ b/indra/newview/llfloaterdaycycle.h @@ -32,15 +32,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; }; @@ -48,72 +52,97 @@ public: /// Menuing system for adjusting the atmospheric settings of the world. class LLFloaterDayCycle : public LLFloater { + LOG_CLASS(LLFloaterDayCycle); public: - - LLFloaterDayCycle(const LLSD& key); + LLFloaterDayCycle(const LLSD &key); virtual ~LLFloaterDayCycle(); - /*virtual*/ BOOL postBuild(); + /*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..a2a6005b14 100644 --- a/indra/newview/llfloaterenvsettings.cpp +++ b/indra/newview/llfloaterenvsettings.cpp @@ -31,55 +31,69 @@ #include "llfloaterreg.h" #include "llfloaterwindlight.h" #include "llfloaterwater.h" +#include "llfloaterdaycycle.h" +#include "llfloaterregioninfo.h" #include "lluictrlfactory.h" #include "llsliderctrl.h" #include "llcombobox.h" #include "llcolorswatch.h" #include "llwlanimator.h" +#include "llnotifications.h" #include "llwlparamset.h" #include "llwlparammanager.h" #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(const LLSD &key) : LLFloater(key) +{ + lldebugs << "Creating env settings floater" << llendl; } -// virtual + LLFloaterEnvSettings::~LLFloaterEnvSettings() { } + // virtual BOOL LLFloaterEnvSettings::postBuild() { // load it up initCallbacks(); syncMenu(); + return TRUE; } 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", &LLFloaterEnvSettings::onChangeDayTime, NULL); + childSetCommitCallback("EnvCloudSlider", &LLFloaterEnvSettings::onChangeCloudCoverage, NULL); + childSetCommitCallback("EnvWaterFogSlider", &LLFloaterEnvSettings::onChangeWaterFogDensity, &LLWaterParamManager::instance().mFogDensity); // color picker - getChild<LLUICtrl>("EnvWaterColor")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeWaterColor, this, _1, &LLWaterParamManager::instance()->mFogColor)); + childSetCommitCallback("EnvWaterColor", &LLFloaterEnvSettings::onChangeWaterColor, &LLWaterParamManager::instance().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)); + childSetCommitCallback("EnvAdvancedSkyButton", &LLFloaterEnvSettings::onOpenAdvancedSky, NULL); + childSetCommitCallback("EnvAdvancedWaterButton", &LLFloaterEnvSettings::onOpenAdvancedWater, NULL); + childSetCommitCallback("EnvUseEstateTimeButton", &LLFloaterEnvSettings::onUseEstateTime, NULL); + getChild<LLUICtrl>("EnvUseLocalTimeButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onUseLocalTime)); + + getChild<LLUICtrl>("EnvUseEstateTimeButton")->setRightMouseDownCallback(boost::bind(&LLEnvManager::dumpScopes, &LLEnvManager::instance())); } + // menu maintenance functions void LLFloaterEnvSettings::syncMenu() @@ -88,8 +102,8 @@ void LLFloaterEnvSettings::syncMenu() sldr = 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"); @@ -106,62 +120,59 @@ 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"); 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) - { - getChildView("EnvUseEstateTimeButton")->setEnabled(FALSE); - } else { - getChildView("EnvUseEstateTimeButton")->setEnabled(TRUE); - } + // turn off Use Estate/Local Time buttons if already being used + + LLWLAnimator& anim = LLWLParamManager::getInstance()->mAnimator; + childSetEnabled("EnvUseEstateTimeButton", !anim.getIsRunning() || !anim.getUseLindenTime()); + childSetEnabled("EnvUseLocalTimeButton", !anim.getIsRunning() || !anim.getUseLocalTime()); 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 { - getChildView("EnvCloudSlider")->setEnabled(TRUE); - getChildView("EnvCloudText")->setEnabled(TRUE); - //getChildView("EnvAdvancedSkyButton")->setEnabled(TRUE); + childEnable("EnvCloudSlider"); + childEnable("EnvCloudText"); + //childEnable("EnvAdvancedSkyButton"); } } -void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl) +void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl); // deactivate animator - LLWLParamManager::instance()->mAnimator.mIsRunning = false; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::instance().mAnimator.deactivate(); F32 val = sldr->getValueF32() + 0.25f; if(val > 1.0) @@ -169,12 +180,12 @@ void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl) val--; } - LLWLParamManager::instance()->mAnimator.setDayTime((F64)val); - LLWLParamManager::instance()->mAnimator.update( - LLWLParamManager::instance()->mCurParams); + LLWLParamManager::instance().mAnimator.setDayTime((F64)val); + LLWLParamManager::instance().mAnimator.update( + LLWLParamManager::instance().mCurParams); } -void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl) +void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl); @@ -183,44 +194,46 @@ void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl) //LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; F32 val = sldr->getValueF32(); - LLWLParamManager::instance()->mCurParams.set("cloud_shadow", val); + LLWLParamManager::instance().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"); - + LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl); F32 val = sldr->getValueF32(); + + WaterExpFloatControl* expFloatControl = static_cast<WaterExpFloatControl*>(userData); expFloatControl->mExp = val; - LLWaterParamManager::instance()->setDensitySliderValue(val); + LLWaterParamManager::instance().setDensitySliderValue(val); - expFloatControl->update(LLWaterParamManager::instance()->mCurParams); - LLWaterParamManager::instance()->propagateParameters(); + expFloatControl->update(LLWaterParamManager::instance().mCurParams); + LLWaterParamManager::instance().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::instance().mCurParams); + LLWaterParamManager::instance().propagateParameters(); } - -void LLFloaterEnvSettings::onOpenAdvancedSky() +void LLFloaterEnvSettings::onOpenAdvancedSky(void* userData1, void* userData2) { + // *TODO: make sure title is displayed correctly. LLFloaterReg::showInstance("env_windlight"); } -void LLFloaterEnvSettings::onOpenAdvancedWater() +void LLFloaterEnvSettings::onOpenAdvancedWater(void* userData1, void* userData2) { + // *TODO: make sure title is displayed correctly. LLFloaterReg::showInstance("env_water"); } -void LLFloaterEnvSettings::onUseEstateTime() +void LLFloaterEnvSettings::onUseEstateTime(void* userData1, void* userData2) { LLFloaterWindLight* wl = LLFloaterReg::findTypedInstance<LLFloaterWindLight>("env_windlight"); if(wl) @@ -229,40 +242,12 @@ void LLFloaterEnvSettings::onUseEstateTime() box->selectByValue(""); } - LLWLParamManager::instance()->mAnimator.mIsRunning = true; - LLWLParamManager::instance()->mAnimator.mUseLindenTime = true; + LLWLParamManager::instance().mAnimator.activate(LLWLAnimator::TIME_LINDEN); } -std::string LLFloaterEnvSettings::timeToString(F32 curTime) +// static +void LLFloaterEnvSettings::onUseLocalTime() { - 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..b93bf07395 100644 --- a/indra/newview/llfloaterenvsettings.h +++ b/indra/newview/llfloaterenvsettings.h @@ -33,50 +33,56 @@ #include "llfloater.h" -struct WaterColorControl; -struct WaterExpFloatControl; /// Menuing system for all of windlight's functionality class LLFloaterEnvSettings : public LLFloater { + LOG_CLASS(LLFloaterEnvSettings); public: - LLFloaterEnvSettings(const LLSD& key); + LLFloaterEnvSettings(const LLSD &key); /*virtual*/ ~LLFloaterEnvSettings(); /*virtual*/ BOOL postBuild(); + /// initialize all the callbacks for the menu void initCallbacks(void); + /// one and one instance only + LLFloaterEnvSettings* instance(); + /// 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* expFloatControl); /// handle change in water fog color - void onChangeWaterColor(LLUICtrl* ctrl, WaterColorControl* colorControl); + static void onChangeWaterColor(LLUICtrl* ctrl, void* colorControl); /// open the advanced sky settings menu - void onOpenAdvancedSky(); + static void onOpenAdvancedSky(void* userData1, void* userData2); /// open the advanced water settings menu - void onOpenAdvancedWater(); + static void onOpenAdvancedWater(void* userData1, void* userData2); /// sync time with the server - void onUseEstateTime(); + static void onUseEstateTime(void* userData1, void* userData2); + + /// sync time with local clock + static void onUseLocalTime(); + //// menu management /// 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 + }; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 7792b3fb40..2acb0936dc 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" @@ -48,7 +50,9 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" +#include "llenvmanager.h" #include "llfilepicker.h" +#include "llfloaterdaycycle.h" #include "llfloatergodtools.h" // for send_sim_wide_deletes() #include "llfloatertopobjects.h" // added to fix SL-32336 #include "llfloatergroups.h" @@ -82,9 +86,14 @@ #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; +#define TMP_DISABLE_WLES // STORM-1180 + ///---------------------------------------------------------------------------- /// Local class declaration ///---------------------------------------------------------------------------- @@ -288,6 +297,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(); @@ -398,6 +411,23 @@ LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() return panel; } +// static +LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain() +{ + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); + if (!floater) + { + llassert(floater); + return NULL; + } + + LLTabContainer* tab_container = floater->getChild<LLTabContainer>("region_panels"); + LLPanelRegionTerrainInfo* panel = + dynamic_cast<LLPanelRegionTerrainInfo*>(tab_container->getChild<LLPanel>("Terrain")); + llassert(panel); + return panel; +} + void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) { if (!region) @@ -1145,9 +1175,36 @@ void LLPanelRegionTextureInfo::onClickDump(void* data) ///////////////////////////////////////////////////////////////////////////// // LLPanelRegionTerrainInfo ///////////////////////////////////////////////////////////////////////////// +// Initialize statics +LLPanelRegionTerrainInfo* LLPanelRegionTerrainInfo::sPanelRegionTerrainInfo = NULL; + +// static +LLPanelRegionTerrainInfo* LLPanelRegionTerrainInfo::instance() +{ + if (!sPanelRegionTerrainInfo) + { + sPanelRegionTerrainInfo = LLFloaterRegionInfo::getPanelRegionTerrain(); + lldebugs << llformat("Instantiating sPanelRegionTerrainInfo: %p", sPanelRegionTerrainInfo) << llendl; + } + return sPanelRegionTerrainInfo; +} + +// static +void LLPanelRegionTerrainInfo::onFloaterClose(bool app_quitting) +{ + if (sPanelRegionTerrainInfo) + { + lldebugs << "Setting LLPanelRegionTerrainInfo to NULL" << llendl; + sPanelRegionTerrainInfo = NULL; + } +} + BOOL LLPanelRegionTerrainInfo::postBuild() { LLPanelRegionInfo::postBuild(); + + sPanelRegionTerrainInfo = this; // singleton instance pointer + lldebugs << llformat("Setting sPanelRegionTerrainInfo to: %p", sPanelRegionTerrainInfo) << llendl; initCtrl("water_height_spin"); initCtrl("terrain_raise_spin"); @@ -1162,20 +1219,45 @@ BOOL LLPanelRegionTerrainInfo::postBuild() childSetAction("upload_raw_btn", onClickUploadRaw, this); childSetAction("bake_terrain_btn", onClickBakeTerrain, this); +#ifdef TMP_DISABLE_WLES + // 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); + childSetAction("WLCurrentApply", onApplyCurrentWL, this); +#endif + 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); @@ -1184,6 +1266,34 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) return LLPanelRegionInfo::refreshFromRegion(region); } +void LLPanelRegionTerrainInfo::setEnvControls(bool available) +{ +#ifdef TMP_DISABLE_WLES + available = false; + getChild<LLUICtrl>("wl_settings_unavailable")->setValue("Temporarily disabled."); +#endif + + 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("WLCurrentApply")->setVisible(available); + getChildView("wl_settings_unavailable")->setVisible(!available); +} + +void LLPanelRegionTerrainInfo::setCommitControls(bool available) +{ +#ifdef TMP_DISABLE_WLES + available = false; +#endif + + getChildView("WLRegionApply")->setEnabled(available); + getChildView("WLRegionCancel")->setEnabled(available); + refresh(); +} + // virtual BOOL LLPanelRegionTerrainInfo::sendUpdate() { @@ -1321,9 +1431,77 @@ 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); +} + +// static +void LLPanelRegionTerrainInfo::onApplyCurrentWL(void* userData) +{ + // Immediately apply current environment settings to region. + LLEnvManager::instance().applyLocalSettingsToRegion(); +} + +void LLPanelRegionTerrainInfo::cancelChanges() +{ + LLFloaterReg::hideInstance("env_windlight"); + LLFloaterReg::hideInstance("env_water"); + LLFloaterReg::hideInstance("env_day_cycle"); + + // disable commmit and cancel + LLPanelRegionTerrainInfo::instance()->setCommitControls(false); +} + ///////////////////////////////////////////////////////////////////////////// // LLPanelEstateInfo // @@ -1997,6 +2175,16 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) return rv; } +// virtual +void LLFloaterRegionInfo::onClose(bool app_quitting) +{ + if(!app_quitting) + { + LLEnvManager::getInstance()->maybeClearEditingScope(true, false); + LLPanelRegionTerrainInfo::onFloaterClose(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 c0758fa92d..f5c5e21938 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -58,6 +58,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; @@ -67,6 +74,8 @@ public: /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quitting); + static void processEstateOwnerRequest(LLMessageSystem* msg, void**); // get and process region info if necessary. @@ -79,6 +88,7 @@ public: static LLPanelEstateInfo* getPanelEstate(); static LLPanelEstateCovenant* getPanelCovenant(); + static LLPanelRegionTerrainInfo* getPanelRegionTerrain(); // from LLPanel virtual void refresh(); @@ -222,19 +232,29 @@ protected: }; ///////////////////////////////////////////////////////////////////////////// - class LLPanelRegionTerrainInfo : public LLPanelRegionInfo { + LOG_CLASS(LLPanelRegionTerrainInfo); + public: - LLPanelRegionTerrainInfo() - : LLPanelRegionInfo() {} + LLPanelRegionTerrainInfo() : LLPanelRegionInfo() {} ~LLPanelRegionTerrainInfo() {} - // LLPanel - virtual BOOL postBuild(); - virtual bool refreshFromRegion(LLViewerRegion* region); + static LLPanelRegionTerrainInfo* instance(); + virtual BOOL postBuild(); // LLPanel + static void onFloaterClose(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(); @@ -245,6 +265,14 @@ 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 + static void onApplyCurrentWL(void* userData); // apply current settings to region }; ///////////////////////////////////////////////////////////////////////////// @@ -332,7 +360,6 @@ public: // If visible from mainland, allowed agent and allowed groups // are ignored, so must disable UI. void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban); - protected: virtual BOOL sendUpdate(); // confirmation dialog callback diff --git a/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp index be4b144f41..533831f181 100644 --- a/indra/newview/llfloaterwater.cpp +++ b/indra/newview/llfloaterwater.cpp @@ -45,6 +45,7 @@ #include "llfloaterdaycycle.h" #include "llboost.h" #include "llmultisliderctrl.h" +#include "llnotifications.h" #include "v4math.h" #include "llviewerdisplay.h" @@ -59,6 +60,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 +73,7 @@ LLFloaterWater::~LLFloaterWater() } BOOL LLFloaterWater::postBuild() { - + sOriginalTitle=getTitle(); std::string def_water = getString("WLDefaultWaterNames"); // no editing or deleting of the blank string @@ -88,8 +91,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); } @@ -102,9 +105,42 @@ BOOL LLFloaterWater::postBuild() syncMenu(); return TRUE; } + +// static +void LLFloaterWater::show(LLEnvKey::EScope scope) +{ + LLFloaterWater* water = LLFloaterReg::getTypedInstance<LLFloaterWater>("env_water"); + llassert(water); + + if(scope != sScope && ((LLView*)water)->getVisible()) + { + LLNotifications::instance().add("EnvOtherScopeAlreadyOpen", LLSD(), 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 + ")"; + water->setTitle(title); + water->syncMenu(); + + LLEnvManager::instance().startEditingScope(scope); + + water->openFloater(); + +} + 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 +199,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 +231,7 @@ void LLFloaterWater::syncMenu() { bool err; - LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); LLWaterParamSet & current_params = param_mgr->mCurParams; @@ -262,9 +298,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 +310,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 +322,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 +335,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 +347,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 +371,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 +395,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 +418,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 +429,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 +490,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 +500,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 +512,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 +547,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 +568,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 +619,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 +630,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 @@ -618,7 +654,7 @@ void LLFloaterWater::onChangePresetName(LLUICtrl* ctrl) std::string data = ctrl->getValue().asString(); if(!data.empty()) { - LLWaterParamManager::instance()->loadPreset(data); + LLWaterParamManager::instance().loadPreset(data); syncMenu(); } } diff --git a/indra/newview/llfloaterwater.h b/indra/newview/llfloaterwater.h index e3db91e80d..25858fba01 100644 --- a/indra/newview/llfloaterwater.h +++ b/indra/newview/llfloaterwater.h @@ -33,8 +33,7 @@ #include "llfloater.h" -#include <vector> -#include "llwlparamset.h" +#include "llenvmanager.h" struct WaterVector2Control; struct WaterVector3Control; @@ -53,6 +52,8 @@ public: /// initialize all void initCallbacks(void); + static void show(LLEnvKey::EScope scope = LLEnvKey::SCOPE_LOCAL); + bool newPromptCallback(const LLSD& notification, const LLSD& response); /// general purpose callbacks for dealing with color controllers @@ -101,6 +102,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..34629ec5c4 100644 --- a/indra/newview/llfloaterwindlight.cpp +++ b/indra/newview/llfloaterwindlight.cpp @@ -35,7 +35,6 @@ #include "llsliderctrl.h" #include "llmultislider.h" #include "llmultisliderctrl.h" -#include "llnotificationsutil.h" #include "llspinctrl.h" #include "llcheckboxctrl.h" #include "lluictrlfactory.h" @@ -44,6 +43,7 @@ #include "lllineeditor.h" #include "llfloaterdaycycle.h" #include "llboost.h" +#include "llnotifications.h" #include "v4math.h" #include "llviewerdisplay.h" @@ -54,48 +54,35 @@ #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() +LLFloaterWindLight::LLFloaterWindLight(const LLSD &key) : LLFloater(key) { } 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); - } - + sWindLight = this; + 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,128 @@ 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; } -void LLFloaterWindLight::initCallbacks(void) { - LLWLParamManager * param_mgr = LLWLParamManager::instance(); +LLFloaterWindLight::~LLFloaterWindLight() +{ +} + +void LLFloaterWindLight::initCallbacks(void) +{ + 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)); + static std::string use_classic_clouds = "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); getChild<LLUICtrl>("DrawClassicClouds")->setCommitCallback(boost::bind(LLSavedSettingsGlue::setBOOL, _1, "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)); - - comboBox->setCommitCallback(boost::bind(&LLFloaterWindLight::onChangePresetName, this, _1)); + childSetAction("WLNewPreset", onNewPreset, comboBox); + childSetAction("WLSavePreset", onSavePreset, comboBox); + childSetAction("WLDeletePreset", onDeletePreset, comboBox); + comboBox->setCommitCallback(boost::bind(&LLFloaterWindLight::onChangePresetName, _1)); // 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); } bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& response) { + llassert(sWindLight); 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 +220,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 +254,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", LLSD(), LLSD()); } } return false; @@ -264,38 +275,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 +314,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) + { + lldebugs << "Creating WL floater" << llendl; + sWindLight = LLFloaterReg::getTypedInstance<LLFloaterWindLight>("env_windlight"); + llassert(sWindLight); + } + return sWindLight; } +// static +void LLFloaterWindLight::show(LLEnvKey::EScope scope) +{ + LLFloaterWindLight* windLight = instance(); + if(scope != sScope && ((LLView*)windLight)->getVisible()) + { + LLNotifications::instance().add("EnvOtherScopeAlreadyOpen", LLSD(), 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->openFloater(); +} + +bool LLFloaterWindLight::isOpen() +{ + return LLFloater::isShown(sWindLight); +} + +// virtual +void LLFloaterWindLight::onClose(bool app_quitting) +{ + lldebugs << "Destroying WL floater" << llendl; + sWindLight = NULL; +} // color control callbacks -void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, WLColorControl* colorControl) +void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + llassert(sWindLight); + 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 +486,26 @@ 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(); + llassert(sWindLight); + 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 +523,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 +559,26 @@ 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(); + llassert(sWindLight); + LLWLParamManager::getInstance()->mAnimator.deactivate(); LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl * colorControl = static_cast<WLColorControl *>(userData); colorControl->i = sldrCtrl->getValueF32(); @@ -565,84 +635,101 @@ 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(); + llassert(sWindLight); + 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 +746,36 @@ 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) { + llassert(sWindLight); // get the name - LLComboBox* comboBox = getChild<LLComboBox>( + LLComboBox* comboBox = sWindLight->getChild<LLComboBox>( "WLPresetsCombo"); // don't save the empty name @@ -685,91 +784,113 @@ void LLFloaterWindLight::onSavePreset() return; } + // If region scope, save immediately. + // We don't actually save to file in this case, but just update the preset + // so that the changes can be uploaded to server. + LLWLParamKey key(comboBox->getSelectedValue()); + if (key.scope == LLEnvKey::SCOPE_REGION) + { + // *TODO: Eliminate code duplication. + LL_DEBUGS("Windlight") << "Saving region sky preset: " << key.name << llendl; + LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); + param_mgr->mCurParams.mName = key.name; + param_mgr->setParamSet(key, param_mgr->mCurParams); + return; + } + // 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(key)); if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("SkyEditPresets")) { - LLNotificationsUtil::add("WLNoEditDefault"); + LLNotifications::instance().add("WLNoEditDefault", LLSD(), LLSD()); 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(); - param_mgr->setParamSet(param_mgr->mCurParams.mName, param_mgr->mCurParams); + // 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(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>( + llassert(sWindLight); + 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", LLSD(), LLSD()); 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 @@ -789,51 +910,56 @@ bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLS void LLFloaterWindLight::onChangePresetName(LLUICtrl* ctrl) { - deactivateAnimator(); + llassert(sWindLight); + 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(); + llassert(sWindLight); + 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 +973,16 @@ void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl) } -void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl) +void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl, void* userData) { - deactivateAnimator(); + llassert(sWindLight); + 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 +994,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..c2607816e5 100644 --- a/indra/newview/llfloaterwindlight.h +++ b/indra/newview/llfloaterwindlight.h @@ -35,77 +35,96 @@ #include <vector> #include "llwlparamset.h" +#include "llwlparammanager.h" struct WLColorControl; struct WLFloatControl; - /// Menuing system for all of windlight's functionality class LLFloaterWindLight : public LLFloater { + LOG_CLASS(LLFloaterWindLight); public: - - LLFloaterWindLight(const LLSD& key); + LLFloaterWindLight(const LLSD &key); virtual ~LLFloaterWindLight(); - /*virtual*/ BOOL postBuild(); + BOOL postBuild(); + /// initialize all void initCallbacks(void); - bool newPromptCallback(const LLSD& notification, const LLSD& response); + /// one and one instance only + static LLFloaterWindLight* instance(); + + 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); /// 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 ca908ef822..078de0cbdf 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1162,8 +1162,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 8593c4cf79..d94ec291a3 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 5a3baf2650..6f06e766e8 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -44,6 +44,7 @@ #include "llcompilequeue.h" #include "llconsole.h" #include "lldebugview.h" +#include "llenvmanager.h" #include "llfilepicker.h" #include "llfirstuse.h" #include "llfloaterbuy.h" @@ -7573,69 +7574,98 @@ class LLWorldEnvSettings : public view_listener_t if (tod == "editor") { // if not there or is hidden, show it + // *TODO replace with LLFloaterWindLight::show(LLEnvKey::SCOPE_LOCAL) to make sure we're using the right scope? LLFloaterReg::toggleInstance("env_settings"); return true; } - + + if (gSavedSettings.getBOOL("UseEnvironmentFromRegion")) + { + LLNotifications::instance().add("EnvLockedUsingRegion", LLSD(), LLSD()); + return true; + } + 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; } }; -/// Water Menu callbacks -class LLWorldWaterSettings : public view_listener_t -{ +class LLWorldCheckEnvironment : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + const std::string& item = userdata.asString(); + + if (item == "use_region_settings") + { + // Check whether we're using region environment settings. + LLEnvKey::EScope cur_scope = LLEnvManager::getInstance()->getNormallyDisplayedScope(); + return cur_scope == LLEnvKey::SCOPE_REGION; + } + + return true; + } +}; + +class LLWorldEnvironment : public view_listener_t +{ bool handleEvent(const LLSD& userdata) { - LLFloaterReg::toggleInstance("env_water"); + const std::string& item = userdata.asString(); + + if (item == "use_region_settings") + { + // Toggle using region environment settings. + LLEnvManager* env_mgr = LLEnvManager::getInstance(); + LLEnvKey::EScope cur_scope = env_mgr->getNormallyDisplayedScope(); + LLEnvKey::EScope new_scope = (cur_scope == LLEnvKey::SCOPE_LOCAL ? LLEnvKey::SCOPE_REGION : LLEnvKey::SCOPE_LOCAL); + env_mgr->setNormallyDisplayedScope(new_scope); + } + return true; } }; @@ -7888,7 +7918,8 @@ void initialize_menus() view_listener_t::addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun"); view_listener_t::addMenu(new LLWorldEnvSettings(), "World.EnvSettings"); - view_listener_t::addMenu(new LLWorldWaterSettings(), "World.WaterSettings"); + view_listener_t::addEnable(new LLWorldCheckEnvironment(), "World.CheckEnvironment"); + view_listener_t::addMenu(new LLWorldEnvironment(), "World.Environment"); view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess"); view_listener_t::addMenu(new LLWorldDayCycle(), "World.DayCycle"); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index c53fdc3393..b4e952ef3c 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1375,6 +1375,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); + capabilityNames.append("EnvironmentSettings"); capabilityNames.append("ObjectMedia"); capabilityNames.append("ObjectMediaNavigate"); @@ -1479,6 +1480,21 @@ bool LLViewerRegion::capabilitiesReceived() const void LLViewerRegion::setCapabilitiesReceived(bool received) { mCapabilitiesReceived = received; + + // Tell interested parties that we've received capabilities, + // so that they can safely use getCapability(). + if (received) + { + mCapabilitiesReceivedSignal(mRegionID); + + // This is a single-shot signal. Forget callbacks to save resources. + mCapabilitiesReceivedSignal.disconnect_all_slots(); + } +} + +boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb) +{ + return mCapabilitiesReceivedSignal.connect(cb); } void LLViewerRegion::logActiveCapabilities() const diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index dd40b876cd..05443ee415 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -30,6 +30,7 @@ // A ViewerRegion is a class that contains a bunch of objects and surfaces // that are in to a particular region. #include <string> +#include <boost/signals2.hpp> #include "lldarray.h" #include "llwind.h" @@ -87,6 +88,8 @@ public: NUM_PARTITIONS } eObjectPartitions; + typedef boost::signals2::signal<void(const LLUUID& region_id)> caps_received_signal_t; + LLViewerRegion(const U64 &handle, const LLHost &host, const U32 surface_grid_width, @@ -234,6 +237,7 @@ public: // has region received its final (not seed) capability list? bool capabilitiesReceived() const; void setCapabilitiesReceived(bool received); + boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb); static bool isSpecialCapabilityName(const std::string &name); void logActiveCapabilities() const; @@ -424,14 +428,15 @@ private: LLEventPoll* mEventPoll; - /// 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; + /// 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 bool mCapabilitiesReceived; + caps_received_signal_t mCapabilitiesReceivedSignal; //spatial partitions for objects in this region std::vector<LLSpatialPartition*> mObjectPartition; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index c1abead36e..09325a8c1b 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 80f43e51d2..e28179a789 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -370,7 +370,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)); @@ -646,24 +646,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 @@ -1033,7 +1033,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; @@ -2123,7 +2123,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 4b3a9a4dc3..4e56be5851 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), @@ -72,8 +70,6 @@ LLWaterParamManager::LLWaterParamManager() : mWave1Dir(.5f, .5f, "wave1Dir"), mWave2Dir(.5f, .5f, "wave2Dir"), mDensitySliderValue(1.0f), - mPrevFogDensity(16.0f), // 2^4 - mPrevFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f), mWaterFogKS(1.0f) { } @@ -248,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); @@ -258,29 +254,15 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader) } } -static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params"); +static LLFastTimer::DeclareTimer FTM_UPDATE_WATERPARAM("Update Water Params"); void LLWaterParamManager::update(LLViewerCamera * cam) { - LLFastTimer ftm(FTM_UPDATE_WLPARAM); + LLFastTimer ftm(FTM_UPDATE_WATERPARAM); // update the shaders and the menu propagateParameters(); - // If water fog color has been changed, save it. - if (mPrevFogColor != mFogColor) - { - gSavedSettings.setColor4("WaterFogColor", mFogColor); - mPrevFogColor = mFogColor; - } - - // If water fog density has been changed, save it. - if (mPrevFogDensity != mFogDensity) - { - gSavedSettings.setF32("WaterFogDensity", mFogDensity); - mPrevFogDensity = mFogDensity; - } - // sync menus if they exist LLFloaterWater* waterfloater = LLFloaterReg::findTypedInstance<LLFloaterWater>("env_water"); if(waterfloater) @@ -336,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 @@ -455,34 +424,9 @@ F32 LLWaterParamManager::getFogDensity(void) return fogDensity; } -// static -LLWaterParamManager * LLWaterParamManager::instance() -{ - if(NULL == sInstance) - { - sInstance = new LLWaterParamManager(); - - sInstance->loadAllPresets(LLStringUtil::null); - - sInstance->getParamSet("Default", sInstance->mCurParams); - sInstance->initOverrides(); - } - - return sInstance; -} - -void LLWaterParamManager::initOverrides() +// virtual static +void LLWaterParamManager::initSingleton() { - // Override fog color from the current preset with the saved setting. - LLColor4 fog_color_override = gSavedSettings.getColor4("WaterFogColor"); - mFogColor = fog_color_override; - mPrevFogColor = fog_color_override; - mCurParams.set("waterFogColor", fog_color_override); - - // Do the same with fog density. - F32 fog_density = gSavedSettings.getF32("WaterFogDensity"); - mPrevFogDensity = fog_density; - mFogDensity = fog_density; - mCurParams.set("waterFogDensity", fog_density); - setDensitySliderValue(mFogDensity.mExp); + loadAllPresets(LLStringUtil::null); + getParamSet("Default", mCurParams); } diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h index f465034c39..3fe0f0d861 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,12 +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(); - /// add a param to the list bool addParamSet(const std::string& name, LLWaterParamSet& param); @@ -281,12 +272,6 @@ public: F32 getFogDensity(void); LLColor4 getFogColor(void); - // singleton pattern implementation - static LLWaterParamManager * instance(); - -private: - void initOverrides(); - public: LLWaterParamSet mCurParams; @@ -314,14 +299,13 @@ public: F32 mDensitySliderValue; private: + friend class LLSingleton<LLWaterParamManager>; + /*virtual*/ void initSingleton(); + LLWaterParamManager(); + ~LLWaterParamManager(); + LLVector4 mWaterPlane; F32 mWaterFogKS; - - LLColor4 mPrevFogColor; - F32 mPrevFogDensity; - - // 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..3d51ad89ff 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..05f7fd9872 100644 --- a/indra/newview/llwldaycycle.cpp +++ b/indra/newview/llwldaycycle.cpp @@ -27,12 +27,12 @@ #include "llviewerprecompiledheaders.h" #include "llwldaycycle.h" - -#include "llnotificationsutil.h" #include "llsdserialize.h" -#include "llxmlnode.h" - #include "llwlparammanager.h" +#include "llfloaterdaycycle.h" +#include "llnotifications.h" + +#include "llviewerwindow.h" #include <map> @@ -45,85 +45,115 @@ LLWLDayCycle::~LLWLDayCycle() { } -void LLWLDayCycle::loadDayCycle(const std::string & fileName) +void LLWLDayCycle::loadDayCycle(const LLSD& day_data, LLWLParamKey::EScope scope) { - // clear the first few things + lldebugs << "Loading day cycle (day_data.size() = " << day_data.size() << ", scope = " << scope << ")" << llendl; 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", LLSD(), 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) + 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); + key.append(mIt->second.name); 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(); + lldebugs << "Dumping day cycle (" << mTimeMap.size() << ") to LLSD: " << day_data << llendl; + return day_data; } - -void LLWLDayCycle::clearKeys() +void LLWLDayCycle::clearKeyframes() { + lldebugs << "Clearing key frames" << llendl; 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,48 +164,58 @@ 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)); + lldebugs << "Adding key frame (" << newTime << ", " << frame.toLLSD() << ")" << llendl; return true; } // otherwise, don't add, and return error + llwarns << "Error adding key frame (" << newTime << ", " << frame.toLLSD() << ")" << llendl; return false; } -bool LLWLDayCycle::changeKeyTime(F32 oldTime, F32 newTime) +bool LLWLDayCycle::changeKeyframeTime(F32 oldTime, F32 newTime) { + lldebugs << "Changing key frame time (" << oldTime << " => " << newTime << ")" << llendl; + // 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) { + lldebugs << "Failed to change key frame time (" << oldTime << " => " << newTime << ")" << llendl; 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) { + lldebugs << "Changing key frame param (" << time << ", " << key.toLLSD() << ")" << llendl; + // 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) { + lldebugs << "Failed to change key frame param (" << time << ", " << key.toLLSD() << ")" << llendl; return stat; } - mTimeMap[time] = name; + mTimeMap[time] = key; return true; } -bool LLWLDayCycle::removeKey(F32 time) +bool LLWLDayCycle::removeKeyframe(F32 time) { + lldebugs << "Removing key frame (" << time << ")" << llendl; + // 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 +225,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,26 +244,46 @@ 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 + lldebugs << "Key " << time << " not found" << llendl; return false; } 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 + lldebugs << "Key " << time << " not found" << llendl; return false; } + +void LLWLDayCycle::removeReferencesTo(const LLWLParamKey& keyframe) +{ + lldebugs << "Removing references to key frame " << keyframe.toLLSD() << llendl; + 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..988003c1af 100644 --- a/indra/newview/llwldaycycle.h +++ b/indra/newview/llwldaycycle.h @@ -34,13 +34,16 @@ class LLWLDayCycle; #include <string> #include "llwlparamset.h" #include "llwlanimator.h" +struct LLWLParamKey; +#include "llenvmanager.h" // for LLEnvKey::EScope class LLWLDayCycle { + LOG_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 +57,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 +104,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..c116265c86 --- /dev/null +++ b/indra/newview/llwlhandlers.cpp @@ -0,0 +1,196 @@ +/** + * @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" +#include "llnotificationsutil.h" + +/**** + * LLEnvironmentRequest + ****/ +// static +bool LLEnvironmentRequest::initiate() +{ + LLViewerRegion* cur_region = gAgent.getRegion(); + + if (!cur_region->capabilitiesReceived()) + { + LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL; + cur_region->setCapabilitiesReceivedCallback(boost::bind(&LLEnvironmentRequest::onRegionCapsReceived, _1)); + return false; + } + + return doRequest(); +} + +// static +void LLEnvironmentRequest::onRegionCapsReceived(const LLUUID& region_id) +{ + if (region_id != gAgent.getRegion()->getRegionID()) + { + LL_INFOS("WindlightCaps") << "Got caps for a non-current region" << LL_ENDL; + return; + } + + LL_DEBUGS("WindlightCaps") << "Received region capabilities" << LL_ENDL; + doRequest(); +} + +// static +bool LLEnvironmentRequest::doRequest() +{ + 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; + } + + LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL; + LLHTTPClient::get(url, new LLEnvironmentRequestResponder()); + return true; +} + +/**** + * LLEnvironmentRequestResponder + ****/ +int LLEnvironmentRequestResponder::sCount = 0; // init to 0 + +LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() +{ + mID = ++sCount; +} +/*virtual*/ void LLEnvironmentRequestResponder::result(const LLSD& unvalidated_content) +{ + LL_INFOS("WindlightCaps") << "Received region 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; + LLNotificationsUtil::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; + LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL; + LLHTTPClient::post(url, content, new LLEnvironmentApplyResponder()); + return true; + } + else + { + LL_WARNS("WindlightCaps") << "Applying windlight settings not supported" << LL_ENDL; + } + 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(); + LLNotificationsUtil::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(); + LLNotificationsUtil::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..4929b4d27b --- /dev/null +++ b/indra/newview/llwlhandlers.h @@ -0,0 +1,100 @@ +/** + * @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" +#include "llhttpclient.h" + +class LLEnvManager; + +class LLEnvironmentRequest +{ +public: + /// @return true if request was successfully sent + static bool initiate(); + +private: + static void onRegionCapsReceived(const LLUUID& region_id); + static bool doRequest(); +}; + +class LLEnvironmentRequestResponder: public LLHTTPClient::Responder +{ +public: + virtual void result(const LLSD& content); + virtual void error(U32 status, const std::string& reason); + +private: + friend class LLEnvironmentRequest; + friend class LLEnvManager; + + 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 e5f52dfc97..1da70b9557 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -36,23 +36,31 @@ #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 +103,168 @@ 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) +{ + lldebugs << "mDay before finalizing:" << llendl; + { + for (std::map<F32, LLWLParamKey>::iterator iter = mDay.mTimeMap.begin(); iter != mDay.mTimeMap.end(); ++iter) + { + LLWLParamKey& key = iter->second; + lldebugs << iter->first << "->" << key.name << llendl; + } + } + + 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; + } + + lldebugs << "mDay after finalizing:" << llendl; + { + for (std::map<F32, LLWLParamKey>::iterator iter = mDay.mTimeMap.begin(); iter != mDay.mTimeMap.end(); ++iter) + { + LLWLParamKey& key = iter->second; + lldebugs << iter->first << "->" << key.name << llendl; + } + } + + 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); if(found) { - name=name.erase(name.length()-4); // bugfix for SL-46920: preventing filenames that break stuff. @@ -117,16 +274,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 +299,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 +316,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 +331,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 +414,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); @@ -280,6 +447,8 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader) } +static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params"); + void LLWLParamManager::propagateParameters(void) { LLFastTimer ftm(FTM_UPDATE_WLPARAM); @@ -359,7 +528,7 @@ void LLWLParamManager::update(LLViewerCamera * cam) mCurParams.updateCloudScrolling(); // update only if running - if(mAnimator.mIsRunning) + if(mAnimator.getIsRunning()) { mAnimator.update(mCurParams); } @@ -386,12 +555,14 @@ void LLWLParamManager::update(LLViewerCamera * cam) 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 +580,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 +587,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 +616,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(); - - sInstance->loadPresets(LLStringUtil::null); + loadPresets(LLStringUtil::null); - // load the day - sInstance->mDay.loadDayCycle(std::string("Default.xml")); + // load the day + mDay.loadDayCycleFromFile(std::string("Default.xml")); - // *HACK - sets cloud scrolling to what we want... fix this better in the future - sInstance->getParamSet("Default", sInstance->mCurParams); + // *HACK - sets cloud scrolling to what we want... fix this better in the future + getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), 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..e85227d3b3 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -29,10 +29,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 +74,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 +117,111 @@ 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> +{ + LOG_CLASS(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 +249,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 +334,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/skins/default/xui/en/floater_day_cycle_options.xml b/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml index 65e2462ef8..b54dc87d24 100644 --- a/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml +++ b/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml @@ -362,7 +362,7 @@ label_width="35" layout="topleft" left_delta="20" - max_val="100" + max_val="23" name="WLCurKeyHour" top_pad="4" width="74" /> @@ -420,31 +420,8 @@ height="16" layout="topleft" left_pad="15" - name="DayCycleText" - top="114" - width="120"> - Snap: - </text> - <combo_box - enabled="false" - height="18" - label="5 min" - layout="topleft" - left_delta="0" - name="WLSnapOptions" - top_pad="7" - width="70" /> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left_delta="0" name="DayCycleText2" - top_pad="17" + top_delta="71" width="120"> Length of Cycle: </text> diff --git a/indra/newview/skins/default/xui/en/floater_env_settings.xml b/indra/newview/skins/default/xui/en/floater_env_settings.xml index 8df5e232d9..e6cf433c8d 100644 --- a/indra/newview/skins/default/xui/en/floater_env_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_env_settings.xml @@ -141,7 +141,15 @@ layout="topleft" left="10" name="EnvUseEstateTimeButton" - top="120" + top_pad="20" + width="137" /> + <button + follows="left|top" + height="23" + label="Use Local Time" + left_pad="5" + name="EnvUseLocalTimeButton" + top_delta="0" width="137" /> <button follows="left|top" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index a5115b0faa..afb78097d8 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -470,7 +470,7 @@ <menu_item_separator/> - <menu + <menu create_jump_keys="true" label="Sun" name="Environment Settings" @@ -523,6 +523,22 @@ parameter="editor" /> </menu_item_call> </menu> + <menu + create_jump_keys="true" + label="Edit My Environment" + name="Environment" + tear_off="true"> + <menu_item_check + label="Use Region Settings" + name="Use Region Settings"> + <on_check + function="World.CheckEnvironment" + parameter="use_region_settings" /> + <on_click + function="World.Environment" + parameter="use_region_settings" /> + </menu_item_check> + </menu> </menu> <menu create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3fb3717e68..ed0c0d674d 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4857,6 +4857,91 @@ This day cycle file references a missing sky file: [SKY]. <notification icon="alertmodal.tga" + name="WLRegionApplyFail" + type="alertmodal"> +Sorry, the settings couldn't be applied to the region. Leaving the region and then returning may help rectify the problem. The reason given was: [FAIL_REASON] + </notification> + + <notification + functor="GenericAcknowledge" + icon="alertmodal.tga" + name="EnvLockedUsingRegion" + type="alertmodal"> +You cannot load environment presets while you are using the region's environment settings. To manually configure your environment setings, select the Environment Editor and uncheck "Use Region Environment Settings." + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + functor="GenericAcknowledge" + icon="alertmodal.tga" + name="EnvEditExternalCancel" + type="alertmodal"> +Warning: an update to the environment settings you were just editing was received, either because settings you recently committed have just been applied or because someone else with editing permissions updated the region's environment settings. In order to avoid overwriting this update, your changes have been cancelled; concurrent edits are not permitted. Please try again. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + functor="GenericAlertYesCancel" + icon="alertmodal.tga" + name="EnvEditUnsavedChangesCancel" + type="alertmodal"> +Warning: you have un-applied changes to the following environment settings: [SCOPE]. Are you sure you want to cancel them? + <usetemplate + name="okcancelbuttons" + yestext="Cancel Changes" + notext="Resume Editing"/> + </notification> + + <notification + functor="GenericAcknowledge" + icon="alertmodal.tga" + name="EnvOtherScopeAlreadyOpen" + type="alertmodal"> +You cannot modify your local environment settings and region environment settings at the same time. Close the environment settings windows currently open and try again. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + functor="GenericAcknowledge" + icon="alertmodal.tga" + name="EnvCannotDeleteLastDayCycleKey" + type="alertmodal"> +Unable to delete the last key in this day cycle because you cannot have an empty day cycle. You should modify the last remaining key instead of attempting to delete it and then to create a new one. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + functor="GenericAcknowledge" + icon="alertmodal.tga" + name="DayCycleTooManyKeyframes" + type="alertmodal"> +You cannot add any more keyframes to this day cycle. The maximum number of keyframes for day cycles of [SCOPE] scope is [MAX]. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + functor="GenericAcknowledge" + icon="alertmodal.tga" + name="EnvUpdateRate" + type="alertmodal"> + You may only update region environmental settings every [WAIT] seconds. Wait at least that long and then try again. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" name="PPSaveEffectAlert" type="alertmodal"> PostProcess Effect exists. Do you still wish overwrite it? diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index 5093c52129..fb94423a5c 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -2,7 +2,7 @@ <panel border="true" follows="top|left" - height="320" + height="400" help_topic="panel_region_terrain_tab" label="Terrain" layout="topleft" @@ -123,15 +123,96 @@ left="8" top="30" width="460" /> + <text + follows="left|top" + height="20" + left="190" + name="wl_settings_label" + top_pad="10" + width="280"> + WindLight environment settings for region: + </text> + <text + follows="left|top" + height="60" + left="190" + name="wl_settings_unavailable" + top_pad="0" + visible="false" + width="400"> +Not supported by this region, or you do not +have permission to change the region's settings. +See '?' for details. + </text> + <button + follows="left|top" + height="20" + label="Use Estate Time" + left="190" + name="EnvUseEstateTimeButton" + top_delta="0" + width="110" /> + <button + follows="left|top" + height="20" + label="Advanced Sky" + left_delta="0" + name="EnvAdvancedSkyButton" + top_pad="3" + width="110" /> + <button + follows="left|top" + height="20" + label="Advanced Water" + left_delta="0" + name="EnvAdvancedWaterButton" + top_pad="3" + width="110" /> + <button + enabled="false" + follows="left|top" + height="20" + label="Apply Changes to Region" + left="-170" + top_delta="-46" + name="WLRegionApply" + width="160" /> + <button + enabled="false" + follows="left|top" + height="20" + label="Cancel Changes" + left_delta="0" + name="WLRegionCancel" + top_pad="3" + width="160" /> + <button + enabled="false" + follows="left|top" + height="20" + label="Revert Region to Default" + left_delta="0" + name="WLRegionDefault" + top_pad="3" + width="160" /> + <button + enabled="false" + follows="left|top" + height="20" + label="Apply Local to Region" + left_delta="0" + top_pad="3" + name="WLCurrentApply" + width="160" /> <button follows="left|top" height="20" label="Download RAW terrain..." layout="topleft" - left_delta="2" + left="10" name="download_raw_btn" tool_tip="Available only to estate owners, not managers" - top_pad="60" + top="330" width="170" /> <button follows="left|top" @@ -141,7 +222,7 @@ left="10" name="upload_raw_btn" tool_tip="Available only to estate owners, not managers" - top="243" + top_pad="0" width="170" /> <button follows="left|top" @@ -151,6 +232,6 @@ left="10" name="bake_terrain_btn" tool_tip="Set current terrain as mid-point for raise/lower limits" - top="283" + top_pad="3" width="100" /> </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 27295150c5..9b1a19d2b2 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2262,6 +2262,12 @@ Requests name of an avatar. When data is available the dataserver event will be <string name="GroupOwned">Group Owned</string> <string name="Public">Public</string> + <!-- Environment settings --> + <string name="LocalSettings">Local Settings</string> + <string name="RegionSettings">Region Settings</string> + <string name="Local">Local</string> + <string name="Region">Region</string> + <!-- panel classified --> <string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string> <string name="ClassifiedUpdateAfterPublish">(will update after publish)</string> 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 +{ +} |