Files
SingularityViewer/indra/newview/llwldaycycle.cpp
2012-04-13 22:39:39 -05:00

365 lines
9.1 KiB
C++

/**
* @file llwldaycycle.cpp
* @brief Implementation for the LLWLDayCycle class.
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llwldaycycle.h"
#include "llsdserialize.h"
#include "llwlparammanager.h"
#include "llnotificationsutil.h"
#include "llviewerwindow.h"
#include <map>
LLWLDayCycle::LLWLDayCycle() : mDayRate(120)
{
}
LLWLDayCycle::~LLWLDayCycle()
{
}
void LLWLDayCycle::loadDayCycle(const LLSD& day_data, LLWLParamKey::EScope scope)
{
lldebugs << "Loading day cycle (day_data.size() = " << day_data.size() << ", scope = " << scope << ")" << llendl;
mTimeMap.clear();
// add each key frame
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)
{
// *HACK: If loading region day cycle, try local sky presets as well.
// Local presets may be referenced by a region day cycle after
// it has been edited but the changes have not been uploaded.
if (scope == LLEnvKey::SCOPE_REGION)
{
frame.scope = LLEnvKey::SCOPE_LOCAL;
success = LLWLParamManager::getInstance()->getParamSet(frame, pset);
}
if (!success)
{
// alert the user
LLSD args;
args["SKY"] = day_data[i][1].asString();
LLNotifications::instance().add("WLMissingSky", args, LLSD());
continue;
}
}
// 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)
{
// *FIX: Cannot load user day cycles.
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
"windlight/days", fileName));
return loadDayCycleFromPath(pathName);
}
// static
LLSD LLWLDayCycle::loadDayCycleFromPath(const std::string& file_path)
{
LL_INFOS("Windlight") << "Loading DayCycle settings from " << file_path << LL_ENDL;
llifstream day_cycle_xml(file_path);
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)
{
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", fileName));
//llinfos << "Saving WindLight settings to " << pathName << llendl;
save(pathName);
}
void LLWLDayCycle::save(const std::string& file_path)
{
LLSD day_data = asLLSD();
llofstream day_cycle_xml(file_path);
LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
formatter->format(day_data, day_cycle_xml, LLSDFormatter::OPTIONS_PRETTY);
day_cycle_xml.close();
}
LLSD LLWLDayCycle::asLLSD()
{
LLSD day_data(LLSD::emptyArray());
for(std::map<F32, LLWLParamKey>::const_iterator mIt = mTimeMap.begin(); mIt != mTimeMap.end(); ++mIt)
{
LLSD key(LLSD::emptyArray());
key.append(mIt->first);
key.append(mIt->second.name);
day_data.append(key);
}
lldebugs << "Dumping day cycle (" << mTimeMap.size() << ") to LLSD: " << day_data << llendl;
return day_data;
}
bool LLWLDayCycle::getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const
{
bool result = true;
LLWLParamManager& wl_mgr = LLWLParamManager::instance();
refs.clear();
for (std::map<F32, LLWLParamKey>::const_iterator iter = mTimeMap.begin(); iter != mTimeMap.end(); ++iter)
{
const LLWLParamKey& key = iter->second;
if (!wl_mgr.getParamSet(key, refs[key]))
{
llwarns << "Cannot find sky [" << key.name << "] referenced by a day cycle" << llendl;
result = false;
}
}
return result;
}
bool LLWLDayCycle::getSkyMap(LLSD& sky_map) const
{
std::map<LLWLParamKey, LLWLParamSet> refs;
if (!getSkyRefs(refs))
{
return false;
}
sky_map = LLWLParamManager::createSkyMap(refs);
return true;
}
void LLWLDayCycle::clearKeyframes()
{
lldebugs << "Clearing key frames" << llendl;
mTimeMap.clear();
}
void LLWLDayCycle::clearKeys()
{
mTimeMap.clear();
}
bool LLWLDayCycle::addKey(F32 newTime, const std::string & paramName)
{
return addKeyframe(newTime, LLWLParamKey(paramName, LLWLParamKey::SCOPE_LOCAL));
}
bool LLWLDayCycle::addKeyframe(F32 newTime, LLWLParamKey frame)
{
// no adding negative time
if(newTime < 0)
{
newTime = 0;
}
// if time not being used, add it and return true
if(mTimeMap.find(newTime) == mTimeMap.end())
{
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)
{
return changeKeyframeTime(oldTime, newTime);
}
bool LLWLDayCycle::changeKeyframeTime(F32 oldTime, F32 newTime)
{
lldebugs << "Changing key frame time (" << oldTime << " => " << newTime << ")" << llendl;
// just remove and add back
LLWLParamKey frame = mTimeMap[oldTime];
bool stat = removeKeyframe(oldTime);
if(stat == false)
{
lldebugs << "Failed to change key frame time (" << oldTime << " => " << newTime << ")" << llendl;
return stat;
}
return addKeyframe(newTime, frame);
}
bool LLWLDayCycle::changeKeyParam(F32 time, const std::string & name)
{
return changeKeyframeParam(time, LLWLParamKey(name, LLWLParamKey::SCOPE_LOCAL));
}
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::getInstance()->getParamSet(key, tmp);
if(stat == false)
{
lldebugs << "Failed to change key frame param (" << time << ", " << key.toLLSD() << ")" << llendl;
return stat;
}
mTimeMap[time] = key;
return true;
}
bool LLWLDayCycle::removeKeyframe(F32 time)
{
lldebugs << "Removing key frame (" << time << ")" << llendl;
// look for the time. If there, erase it
std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time);
if(mIt != mTimeMap.end())
{
mTimeMap.erase(mIt);
return true;
}
return false;
}
bool LLWLDayCycle::getKey(const std::string & name, F32& key)
{
return getKeytime(LLWLParamKey(name, LLWLParamKey::SCOPE_LOCAL), key);
}
bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) const
{
// scroll through till we find the correct value in the map
std::map<F32, LLWLParamKey>::const_iterator mIt = mTimeMap.begin();
for(; mIt != mTimeMap.end(); ++mIt)
{
if(frame == mIt->second)
{
key_time = mIt->first;
return true;
}
}
return false;
}
bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param)
{
// just scroll on through till you find it
std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time);
if(mIt != mTimeMap.end())
{
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, LLWLParamKey>::iterator mIt = mTimeMap.find(time);
if(mIt != mTimeMap.end())
{
name = mTimeMap[time].name;
return true;
}
// return error if not found
lldebugs << "Key " << time << " not found" << llendl;
return false;
}
bool LLWLDayCycle::hasReferencesTo(const LLWLParamKey& keyframe) const
{
F32 dummy;
return getKeytime(keyframe, dummy);
}
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
}