Merge branch 'master' into buttons

Conflicts:
	apps/opencs/view/render/instancemode.cpp
coverity_scan
Marc Zinnschlag 9 years ago
commit 4a02563708

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

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

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

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

@ -8,6 +8,8 @@
#include <components/vfs/manager.hpp>
#include <components/vfs/registerarchives.hpp>
#include <components/fallback/validate.hpp>
#include <components/nifosg/nifloader.hpp>
#include "model/doc/document.hpp"
@ -17,6 +19,8 @@
#include <Windows.h>
#endif
using namespace Fallback;
CS::Editor::Editor ()
: mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr),
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"))
("fallback-archive", boost::program_options::value<std::vector<std::string> >()->
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>(), "")
->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)
@ -114,6 +120,8 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>());
mDocumentManager.setFallbackMap (variables["fallback"].as<FallbackMap>().mMap);
if (variables["script-blacklist-use"].as<bool>())
mDocumentManager.setBlacklistedScripts (
variables["script-blacklist"].as<std::vector<std::string> >());

File diff suppressed because it is too large Load Diff

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

@ -64,7 +64,7 @@ CSMDoc::Document *CSMDoc::DocumentManager::makeDocument (
const std::vector< boost::filesystem::path >& files,
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)
@ -100,6 +100,11 @@ void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& par
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)
{
mEncoding = encoding;

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

@ -394,10 +394,6 @@ void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages)
CSMWorld::Land record = land.get();
writer.startRecord (record.sRecordId);
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);
}
}

@ -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";
}
}

@ -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

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

@ -59,9 +59,10 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
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),
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;
@ -1201,3 +1202,8 @@ const VFS::Manager* CSMWorld::Data::getVFS() const
{
return mResourcesManager.getVFS();
}
const Fallback::Map* CSMWorld::Data::getFallbackMap() const
{
return mFallbackMap;
}

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

File diff suppressed because it is too large Load Diff

@ -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

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

@ -11,7 +11,7 @@
#include "../../model/world/refcollection.hpp"
#include "../../model/world/cellcoordinates.hpp"
#include "elements.hpp"
#include "mask.hpp"
#include "terrainstorage.hpp"
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))
{
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,
esmLand.mY);
}
@ -230,7 +230,7 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int
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());
iter!=mObjects.end(); ++iter)

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

@ -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

@ -9,17 +9,19 @@
#include "../../model/world/idtree.hpp"
#include "../../model/world/commands.hpp"
#include "../widget/scenetoolbar.hpp"
#include "../widget/scenetoolmode.hpp"
#include "elements.hpp"
#include "mask.hpp"
#include "object.hpp"
#include "worldspacewidget.hpp"
#include "pagedworldspacewidget.hpp"
#include "instanceselectionmode.hpp"
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)
{
}
@ -91,7 +93,7 @@ void CSVRender::InstanceMode::secondaryEditPressed (osg::ref_ptr<TagBase> tag)
void CSVRender::InstanceMode::primarySelectPressed (osg::ref_ptr<TagBase> tag)
{
getWorldspaceWidget().clearSelection (Element_Reference);
getWorldspaceWidget().clearSelection (Mask_Reference);
if (tag)
{

@ -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

@ -17,9 +17,11 @@
#include "../../model/world/refidcollection.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
{
@ -39,7 +41,7 @@ namespace
CSVRender::ObjectTag::ObjectTag (Object* object)
: TagBase (Element_Reference), mObject (object)
: TagBase (Mask_Reference), mObject (object)
{}
QString CSVRender::ObjectTag::getToolTip (bool hideBasics) const
@ -62,6 +64,7 @@ void CSVRender::Object::update()
const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables();
int index = referenceables.searchId (mReferenceableId);
const ESM::Light* light = NULL;
if (index==-1)
error = 1;
@ -73,6 +76,14 @@ void CSVRender::Object::update()
referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Model)).
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())
error = 2;
}
@ -97,6 +108,21 @@ void CSVRender::Object::update()
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()
@ -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)
{
mBaseNode = new osg::PositionAttitudeTransform;
mBaseNode->addCullCallback(new SceneUtil::LightListCallback);
mOutline = new osgFX::Scribe;
mOutline->addChild(mBaseNode);
@ -138,8 +166,7 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
parentNode->addChild(mBaseNode);
// 0x1 reserved for separating cull and update visitors
mBaseNode->setNodeMask(Element_Reference<<1);
mBaseNode->setNodeMask(Mask_Reference);
if (referenceable)
{

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

@ -14,10 +14,12 @@
#include <components/resource/scenemanager.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include "../widget/scenetoolmode.hpp"
#include "lighting.hpp"
#include "mask.hpp"
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()->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_CULL_FACE, osg::StateAttribute::ON);
@ -73,7 +78,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
// Press S to reveal profiling stats
mView->addEventHandler(new osgViewer::StatsHandler);
mView->getCamera()->setCullMask(~(0x1));
mView->getCamera()->setCullMask(~(Mask_UpdateVisitor));
viewer.addView(mView);
viewer.setDone(false);
@ -92,8 +97,7 @@ void RenderWidget::flagAsModified()
void RenderWidget::setVisibilityMask(int mask)
{
// 0x1 reserved for separating cull and update visitors
mView->getCamera()->setCullMask(mask<<1);
mView->getCamera()->setCullMask(mask | Mask_ParticleSystem | Mask_Lighting);
}
bool RenderWidget::eventFilter(QObject* obj, QEvent* event)
@ -167,6 +171,8 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
setLighting(&mLightingDay);
mResourceSystem->getSceneManager()->setParticleSystemMask(Mask_ParticleSystem);
/// \todo make shortcut configurable
QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest()));

