Merge branch 'master' into buttons

Conflicts:
	apps/opencs/view/render/instancemode.cpp
This commit is contained in:
Marc Zinnschlag 2016-01-19 13:59:24 +01:00
commit 4a02563708
63 changed files with 3081 additions and 2311 deletions

View file

@ -48,6 +48,7 @@ Programmers
Gašper Sedej Gašper Sedej
gugus/gus gugus/gus
Hallfaer Tuilinn Hallfaer Tuilinn
hristoast
Internecine Internecine
Jacob Essex (Yacoby) Jacob Essex (Yacoby)
Jannik Heller (scrawl) Jannik Heller (scrawl)
@ -96,6 +97,7 @@ Programmers
Pieter van der Kloet (pvdk) Pieter van der Kloet (pvdk)
pkubik pkubik
Radu-Marius Popovici (rpopovici) Radu-Marius Popovici (rpopovici)
rcutmore
rdimesio rdimesio
riothamus riothamus
Robert MacGregor (Ragora) Robert MacGregor (Ragora)

View file

@ -51,10 +51,6 @@ int main(int argc, char *argv[])
if (result == Launcher::FirstRunDialogResultFailure) if (result == Launcher::FirstRunDialogResultFailure)
return 0; return 0;
// if (!mainWin.setup()) {
// return 0;
// }
if (result == Launcher::FirstRunDialogResultContinue) if (result == Launcher::FirstRunDialogResultContinue)
mainWin.show(); mainWin.show();

View file

@ -50,7 +50,6 @@ namespace Launcher
explicit MainDialog(QWidget *parent = 0); explicit MainDialog(QWidget *parent = 0);
~MainDialog(); ~MainDialog();
bool setup();
FirstRunDialogResult showFirstRunDialog(); FirstRunDialogResult showFirstRunDialog();
bool reloadSettings(); bool reloadSettings();
@ -65,6 +64,8 @@ namespace Launcher
void wizardFinished(int exitCode, QProcess::ExitStatus exitStatus); void wizardFinished(int exitCode, QProcess::ExitStatus exitStatus);
private: private:
bool setup();
void createIcons(); void createIcons();
void createPages(); void createPages();

View file

@ -26,7 +26,7 @@ opencs_units_noqt (model/world
universalid record commands columnbase columnimp scriptcontext cell refidcollection universalid record commands columnbase columnimp scriptcontext cell refidcollection
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection
idcompletionmanager metadata idcompletionmanager metadata defaultgmsts
) )
opencs_hdrs_noqt (model/world opencs_hdrs_noqt (model/world
@ -42,7 +42,7 @@ opencs_units_noqt (model/tools
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck
startscriptcheck search searchoperation searchstage pathgridcheck soundgencheck magiceffectcheck startscriptcheck search searchoperation searchstage pathgridcheck soundgencheck magiceffectcheck
mergestages mergestages gmstcheck
) )
opencs_hdrs_noqt (model/tools opencs_hdrs_noqt (model/tools
@ -94,7 +94,7 @@ opencs_units_noqt (view/render
) )
opencs_hdrs_noqt (view/render opencs_hdrs_noqt (view/render
elements mask
) )

View file

@ -8,6 +8,8 @@
#include <components/vfs/manager.hpp> #include <components/vfs/manager.hpp>
#include <components/vfs/registerarchives.hpp> #include <components/vfs/registerarchives.hpp>
#include <components/fallback/validate.hpp>
#include <components/nifosg/nifloader.hpp> #include <components/nifosg/nifloader.hpp>
#include "model/doc/document.hpp" #include "model/doc/document.hpp"
@ -17,6 +19,8 @@
#include <Windows.h> #include <Windows.h>
#endif #endif
using namespace Fallback;
CS::Editor::Editor () CS::Editor::Editor ()
: mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr), : mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr),
mViewManager (mDocumentManager), mPid(""), mViewManager (mDocumentManager), mPid(""),
@ -100,6 +104,8 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
("resources", boost::program_options::value<std::string>()->default_value("resources")) ("resources", boost::program_options::value<std::string>()->default_value("resources"))
("fallback-archive", boost::program_options::value<std::vector<std::string> >()-> ("fallback-archive", boost::program_options::value<std::vector<std::string> >()->
default_value(std::vector<std::string>(), "fallback-archive")->multitoken()) default_value(std::vector<std::string>(), "fallback-archive")->multitoken())
("fallback", boost::program_options::value<FallbackMap>()->default_value(FallbackMap(), "")
->multitoken()->composing(), "fallback values")
("script-blacklist", boost::program_options::value<std::vector<std::string> >()->default_value(std::vector<std::string>(), "") ("script-blacklist", boost::program_options::value<std::vector<std::string> >()->default_value(std::vector<std::string>(), "")
->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)") ->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)")
("script-blacklist-use", boost::program_options::value<bool>()->implicit_value(true) ("script-blacklist-use", boost::program_options::value<bool>()->implicit_value(true)
@ -114,6 +120,8 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>()); mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>());
mDocumentManager.setFallbackMap (variables["fallback"].as<FallbackMap>().mMap);
if (variables["script-blacklist-use"].as<bool>()) if (variables["script-blacklist-use"].as<bool>())
mDocumentManager.setBlacklistedScripts ( mDocumentManager.setBlacklistedScripts (
variables["script-blacklist"].as<std::vector<std::string> >()); variables["script-blacklist"].as<std::vector<std::string> >());

File diff suppressed because it is too large Load diff

View file

@ -25,9 +25,13 @@
class QAbstractItemModel; class QAbstractItemModel;
namespace Fallback
{
class Map;
}
namespace VFS namespace VFS
{ {
class Manager; class Manager;
} }
@ -66,6 +70,7 @@ namespace CSMDoc
Saving mSavingOperation; Saving mSavingOperation;
OperationHolder mSaving; OperationHolder mSaving;
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
const Fallback::Map* mFallbackMap;
Blacklist mBlacklist; Blacklist mBlacklist;
Runner mRunner; Runner mRunner;
bool mDirty; bool mDirty;
@ -101,6 +106,7 @@ namespace CSMDoc
Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration, Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration,
const std::vector< boost::filesystem::path >& files, bool new_, const std::vector< boost::filesystem::path >& files, bool new_,
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
const Fallback::Map* fallback,
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager, ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
const std::vector<std::string>& blacklistedScripts); const std::vector<std::string>& blacklistedScripts);

View file

@ -64,7 +64,7 @@ CSMDoc::Document *CSMDoc::DocumentManager::makeDocument (
const std::vector< boost::filesystem::path >& files, const std::vector< boost::filesystem::path >& files,
const boost::filesystem::path& savePath, bool new_) const boost::filesystem::path& savePath, bool new_)
{ {
return new Document (mVFS, mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager, mBlacklistedScripts); return new Document (mVFS, mConfiguration, files, new_, savePath, mResDir, &mFallbackMap, mEncoding, mResourcesManager, mBlacklistedScripts);
} }
void CSMDoc::DocumentManager::insertDocument (CSMDoc::Document *document) void CSMDoc::DocumentManager::insertDocument (CSMDoc::Document *document)
@ -100,6 +100,11 @@ void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& par
mResDir = boost::filesystem::system_complete(parResDir); mResDir = boost::filesystem::system_complete(parResDir);
} }
void CSMDoc::DocumentManager::setFallbackMap(const std::map<std::string, std::string>& fallbackMap)
{
mFallbackMap = Fallback::Map(fallbackMap);
}
void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding) void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding)
{ {
mEncoding = encoding; mEncoding = encoding;

View file

@ -10,6 +10,7 @@
#include <QThread> #include <QThread>
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
#include <components/fallback/fallback.hpp>
#include "../world/resourcesmanager.hpp" #include "../world/resourcesmanager.hpp"
@ -67,6 +68,8 @@ namespace CSMDoc
void setResourceDir (const boost::filesystem::path& parResDir); void setResourceDir (const boost::filesystem::path& parResDir);
void setFallbackMap (const std::map<std::string, std::string>& fallbackMap);
void setEncoding (ToUTF8::FromType encoding); void setEncoding (ToUTF8::FromType encoding);
void setBlacklistedScripts (const std::vector<std::string>& scriptIds); void setBlacklistedScripts (const std::vector<std::string>& scriptIds);
@ -78,6 +81,7 @@ namespace CSMDoc
private: private:
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
Fallback::Map mFallbackMap;
private slots: private slots:

View file

@ -394,10 +394,6 @@ void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages)
CSMWorld::Land record = land.get(); CSMWorld::Land record = land.get();
writer.startRecord (record.sRecordId); writer.startRecord (record.sRecordId);
record.save (writer, land.mState == CSMWorld::RecordBase::State_Deleted); record.save (writer, land.mState == CSMWorld::RecordBase::State_Deleted);
if (const ESM::Land::LandData *data = record.getLandData (record.mDataTypes))
data->save (mState.getWriter());
writer.endRecord (record.sRecordId); writer.endRecord (record.sRecordId);
} }
} }

View file

@ -0,0 +1,123 @@
#include "gmstcheck.hpp"
#include <sstream>
#include "../world/defaultgmsts.hpp"
CSMTools::GmstCheckStage::GmstCheckStage(const CSMWorld::IdCollection<ESM::GameSetting>& gameSettings)
: mGameSettings(gameSettings)
{}
int CSMTools::GmstCheckStage::setup()
{
return mGameSettings.getSize();
}
void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages)
{
const CSMWorld::Record<ESM::GameSetting>& record = mGameSettings.getRecord (stage);
if (record.isDeleted())
return;
const ESM::GameSetting& gmst = record.get();
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Gmst, gmst.mId);
// Test for empty string
if (gmst.mValue.getType() == ESM::VT_String && gmst.mValue.getString().empty())
messages.add(id, gmst.mId + " is an empty string", "", CSMDoc::Message::Severity_Warning);
// Checking type and limits
// optimization - compare it to lists based on naming convention (f-float,i-int,s-string)
if (gmst.mId[0] == 'f')
{
for (size_t i = 0; i < CSMWorld::DefaultGmsts::FloatCount; ++i)
{
if (gmst.mId == CSMWorld::DefaultGmsts::Floats[i])
{
if (gmst.mValue.getType() != ESM::VT_Float)
{
std::ostringstream stream;
stream << "Expected float type for " << gmst.mId << " but found "
<< varTypeToString(gmst.mValue.getType()) << " type";
messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error);
}
if (gmst.mValue.getFloat() < CSMWorld::DefaultGmsts::FloatLimits[i*2])
messages.add(id, gmst.mId + " is less than the suggested range", "",
CSMDoc::Message::Severity_Warning);
if (gmst.mValue.getFloat() > CSMWorld::DefaultGmsts::FloatLimits[i*2+1])
messages.add(id, gmst.mId + " is more than the suggested range", "",
CSMDoc::Message::Severity_Warning);
break; // for loop
}
}
}
else if (gmst.mId[0] == 'i')
{
for (size_t i = 0; i < CSMWorld::DefaultGmsts::IntCount; ++i)
{
if (gmst.mId == CSMWorld::DefaultGmsts::Ints[i])
{
if (gmst.mValue.getType() != ESM::VT_Int)
{
std::ostringstream stream;
stream << "Expected int type for " << gmst.mId << " but found "
<< varTypeToString(gmst.mValue.getType()) << " type";
messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error);
}
if (gmst.mValue.getInteger() < CSMWorld::DefaultGmsts::IntLimits[i*2])
messages.add(id, gmst.mId + " is less than the suggested range", "",
CSMDoc::Message::Severity_Warning);
if (gmst.mValue.getInteger() > CSMWorld::DefaultGmsts::IntLimits[i*2+1])
messages.add(id, gmst.mId + " is more than the suggested range", "",
CSMDoc::Message::Severity_Warning);
break; // for loop
}
}
}
else if (gmst.mId[0] == 's')
{
for (size_t i = 0; i < CSMWorld::DefaultGmsts::StringCount; ++i)
{
if (gmst.mId == CSMWorld::DefaultGmsts::Strings[i])
{
ESM::VarType type = gmst.mValue.getType();
if (type != ESM::VT_String && type != ESM::VT_None)
{
std::ostringstream stream;
stream << "Expected string or none type for " << gmst.mId << " but found "
<< varTypeToString(gmst.mValue.getType()) << " type";
messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error);
}
break; // for loop
}
}
}
}
std::string CSMTools::GmstCheckStage::varTypeToString(ESM::VarType type)
{
switch (type)
{
case ESM::VT_Unknown: return "unknown";
case ESM::VT_None: return "none";
case ESM::VT_Short: return "short";
case ESM::VT_Int: return "int";
case ESM::VT_Long: return "long";
case ESM::VT_Float: return "float";
case ESM::VT_String: return "string";
default: return "unhandled";
}
}

