/** * * Copyright (c) 2009-2011, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt * * 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. * */ #include "llviewerprecompiledheaders.h" #include "llagent.h" #include "llagentcamera.h" #include "lldaycyclemanager.h" #include "llviewercontrol.h" #include "llvoavatarself.h" #include "llwlparammanager.h" #include "rlvextensions.h" #include "rlvhandler.h" #include "rlvhelper.h" // ============================================================================ class RlvWindLightControl { public: enum EType { TYPE_COLOR, TYPE_COLOR_R, TYPE_FLOAT, TYPE_UNKNOWN }; enum EColorComponent { COMPONENT_R, COMPONENT_G, COMPONENT_B, COMPONENT_I, COMPONENT_NONE }; public: RlvWindLightControl(WLColorControl* pCtrl, bool fColorR) : m_eType((!fColorR) ? TYPE_COLOR: TYPE_COLOR_R), m_pColourCtrl(pCtrl), m_pFloatCtrl(NULL) {} RlvWindLightControl(WLFloatControl* pCtrl) : m_eType(TYPE_FLOAT), m_pColourCtrl(NULL), m_pFloatCtrl(pCtrl) {} EType getControlType() const { return m_eType; } bool isColorType() const { return (TYPE_COLOR == m_eType) || (TYPE_COLOR_R == m_eType); } bool isFloatType() const { return (TYPE_FLOAT == m_eType); } // TYPE_COLOR and TYPE_COLOR_R F32 getColorComponent(EColorComponent eComponent, bool& fError) const; LLVector4 getColorVector(bool& fError) const; bool setColorComponent(EColorComponent eComponent, F32 nValue); // TYPE_FLOAT F32 getFloat(bool& fError) const; bool setFloat(F32 nValue); static EColorComponent getComponentFromCharacter(char ch); protected: EType m_eType; // Type of the WindLight control WLColorControl* m_pColourCtrl; WLFloatControl* m_pFloatCtrl; }; // Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a static F32 get_intensity_from_color(const LLVector4& v) { return llmax(v.mV[0], v.mV[1], v.mV[2]); } // Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a F32 RlvWindLightControl::getColorComponent(EColorComponent eComponent, bool& fError) const { switch (eComponent) { case COMPONENT_R: return getColorVector(fError).mV[0]; case COMPONENT_G: return getColorVector(fError).mV[1]; case COMPONENT_B: return getColorVector(fError).mV[2]; case COMPONENT_I: return get_intensity_from_color(getColorVector(fError)); // SL-2.8: Always seems to be 1.0 so get it manually default : RLV_ASSERT(false); fError = true; return 0.0; } } // Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a RlvWindLightControl::EColorComponent RlvWindLightControl::getComponentFromCharacter(char ch) { if (('r' == ch) || ('x' == ch)) return COMPONENT_R; else if (('g' == ch) || ('y' == ch)) return COMPONENT_G; else if (('b' == ch) || ('d' == ch)) return COMPONENT_B; else if ('i' == ch) return COMPONENT_I; return COMPONENT_NONE; } // Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a LLVector4 RlvWindLightControl::getColorVector(bool& fError) const { if ((fError = !isColorType())) return LLVector4(0, 0, 0, 0); F32 nMult = (m_pColourCtrl->isSunOrAmbientColor) ? 3.0f : ((m_pColourCtrl->isBlueHorizonOrDensity) ? 2.0f : 1.0f); return LLWLParamManager::getInstance()->mCurParams.getVector(m_pColourCtrl->mName, fError) / nMult; } // Checked: 2011-08-28 (RLVa-1.4.1a) | Added: RLVa-1.4.1a bool RlvWindLightControl::setColorComponent(EColorComponent eComponent, F32 nValue) { if (isColorType()) { nValue *= (m_pColourCtrl->isSunOrAmbientColor) ? 3.0f : ((m_pColourCtrl->isBlueHorizonOrDensity) ? 2.0f : 1.0f); if (COMPONENT_I == eComponent) // (See: LLFloaterWindLight::onColorControlIMoved) { if (m_pColourCtrl->hasSliderName) { F32 curMax = llmax(m_pColourCtrl->r, m_pColourCtrl->g, m_pColourCtrl->b); if ( (0.0f == nValue) || (0.0f == curMax) ) { m_pColourCtrl->r = m_pColourCtrl->g = m_pColourCtrl->b = m_pColourCtrl->i = nValue; } else { F32 nDelta = (nValue - curMax) / curMax; m_pColourCtrl->r *= (1.0f + nDelta); m_pColourCtrl->g *= (1.0f + nDelta); m_pColourCtrl->b *= (1.0f + nDelta); m_pColourCtrl->i = nValue; } } } else // (See: LLFloaterWindLight::onColorControlRMoved) { F32* pnValue = (COMPONENT_R == eComponent) ? &m_pColourCtrl->r : (COMPONENT_G == eComponent) ? &m_pColourCtrl->g : (COMPONENT_B == eComponent) ? &m_pColourCtrl->b : NULL; if (pnValue) *pnValue = nValue; if (m_pColourCtrl->hasSliderName) m_pColourCtrl->i = llmax(m_pColourCtrl->r, m_pColourCtrl->g, m_pColourCtrl->b); } m_pColourCtrl->update(LLWLParamManager::getInstance()->mCurParams); LLWLParamManager::getInstance()->propagateParameters(); } return isColorType(); } // Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a F32 RlvWindLightControl::getFloat(bool& fError) const { return (!(fError = (TYPE_FLOAT != m_eType))) ? LLWLParamManager::getInstance()->mCurParams.getVector(m_pFloatCtrl->mName, fError).mV[0] * m_pFloatCtrl->mult : 0.0; } // Checked: 2011-08-28 (RLVa-1.4.1a) | Added: RLVa-1.4.1a bool RlvWindLightControl::setFloat(F32 nValue) { if (TYPE_FLOAT == m_eType) { m_pFloatCtrl->x = nValue / m_pFloatCtrl->mult; m_pFloatCtrl->update(LLWLParamManager::getInstance()->mCurParams); LLWLParamManager::getInstance()->propagateParameters(); } return (TYPE_FLOAT == m_eType); } // ============================================================================ class RlvWindLight : public LLSingleton { friend class LLSingleton; public: RlvWindLight(); std::string getValue(const std::string& strSetting, bool& fError); bool setValue(const std::string& strRlvName, const std::string& strValue); protected: std::map m_ControlLookupMap; }; // Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a RlvWindLight::RlvWindLight() { LLWLParamManager* pWLParamMgr = LLWLParamManager::getInstance(); // TYPE_FLOAT m_ControlLookupMap.insert(std::pair("cloudcoverage", RlvWindLightControl(&pWLParamMgr->mCloudCoverage))); m_ControlLookupMap.insert(std::pair("cloudscale", RlvWindLightControl(&pWLParamMgr->mCloudScale))); m_ControlLookupMap.insert(std::pair("densitymultiplier", RlvWindLightControl(&pWLParamMgr->mDensityMult))); m_ControlLookupMap.insert(std::pair("distancemultiplier", RlvWindLightControl(&pWLParamMgr->mDistanceMult))); m_ControlLookupMap.insert(std::pair("maxaltitude", RlvWindLightControl(&pWLParamMgr->mMaxAlt))); m_ControlLookupMap.insert(std::pair("scenegamma", RlvWindLightControl(&pWLParamMgr->mWLGamma))); m_ControlLookupMap.insert(std::pair("hazedensity", RlvWindLightControl(&pWLParamMgr->mHazeDensity))); m_ControlLookupMap.insert(std::pair("hazehorizon", RlvWindLightControl(&pWLParamMgr->mHazeHorizon))); // TYPE_COLOR m_ControlLookupMap.insert(std::pair("ambient", RlvWindLightControl(&pWLParamMgr->mAmbient, false))); m_ControlLookupMap.insert(std::pair("bluedensity", RlvWindLightControl(&pWLParamMgr->mBlueDensity, false))); m_ControlLookupMap.insert(std::pair("bluehorizon", RlvWindLightControl(&pWLParamMgr->mBlueHorizon, false))); m_ControlLookupMap.insert(std::pair("cloud", RlvWindLightControl(&pWLParamMgr->mCloudMain, false))); m_ControlLookupMap.insert(std::pair("cloudcolor", RlvWindLightControl(&pWLParamMgr->mCloudColor, false))); m_ControlLookupMap.insert(std::pair("clouddetail", RlvWindLightControl(&pWLParamMgr->mCloudDetail, false))); m_ControlLookupMap.insert(std::pair("sunmooncolor", RlvWindLightControl(&pWLParamMgr->mSunlight, false))); } // Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a std::string RlvWindLight::getValue(const std::string& strSetting, bool& fError) { LLWLParamManager* pWLParams = LLWLParamManager::getInstance(); LLEnvManagerNew* pEnvMgr = LLEnvManagerNew::getInstance(); fError = false; // Assume we won't fail if ("preset" == strSetting) return (pEnvMgr->getUseFixedSky()) ? pEnvMgr->getSkyPresetName() : std::string(); else if ("daycycle" == strSetting) return (pEnvMgr->getUseDayCycle()) ? pEnvMgr->getDayCycleName() : std::string(); F32 nValue = 0.0f; if ("daytime" == strSetting) { nValue = (pEnvMgr->getUseFixedSky()) ? pWLParams->mCurParams.getFloat("sun_angle", fError) / F_TWO_PI : -1.0f; } else if (("sunglowfocus" == strSetting) || ("sunglowsize" == strSetting)) { pWLParams->mGlow = pWLParams->mCurParams.getVector(pWLParams->mGlow.mName, fError); RLV_ASSERT_DBG(!fError); if ("sunglowfocus" == strSetting) nValue = -pWLParams->mGlow.b / 5.0f; else nValue = 2 - pWLParams->mGlow.r / 20.0f; } else if ("starbrightness" == strSetting) nValue = pWLParams->mCurParams.getStarBrightness(); else if ("eastangle" == strSetting) nValue = pWLParams->mCurParams.getEastAngle() / F_TWO_PI; else if ("sunmoonposition" == strSetting) nValue = pWLParams->mCurParams.getSunAngle() / F_TWO_PI; else if ("cloudscrollx" == strSetting) nValue = pWLParams->mCurParams.getCloudScrollX() - 10.0f; else if ("cloudscrolly" == strSetting) nValue = pWLParams->mCurParams.getCloudScrollY() - 10.0f; else { std::map::const_iterator itControl = m_ControlLookupMap.find(strSetting); if (m_ControlLookupMap.end() != itControl) { switch (itControl->second.getControlType()) { case RlvWindLightControl::TYPE_FLOAT: nValue = itControl->second.getFloat(fError); break; case RlvWindLightControl::TYPE_COLOR_R: nValue = itControl->second.getColorComponent(RlvWindLightControl::COMPONENT_R, fError); break; default: fError = true; break; } } else { // Couldn't find the exact name, check for a color control name RlvWindLightControl::EColorComponent eComponent = RlvWindLightControl::getComponentFromCharacter(strSetting[strSetting.length() - 1]); if (RlvWindLightControl::COMPONENT_NONE != eComponent) itControl = m_ControlLookupMap.find(strSetting.substr(0, strSetting.length() - 1)); if ( (m_ControlLookupMap.end() != itControl) && (itControl->second.isColorType()) ) nValue = itControl->second.getColorComponent(eComponent, fError); else fError = true; } } return llformat("%f", nValue); } // Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a bool RlvWindLight::setValue(const std::string& strRlvName, const std::string& strValue) { F32 nValue = 0.0f; // Sanity check - make sure strValue specifies a number for all settings except "preset" and "daycycle" if ( (RlvSettings::getNoSetEnv()) || ( (!LLStringUtil::convertToF32(strValue, nValue)) && (("preset" != strRlvName) && ("daycycle" != strRlvName)) ) ) { return false; } LLWLParamManager* pWLParams = LLWLParamManager::getInstance(); LLEnvManagerNew* pEnvMgr = LLEnvManagerNew::getInstance(); if ("daytime" == strRlvName) { if (0.0f <= nValue) { pWLParams->mAnimator.deactivate(); pWLParams->mAnimator.setDayTime(nValue); pWLParams->mAnimator.update(pWLParams->mCurParams); } else { pEnvMgr->useRegionSettings(); } return true; } else if ("preset" == strRlvName) { std::string strPresetName = pWLParams->findPreset(strValue, LLEnvKey::SCOPE_LOCAL); if (!strPresetName.empty()) pEnvMgr->useSkyPreset(strPresetName); return !strPresetName.empty(); } else if ("daycycle" == strRlvName) { std::string strPresetName = LLDayCycleManager::instance().findPreset(strValue); if (!strPresetName.empty()) pEnvMgr->useDayCycle(strValue, LLEnvKey::SCOPE_LOCAL); return !strPresetName.empty(); } bool fError = false; pWLParams->mAnimator.deactivate(); if (("sunglowfocus" == strRlvName) || ("sunglowsize" == strRlvName)) { pWLParams->mGlow = pWLParams->mCurParams.getVector(pWLParams->mGlow.mName, fError); RLV_ASSERT_DBG(!fError); if ("sunglowfocus" == strRlvName) pWLParams->mGlow.b = -nValue * 5; else pWLParams->mGlow.r = (2 - nValue) * 20; pWLParams->mGlow.update(pWLParams->mCurParams); pWLParams->propagateParameters(); return true; } else if ("starbrightness" == strRlvName) { pWLParams->mCurParams.setStarBrightness(nValue); return true; } else if (("eastangle" == strRlvName) || ("sunmoonposition" == strRlvName)) { if ("eastangle" == strRlvName) pWLParams->mCurParams.setEastAngle(F_TWO_PI * nValue); else pWLParams->mCurParams.setSunAngle(F_TWO_PI * nValue); // Set the sun vector pWLParams->mLightnorm.r = -sin(pWLParams->mCurParams.getEastAngle()) * cos(pWLParams->mCurParams.getSunAngle()); pWLParams->mLightnorm.g = sin(pWLParams->mCurParams.getSunAngle()); pWLParams->mLightnorm.b = cos(pWLParams->mCurParams.getEastAngle()) * cos(pWLParams->mCurParams.getSunAngle()); pWLParams->mLightnorm.i = 1.f; pWLParams->propagateParameters(); return true; } else if ("cloudscrollx" == strRlvName) { pWLParams->mCurParams.setCloudScrollX(nValue + 10.0f); return true; } else if ("cloudscrolly" == strRlvName) { pWLParams->mCurParams.setCloudScrollY(nValue + 10.0f); return true; } std::map::iterator itControl = m_ControlLookupMap.find(strRlvName); if (m_ControlLookupMap.end() != itControl) { switch (itControl->second.getControlType()) { case RlvWindLightControl::TYPE_FLOAT: return itControl->second.setFloat(nValue); case RlvWindLightControl::TYPE_COLOR_R: return itControl->second.setColorComponent(RlvWindLightControl::COMPONENT_R, nValue); default: RLV_ASSERT(false); } } else { // Couldn't find the exact name, check for a color control name RlvWindLightControl::EColorComponent eComponent = RlvWindLightControl::getComponentFromCharacter(strRlvName[strRlvName.length() - 1]); if (RlvWindLightControl::COMPONENT_NONE != eComponent) itControl = m_ControlLookupMap.find(strRlvName.substr(0, strRlvName.length() - 1)); if ( (m_ControlLookupMap.end() != itControl) && (itControl->second.isColorType()) ) return itControl->second.setColorComponent(eComponent, nValue); } return false; } // ============================================================================ std::map RlvExtGetSet::m_DbgAllowed; std::map RlvExtGetSet::m_PseudoDebug; // Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h RlvExtGetSet::RlvExtGetSet() { if (!m_DbgAllowed.size()) // m_DbgAllowed is static and should only be initialized once { m_DbgAllowed.insert(std::pair("AvatarSex", DBG_READ | DBG_WRITE | DBG_PSEUDO)); m_DbgAllowed.insert(std::pair("RenderResolutionDivisor", DBG_READ | DBG_WRITE)); #ifdef RLV_EXTENSION_CMD_GETSETDEBUG_EX m_DbgAllowed.insert(std::pair(RLV_SETTING_FORBIDGIVETORLV, DBG_READ)); m_DbgAllowed.insert(std::pair(RLV_SETTING_NOSETENV, DBG_READ)); m_DbgAllowed.insert(std::pair("WindLightUseAtmosShaders", DBG_READ)); #endif // RLV_EXTENSION_CMD_GETSETDEBUG_EX // Cache persistance of every setting LLControlVariable* pSetting; for (std::map::iterator itDbg = m_DbgAllowed.begin(); itDbg != m_DbgAllowed.end(); ++itDbg) { if ( ((pSetting = gSavedSettings.getControl(itDbg->first)) != NULL) && (pSetting->isPersisted()) ) itDbg->second |= DBG_PERSIST; } } } // Checked: 2009-05-17 (RLVa-0.2.0a) bool RlvExtGetSet::onForceCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) { return processCommand(rlvCmd, cmdRet); } // Checked: 2009-05-17 (RLVa-0.2.0a) bool RlvExtGetSet::onReplyCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) { return processCommand(rlvCmd, cmdRet); } // Checked: 2009-12-23 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k bool RlvExtGetSet::processCommand(const RlvCommand& rlvCmd, ERlvCmdRet& eRet) { std::string strBehaviour = rlvCmd.getBehaviour(), strGetSet, strSetting; int idxSetting = strBehaviour.find('_'); if ( (strBehaviour.length() >= 6) && (-1 != idxSetting) && ((int)strBehaviour.length() > idxSetting + 1) ) { strSetting = strBehaviour.substr(idxSetting + 1); strBehaviour.erase(idxSetting); // Get rid of "_" strGetSet = strBehaviour.substr(0, 3); strBehaviour.erase(0, 3); // Get rid of get/set if ("debug" == strBehaviour) { if ( ("get" == strGetSet) && (RLV_TYPE_REPLY == rlvCmd.getParamType()) ) { RlvUtil::sendChatReply(rlvCmd.getParam(), onGetDebug(strSetting)); eRet = RLV_RET_SUCCESS; return true; } else if ( ("set" == strGetSet) && (RLV_TYPE_FORCE == rlvCmd.getParamType()) ) { if (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETDEBUG, rlvCmd.getObjectID())) eRet = onSetDebug(strSetting, rlvCmd.getOption()); else eRet = RLV_RET_FAILED_LOCK; return true; } } else if ("env" == strBehaviour) { bool fError = false; if ( ("get" == strGetSet) && (RLV_TYPE_REPLY == rlvCmd.getParamType()) ) { RlvUtil::sendChatReply(rlvCmd.getParam(), RlvWindLight::instance().getValue(strSetting, fError)); eRet = (!fError) ? RLV_RET_SUCCESS : RLV_RET_FAILED_UNKNOWN; return true; } else if ( ("set" == strGetSet) && (RLV_TYPE_FORCE == rlvCmd.getParamType()) ) { if (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETENV, rlvCmd.getObjectID())) eRet = (RlvWindLight::instance().setValue(strSetting, rlvCmd.getOption())) ? RLV_RET_SUCCESS : RLV_RET_FAILED_UNKNOWN; else eRet = RLV_RET_FAILED_LOCK; return true; } } } else if ("setrot" == rlvCmd.getBehaviour()) { // NOTE: if