@ -1,11 +1,11 @@
#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

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

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

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

@ -11,7 +11,7 @@
#include "../../model/world/tablemimedata.hpp"
#include "scenewidget.hpp"
#include "elements.hpp"
#include "mask.hpp"
namespace CSMPrefs
{
@ -135,13 +135,24 @@ namespace CSVRender
/// \param ignoreHidden ignore elements specified in interactionMask that are
/// flagged as not visible.
osg::Vec3f getIntersectionPoint (const QPoint& localPos,
unsigned int interactionMask = Element_Reference | Element_Terrain,
unsigned int interactionMask = Mask_Reference | Mask_Terrain,
bool ignoreHidden = false) const;
virtual std::string getCellId (const osg::Vec3f& point) const = 0;
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 addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);

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

@ -20,7 +20,7 @@ namespace CSVWidget
struct ButtonDesc
{
unsigned int mId;
unsigned int mMask;
std::string mSmallIcon;
QString mName;
int mIndex;
@ -54,13 +54,13 @@ namespace CSVWidget
/// \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.
/// 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 = "");
unsigned int getSelection() const;
unsigned int getSelectionMask() const;
/// \param or'ed button IDs. IDs that do not exist will be ignored.
void setSelection (unsigned int selection);
/// \param or'ed button masks. buttons that do not exist will be ignored.
void setSelectionMask (unsigned int selection);
signals:

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

@ -22,7 +22,8 @@ namespace CSVWidget
struct ButtonDesc
{
unsigned int mId;
unsigned int mButtonId;
unsigned int mMask;
QString mName;
int mIndex;
};
@ -53,15 +54,17 @@ namespace CSVWidget
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
/// 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);
unsigned int getSelection() const;
unsigned int getSelectionMask() const;
/// \param or'ed button IDs. IDs that do not exist will be ignored.
void setSelection (unsigned int selection);
/// \param or'ed button masks. buttons that do not exist will be ignored.
void setSelectionMask (unsigned int selection);
signals:

@ -3,6 +3,7 @@
#include <components/version/version.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/fallback/validate.hpp>
#include <SDL_messagebox.h>
#include <SDL_main.h>
@ -52,39 +53,8 @@ inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string
} /* namespace boost */
#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

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