View file

@ -0,0 +1,34 @@
#ifndef CSM_TOOLS_GMSTCHECK_H
#define CSM_TOOLS_GMSTCHECK_H
#include <components/esm/loadgmst.hpp>
#include "../world/idcollection.hpp"
#include "../doc/stage.hpp"
namespace CSMTools
{
/// \brief VerifyStage: make sure that GMSTs are alright
class GmstCheckStage : public CSMDoc::Stage
{
public:
GmstCheckStage(const CSMWorld::IdCollection<ESM::GameSetting>& gameSettings);
virtual int setup();
///< \return number of steps
virtual void perform(int stage, CSMDoc::Messages& messages);
///< Messages resulting from this stage will be appended to \a messages
private:
const CSMWorld::IdCollection<ESM::GameSetting>& mGameSettings;
std::string varTypeToString(ESM::VarType);
};
}
#endif

View file

@ -29,6 +29,7 @@
#include "soundgencheck.hpp" #include "soundgencheck.hpp"
#include "magiceffectcheck.hpp" #include "magiceffectcheck.hpp"
#include "mergeoperation.hpp" #include "mergeoperation.hpp"
#include "gmstcheck.hpp"
CSMDoc::OperationHolder *CSMTools::Tools::get (int type) CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
{ {
@ -111,6 +112,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
mData.getResources (CSMWorld::UniversalId::Type_Icons), mData.getResources (CSMWorld::UniversalId::Type_Icons),
mData.getResources (CSMWorld::UniversalId::Type_Textures))); mData.getResources (CSMWorld::UniversalId::Type_Textures)));
mVerifierOperation->appendStage (new GmstCheckStage (mData.getGmsts()));
mVerifier.setOperation (mVerifierOperation); mVerifier.setOperation (mVerifierOperation);
} }

View file

@ -59,9 +59,10 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
return number; return number;
} }
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager) CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager, const Fallback::Map* fallback)
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), : mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0), mResourceSystem(new Resource::ResourceSystem(resourcesManager.getVFS())) mResourcesManager (resourcesManager), mFallbackMap(fallback),
mReader (0), mDialogue (0), mReaderIndex(0), mResourceSystem(new Resource::ResourceSystem(resourcesManager.getVFS()))
{ {
int index = 0; int index = 0;
@ -1201,3 +1202,8 @@ const VFS::Manager* CSMWorld::Data::getVFS() const
{ {
return mResourcesManager.getVFS(); return mResourcesManager.getVFS();
} }
const Fallback::Map* CSMWorld::Data::getFallbackMap() const
{
return mFallbackMap;
}

View file

@ -58,6 +58,11 @@ namespace VFS
class Manager; class Manager;
} }
namespace Fallback
{
class Map;
}
namespace ESM namespace ESM
{ {
class ESMReader; class ESMReader;
@ -104,6 +109,7 @@ namespace CSMWorld
IdCollection<ESM::Filter> mFilters; IdCollection<ESM::Filter> mFilters;
Collection<MetaData> mMetaData; Collection<MetaData> mMetaData;
const ResourcesManager& mResourcesManager; const ResourcesManager& mResourcesManager;
const Fallback::Map* mFallbackMap;
std::vector<QAbstractItemModel *> mModels; std::vector<QAbstractItemModel *> mModels;
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex; std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
ESM::ESMReader *mReader; ESM::ESMReader *mReader;
@ -132,12 +138,14 @@ namespace CSMWorld
public: public:
Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager); Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager, const Fallback::Map* fallback);
virtual ~Data(); virtual ~Data();
const VFS::Manager* getVFS() const; const VFS::Manager* getVFS() const;
const Fallback::Map* getFallbackMap() const;
boost::shared_ptr<Resource::ResourceSystem> getResourceSystem(); boost::shared_ptr<Resource::ResourceSystem> getResourceSystem();
boost::shared_ptr<const Resource::ResourceSystem> getResourceSystem() const; boost::shared_ptr<const Resource::ResourceSystem> getResourceSystem() const;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
#ifndef CSM_WORLD_DEFAULTGMSTS_H
#define CSM_WORLD_DEFAULTGMSTS_H
#include <cstddef>
namespace CSMWorld {
namespace DefaultGmsts {
const size_t FloatCount = 258;
const size_t IntCount = 89;
const size_t StringCount = 1174;
const size_t OptionalFloatCount = 42;
const size_t OptionalIntCount = 4;
const size_t OptionalStringCount = 26;
extern const char* Floats[];
extern const char * Ints[];
extern const char * Strings[];
extern const char * OptionalFloats[];
extern const char * OptionalInts[];
extern const char * OptionalStrings[];
extern const float FloatsDefaultValues[];
extern const int IntsDefaultValues[];
extern const float FloatLimits[];
extern const int IntLimits[];
}
}
#endif

View file

@ -14,9 +14,6 @@ Q_DECLARE_METATYPE (boost::filesystem::path)
#include "ui_filedialog.h" #include "ui_filedialog.h"
class DataFilesModel;
class PluginsProxyModel;
namespace ContentSelectorView namespace ContentSelectorView
{ {
class ContentSelector; class ContentSelector;

View file

@ -11,7 +11,7 @@
#include "../../model/world/refcollection.hpp" #include "../../model/world/refcollection.hpp"
#include "../../model/world/cellcoordinates.hpp" #include "../../model/world/cellcoordinates.hpp"
#include "elements.hpp" #include "mask.hpp"
#include "terrainstorage.hpp" #include "terrainstorage.hpp"
bool CSVRender::Cell::removeObject (const std::string& id) bool CSVRender::Cell::removeObject (const std::string& id)
@ -80,7 +80,7 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st
if (esmLand.getLandData (ESM::Land::DATA_VHGT)) if (esmLand.getLandData (ESM::Land::DATA_VHGT))
{ {
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Element_Terrain<<1)); mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Mask_Terrain));
mTerrain->loadCell(esmLand.mX, mTerrain->loadCell(esmLand.mX,
esmLand.mY); esmLand.mY);
} }
@ -230,7 +230,7 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int
void CSVRender::Cell::setSelection (int elementMask, Selection mode) void CSVRender::Cell::setSelection (int elementMask, Selection mode)
{ {
if (elementMask & Element_Reference) if (elementMask & Mask_Reference)
{ {
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin()); for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter) iter!=mObjects.end(); ++iter)

View file

@ -7,10 +7,10 @@
#include <osg/Geometry> #include <osg/Geometry>
#include <osg/PrimitiveSet> #include <osg/PrimitiveSet>
#include "elements.hpp" #include "mask.hpp"
CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow) CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow)
: TagBase (Element_CellArrow), mArrow (arrow) : TagBase (Mask_CellArrow), mArrow (arrow)
{} {}
CSVRender::CellArrow *CSVRender::CellArrowTag::getCellArrow() const CSVRender::CellArrow *CSVRender::CellArrowTag::getCellArrow() const
@ -165,8 +165,7 @@ CSVRender::CellArrow::CellArrow (osg::Group *cellNode, Direction direction,
mParentNode->addChild (mBaseNode); mParentNode->addChild (mBaseNode);
// 0x1 reserved for separating cull and update visitors mBaseNode->setNodeMask (Mask_CellArrow);
mBaseNode->setNodeMask (Element_CellArrow<<1);
adjustTransform(); adjustTransform();
buildShape(); buildShape();

View file

@ -1,23 +0,0 @@
#ifndef CSV_RENDER_ELEMENTS_H
#define CSV_RENDER_ELEMENTS_H
namespace CSVRender
{
/// Visual elements in a scene
enum Elements
{
// elements that are part of the actual scene
Element_Reference = 0x1,
Element_Pathgrid = 0x2,
Element_Water = 0x4,
Element_Fog = 0x8,
Element_Terrain = 0x10,
// control elements
Element_CellMarker = 0x10000,
Element_CellArrow = 0x20000,
Element_CellBorder = 0x40000
};
}
#endif

View file

@ -9,17 +9,19 @@
#include "../../model/world/idtree.hpp" #include "../../model/world/idtree.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolbar.hpp"
#include "../widget/scenetoolmode.hpp" #include "../widget/scenetoolmode.hpp"
#include "elements.hpp" #include "mask.hpp"
#include "object.hpp" #include "object.hpp"
#include "worldspacewidget.hpp" #include "worldspacewidget.hpp"
#include "pagedworldspacewidget.hpp" #include "pagedworldspacewidget.hpp"
#include "instanceselectionmode.hpp" #include "instanceselectionmode.hpp"
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
: EditMode (worldspaceWidget, QIcon (":placeholder"), Element_Reference, "Instance editing", : EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing",
parent), mSubMode (0), mSelectionMode (0) parent), mSubMode (0), mSelectionMode (0)
{ {
} }
@ -91,7 +93,7 @@ void CSVRender::InstanceMode::secondaryEditPressed (osg::ref_ptr<TagBase> tag)
void CSVRender::InstanceMode::primarySelectPressed (osg::ref_ptr<TagBase> tag) void CSVRender::InstanceMode::primarySelectPressed (osg::ref_ptr<TagBase> tag)
{ {
getWorldspaceWidget().clearSelection (Element_Reference); getWorldspaceWidget().clearSelection (Mask_Reference);
if (tag) if (tag)
{ {

View file

@ -0,0 +1,35 @@
#ifndef CSV_RENDER_ELEMENTS_H
#define CSV_RENDER_ELEMENTS_H
namespace CSVRender
{
/// Node masks used on the OSG scene graph in OpenMW-CS.
/// @note See the respective file in OpenMW (apps/openmw/mwrender/vismask.hpp)
/// for general usage hints about node masks.
/// @copydoc MWRender::VisMask
enum Mask
{
// internal use within NifLoader, do not change
Mask_UpdateVisitor = 0x1,
// elements that are part of the actual scene
Mask_Reference = 0x2,
Mask_Pathgrid = 0x4,
Mask_Water = 0x8,
Mask_Fog = 0x10,
Mask_Terrain = 0x20,
// used within models
Mask_ParticleSystem = 0x100,
Mask_Lighting = 0x200,
// control elements
Mask_CellMarker = 0x10000,
Mask_CellArrow = 0x20000,
Mask_CellBorder = 0x40000
};
}
#endif

View file

@ -17,9 +17,11 @@
#include "../../model/world/refidcollection.hpp" #include "../../model/world/refidcollection.hpp"
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/sceneutil/clone.hpp> #include <components/sceneutil/lightutil.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/fallback/fallback.hpp>
#include "elements.hpp" #include "mask.hpp"
namespace namespace
{ {
@ -39,7 +41,7 @@ namespace
CSVRender::ObjectTag::ObjectTag (Object* object) CSVRender::ObjectTag::ObjectTag (Object* object)
: TagBase (Element_Reference), mObject (object) : TagBase (Mask_Reference), mObject (object)
{} {}
QString CSVRender::ObjectTag::getToolTip (bool hideBasics) const QString CSVRender::ObjectTag::getToolTip (bool hideBasics) const
@ -62,6 +64,7 @@ void CSVRender::Object::update()
const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables();
int index = referenceables.searchId (mReferenceableId); int index = referenceables.searchId (mReferenceableId);
const ESM::Light* light = NULL;
if (index==-1) if (index==-1)
error = 1; error = 1;
@ -73,6 +76,14 @@ void CSVRender::Object::update()
referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Model)). referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Model)).
toString().toUtf8().constData(); toString().toUtf8().constData();
int recordType =
referenceables.getData (index,
referenceables.findColumnIndex(CSMWorld::Columns::ColumnId_RecordType)).toInt();
if (recordType == CSMWorld::UniversalId::Type_Light)
{
light = &dynamic_cast<const CSMWorld::Record<ESM::Light>& >(referenceables.getRecord(index)).get();
}
if (model.empty()) if (model.empty())
error = 2; error = 2;
} }
@ -97,6 +108,21 @@ void CSVRender::Object::update()
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
} }
} }
if (light)
{
const Fallback::Map* fallback = mData.getFallbackMap();
static bool outQuadInLin = fallback->getFallbackBool("LightAttenuation_OutQuadInLin");
static bool useQuadratic = fallback->getFallbackBool("LightAttenuation_UseQuadratic");
static float quadraticValue = fallback->getFallbackFloat("LightAttenuation_QuadraticValue");
static float quadraticRadiusMult = fallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
static bool useLinear = fallback->getFallbackBool("LightAttenuation_UseLinear");
static float linearRadiusMult = fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
static float linearValue = fallback->getFallbackFloat("LightAttenuation_LinearValue");
bool isExterior = false; // FIXME
SceneUtil::addLight(mBaseNode, light, Mask_ParticleSystem, Mask_Lighting, isExterior, outQuadInLin, useQuadratic,
quadraticValue, quadraticRadiusMult, useLinear, linearRadiusMult, linearValue);
}
} }
void CSVRender::Object::adjustTransform() void CSVRender::Object::adjustTransform()
@ -131,6 +157,8 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
: mData (data), mBaseNode(0), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero) : mData (data), mBaseNode(0), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero)
{ {
mBaseNode = new osg::PositionAttitudeTransform; mBaseNode = new osg::PositionAttitudeTransform;
mBaseNode->addCullCallback(new SceneUtil::LightListCallback);
mOutline = new osgFX::Scribe; mOutline = new osgFX::Scribe;
mOutline->addChild(mBaseNode); mOutline->addChild(mBaseNode);
@ -138,8 +166,7 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
parentNode->addChild(mBaseNode); parentNode->addChild(mBaseNode);
// 0x1 reserved for separating cull and update visitors mBaseNode->setNodeMask(Mask_Reference);
mBaseNode->setNodeMask(Element_Reference<<1);
if (referenceable) if (referenceable)
{ {

View file

@ -18,7 +18,7 @@
#include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetooltoggle2.hpp"
#include "editmode.hpp" #include "editmode.hpp"
#include "elements.hpp" #include "mask.hpp"
bool CSVRender::PagedWorldspaceWidget::adjustCells() bool CSVRender::PagedWorldspaceWidget::adjustCells()
{ {
@ -126,8 +126,8 @@ void CSVRender::PagedWorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool) CSVWidget::SceneToolToggle2 *tool)
{ {
WorldspaceWidget::addVisibilitySelectorButtons (tool); WorldspaceWidget::addVisibilitySelectorButtons (tool);
tool->addButton (Element_Terrain, "Terrain"); tool->addButton (Button_Terrain, Mask_Terrain, "Terrain");
tool->addButton (Element_Fog, "Fog", "", true); tool->addButton (Button_Fog, Mask_Fog, "Fog", "", true);
} }
void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons ( void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
@ -137,22 +137,22 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
/// \todo replace EditMode with suitable subclasses /// \todo replace EditMode with suitable subclasses
tool->addButton ( tool->addButton (
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Terrain shape editing"), new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain shape editing"),
"terrain-shape"); "terrain-shape");
tool->addButton ( tool->addButton (
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Terrain texture editing"), new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain texture editing"),
"terrain-texture"); "terrain-texture");
tool->addButton ( tool->addButton (
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Terrain vertex paint editing"), new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain vertex paint editing"),
"terrain-vertex"); "terrain-vertex");
tool->addButton ( tool->addButton (
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Terrain movement"), new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain movement"),
"terrain-move"); "terrain-move");
} }
void CSVRender::PagedWorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button, bool shift) void CSVRender::PagedWorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button, bool shift)
{ {
if (tag && tag->getElement()==Element_CellArrow) if (tag && tag->getMask()==Mask_CellArrow)
{ {
if (button=="p-edit" || button=="s-edit") if (button=="p-edit" || button=="s-edit")
{ {
@ -497,7 +497,7 @@ CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::g
unsigned int CSVRender::PagedWorldspaceWidget::getVisibilityMask() const unsigned int CSVRender::PagedWorldspaceWidget::getVisibilityMask() const
{ {
return WorldspaceWidget::getVisibilityMask() | mControlElements->getSelection(); return WorldspaceWidget::getVisibilityMask() | mControlElements->getSelectionMask();
} }
void CSVRender::PagedWorldspaceWidget::clearSelection (int elementMask) void CSVRender::PagedWorldspaceWidget::clearSelection (int elementMask)
@ -526,12 +526,12 @@ CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibil
mControlElements = new CSVWidget::SceneToolToggle (parent, mControlElements = new CSVWidget::SceneToolToggle (parent,
"Controls & Guides Visibility", ":placeholder"); "Controls & Guides Visibility", ":placeholder");
mControlElements->addButton (":placeholder", Element_CellMarker, ":placeholder", mControlElements->addButton (":placeholder", Mask_CellMarker, ":placeholder",
"Cell marker"); "Cell marker");
mControlElements->addButton (":placeholder", Element_CellArrow, ":placeholder", "Cell arrows"); mControlElements->addButton (":placeholder", Mask_CellArrow, ":placeholder", "Cell arrows");
mControlElements->addButton (":placeholder", Element_CellBorder, ":placeholder", "Cell border"); mControlElements->addButton (":placeholder", Mask_CellBorder, ":placeholder", "Cell border");
mControlElements->setSelection (0xffffffff); mControlElements->setSelectionMask (0xffffffff);
connect (mControlElements, SIGNAL (selectionChanged()), connect (mControlElements, SIGNAL (selectionChanged()),
this, SLOT (elementSelectionChanged())); this, SLOT (elementSelectionChanged()));

View file

@ -14,10 +14,12 @@
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include "../widget/scenetoolmode.hpp" #include "../widget/scenetoolmode.hpp"
#include "lighting.hpp" #include "lighting.hpp"
#include "mask.hpp"
namespace CSVRender namespace CSVRender
{ {
@ -63,7 +65,10 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );
mView->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f ); mView->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );
mRootNode = new osg::Group; SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager;
lightMgr->setStartLight(1);
lightMgr->setLightingMask(Mask_Lighting);
mRootNode = lightMgr;
mView->getCamera()->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); mView->getCamera()->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
mView->getCamera()->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON); mView->getCamera()->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
@ -73,7 +78,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
// Press S to reveal profiling stats // Press S to reveal profiling stats
mView->addEventHandler(new osgViewer::StatsHandler); mView->addEventHandler(new osgViewer::StatsHandler);
mView->getCamera()->setCullMask(~(0x1)); mView->getCamera()->setCullMask(~(Mask_UpdateVisitor));
viewer.addView(mView); viewer.addView(mView);
viewer.setDone(false); viewer.setDone(false);
@ -92,8 +97,7 @@ void RenderWidget::flagAsModified()
void RenderWidget::setVisibilityMask(int mask) void RenderWidget::setVisibilityMask(int mask)
{ {
// 0x1 reserved for separating cull and update visitors mView->getCamera()->setCullMask(mask | Mask_ParticleSystem | Mask_Lighting);
mView->getCamera()->setCullMask(mask<<1);
} }
bool RenderWidget::eventFilter(QObject* obj, QEvent* event) bool RenderWidget::eventFilter(QObject* obj, QEvent* event)
@ -167,6 +171,8 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
setLighting(&mLightingDay); setLighting(&mLightingDay);
mResourceSystem->getSceneManager()->setParticleSystemMask(Mask_ParticleSystem);
/// \todo make shortcut configurable /// \todo make shortcut configurable
QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut); QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest())); connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest()));

View file

@ -1,11 +1,11 @@
#include "tagbase.hpp" #include "tagbase.hpp"
CSVRender::TagBase::TagBase (Elements element) : mElement (element) {} CSVRender::TagBase::TagBase (Mask mask) : mMask (mask) {}
CSVRender::Elements CSVRender::TagBase::getElement() const CSVRender::Mask CSVRender::TagBase::getMask() const
{ {
return mElement; return mMask;
} }
QString CSVRender::TagBase::getToolTip (bool hideBasics) const QString CSVRender::TagBase::getToolTip (bool hideBasics) const

View file