@ -1,5 +1,7 @@
#include "charactercreation.hpp"
#include <components/fallback/fallback.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
@ -10,7 +12,6 @@
#include "../mwmechanics/actorutil.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/fallback.hpp"
#include "../mwworld/esmstore.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
Step sGenerateClassSteps(int 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"),
{fallback->getFallbackString("Question_"+MyGUI::utility::toString(number)+"_AnswerOne"),
fallback->getFallbackString("Question_"+MyGUI::utility::toString(number)+"_AnswerTwo"),

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

@ -6,7 +6,6 @@
#include <osg/PositionAttitudeTransform>
#include <osg/TexGen>
#include <osg/TexEnvCombine>
#include <osg/ComputeBoundsVisitor>
#include <osg/MatrixTransform>
#include <osg/Geode>
#include <osg/BlendFunc>
@ -30,16 +29,16 @@
#include <components/sceneutil/statesetupdater.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/util.hpp>
#include <components/sceneutil/lightcontroller.hpp>
#include <components/sceneutil/lightutil.hpp>
#include <components/sceneutil/skeleton.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/fallback/fallback.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/fallback.hpp"
#include "../mwworld/cellstore.hpp"
#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)
{
SceneUtil::FindByNameVisitor visitor("AttachLight");
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);
const Fallback::Map* fallback = MWBase::Environment::get().getWorld()->getFallback();
static bool outQuadInLin = fallback->getFallbackBool("LightAttenuation_OutQuadInLin");
static bool useQuadratic = fallback->getFallbackBool("LightAttenuation_UseQuadratic");
static float quadraticValue = fallback->getFallbackFloat("LightAttenuation_QuadraticValue");
@ -1125,38 +1093,10 @@ namespace MWRender
static bool useLinear = fallback->getFallbackBool("LightAttenuation_UseLinear");
static float linearRadiusMult = fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
static float linearValue = fallback->getFallbackFloat("LightAttenuation_LinearValue");
bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior();
SceneUtil::configureLight(light, radius, exterior, 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);
SceneUtil::addLight(parent, esmLight, Mask_ParticleSystem, Mask_Lighting, exterior, outQuadInLin,
useQuadratic, quadraticValue, quadraticRadiusMult, useLinear, linearRadiusMult, linearValue);
}
void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, std::string texture)

@ -30,8 +30,8 @@
#include <components/terrain/terraingrid.hpp>
#include <components/esm/loadcell.hpp>
#include <components/fallback/fallback.hpp>
#include "../mwworld/fallback.hpp"
#include "../mwworld/cellstore.hpp"
#include "sky.hpp"
@ -126,7 +126,7 @@ namespace MWRender
};
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)
, mRootNode(rootNode)
, mResourceSystem(resourceSystem)

@ -37,9 +37,9 @@ namespace Terrain
class World;
}
namespace MWWorld
namespace Fallback
{
class Fallback;
class Map;
}
namespace MWRender
@ -58,7 +58,7 @@ namespace MWRender
{
public:
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();
MWRender::Objects& getObjects();

@ -15,19 +15,18 @@
#include <components/nifosg/controller.hpp>
#include <components/resource/texturemanager.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/fallback/fallback.hpp>
#include "vismask.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/fallback.hpp"
#include "../mwmechanics/actorutil.hpp"
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");
if (rippleFrameCount <= 0)
@ -78,7 +77,7 @@ namespace
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)
{
osg::ref_ptr<osg::Geode> geode (new osg::Geode);

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

@ -33,6 +33,7 @@
#include <components/resource/texturemanager.hpp>
#include <components/vfs/manager.hpp>
#include <components/fallback/fallback.hpp>
#include <components/sceneutil/util.hpp>
#include <components/sceneutil/statesetupdater.hpp>
@ -42,8 +43,6 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/fallback.hpp"
#include "vismask.hpp"
#include "renderbin.hpp"
@ -827,7 +826,7 @@ private:
, mTimeOfDayFade(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");
mSunGlareFaderMax = fallback->getFallbackFloat("Weather_Sun_Glare_Fader_Max");
mSunGlareFaderAngleMax = fallback->getFallbackFloat("Weather_Sun_Glare_Fader_Angle_Max");
@ -1161,7 +1160,7 @@ void SkyManager::create()
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));
mSecunda.reset(new Moon(mEarlyRenderBinRoot, *mSceneManager->getTextureManager(), fallback->getFallbackFloat("Moons_Secunda_Size")/125, Moon::Type_Secunda));

@ -5,6 +5,20 @@ namespace MWRender
{
/// 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
{
Mask_UpdateVisitor = 0x1, // reserved for separating UpdateVisitors from CullVisitors
@ -24,8 +38,6 @@ namespace MWRender
Mask_Sun = (1<<10),
Mask_WeatherParticles = (1<<11),
// child of Water
// top level masks
Mask_Scene = (1<<12),
Mask_GUI = (1<<13),

@ -34,8 +34,9 @@
#include <components/esm/loadcell.hpp>
#include <components/fallback/fallback.hpp>
#include "../mwworld/cellstore.hpp"
#include "../mwworld/fallback.hpp"
#include "vismask.hpp"
#include "ripplesimulation.hpp"
@ -457,7 +458,7 @@ public:
};
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)
, mSceneRoot(sceneRoot)
, mResourceSystem(resourceSystem)

@ -28,11 +28,15 @@ namespace Resource
namespace MWWorld
{
class Fallback;
class CellStore;
class Ptr;
}
namespace Fallback
{
class Map;
}
namespace MWRender
{
@ -50,7 +54,7 @@ namespace MWRender
osg::ref_ptr<osg::PositionAttitudeTransform> mWaterNode;
osg::ref_ptr<osg::Geode> mWaterGeode;
Resource::ResourceSystem* mResourceSystem;
const MWWorld::Fallback* mFallback;
const Fallback::Map* mFallback;
osg::ref_ptr<osgUtil::IncrementalCompileOperation> mIncrementalCompileOperation;
std::auto_ptr<RippleSimulation> mSimulation;
@ -77,7 +81,7 @@ namespace MWRender
public:
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);
~Water();

@ -627,7 +627,7 @@ int MWWorld::ContainerStore::getType (const ConstPtr& ptr)
return Type_Weapon;
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)

@ -6,6 +6,7 @@
#include <components/esm/esmwriter.hpp>
#include <components/esm/savedgame.hpp>
#include <components/esm/weatherstate.hpp>
#include <components/fallback/fallback.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -20,7 +21,6 @@
#include "player.hpp"
#include "esmstore.hpp"
#include "fallback.hpp"
#include "cellstore.hpp"
#include <cmath>
@ -100,7 +100,7 @@ template class TimeOfDayInterpolator<float>;
template class TimeOfDayInterpolator<osg::Vec4f>;
Weather::Weather(const std::string& name,
const MWWorld::Fallback& fallback,
const Fallback::Map& fallback,
float stormWindSpeed,
float rainSpeed,
const std::string& particleEffect)
@ -321,13 +321,17 @@ void RegionWeather::chooseNewWeather()
{
sum += mChances[i];
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"))
, mFadeInFinish(fallback.getFallbackFloat("Moons_" + name + "_Fade_In_Finish"))
, mFadeOutStart(fallback.getFallbackFloat("Moons_" + name + "_Fade_Out_Start"))
@ -496,7 +500,7 @@ inline float MoonModel::earlyMoonShadowAlpha(float angle) const
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)
, mRendering(rendering)
, mSunriseTime(fallback.getFallbackFloat("Weather_Sunrise_Time"))
@ -862,7 +866,7 @@ void WeatherManager::clear()
}
inline void WeatherManager::addWeather(const std::string& name,
const MWWorld::Fallback& fallback,
const Fallback::Map& fallback,
const std::string& particleEffect)
{
static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().find("fStromWindSpeed")->getFloat();

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

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

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

@ -101,7 +101,7 @@ ELSE (WIN32) #Unix
SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "")
ELSE (MYGUI_INCLUDE_DIRS)
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})
STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}")
STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}")

@ -45,7 +45,8 @@ add_component_dir (resource
)
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
#workqueue
)
@ -138,6 +139,10 @@ add_component_dir (version
version
)
add_component_dir (fallback
fallback validate
)
set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
)

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

@ -2,12 +2,12 @@
#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;
if((it = mFallbackMap.find(fall)) == mFallbackMap.end())
@ -16,7 +16,7 @@ namespace MWWorld
}
return it->second;
}
float Fallback::getFallbackFloat(const std::string& fall) const
float Map::getFallbackFloat(const std::string& fall) const
{
std::string fallback=getFallbackString(fall);
if(fallback.empty())
@ -24,7 +24,7 @@ namespace MWWorld
else
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);
if(fallback.empty())
@ -33,7 +33,7 @@ namespace MWWorld
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);
if(fallback.empty())
@ -41,7 +41,7 @@ namespace MWWorld
else
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);
if(sum.empty())

@ -1,18 +1,21 @@
#ifndef GAME_MWWORLD_FALLBACK_H
#define GAME_MWWORLD_FALLBACK_H
#ifndef OPENMW_COMPONENTS_FALLBACK_H
#define OPENMW_COMPONENTS_FALLBACK_H
#include <map>
#include <string>
#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:
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;
float getFallbackFloat(const std::string& fall) const;
int getFallbackInt(const std::string& fall) const;

@ -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

@ -309,8 +309,15 @@ namespace SceneUtil
const osg::RefMatrix* viewMatrix = cv->getCurrentRenderStage()->getInitialViewMatrix();
const std::vector<LightManager::LightSourceViewBound>& lights = mLightManager->getLightsInViewSpace(cv->getCurrentCamera(), viewMatrix);
// we do the intersections in view space
osg::BoundingSphere nodeBound = node->getBound();
// get the node bounds in view space
// 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();
transformBoundingSphere(mat, nodeBound);
@ -371,28 +378,4 @@ namespace SceneUtil
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);
}
}

@ -168,10 +168,6 @@ namespace SceneUtil
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

@ -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);
}
}

@ -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
Loading…
Cancel
Save