@ -5,19 +5,19 @@
#include <QString> #include <QString>
#include "elements.hpp" #include "mask.hpp"
namespace CSVRender namespace CSVRender
{ {
class TagBase : public osg::Referenced class TagBase : public osg::Referenced
{ {
Elements mElement; Mask mMask;
public: public:
TagBase (Elements element); TagBase (Mask mask);
Elements getElement() const; Mask getMask() const;
virtual QString getToolTip (bool hideBasics) const; virtual QString getToolTip (bool hideBasics) const;

View file

@ -17,7 +17,7 @@
#include "../widget/scenetooltoggle.hpp" #include "../widget/scenetooltoggle.hpp"
#include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetooltoggle2.hpp"
#include "elements.hpp" #include "mask.hpp"
void CSVRender::UnpagedWorldspaceWidget::update() void CSVRender::UnpagedWorldspaceWidget::update()
{ {
@ -171,8 +171,8 @@ void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool) CSVWidget::SceneToolToggle2 *tool)
{ {
WorldspaceWidget::addVisibilitySelectorButtons (tool); WorldspaceWidget::addVisibilitySelectorButtons (tool);
tool->addButton (Element_Terrain, "Terrain", "", true); tool->addButton (Button_Terrain, Mask_Terrain, "Terrain", "", true);
tool->addButton (Element_Fog, "Fog"); tool->addButton (Button_Fog, Mask_Fog, "Fog");
} }
std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction() std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction()

View file

@ -27,7 +27,7 @@
#include "../widget/scenetoolrun.hpp" #include "../widget/scenetoolrun.hpp"
#include "object.hpp" #include "object.hpp"
#include "elements.hpp" #include "mask.hpp"
#include "editmode.hpp" #include "editmode.hpp"
#include "instancemode.hpp" #include "instancemode.hpp"
@ -160,7 +160,7 @@ CSVWidget::SceneToolToggle2 *CSVRender::WorldspaceWidget::makeSceneVisibilitySel
addVisibilitySelectorButtons (mSceneElements); addVisibilitySelectorButtons (mSceneElements);
mSceneElements->setSelection (0xffffffff); mSceneElements->setSelectionMask (0xffffffff);
connect (mSceneElements, SIGNAL (selectionChanged()), connect (mSceneElements, SIGNAL (selectionChanged()),
this, SLOT (elementSelectionChanged())); this, SLOT (elementSelectionChanged()));
@ -275,12 +275,12 @@ bool CSVRender::WorldspaceWidget::handleDrop (const std::vector<CSMWorld::Univer
unsigned int CSVRender::WorldspaceWidget::getVisibilityMask() const unsigned int CSVRender::WorldspaceWidget::getVisibilityMask() const
{ {
return mSceneElements->getSelection(); return mSceneElements->getSelectionMask();
} }
void CSVRender::WorldspaceWidget::setInteractionMask (unsigned int mask) void CSVRender::WorldspaceWidget::setInteractionMask (unsigned int mask)
{ {
mInteractionMask = mask | Element_CellMarker | Element_CellArrow; mInteractionMask = mask | Mask_CellMarker | Mask_CellArrow;
} }
unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const
@ -296,9 +296,9 @@ void CSVRender::WorldspaceWidget::setEditLock (bool locked)
void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons ( void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool) CSVWidget::SceneToolToggle2 *tool)
{ {
tool->addButton (Element_Reference, "Instances"); tool->addButton (Button_Reference, Mask_Reference, "Instances");
tool->addButton (Element_Water, "Water"); tool->addButton (Button_Water, Mask_Water, "Water");
tool->addButton (Element_Pathgrid, "Pathgrid"); tool->addButton (Button_Pathgrid, Mask_Pathgrid, "Pathgrid");
} }
void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool) void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool)
@ -306,7 +306,7 @@ void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneTo
/// \todo replace EditMode with suitable subclasses /// \todo replace EditMode with suitable subclasses
tool->addButton (new InstanceMode (this, tool), "object"); tool->addButton (new InstanceMode (this, tool), "object");
tool->addButton ( tool->addButton (
new EditMode (this, QIcon (":placeholder"), Element_Pathgrid, "Pathgrid editing"), new EditMode (this, QIcon (":placeholder"), Mask_Pathgrid, "Pathgrid editing"),
"pathgrid"); "pathgrid");
} }
@ -333,7 +333,7 @@ osg::Vec3f CSVRender::WorldspaceWidget::getIntersectionPoint (const QPoint& loca
if (ignoreHidden) if (ignoreHidden)
mask &= getVisibilityMask(); mask &= getVisibilityMask();
visitor.setTraversalMask (mask << 1); visitor.setTraversalMask (mask);
mView->getCamera()->accept (visitor); mView->getCamera()->accept (visitor);
@ -452,7 +452,7 @@ osg::ref_ptr<CSVRender::TagBase> CSVRender::WorldspaceWidget::mousePick (const Q
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
osgUtil::IntersectionVisitor visitor(intersector); osgUtil::IntersectionVisitor visitor(intersector);
visitor.setTraversalMask(getInteractionMask() << 1); visitor.setTraversalMask(getInteractionMask());
mView->getCamera()->accept(visitor); mView->getCamera()->accept(visitor);

View file

@ -11,7 +11,7 @@
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "scenewidget.hpp" #include "scenewidget.hpp"
#include "elements.hpp" #include "mask.hpp"
namespace CSMPrefs namespace CSMPrefs
{ {
@ -135,13 +135,24 @@ namespace CSVRender
/// \param ignoreHidden ignore elements specified in interactionMask that are /// \param ignoreHidden ignore elements specified in interactionMask that are
/// flagged as not visible. /// flagged as not visible.
osg::Vec3f getIntersectionPoint (const QPoint& localPos, osg::Vec3f getIntersectionPoint (const QPoint& localPos,
unsigned int interactionMask = Element_Reference | Element_Terrain, unsigned int interactionMask = Mask_Reference | Mask_Terrain,
bool ignoreHidden = false) const; bool ignoreHidden = false) const;
virtual std::string getCellId (const osg::Vec3f& point) const = 0; virtual std::string getCellId (const osg::Vec3f& point) const = 0;
protected: protected:
/// Visual elements in a scene
/// @note do not change the enumeration values, they are used in pre-existing button file names!
enum ButtonId
{
Button_Reference = 0x1,
Button_Pathgrid = 0x2,
Button_Water = 0x4,
Button_Fog = 0x8,
Button_Terrain = 0x10
};
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool); virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);

View file

@ -40,7 +40,7 @@ void CSVWidget::SceneToolToggle::adjustToolTip()
void CSVWidget::SceneToolToggle::adjustIcon() void CSVWidget::SceneToolToggle::adjustIcon()
{ {
unsigned int selection = getSelection(); unsigned int selection = getSelectionMask();
if (!selection) if (!selection)
setIcon (QIcon (QString::fromUtf8 (mEmptyIcon.c_str()))); setIcon (QIcon (QString::fromUtf8 (mEmptyIcon.c_str())));
else else
@ -135,7 +135,7 @@ void CSVWidget::SceneToolToggle::showPanel (const QPoint& position)
mFirst->setFocus (Qt::OtherFocusReason); mFirst->setFocus (Qt::OtherFocusReason);
} }
void CSVWidget::SceneToolToggle::addButton (const std::string& icon, unsigned int id, void CSVWidget::SceneToolToggle::addButton (const std::string& icon, unsigned int mask,
const std::string& smallIcon, const QString& name, const QString& tooltip) const std::string& smallIcon, const QString& name, const QString& tooltip)
{ {
if (mButtons.size()>=9) if (mButtons.size()>=9)
@ -151,7 +151,7 @@ void CSVWidget::SceneToolToggle::addButton (const std::string& icon, unsigned in
mLayout->addWidget (button); mLayout->addWidget (button);
ButtonDesc desc; ButtonDesc desc;
desc.mId = id; desc.mMask = mask;
desc.mSmallIcon = smallIcon; desc.mSmallIcon = smallIcon;
desc.mName = name; desc.mName = name;
desc.mIndex = mButtons.size(); desc.mIndex = mButtons.size();
@ -164,23 +164,23 @@ void CSVWidget::SceneToolToggle::addButton (const std::string& icon, unsigned in
mFirst = button; mFirst = button;
} }
unsigned int CSVWidget::SceneToolToggle::getSelection() const unsigned int CSVWidget::SceneToolToggle::getSelectionMask() const
{ {
unsigned int selection = 0; unsigned int selection = 0;
for (std::map<PushButton *, ButtonDesc>::const_iterator iter (mButtons.begin()); for (std::map<PushButton *, ButtonDesc>::const_iterator iter (mButtons.begin());
iter!=mButtons.end(); ++iter) iter!=mButtons.end(); ++iter)
if (iter->first->isChecked()) if (iter->first->isChecked())
selection |= iter->second.mId; selection |= iter->second.mMask;
return selection; return selection;
} }
void CSVWidget::SceneToolToggle::setSelection (unsigned int selection) void CSVWidget::SceneToolToggle::setSelectionMask (unsigned int selection)
{ {
for (std::map<PushButton *, ButtonDesc>::iterator iter (mButtons.begin()); for (std::map<PushButton *, ButtonDesc>::iterator iter (mButtons.begin());
iter!=mButtons.end(); ++iter) iter!=mButtons.end(); ++iter)
iter->first->setChecked (selection & iter->second.mId); iter->first->setChecked (selection & iter->second.mMask);
adjustToolTip(); adjustToolTip();
adjustIcon(); adjustIcon();

View file

@ -20,7 +20,7 @@ namespace CSVWidget
struct ButtonDesc struct ButtonDesc
{ {
unsigned int mId; unsigned int mMask;
std::string mSmallIcon; std::string mSmallIcon;
QString mName; QString mName;
int mIndex; int mIndex;
@ -54,13 +54,13 @@ namespace CSVWidget
/// \note The layout algorithm can not handle more than 9 buttons. To prevent this An /// \note The layout algorithm can not handle more than 9 buttons. To prevent this An
/// attempt to add more will result in an exception being thrown. /// attempt to add more will result in an exception being thrown.
/// The small icons will be sized at (x-4)/3 (where x is the main icon size). /// The small icons will be sized at (x-4)/3 (where x is the main icon size).
void addButton (const std::string& icon, unsigned int id, void addButton (const std::string& icon, unsigned int mask,
const std::string& smallIcon, const QString& name, const QString& tooltip = ""); const std::string& smallIcon, const QString& name, const QString& tooltip = "");
unsigned int getSelection() const; unsigned int getSelectionMask() const;
/// \param or'ed button IDs. IDs that do not exist will be ignored. /// \param or'ed button masks. buttons that do not exist will be ignored.
void setSelection (unsigned int selection); void setSelectionMask (unsigned int selection);
signals: signals:

View file

@ -41,8 +41,15 @@ void CSVWidget::SceneToolToggle2::adjustToolTip()
void CSVWidget::SceneToolToggle2::adjustIcon() void CSVWidget::SceneToolToggle2::adjustIcon()
{ {
unsigned int buttonIds = 0;
for (std::map<PushButton *, ButtonDesc>::const_iterator iter (mButtons.begin());
iter!=mButtons.end(); ++iter)
if (iter->first->isChecked())
buttonIds |= iter->second.mButtonId;
std::ostringstream stream; std::ostringstream stream;
stream << mCompositeIcon << getSelection(); stream << mCompositeIcon << buttonIds;
setIcon (QIcon (QString::fromUtf8 (stream.str().c_str()))); setIcon (QIcon (QString::fromUtf8 (stream.str().c_str())));
} }
@ -70,7 +77,7 @@ void CSVWidget::SceneToolToggle2::showPanel (const QPoint& position)
mFirst->setFocus (Qt::OtherFocusReason); mFirst->setFocus (Qt::OtherFocusReason);
} }
void CSVWidget::SceneToolToggle2::addButton (unsigned int id, void CSVWidget::SceneToolToggle2::addButton (unsigned int id, unsigned int mask,
const QString& name, const QString& tooltip, bool disabled) const QString& name, const QString& tooltip, bool disabled)
{ {
std::ostringstream stream; std::ostringstream stream;
@ -89,7 +96,8 @@ void CSVWidget::SceneToolToggle2::addButton (unsigned int id,
mLayout->addWidget (button); mLayout->addWidget (button);
ButtonDesc desc; ButtonDesc desc;
desc.mId = id; desc.mButtonId = id;
desc.mMask = mask;
desc.mName = name; desc.mName = name;
desc.mIndex = mButtons.size(); desc.mIndex = mButtons.size();
@ -101,23 +109,23 @@ void CSVWidget::SceneToolToggle2::addButton (unsigned int id,
mFirst = button; mFirst = button;
} }
unsigned int CSVWidget::SceneToolToggle2::getSelection() const unsigned int CSVWidget::SceneToolToggle2::getSelectionMask() const
{ {
unsigned int selection = 0; unsigned int selection = 0;
for (std::map<PushButton *, ButtonDesc>::const_iterator iter (mButtons.begin()); for (std::map<PushButton *, ButtonDesc>::const_iterator iter (mButtons.begin());
iter!=mButtons.end(); ++iter) iter!=mButtons.end(); ++iter)
if (iter->first->isChecked()) if (iter->first->isChecked())
selection |= iter->second.mId; selection |= iter->second.mMask;
return selection; return selection;
} }
void CSVWidget::SceneToolToggle2::setSelection (unsigned int selection) void CSVWidget::SceneToolToggle2::setSelectionMask (unsigned int selection)
{ {
for (std::map<PushButton *, ButtonDesc>::iterator iter (mButtons.begin()); for (std::map<PushButton *, ButtonDesc>::iterator iter (mButtons.begin());
iter!=mButtons.end(); ++iter) iter!=mButtons.end(); ++iter)
iter->first->setChecked (selection & iter->second.mId); iter->first->setChecked (selection & iter->second.mMask);
adjustToolTip(); adjustToolTip();
adjustIcon(); adjustIcon();

View file

@ -22,7 +22,8 @@ namespace CSVWidget
struct ButtonDesc struct ButtonDesc
{ {
unsigned int mId; unsigned int mButtonId;
unsigned int mMask;
QString mName; QString mName;
int mIndex; int mIndex;
}; };
@ -53,15 +54,17 @@ namespace CSVWidget
virtual void showPanel (const QPoint& position); virtual void showPanel (const QPoint& position);
/// \param buttonId used to compose the icon filename
/// \param mask used for the reported getSelectionMask() / setSelectionMask()
/// \attention After the last button has been added, setSelection must be called at /// \attention After the last button has been added, setSelection must be called at
/// least once to finalise the layout. /// least once to finalise the layout.
void addButton (unsigned int id, void addButton (unsigned int buttonId, unsigned int mask,
const QString& name, const QString& tooltip = "", bool disabled = false); const QString& name, const QString& tooltip = "", bool disabled = false);
unsigned int getSelection() const; unsigned int getSelectionMask() const;
/// \param or'ed button IDs. IDs that do not exist will be ignored. /// \param or'ed button masks. buttons that do not exist will be ignored.
void setSelection (unsigned int selection); void setSelectionMask (unsigned int selection);
signals: signals:

View file

@ -3,6 +3,7 @@
#include <components/version/version.hpp> #include <components/version/version.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include <components/fallback/validate.hpp>
#include <SDL_messagebox.h> #include <SDL_messagebox.h>
#include <SDL_main.h> #include <SDL_main.h>
@ -52,39 +53,8 @@ inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string
} /* namespace boost */ } /* namespace boost */
#endif /* (BOOST_VERSION <= 104600) */ #endif /* (BOOST_VERSION <= 104600) */
struct FallbackMap {
std::map<std::string,std::string> mMap;
};
void validate(boost::any &v, std::vector<std::string> const &tokens, FallbackMap*, int)
{
if(v.empty())
{
v = boost::any(FallbackMap());
}
FallbackMap *map = boost::any_cast<FallbackMap>(&v);
for(std::vector<std::string>::const_iterator it=tokens.begin(); it != tokens.end(); ++it)
{
int sep = it->find(",");
if(sep < 1 || sep == (int)it->length()-1)
#if (BOOST_VERSION < 104200)
throw boost::program_options::validation_error("invalid value");
#else
throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value);
#endif
std::string key(it->substr(0,sep));
std::string value(it->substr(sep+1));
if(map->mMap.find(key) == map->mMap.end())
{
map->mMap.insert(std::make_pair (key,value));
}
}
}
using namespace Fallback;
/** /**
* \brief Parses application command line and calls \ref Cfg::ConfigurationManager * \brief Parses application command line and calls \ref Cfg::ConfigurationManager

View file

@ -56,7 +56,6 @@ namespace MWMechanics
namespace MWWorld namespace MWWorld
{ {
class Fallback;
class CellStore; class CellStore;
class Player; class Player;
class LocalScripts; class LocalScripts;
@ -67,6 +66,11 @@ namespace MWWorld
typedef std::vector<std::pair<MWWorld::Ptr,MWMechanics::Movement> > PtrMovementList; typedef std::vector<std::pair<MWWorld::Ptr,MWMechanics::Movement> > PtrMovementList;
} }
namespace Fallback
{
class Map;
}
namespace MWBase namespace MWBase
{ {
/// \brief Interface for the World (implemented in MWWorld) /// \brief Interface for the World (implemented in MWWorld)
@ -119,7 +123,7 @@ namespace MWBase
virtual void adjustSky() = 0; virtual void adjustSky() = 0;
virtual const MWWorld::Fallback *getFallback () const = 0; virtual const Fallback::Map *getFallback () const = 0;
virtual MWWorld::Player& getPlayer() = 0; virtual MWWorld::Player& getPlayer() = 0;
virtual MWWorld::Ptr getPlayerPtr() = 0; virtual MWWorld::Ptr getPlayerPtr() = 0;

View file

@ -1,5 +1,7 @@
#include "charactercreation.hpp" #include "charactercreation.hpp"
#include <components/fallback/fallback.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
@ -10,7 +12,6 @@
#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/actorutil.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/fallback.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "textinput.hpp" #include "textinput.hpp"
@ -32,7 +33,7 @@ namespace
const ESM::Class::Specialization mSpecializations[3]={ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}; // The specialization for each answer const ESM::Class::Specialization mSpecializations[3]={ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}; // The specialization for each answer
Step sGenerateClassSteps(int number) { Step sGenerateClassSteps(int number) {
number++; number++;
const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback(); const Fallback::Map* fallback=MWBase::Environment::get().getWorld()->getFallback();
Step step = {fallback->getFallbackString("Question_"+MyGUI::utility::toString(number)+"_Question"), Step step = {fallback->getFallbackString("Question_"+MyGUI::utility::toString(number)+"_Question"),
{fallback->getFallbackString("Question_"+MyGUI::utility::toString(number)+"_AnswerOne"), {fallback->getFallbackString("Question_"+MyGUI::utility::toString(number)+"_AnswerOne"),
fallback->getFallbackString("Question_"+MyGUI::utility::toString(number)+"_AnswerTwo"), fallback->getFallbackString("Question_"+MyGUI::utility::toString(number)+"_AnswerTwo"),

View file

@ -4,13 +4,14 @@
#include <MyGUI_ImageBox.h> #include <MyGUI_ImageBox.h>
#include <MyGUI_EditBox.h> #include <MyGUI_EditBox.h>
#include <components/fallback/fallback.hpp>
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/fallback.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"

View file

@ -6,7 +6,6 @@
#include <osg/PositionAttitudeTransform> #include <osg/PositionAttitudeTransform>
#include <osg/TexGen> #include <osg/TexGen>
#include <osg/TexEnvCombine> #include <osg/TexEnvCombine>
#include <osg/ComputeBoundsVisitor>
#include <osg/MatrixTransform> #include <osg/MatrixTransform>
#include <osg/Geode> #include <osg/Geode>
#include <osg/BlendFunc> #include <osg/BlendFunc>
@ -30,16 +29,16 @@
#include <components/sceneutil/statesetupdater.hpp> #include <components/sceneutil/statesetupdater.hpp>
#include <components/sceneutil/visitor.hpp> #include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/lightmanager.hpp> #include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/util.hpp> #include <components/sceneutil/lightutil.hpp>
#include <components/sceneutil/lightcontroller.hpp>
#include <components/sceneutil/skeleton.hpp> #include <components/sceneutil/skeleton.hpp>
#include <components/sceneutil/positionattitudetransform.hpp> #include <components/sceneutil/positionattitudetransform.hpp>
#include <components/fallback/fallback.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/fallback.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwmechanics/character.hpp" // FIXME: for MWMechanics::Priority #include "../mwmechanics/character.hpp" // FIXME: for MWMechanics::Priority
@ -1086,38 +1085,7 @@ namespace MWRender
void Animation::addExtraLight(osg::ref_ptr<osg::Group> parent, const ESM::Light *esmLight) void Animation::addExtraLight(osg::ref_ptr<osg::Group> parent, const ESM::Light *esmLight)
{ {
SceneUtil::FindByNameVisitor visitor("AttachLight"); const Fallback::Map* fallback = MWBase::Environment::get().getWorld()->getFallback();
parent->accept(visitor);
osg::Group* attachTo = NULL;
if (visitor.mFoundNode)
{
attachTo = visitor.mFoundNode;
}
else
{
osg::ComputeBoundsVisitor computeBound;
computeBound.setTraversalMask(~Mask_ParticleSystem);
parent->accept(computeBound);
// PositionAttitudeTransform seems to be slightly faster than MatrixTransform
osg::ref_ptr<osg::PositionAttitudeTransform> trans(new osg::PositionAttitudeTransform);
trans->setPosition(computeBound.getBoundingBox().center());
parent->addChild(trans);
attachTo = trans;
}
osg::ref_ptr<SceneUtil::LightSource> lightSource = new SceneUtil::LightSource;
osg::ref_ptr<osg::Light> light (new osg::Light);
lightSource->setNodeMask(Mask_Lighting);
const MWWorld::Fallback* fallback = MWBase::Environment::get().getWorld()->getFallback();
float radius = esmLight->mData.mRadius;
lightSource->setRadius(radius);
static bool outQuadInLin = fallback->getFallbackBool("LightAttenuation_OutQuadInLin"); static bool outQuadInLin = fallback->getFallbackBool("LightAttenuation_OutQuadInLin");
static bool useQuadratic = fallback->getFallbackBool("LightAttenuation_UseQuadratic"); static bool useQuadratic = fallback->getFallbackBool("LightAttenuation_UseQuadratic");
static float quadraticValue = fallback->getFallbackFloat("LightAttenuation_QuadraticValue"); static float quadraticValue = fallback->getFallbackFloat("LightAttenuation_QuadraticValue");
@ -1125,38 +1093,10 @@ namespace MWRender
static bool useLinear = fallback->getFallbackBool("LightAttenuation_UseLinear"); static bool useLinear = fallback->getFallbackBool("LightAttenuation_UseLinear");
static float linearRadiusMult = fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult"); static float linearRadiusMult = fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
static float linearValue = fallback->getFallbackFloat("LightAttenuation_LinearValue"); static float linearValue = fallback->getFallbackFloat("LightAttenuation_LinearValue");
bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior(); bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior();
SceneUtil::configureLight(light, radius, exterior, outQuadInLin, useQuadratic, quadraticValue, SceneUtil::addLight(parent, esmLight, Mask_ParticleSystem, Mask_Lighting, exterior, outQuadInLin,
quadraticRadiusMult, useLinear, linearRadiusMult, linearValue); useQuadratic, quadraticValue, quadraticRadiusMult, useLinear, linearRadiusMult, linearValue);
osg::Vec4f diffuse = SceneUtil::colourFromRGB(esmLight->mData.mColor);
if (esmLight->mData.mFlags & ESM::Light::Negative)
{
diffuse *= -1;
diffuse.a() = 1;
}
light->setDiffuse(diffuse);
light->setAmbient(osg::Vec4f(0,0,0,1));
light->setSpecular(osg::Vec4f(0,0,0,0));
lightSource->setLight(light);
osg::ref_ptr<SceneUtil::LightController> ctrl (new SceneUtil::LightController);
ctrl->setDiffuse(light->getDiffuse());
if (esmLight->mData.mFlags & ESM::Light::Flicker)
ctrl->setType(SceneUtil::LightController::LT_Flicker);
if (esmLight->mData.mFlags & ESM::Light::FlickerSlow)
ctrl->setType(SceneUtil::LightController::LT_FlickerSlow);
if (esmLight->mData.mFlags & ESM::Light::Pulse)
ctrl->setType(SceneUtil::LightController::LT_Pulse);
if (esmLight->mData.mFlags & ESM::Light::PulseSlow)
ctrl->setType(SceneUtil::LightController::LT_PulseSlow);
lightSource->addUpdateCallback(ctrl);
attachTo->addChild(lightSource);
} }
void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, std::string texture) void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, std::string texture)

View file

@ -30,8 +30,8 @@
#include <components/terrain/terraingrid.hpp> #include <components/terrain/terraingrid.hpp>
#include <components/esm/loadcell.hpp> #include <components/esm/loadcell.hpp>
#include <components/fallback/fallback.hpp>
#include "../mwworld/fallback.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "sky.hpp" #include "sky.hpp"
@ -126,7 +126,7 @@ namespace MWRender
}; };
RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem, RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem,
const MWWorld::Fallback* fallback, const std::string& resourcePath) const Fallback::Map* fallback, const std::string& resourcePath)
: mViewer(viewer) : mViewer(viewer)
, mRootNode(rootNode) , mRootNode(rootNode)
, mResourceSystem(resourceSystem) , mResourceSystem(resourceSystem)

View file

@ -37,9 +37,9 @@ namespace Terrain
class World; class World;
} }
namespace MWWorld namespace Fallback
{ {
class Fallback; class Map;
} }
namespace MWRender namespace MWRender
@ -58,7 +58,7 @@ namespace MWRender
{ {
public: public:
RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem, RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem,
const MWWorld::Fallback* fallback, const std::string& resourcePath); const Fallback::Map* fallback, const std::string& resourcePath);
~RenderingManager(); ~RenderingManager();
MWRender::Objects& getObjects(); MWRender::Objects& getObjects();

View file

@ -15,19 +15,18 @@
#include <components/nifosg/controller.hpp> #include <components/nifosg/controller.hpp>
#include <components/resource/texturemanager.hpp> #include <components/resource/texturemanager.hpp>
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/fallback/fallback.hpp>
#include "vismask.hpp" #include "vismask.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwworld/fallback.hpp"
#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/actorutil.hpp"
namespace namespace
{ {
void createWaterRippleStateSet(Resource::ResourceSystem* resourceSystem, const MWWorld::Fallback* fallback, osg::Node* node) void createWaterRippleStateSet(Resource::ResourceSystem* resourceSystem, const Fallback::Map* fallback, osg::Node* node)
{ {
int rippleFrameCount = fallback->getFallbackInt("Water_RippleFrameCount"); int rippleFrameCount = fallback->getFallbackInt("Water_RippleFrameCount");
if (rippleFrameCount <= 0) if (rippleFrameCount <= 0)
@ -78,7 +77,7 @@ namespace
namespace MWRender namespace MWRender
{ {
RippleSimulation::RippleSimulation(osg::Group *parent, Resource::ResourceSystem* resourceSystem, const MWWorld::Fallback* fallback) RippleSimulation::RippleSimulation(osg::Group *parent, Resource::ResourceSystem* resourceSystem, const Fallback::Map* fallback)
: mParent(parent) : mParent(parent)
{ {
osg::ref_ptr<osg::Geode> geode (new osg::Geode); osg::ref_ptr<osg::Geode> geode (new osg::Geode);

View file

@ -21,9 +21,9 @@ namespace Resource
class ResourceSystem; class ResourceSystem;
} }
namespace MWWorld namespace Fallback
{ {
class Fallback; class Map;
} }
namespace MWRender namespace MWRender
@ -40,7 +40,7 @@ namespace MWRender
class RippleSimulation class RippleSimulation
{ {
public: public:
RippleSimulation(osg::Group* parent, Resource::ResourceSystem* resourceSystem, const MWWorld::Fallback* fallback); RippleSimulation(osg::Group* parent, Resource::ResourceSystem* resourceSystem, const Fallback::Map* fallback);
~RippleSimulation(); ~RippleSimulation();
/// @param dt Time since the last frame /// @param dt Time since the last frame

View file

@ -33,6 +33,7 @@
#include <components/resource/texturemanager.hpp> #include <components/resource/texturemanager.hpp>
#include <components/vfs/manager.hpp> #include <components/vfs/manager.hpp>
#include <components/fallback/fallback.hpp>
#include <components/sceneutil/util.hpp> #include <components/sceneutil/util.hpp>
#include <components/sceneutil/statesetupdater.hpp> #include <components/sceneutil/statesetupdater.hpp>
@ -42,8 +43,6 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwworld/fallback.hpp"
#include "vismask.hpp" #include "vismask.hpp"
#include "renderbin.hpp" #include "renderbin.hpp"
@ -827,7 +826,7 @@ private:
, mTimeOfDayFade(1.f) , mTimeOfDayFade(1.f)
, mGlareView(1.f) , mGlareView(1.f)
{ {
const MWWorld::Fallback* fallback = MWBase::Environment::get().getWorld()->getFallback(); const Fallback::Map* fallback = MWBase::Environment::get().getWorld()->getFallback();
mColor = fallback->getFallbackColour("Weather_Sun_Glare_Fader_Color"); mColor = fallback->getFallbackColour("Weather_Sun_Glare_Fader_Color");
mSunGlareFaderMax = fallback->getFallbackFloat("Weather_Sun_Glare_Fader_Max"); mSunGlareFaderMax = fallback->getFallbackFloat("Weather_Sun_Glare_Fader_Max");
mSunGlareFaderAngleMax = fallback->getFallbackFloat("Weather_Sun_Glare_Fader_Angle_Max"); mSunGlareFaderAngleMax = fallback->getFallbackFloat("Weather_Sun_Glare_Fader_Angle_Max");
@ -1161,7 +1160,7 @@ void SkyManager::create()
mSun.reset(new Sun(mEarlyRenderBinRoot, *mSceneManager->getTextureManager())); mSun.reset(new Sun(mEarlyRenderBinRoot, *mSceneManager->getTextureManager()));
const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback(); const Fallback::Map* fallback=MWBase::Environment::get().getWorld()->getFallback();
mMasser.reset(new Moon(mEarlyRenderBinRoot, *mSceneManager->getTextureManager(), fallback->getFallbackFloat("Moons_Masser_Size")/125, Moon::Type_Masser)); mMasser.reset(new Moon(mEarlyRenderBinRoot, *mSceneManager->getTextureManager(), fallback->getFallbackFloat("Moons_Masser_Size")/125, Moon::Type_Masser));
mSecunda.reset(new Moon(mEarlyRenderBinRoot, *mSceneManager->getTextureManager(), fallback->getFallbackFloat("Moons_Secunda_Size")/125, Moon::Type_Secunda)); mSecunda.reset(new Moon(mEarlyRenderBinRoot, *mSceneManager->getTextureManager(), fallback->getFallbackFloat("Moons_Secunda_Size")/125, Moon::Type_Secunda));

View file

@ -5,6 +5,20 @@ namespace MWRender
{ {
/// Node masks used for controlling visibility of game objects. /// Node masks used for controlling visibility of game objects.
/// @par Any node in the OSG scene graph can have a node mask. When traversing the scene graph,
/// the node visitor's traversal mask is bitwise AND'ed with the node mask. If the result of this test is
/// 0, then the node <i>and all its child nodes</i> are not processed.
/// @par Important traversal masks are the camera's cull mask (determines what is visible),
/// the update visitor mask (what is updated) and the intersection visitor mask (what is
/// selectable through mouse clicks or other intersection tests).
/// @par In practice, it can be useful to make a "hierarchy" out of the node masks - e.g. in OpenMW,
/// all 3D rendering nodes are child of a Scene Root node with Mask_Scene. When we do not want 3D rendering,
/// we can just omit Mask_Scene from the traversal mask, and do not need to omit all the individual
/// element masks (water, sky, terrain, etc.) since the traversal will already have stopped at the Scene root node.
/// @par The comments within the VisMask enum should give some hints as to what masks are commonly "child" of
/// another mask, or what type of node this mask is usually set on.
/// @note The mask values are not serialized within models, nor used in any other way that would break backwards
/// compatibility if the enumeration values were to be changed. Feel free to change them when it makes sense.
enum VisMask enum VisMask
{ {
Mask_UpdateVisitor = 0x1, // reserved for separating UpdateVisitors from CullVisitors Mask_UpdateVisitor = 0x1, // reserved for separating UpdateVisitors from CullVisitors
@ -24,8 +38,6 @@ namespace MWRender
Mask_Sun = (1<<10), Mask_Sun = (1<<10),
Mask_WeatherParticles = (1<<11), Mask_WeatherParticles = (1<<11),
// child of Water
// top level masks // top level masks
Mask_Scene = (1<<12), Mask_Scene = (1<<12),
Mask_GUI = (1<<13), Mask_GUI = (1<<13),

View file

@ -34,8 +34,9 @@
#include <components/esm/loadcell.hpp> #include <components/esm/loadcell.hpp>
#include <components/fallback/fallback.hpp>
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/fallback.hpp"
#include "vismask.hpp" #include "vismask.hpp"
#include "ripplesimulation.hpp" #include "ripplesimulation.hpp"
@ -457,7 +458,7 @@ public:
}; };
Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem, osgUtil::IncrementalCompileOperation *ico, Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem, osgUtil::IncrementalCompileOperation *ico,
const MWWorld::Fallback* fallback, const std::string& resourcePath) const Fallback::Map* fallback, const std::string& resourcePath)
: mParent(parent) : mParent(parent)
, mSceneRoot(sceneRoot) , mSceneRoot(sceneRoot)
, mResourceSystem(resourceSystem) , mResourceSystem(resourceSystem)

View file

@ -28,11 +28,15 @@ namespace Resource
namespace MWWorld namespace MWWorld
{ {
class Fallback;
class CellStore; class CellStore;
class Ptr; class Ptr;
} }
namespace Fallback
{
class Map;
}
namespace MWRender namespace MWRender
{ {
@ -50,7 +54,7 @@ namespace MWRender
osg::ref_ptr<osg::PositionAttitudeTransform> mWaterNode; osg::ref_ptr<osg::PositionAttitudeTransform> mWaterNode;
osg::ref_ptr<osg::Geode> mWaterGeode; osg::ref_ptr<osg::Geode> mWaterGeode;
Resource::ResourceSystem* mResourceSystem; Resource::ResourceSystem* mResourceSystem;
const MWWorld::Fallback* mFallback; const Fallback::Map* mFallback;
osg::ref_ptr<osgUtil::IncrementalCompileOperation> mIncrementalCompileOperation; osg::ref_ptr<osgUtil::IncrementalCompileOperation> mIncrementalCompileOperation;
std::auto_ptr<RippleSimulation> mSimulation; std::auto_ptr<RippleSimulation> mSimulation;
@ -77,7 +81,7 @@ namespace MWRender
public: public:
Water(osg::Group* parent, osg::Group* sceneRoot, Water(osg::Group* parent, osg::Group* sceneRoot,
Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico, const MWWorld::Fallback* fallback, Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico, const Fallback::Map* fallback,
const std::string& resourcePath); const std::string& resourcePath);
~Water(); ~Water();

View file

@ -627,7 +627,7 @@ int MWWorld::ContainerStore::getType (const ConstPtr& ptr)
return Type_Weapon; return Type_Weapon;
throw std::runtime_error ( throw std::runtime_error (
"Object of type " + ptr.getTypeName() + " can not be placed into a container"); "Object '" + ptr.getCellRef().getRefId() + "' of type " + ptr.getTypeName() + " can not be placed into a container");
} }
MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id) MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id)

View file

@ -6,6 +6,7 @@
#include <components/esm/esmwriter.hpp> #include <components/esm/esmwriter.hpp>
#include <components/esm/savedgame.hpp> #include <components/esm/savedgame.hpp>
#include <components/esm/weatherstate.hpp> #include <components/esm/weatherstate.hpp>
#include <components/fallback/fallback.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -20,7 +21,6 @@
#include "player.hpp" #include "player.hpp"
#include "esmstore.hpp" #include "esmstore.hpp"
#include "fallback.hpp"
#include "cellstore.hpp" #include "cellstore.hpp"
#include <cmath> #include <cmath>
@ -100,7 +100,7 @@ template class TimeOfDayInterpolator<float>;
template class TimeOfDayInterpolator<osg::Vec4f>; template class TimeOfDayInterpolator<osg::Vec4f>;
Weather::Weather(const std::string& name, Weather::Weather(const std::string& name,
const MWWorld::Fallback& fallback, const Fallback::Map& fallback,
float stormWindSpeed, float stormWindSpeed,
float rainSpeed, float rainSpeed,
const std::string& particleEffect) const std::string& particleEffect)
@ -321,13 +321,17 @@ void RegionWeather::chooseNewWeather()
{ {
sum += mChances[i]; sum += mChances[i];
if(chance <= sum) if(chance <= sum)
break; {
mWeather = i;
return;
}
} }
mWeather = i; // if we hit this path then the chances don't add to 100, choose a default weather instead
mWeather = 0;
} }
MoonModel::MoonModel(const std::string& name, const MWWorld::Fallback& fallback) MoonModel::MoonModel(const std::string& name, const Fallback::Map& fallback)
: mFadeInStart(fallback.getFallbackFloat("Moons_" + name + "_Fade_In_Start")) : mFadeInStart(fallback.getFallbackFloat("Moons_" + name + "_Fade_In_Start"))
, mFadeInFinish(fallback.getFallbackFloat("Moons_" + name + "_Fade_In_Finish")) , mFadeInFinish(fallback.getFallbackFloat("Moons_" + name + "_Fade_In_Finish"))
, mFadeOutStart(fallback.getFallbackFloat("Moons_" + name + "_Fade_Out_Start")) , mFadeOutStart(fallback.getFallbackFloat("Moons_" + name + "_Fade_Out_Start"))
@ -496,7 +500,7 @@ inline float MoonModel::earlyMoonShadowAlpha(float angle) const
return 0.0f; return 0.0f;
} }
WeatherManager::WeatherManager(MWRender::RenderingManager& rendering, const MWWorld::Fallback& fallback, MWWorld::ESMStore& store) WeatherManager::WeatherManager(MWRender::RenderingManager& rendering, const Fallback::Map& fallback, MWWorld::ESMStore& store)
: mStore(store) : mStore(store)
, mRendering(rendering) , mRendering(rendering)
, mSunriseTime(fallback.getFallbackFloat("Weather_Sunrise_Time")) , mSunriseTime(fallback.getFallbackFloat("Weather_Sunrise_Time"))
@ -862,7 +866,7 @@ void WeatherManager::clear()
} }
inline void WeatherManager::addWeather(const std::string& name, inline void WeatherManager::addWeather(const std::string& name,
const MWWorld::Fallback& fallback, const Fallback::Map& fallback,
const std::string& particleEffect) const std::string& particleEffect)
{ {
static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().find("fStromWindSpeed")->getFloat(); static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().find("fStromWindSpeed")->getFloat();

View file

@ -29,9 +29,13 @@ namespace Loading
class Listener; class Listener;
} }
namespace Fallback
{
class Map;
}
namespace MWWorld namespace MWWorld
{ {
class Fallback;
class TimeStamp; class TimeStamp;
@ -66,7 +70,7 @@ namespace MWWorld
{ {
public: public:
Weather(const std::string& name, Weather(const std::string& name,
const MWWorld::Fallback& fallback, const Fallback::Map& fallback,
float stormWindSpeed, float stormWindSpeed,
float rainSpeed, float rainSpeed,
const std::string& particleEffect); const std::string& particleEffect);
@ -172,7 +176,7 @@ namespace MWWorld
class MoonModel class MoonModel
{ {
public: public:
MoonModel(const std::string& name, const MWWorld::Fallback& fallback); MoonModel(const std::string& name, const Fallback::Map& fallback);
MWRender::MoonState calculateState(const TimeStamp& gameTime) const; MWRender::MoonState calculateState(const TimeStamp& gameTime) const;
@ -203,7 +207,7 @@ namespace MWWorld
public: public:
// Have to pass fallback and Store, can't use singleton since World isn't fully constructed yet at the time // Have to pass fallback and Store, can't use singleton since World isn't fully constructed yet at the time
WeatherManager(MWRender::RenderingManager& rendering, WeatherManager(MWRender::RenderingManager& rendering,
const MWWorld::Fallback& fallback, const Fallback::Map& fallback,
MWWorld::ESMStore& store); MWWorld::ESMStore& store);
~WeatherManager(); ~WeatherManager();
@ -288,7 +292,7 @@ namespace MWWorld
std::string mPlayingSoundID; std::string mPlayingSoundID;
void addWeather(const std::string& name, void addWeather(const std::string& name,
const MWWorld::Fallback& fallback, const Fallback::Map& fallback,
const std::string& particleEffect = ""); const std::string& particleEffect = "");
void importRegions(); void importRegions();

View file

@ -511,7 +511,7 @@ namespace MWWorld
return 0; return 0;
} }
const MWWorld::Fallback *World::getFallback() const const Fallback::Map *World::getFallback() const
{ {
return &mFallback; return &mFallback;
} }

View file

@ -5,21 +5,20 @@
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <components/settings/settings.hpp>
#include <components/fallback/fallback.hpp>
#include "../mwbase/world.hpp"
#include "ptr.hpp" #include "ptr.hpp"
#include "scene.hpp" #include "scene.hpp"
#include "esmstore.hpp" #include "esmstore.hpp"
#include "cells.hpp" #include "cells.hpp"
#include "localscripts.hpp" #include "localscripts.hpp"
#include "timestamp.hpp" #include "timestamp.hpp"
#include "fallback.hpp"
#include "globals.hpp" #include "globals.hpp"
#include "../mwbase/world.hpp"
#include "contentloader.hpp" #include "contentloader.hpp"
#include <components/settings/settings.hpp>
namespace osg namespace osg
{ {
class Group; class Group;
@ -71,7 +70,7 @@ namespace MWWorld
{ {
Resource::ResourceSystem* mResourceSystem; Resource::ResourceSystem* mResourceSystem;
MWWorld::Fallback mFallback; Fallback::Map mFallback;
MWRender::RenderingManager* mRendering; MWRender::RenderingManager* mRendering;
MWWorld::WeatherManager* mWeatherManager; MWWorld::WeatherManager* mWeatherManager;
@ -210,7 +209,7 @@ namespace MWWorld
virtual void adjustSky(); virtual void adjustSky();
virtual const Fallback *getFallback() const; virtual const Fallback::Map *getFallback() const;
virtual Player& getPlayer(); virtual Player& getPlayer();
virtual MWWorld::Ptr getPlayerPtr(); virtual MWWorld::Ptr getPlayerPtr();

View file

@ -101,7 +101,7 @@ ELSE (WIN32) #Unix
SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "")
ELSE (MYGUI_INCLUDE_DIRS) ELSE (MYGUI_INCLUDE_DIRS)
FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI)
FIND_LIBRARY(MYGUI_LIBRARIES mygui PATHS /usr/lib /usr/local/lib) FIND_LIBRARY(MYGUI_LIBRARIES MyGUIEngine PATHS /usr/local/lib /usr/lib)
SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES})
STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}")
STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}")

View file

@ -45,7 +45,8 @@ add_component_dir (resource
) )
add_component_dir (sceneutil add_component_dir (sceneutil
clone attach lightmanager visitor util statesetupdater controller skeleton riggeometry lightcontroller positionattitudetransform clone attach visitor util statesetupdater controller skeleton riggeometry lightcontroller
lightmanager lightutil positionattitudetransform
# not used yet # not used yet
#workqueue #workqueue
) )
@ -138,6 +139,10 @@ add_component_dir (version
version version
) )
add_component_dir (fallback
fallback validate
)
set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
) )

View file

@ -14,6 +14,8 @@
namespace ESMTerrain namespace ESMTerrain
{ {
const float defaultHeight = -2048;
Storage::Storage(const VFS::Manager *vfs) Storage::Storage(const VFS::Manager *vfs)
: mVFS(vfs) : mVFS(vfs)
{ {
@ -62,7 +64,9 @@ namespace ESMTerrain
return true; return true;
} }
return false; min = defaultHeight;
max = defaultHeight;
return true;
} }
void Storage::fixNormal (osg::Vec3f& normal, int cellX, int cellY, int col, int row) void Storage::fixNormal (osg::Vec3f& normal, int cellX, int cellY, int col, int row)
@ -203,7 +207,7 @@ namespace ESMTerrain
assert (vertX < numVerts); assert (vertX < numVerts);
assert (vertY < numVerts); assert (vertY < numVerts);
float height = -2048; float height = defaultHeight;
if (heightData) if (heightData)
height = heightData->mHeights[col*ESM::Land::LAND_SIZE + row]; height = heightData->mHeights[col*ESM::Land::LAND_SIZE + row];
@ -412,7 +416,7 @@ namespace ESMTerrain
const ESM::Land* land = getLand(cellX, cellY); const ESM::Land* land = getLand(cellX, cellY);
if (!land || !(land->mDataTypes&ESM::Land::DATA_VHGT)) if (!land || !(land->mDataTypes&ESM::Land::DATA_VHGT))
return -2048; return defaultHeight;
// Mostly lifted from Ogre::Terrain::getHeightAtTerrainPosition // Mostly lifted from Ogre::Terrain::getHeightAtTerrainPosition

View file

@ -2,12 +2,12 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
namespace MWWorld namespace Fallback
{ {
Fallback::Fallback(const std::map<std::string,std::string>& fallback):mFallbackMap(fallback) Map::Map(const std::map<std::string,std::string>& fallback):mFallbackMap(fallback)
{} {}
std::string Fallback::getFallbackString(const std::string& fall) const std::string Map::getFallbackString(const std::string& fall) const
{ {
std::map<std::string,std::string>::const_iterator it; std::map<std::string,std::string>::const_iterator it;
if((it = mFallbackMap.find(fall)) == mFallbackMap.end()) if((it = mFallbackMap.find(fall)) == mFallbackMap.end())
@ -16,7 +16,7 @@ namespace MWWorld
} }
return it->second; return it->second;
} }
float Fallback::getFallbackFloat(const std::string& fall) const float Map::getFallbackFloat(const std::string& fall) const
{ {
std::string fallback=getFallbackString(fall); std::string fallback=getFallbackString(fall);
if(fallback.empty()) if(fallback.empty())
@ -24,7 +24,7 @@ namespace MWWorld
else else
return boost::lexical_cast<float>(fallback); return boost::lexical_cast<float>(fallback);
} }
int Fallback::getFallbackInt(const std::string& fall) const int Map::getFallbackInt(const std::string& fall) const
{ {
std::string fallback=getFallbackString(fall); std::string fallback=getFallbackString(fall);
if(fallback.empty()) if(fallback.empty())
@ -33,7 +33,7 @@ namespace MWWorld
return boost::lexical_cast<int>(fallback); return boost::lexical_cast<int>(fallback);
} }
bool Fallback::getFallbackBool(const std::string& fall) const bool Map::getFallbackBool(const std::string& fall) const
{ {
std::string fallback=getFallbackString(fall); std::string fallback=getFallbackString(fall);
if(fallback.empty()) if(fallback.empty())
@ -41,7 +41,7 @@ namespace MWWorld
else else
return boost::lexical_cast<bool>(fallback); return boost::lexical_cast<bool>(fallback);
} }
osg::Vec4f Fallback::getFallbackColour(const std::string& fall) const osg::Vec4f Map::getFallbackColour(const std::string& fall) const
{ {
std::string sum=getFallbackString(fall); std::string sum=getFallbackString(fall);
if(sum.empty()) if(sum.empty())

View file

@ -1,18 +1,21 @@
#ifndef GAME_MWWORLD_FALLBACK_H #ifndef OPENMW_COMPONENTS_FALLBACK_H
#define GAME_MWWORLD_FALLBACK_H #define OPENMW_COMPONENTS_FALLBACK_H
#include <map> #include <map>
#include <string> #include <string>
#include <osg/Vec4f> #include <osg/Vec4f>
namespace MWWorld namespace Fallback
{ {
class Fallback /// @brief contains settings imported from the Morrowind INI file.
class Map
{ {
const std::map<std::string,std::string> mFallbackMap; std::map<std::string,std::string> mFallbackMap;
public: public:
Fallback(const std::map<std::string,std::string>& fallback); Map(const std::map<std::string,std::string>& fallback);
Map() {}
std::string getFallbackString(const std::string& fall) const; std::string getFallbackString(const std::string& fall) const;
float getFallbackFloat(const std::string& fall) const; float getFallbackFloat(const std::string& fall) const;
int getFallbackInt(const std::string& fall) const; int getFallbackInt(const std::string& fall) const;

View file

@ -0,0 +1,48 @@
#ifndef OPENMW_COMPONENTS_FALLBACK_VALIDATE_H
#define OPENMW_COMPONENTS_FALLBACK_VALIDATE_H
#include <boost/program_options.hpp>
// Parses and validates a fallback map from boost program_options.
// Note: for boost to pick up the validate function, you need to pull in the namespace e.g.
// by using namespace Fallback;
namespace Fallback
{
struct FallbackMap {
std::map<std::string,std::string> mMap;
};
void validate(boost::any &v, std::vector<std::string> const &tokens, FallbackMap*, int)
{
if(v.empty())
{
v = boost::any(FallbackMap());
}
FallbackMap *map = boost::any_cast<FallbackMap>(&v);
for(std::vector<std::string>::const_iterator it=tokens.begin(); it != tokens.end(); ++it)
{
int sep = it->find(",");
if(sep < 1 || sep == (int)it->length()-1)
#if (BOOST_VERSION < 104200)
throw boost::program_options::validation_error("invalid value");
#else
throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value);
#endif
std::string key(it->substr(0,sep));
std::string value(it->substr(sep+1));
if(map->mMap.find(key) == map->mMap.end())
{
map->mMap.insert(std::make_pair (key,value));
}
}
}
}
#endif

View file

@ -309,8 +309,15 @@ namespace SceneUtil
const osg::RefMatrix* viewMatrix = cv->getCurrentRenderStage()->getInitialViewMatrix(); const osg::RefMatrix* viewMatrix = cv->getCurrentRenderStage()->getInitialViewMatrix();
const std::vector<LightManager::LightSourceViewBound>& lights = mLightManager->getLightsInViewSpace(cv->getCurrentCamera(), viewMatrix); const std::vector<LightManager::LightSourceViewBound>& lights = mLightManager->getLightsInViewSpace(cv->getCurrentCamera(), viewMatrix);
// we do the intersections in view space // get the node bounds in view space
osg::BoundingSphere nodeBound = node->getBound(); // NB do not node->getBound() * modelView, that would apply the node's transformation twice
osg::BoundingSphere nodeBound;
osg::Group* group = node->asGroup();
if (group)
{
for (unsigned int i=0; i<group->getNumChildren(); ++i)
nodeBound.expandBy(group->getChild(i)->getBound());
}
osg::Matrixf mat = *cv->getModelViewMatrix(); osg::Matrixf mat = *cv->getModelViewMatrix();
transformBoundingSphere(mat, nodeBound); transformBoundingSphere(mat, nodeBound);
@ -371,28 +378,4 @@ namespace SceneUtil
traverse(node, nv); traverse(node, nv);
} }
void configureLight(osg::Light *light, float radius, bool isExterior, bool outQuadInLin, bool useQuadratic,
float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult, float linearValue)
{
bool quadratic = useQuadratic && (!outQuadInLin || isExterior);
float quadraticAttenuation = 0;
float linearAttenuation = 0;
if (quadratic)
{
float r = radius * quadraticRadiusMult;
quadraticAttenuation = quadraticValue / std::pow(r, 2);
}
if (useLinear)
{
float r = radius * linearRadiusMult;
linearAttenuation = linearValue / r;
}
light->setLinearAttenuation(linearAttenuation);
light->setQuadraticAttenuation(quadraticAttenuation);
light->setConstantAttenuation(0.f);
}
} }

View file

@ -168,10 +168,6 @@ namespace SceneUtil
LightManager::LightList mLightList; LightManager::LightList mLightList;
}; };
/// @brief Configures a light's attenuation according to vanilla Morrowind attenuation settings.
void configureLight(osg::Light* light, float radius, bool isExterior, bool outQuadInLin, bool useQuadratic, float quadraticValue,
float quadraticRadiusMult, bool useLinear, float linearRadiusMult, float linearValue);
} }
#endif #endif

View file

@ -0,0 +1,109 @@
#include "lightutil.hpp"
#include <osg/Light>
#include <osg/Group>
#include <osg/ComputeBoundsVisitor>
#include <components/esm/loadligh.hpp>
#include "lightmanager.hpp"
#include "lightcontroller.hpp"
#include "util.hpp"
#include "visitor.hpp"
#include "positionattitudetransform.hpp"
namespace SceneUtil
{
void configureLight(osg::Light *light, float radius, bool isExterior, bool outQuadInLin, bool useQuadratic,
float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult, float linearValue)
{
bool quadratic = useQuadratic && (!outQuadInLin || isExterior);
float quadraticAttenuation = 0;
float linearAttenuation = 0;
if (quadratic)
{
float r = radius * quadraticRadiusMult;
quadraticAttenuation = quadraticValue / std::pow(r, 2);
}
if (useLinear)
{
float r = radius * linearRadiusMult;
linearAttenuation = linearValue / r;
}
light->setLinearAttenuation(linearAttenuation);
light->setQuadraticAttenuation(quadraticAttenuation);
light->setConstantAttenuation(0.f);
}
void addLight (osg::Group* node, const ESM::Light* esmLight, unsigned int partsysMask, unsigned int lightMask, bool isExterior, bool outQuadInLin, bool useQuadratic,
float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult,
float linearValue)
{
SceneUtil::FindByNameVisitor visitor("AttachLight");
node->accept(visitor);
osg::Group* attachTo = NULL;
if (visitor.mFoundNode)
{
attachTo = visitor.mFoundNode;
}
else
{
osg::ComputeBoundsVisitor computeBound;
computeBound.setTraversalMask(~partsysMask);
// We want the bounds of all children of the node, ignoring the node's local transformation
// So do a traverse(), not accept()
computeBound.traverse(*node);
// PositionAttitudeTransform seems to be slightly faster than MatrixTransform
osg::ref_ptr<SceneUtil::PositionAttitudeTransform> trans(new SceneUtil::PositionAttitudeTransform);
trans->setPosition(computeBound.getBoundingBox().center());
node->addChild(trans);
attachTo = trans;
}
osg::ref_ptr<SceneUtil::LightSource> lightSource (new SceneUtil::LightSource);
osg::ref_ptr<osg::Light> light (new osg::Light);
lightSource->setNodeMask(lightMask);
float radius = esmLight->mData.mRadius;
lightSource->setRadius(radius);
configureLight(light, radius, isExterior, outQuadInLin, useQuadratic, quadraticValue,
quadraticRadiusMult, useLinear, linearRadiusMult, linearValue);
osg::Vec4f diffuse = SceneUtil::colourFromRGB(esmLight->mData.mColor);
if (esmLight->mData.mFlags & ESM::Light::Negative)
{
diffuse *= -1;
diffuse.a() = 1;
}
light->setDiffuse(diffuse);
light->setAmbient(osg::Vec4f(0,0,0,1));
light->setSpecular(osg::Vec4f(0,0,0,0));
lightSource->setLight(light);
osg::ref_ptr<SceneUtil::LightController> ctrl (new SceneUtil::LightController);
ctrl->setDiffuse(light->getDiffuse());
if (esmLight->mData.mFlags & ESM::Light::Flicker)
ctrl->setType(SceneUtil::LightController::LT_Flicker);
if (esmLight->mData.mFlags & ESM::Light::FlickerSlow)
ctrl->setType(SceneUtil::LightController::LT_FlickerSlow);
if (esmLight->mData.mFlags & ESM::Light::Pulse)
ctrl->setType(SceneUtil::LightController::LT_Pulse);
if (esmLight->mData.mFlags & ESM::Light::PulseSlow)
ctrl->setType(SceneUtil::LightController::LT_PulseSlow);
lightSource->addUpdateCallback(ctrl);
attachTo->addChild(lightSource);
}
}

View file

@ -0,0 +1,32 @@
#ifndef OPENMW_COMPONENTS_LIGHTUTIL_H
#define OPENMW_COMPONENTS_LIGHTUTIL_H
namespace osg
{
class Group;
}
namespace ESM
{
class Light;
}
namespace SceneUtil
{
/// @brief Convert an ESM::Light to a SceneUtil::LightSource, and add it to a sub graph.
/// @note If the sub graph contains a node named "AttachLight" (case insensitive), then the light is added to that.
/// Otherwise, the light is added in the center of the node's bounds.
/// @param node The sub graph to add a light to
/// @param esmLight The light definition coming from the game files containing radius, color, flicker, etc.
/// @param partsysMask Node mask to ignore when computing the sub graph's bounding box.
/// @param lightMask Mask to assign to the newly created LightSource.
/// @param isExterior Is the light outside? May be used for deciding which attenuation settings to use.
/// @par Attenuation parameters come from the game INI file.
void addLight (osg::Group* node, const ESM::Light* esmLight, unsigned int partsysMask, unsigned int lightMask, bool isExterior, bool outQuadInLin, bool useQuadratic,
float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult,
float linearValue);
}
#endif