Add OpenMW commits up to 19 Feb 2020

# Conflicts:
#	apps/openmw/mwworld/scene.cpp
pull/558/head
David Cernat 5 years ago
commit 85fb1d1a0b

@ -192,10 +192,15 @@
Bug #5239: OpenMW-CS does not support non-ASCII characters in path names
Bug #5241: On-self absorb spells cannot be detected
Bug #5242: ExplodeSpell behavior differs from Cast behavior
Bug #5246: Water ripples persist after cell change
Bug #5249: Wandering NPCs start walking too soon after they hello
Bug #5250: Creatures display shield ground mesh instead of shield body part
Bug #5255: "GetTarget, player" doesn't return 1 during NPC hello
Bug #5261: Creatures can sometimes become stuck playing idles and never wander again
Bug #5264: "Damage Fatigue" Magic Effect Can Bring Fatigue below 0
Bug #5269: Editor: Cell lighting in resaved cleaned content files is corrupted
Bug #5278: Console command Show doesn't fall back to global variable after local var not found
Feature #1415: Infinite fall failsafe
Feature #1774: Handle AvoidNode
Feature #2229: Improve pathfinding AI
Feature #3025: Analogue gamepad movement controls

@ -534,10 +534,18 @@ void Record<ESM::Cell>::print()
if (mData.mData.mFlags & ESM::Cell::Interior &&
!(mData.mData.mFlags & ESM::Cell::QuasiEx))
{
std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl;
std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl;
std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl;
std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl;
if (mData.hasAmbient())
{
// TODO: see if we can change the integer representation to something more sensible
std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl;
std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl;
std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl;
std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl;
}
else
{
std::cout << " No Ambient Information" << std::endl;
}
std::cout << " Water Level: " << mData.mWater << std::endl;
}
else

@ -89,6 +89,7 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game");
loadSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game");
}
loadSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game");
// Input Settings
loadSettingBool(grabCursorCheckBox, "grab cursor", "Input");
@ -152,6 +153,7 @@ void Launcher::AdvancedPage::saveSettings()
saveSettingBool(animSourcesCheckBox, "use additional anim sources", "Game");
saveSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game");
saveSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game");
saveSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game");
// Input Settings
saveSettingBool(grabCursorCheckBox, "grab cursor", "Input");

@ -97,10 +97,6 @@ opencs_units_noqt (view/render
cellarrow cellmarker cellborder pathgrid
)
opencs_hdrs_noqt (view/render
mask
)
opencs_units (view/tools
reportsubview reporttable searchsubview searchbox merge

@ -867,6 +867,8 @@ namespace CSMWorld
switch (subColIndex)
{
case 0: return isInterior;
// While the ambient information is not necessarily valid if the subrecord wasn't loaded,
// the user should still be allowed to edit it
case 1: return (isInterior && !behaveLikeExterior) ?
cell.mAmbi.mAmbient : QVariant(QVariant::UserType);
case 2: return (isInterior && !behaveLikeExterior) ?
@ -912,7 +914,10 @@ namespace CSMWorld
case 1:
{
if (isInterior && !behaveLikeExterior)
{
cell.mAmbi.mAmbient = static_cast<int32_t>(value.toInt());
cell.setHasAmbient(true);
}
else
return; // return without saving
break;
@ -920,7 +925,10 @@ namespace CSMWorld
case 2:
{
if (isInterior && !behaveLikeExterior)
{
cell.mAmbi.mSunlight = static_cast<int32_t>(value.toInt());
cell.setHasAmbient(true);
}
else
return; // return without saving
break;
@ -928,7 +936,10 @@ namespace CSMWorld
case 3:
{
if (isInterior && !behaveLikeExterior)
{
cell.mAmbi.mFog = static_cast<int32_t>(value.toInt());
cell.setHasAmbient(true);
}
else
return; // return without saving
break;
@ -936,7 +947,10 @@ namespace CSMWorld
case 4:
{
if (isInterior && !behaveLikeExterior)
{
cell.mAmbi.mFogDensity = value.toFloat();
cell.setHasAmbient(true);
}
else
return; // return without saving
break;

@ -9,6 +9,7 @@
#include <components/esm/loadcell.hpp>
#include <components/esm/loadland.hpp>
#include <components/sceneutil/pathgridutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/terrain/terraingrid.hpp>
#include "../../model/world/idtable.hpp"
@ -21,7 +22,6 @@
#include "cellborder.hpp"
#include "cellarrow.hpp"
#include "cellmarker.hpp"
#include "mask.hpp"
#include "pathgrid.hpp"
#include "terrainstorage.hpp"
#include "object.hpp"
@ -92,7 +92,7 @@ bool CSVRender::Cell::addObjects (int start, int end)
std::unique_ptr<Object> object (new Object (mData, mCellNode, id, false));
if (mSubModeElementMask & Mask_Reference)
if (mSubModeElementMask & SceneUtil::Mask_EditorReference)
object->setSubMode (mSubMode);
mObjects.insert (std::make_pair (id, object.release()));
@ -134,7 +134,7 @@ void CSVRender::Cell::updateLand()
else
{
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, mCellNode,
mData.getResourceSystem().get(), mTerrainStorage, Mask_Terrain));
mData.getResourceSystem().get(), mTerrainStorage));
}
mTerrain->loadCell(esmLand.mX, esmLand.mY);
@ -434,7 +434,7 @@ void CSVRender::Cell::reloadAssets()
void CSVRender::Cell::setSelection (int elementMask, Selection mode)
{
if (elementMask & Mask_Reference)
if (elementMask & SceneUtil::Mask_EditorReference)
{
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
@ -451,7 +451,7 @@ void CSVRender::Cell::setSelection (int elementMask, Selection mode)
iter->second->setSelected (selected);
}
}
if (mPathgrid && elementMask & Mask_Pathgrid)
if (mPathgrid && elementMask & SceneUtil::Mask_Pathgrid)
{
// Only one pathgrid may be selected, so some operations will only have an effect
// if the pathgrid is already focused
@ -546,12 +546,12 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getSelection (un
{
std::vector<osg::ref_ptr<TagBase> > result;
if (elementMask & Mask_Reference)
if (elementMask & SceneUtil::Mask_EditorReference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
if (iter->second->getSelected())
result.push_back (iter->second->getTag());
if (mPathgrid && elementMask & Mask_Pathgrid)
if (mPathgrid && elementMask & SceneUtil::Mask_Pathgrid)
if (mPathgrid->isSelected())
result.push_back(mPathgrid->getTag());
@ -562,7 +562,7 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getEdited (unsig
{
std::vector<osg::ref_ptr<TagBase> > result;
if (elementMask & Mask_Reference)
if (elementMask & SceneUtil::Mask_EditorReference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
if (iter->second->isEdited())
@ -576,7 +576,7 @@ void CSVRender::Cell::setSubMode (int subMode, unsigned int elementMask)
mSubMode = subMode;
mSubModeElementMask = elementMask;
if (elementMask & Mask_Reference)
if (elementMask & SceneUtil::Mask_EditorReference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
iter->second->setSubMode (subMode);
@ -584,10 +584,10 @@ void CSVRender::Cell::setSubMode (int subMode, unsigned int elementMask)
void CSVRender::Cell::reset (unsigned int elementMask)
{
if (elementMask & Mask_Reference)
if (elementMask & SceneUtil::Mask_EditorReference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
iter->second->reset();
if (mPathgrid && elementMask & Mask_Pathgrid)
if (mPathgrid && elementMask & SceneUtil::Mask_Pathgrid)
mPathgrid->resetIndicators();
}

@ -11,11 +11,10 @@
#include "../../model/prefs/shortcutmanager.hpp"
#include <components/misc/constants.hpp>
#include "mask.hpp"
#include <components/sceneutil/vismask.hpp>
CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow)
: TagBase (Mask_CellArrow), mArrow (arrow)
: TagBase (SceneUtil::Mask_EditorCellArrow), mArrow (arrow)
{}
CSVRender::CellArrow *CSVRender::CellArrowTag::getCellArrow() const
@ -175,7 +174,7 @@ CSVRender::CellArrow::CellArrow (osg::Group *cellNode, Direction direction,
mParentNode->addChild (mBaseNode);
mBaseNode->setNodeMask (Mask_CellArrow);
mBaseNode->setNodeMask (SceneUtil::Mask_EditorCellArrow);
adjustTransform();
buildShape();

@ -7,8 +7,7 @@
#include <osg/PrimitiveSet>
#include <components/esm/loadland.hpp>
#include "mask.hpp"
#include <components/sceneutil/vismask.hpp>
#include "../../model/world/cellcoordinates.hpp"
@ -20,7 +19,7 @@ CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoor
: mParentNode(cellNode)
{
mBaseNode = new osg::PositionAttitudeTransform();
mBaseNode->setNodeMask(Mask_CellBorder);
mBaseNode->setNodeMask(SceneUtil::Mask_EditorCellBorder);
mBaseNode->setPosition(osg::Vec3f(coords.getX() * CellSize, coords.getY() * CellSize, 10));
mParentNode->addChild(mBaseNode);

@ -8,7 +8,7 @@
#include <components/misc/constants.hpp>
CSVRender::CellMarkerTag::CellMarkerTag(CellMarker *marker)
: TagBase(Mask_CellMarker), mMarker(marker)
: TagBase(SceneUtil::Mask_EditorCellMarker), mMarker(marker)
{}
CSVRender::CellMarker *CSVRender::CellMarkerTag::getCellMarker() const
@ -79,7 +79,7 @@ CSVRender::CellMarker::CellMarker(
mMarkerNode->getOrCreateStateSet()->setAttribute(mat);
mMarkerNode->setUserData(new CellMarkerTag(this));
mMarkerNode->setNodeMask(Mask_CellMarker);
mMarkerNode->setNodeMask(SceneUtil::Mask_EditorCellMarker);
mCellNode->addChild(mMarkerNode);

@ -11,12 +11,12 @@
#include <components/resource/imagemanager.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/sceneutil/waterutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../../model/world/cell.hpp"
#include "../../model/world/cellcoordinates.hpp"
#include "../../model/world/data.hpp"
#include "mask.hpp"
namespace CSVRender
{
@ -38,7 +38,7 @@ namespace CSVRender
mWaterTransform->setPosition(osg::Vec3f(cellCoords.getX() * CellSize + CellSize / 2.f,
cellCoords.getY() * CellSize + CellSize / 2.f, 0));
mWaterTransform->setNodeMask(Mask_Water);
mWaterTransform->setNodeMask(SceneUtil::Mask_Water);
mParentNode->addChild(mWaterTransform);
mWaterNode = new osg::Geode();

@ -14,7 +14,7 @@
#include "../widget/scenetoolbar.hpp"
#include "../widget/scenetoolmode.hpp"
#include "mask.hpp"
#include <components/sceneutil/vismask.hpp>
#include "object.hpp"
#include "worldspacewidget.hpp"
@ -90,7 +90,7 @@ osg::Vec3f CSVRender::InstanceMode::getScreenCoords(const osg::Vec3f& pos)
}
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
: EditMode (worldspaceWidget, QIcon (":scenetoolbar/editing-instance"), Mask_Reference | Mask_Terrain, "Instance editing",
: EditMode (worldspaceWidget, QIcon (":scenetoolbar/editing-instance"), SceneUtil::Mask_EditorReference | SceneUtil::Mask_Terrain, "Instance editing",
parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None),
mDragAxis (-1), mLocked (false), mUnitScaleDist(1)
{
@ -137,13 +137,13 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
std::string subMode = mSubMode->getCurrentId();
getWorldspaceWidget().setSubMode (getSubModeFromId (subMode), Mask_Reference);
getWorldspaceWidget().setSubMode (getSubModeFromId (subMode), SceneUtil::Mask_EditorReference);
}
void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar)
{
mDragMode = DragMode_None;
getWorldspaceWidget().reset (Mask_Reference);
getWorldspaceWidget().reset (SceneUtil::Mask_EditorReference);
if (mSelectionMode)
{
@ -196,7 +196,7 @@ void CSVRender::InstanceMode::secondaryEditPressed (const WorldspaceHitResult& h
void CSVRender::InstanceMode::primarySelectPressed (const WorldspaceHitResult& hit)
{
getWorldspaceWidget().clearSelection (Mask_Reference);
getWorldspaceWidget().clearSelection (SceneUtil::Mask_EditorReference);
if (hit.tag)
{
@ -231,13 +231,13 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos)
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Reference);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_EditorReference);
if (selection.empty())
{
// Only change selection at the start of drag if no object is already selected
if (hit.tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
{
getWorldspaceWidget().clearSelection (Mask_Reference);
getWorldspaceWidget().clearSelection (SceneUtil::Mask_EditorReference);
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (hit.tag.get()))
{
CSVRender::Object* object = objectTag->mObject;
@ -245,7 +245,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos)
}
}
selection = getWorldspaceWidget().getSelection (Mask_Reference);
selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_EditorReference);
if (selection.empty())
return false;
}
@ -271,7 +271,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos)
mDragMode = DragMode_Scale;
// Calculate scale factor
std::vector<osg::ref_ptr<TagBase> > editedSelection = getWorldspaceWidget().getEdited (Mask_Reference);
std::vector<osg::ref_ptr<TagBase> > editedSelection = getWorldspaceWidget().getEdited (SceneUtil::Mask_EditorReference);
osg::Vec3f center = getScreenCoords(getSelectionCenter(editedSelection));
int widgetHeight = getWorldspaceWidget().height();
@ -307,7 +307,7 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou
osg::Vec3f offset;
osg::Quat rotation;
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getEdited (Mask_Reference);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getEdited (SceneUtil::Mask_EditorReference);
if (mDragMode == DragMode_Move)
{
@ -464,7 +464,7 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou
void CSVRender::InstanceMode::dragCompleted(const QPoint& pos)
{
std::vector<osg::ref_ptr<TagBase> > selection =
getWorldspaceWidget().getEdited (Mask_Reference);
getWorldspaceWidget().getEdited (SceneUtil::Mask_EditorReference);
QUndoStack& undoStack = getWorldspaceWidget().getDocument().getUndoStack();
@ -496,7 +496,7 @@ void CSVRender::InstanceMode::dragCompleted(const QPoint& pos)
void CSVRender::InstanceMode::dragAborted()
{
getWorldspaceWidget().reset (Mask_Reference);
getWorldspaceWidget().reset (SceneUtil::Mask_EditorReference);
mDragMode = DragMode_None;
}
@ -515,7 +515,7 @@ void CSVRender::InstanceMode::dragWheel (int diff, double speedFactor)
offset *= diff * speedFactor;
std::vector<osg::ref_ptr<TagBase> > selection =
getWorldspaceWidget().getEdited (Mask_Reference);
getWorldspaceWidget().getEdited (SceneUtil::Mask_EditorReference);
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin());
iter!=selection.end(); ++iter)
@ -657,5 +657,5 @@ void CSVRender::InstanceMode::subModeChanged (const std::string& id)
{
mSubModeId = id;
getWorldspaceWidget().abortDrag();
getWorldspaceWidget().setSubMode (getSubModeFromId (id), Mask_Reference);
getWorldspaceWidget().setSubMode (getSubModeFromId (id), SceneUtil::Mask_EditorReference);
}

@ -6,13 +6,15 @@
#include "../../model/world/idtable.hpp"
#include "../../model/world/commands.hpp"
#include <components/sceneutil/vismask.hpp>
#include "worldspacewidget.hpp"
#include "object.hpp"
namespace CSVRender
{
InstanceSelectionMode::InstanceSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget)
: SelectionMode(parent, worldspaceWidget, Mask_Reference)
: SelectionMode(parent, worldspaceWidget, SceneUtil::Mask_EditorReference)
{
mSelectSame = new QAction("Extend selection to instances with same object ID", this);
mDeleteSelection = new QAction("Delete selected instances", this);
@ -36,12 +38,12 @@ namespace CSVRender
void InstanceSelectionMode::selectSame()
{
getWorldspaceWidget().selectAllWithSameParentId(Mask_Reference);
getWorldspaceWidget().selectAllWithSameParentId(SceneUtil::Mask_EditorReference);
}
void InstanceSelectionMode::deleteSelection()
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection(Mask_Reference);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection(SceneUtil::Mask_EditorReference);
CSMWorld::IdTable& referencesTable = dynamic_cast<CSMWorld::IdTable&>(
*getWorldspaceWidget().getDocument().getData().getTableModel(CSMWorld::UniversalId::Type_References));

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

@ -29,9 +29,9 @@
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/lightutil.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/vismask.hpp>
#include "actor.hpp"
#include "mask.hpp"
const float CSVRender::Object::MarkerShaftWidth = 30;
@ -58,7 +58,7 @@ namespace
CSVRender::ObjectTag::ObjectTag (Object* object)
: TagBase (Mask_Reference), mObject (object)
: TagBase (SceneUtil::Mask_EditorReference), mObject (object)
{}
QString CSVRender::ObjectTag::getToolTip (bool hideBasics) const
@ -140,7 +140,7 @@ void CSVRender::Object::update()
if (light)
{
bool isExterior = false; // FIXME
SceneUtil::addLight(mBaseNode, light, Mask_ParticleSystem, Mask_Lighting, isExterior);
SceneUtil::addLight(mBaseNode, light, isExterior);
}
}
@ -429,7 +429,7 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
parentNode->addChild (mRootNode);
mRootNode->setNodeMask(Mask_Reference);
mRootNode->setNodeMask(SceneUtil::Mask_EditorReference);
if (referenceable)
{

@ -21,7 +21,6 @@
#include "../widget/scenetooltoggle2.hpp"
#include "editmode.hpp"
#include "mask.hpp"
#include "cameracontroller.hpp"
#include "cellarrow.hpp"
#include "terraintexturemode.hpp"
@ -127,8 +126,8 @@ void CSVRender::PagedWorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool)
{
WorldspaceWidget::addVisibilitySelectorButtons (tool);
tool->addButton (Button_Terrain, Mask_Terrain, "Terrain");
tool->addButton (Button_Fog, Mask_Fog, "Fog", "", true);
tool->addButton (Button_Terrain, SceneUtil::Mask_Terrain, "Terrain");
//tool->addButton (Button_Fog, Mask_Fog, "Fog", "", true);
}
void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
@ -142,16 +141,16 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
tool->addButton (
new TerrainTextureMode (this, mRootNode, tool), "terrain-texture");
tool->addButton (
new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain vertex paint editing"),
new EditMode (this, QIcon (":placeholder"), SceneUtil::Mask_EditorReference, "Terrain vertex paint editing"),
"terrain-vertex");
tool->addButton (
new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain movement"),
new EditMode (this, QIcon (":placeholder"), SceneUtil::Mask_EditorReference, "Terrain movement"),
"terrain-move");
}
void CSVRender::PagedWorldspaceWidget::handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type)
{
if (hit.tag && hit.tag->getMask()==Mask_CellArrow)
if (hit.tag && hit.tag->getMask()==SceneUtil::Mask_EditorCellArrow)
{
if (CellArrowTag *cellArrowTag = dynamic_cast<CSVRender::CellArrowTag *> (hit.tag.get()))
{
@ -874,9 +873,9 @@ CSVWidget::SceneToolToggle2 *CSVRender::PagedWorldspaceWidget::makeControlVisibi
mControlElements = new CSVWidget::SceneToolToggle2 (parent,
"Controls & Guides Visibility", ":scenetoolbar/scene-view-marker-c", ":scenetoolbar/scene-view-marker-");
mControlElements->addButton (1, Mask_CellMarker, "Cell Marker");
mControlElements->addButton (2, Mask_CellArrow, "Cell Arrows");
mControlElements->addButton (4, Mask_CellBorder, "Cell Border");
mControlElements->addButton (1, SceneUtil::Mask_EditorCellMarker, "Cell Marker");
mControlElements->addButton (2, SceneUtil::Mask_EditorCellArrow, "Cell Arrows");
mControlElements->addButton (4, SceneUtil::Mask_EditorCellBorder, "Cell Border");
mControlElements->setSelectionMask (0xffffffff);

@ -10,6 +10,7 @@
#include <osg/Vec3>
#include <components/sceneutil/pathgridutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../../model/world/cell.hpp"
#include "../../model/world/commands.hpp"
@ -31,7 +32,7 @@ namespace CSVRender
};
PathgridTag::PathgridTag(Pathgrid* pathgrid)
: TagBase(Mask_Pathgrid), mPathgrid(pathgrid)
: TagBase(SceneUtil::Mask_Pathgrid), mPathgrid(pathgrid)
{
}
@ -70,7 +71,7 @@ namespace CSVRender
mBaseNode->setPosition(osg::Vec3f(mCoords.getX() * CoordScalar, mCoords.getY() * CoordScalar, 0.f));
mBaseNode->setUserData(mTag);
mBaseNode->setUpdateCallback(new PathgridNodeCallback());
mBaseNode->setNodeMask(Mask_Pathgrid);
mBaseNode->setNodeMask(SceneUtil::Mask_Pathgrid);
mParent->addChild(mBaseNode);
mPathgridGeode = new osg::Geode();

@ -4,6 +4,7 @@
#include <QPoint>
#include <components/sceneutil/pathgridutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../../model/prefs/state.hpp"
@ -15,7 +16,6 @@
#include "../widget/scenetoolbar.hpp"
#include "cell.hpp"
#include "mask.hpp"
#include "pathgrid.hpp"
#include "pathgridselectionmode.hpp"
#include "worldspacewidget.hpp"
@ -23,7 +23,7 @@
namespace CSVRender
{
PathgridMode::PathgridMode(WorldspaceWidget* worldspaceWidget, QWidget* parent)
: EditMode(worldspaceWidget, QIcon(":placeholder"), Mask_Pathgrid | Mask_Terrain | Mask_Reference,
: EditMode(worldspaceWidget, QIcon(":placeholder"), SceneUtil::Mask_Pathgrid | SceneUtil::Mask_Terrain | SceneUtil::Mask_EditorReference,
getTooltip(), parent)
, mDragMode(DragMode_None)
, mFromNode(0)
@ -110,7 +110,7 @@ namespace CSVRender
void PathgridMode::primarySelectPressed(const WorldspaceHitResult& hit)
{
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
getWorldspaceWidget().clearSelection(SceneUtil::Mask_Pathgrid);
if (hit.tag)
{
@ -131,7 +131,7 @@ namespace CSVRender
{
if (tag->getPathgrid()->getId() != mLastId)
{
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
getWorldspaceWidget().clearSelection(SceneUtil::Mask_Pathgrid);
mLastId = tag->getPathgrid()->getId();
}
@ -142,12 +142,12 @@ namespace CSVRender
}
}
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
getWorldspaceWidget().clearSelection(SceneUtil::Mask_Pathgrid);
}
bool PathgridMode::primaryEditStartDrag(const QPoint& pos)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
{
@ -156,7 +156,7 @@ namespace CSVRender
if (dynamic_cast<PathgridTag*>(hit.tag.get()))
{
primarySelectPressed(hit);
selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
}
}
@ -192,7 +192,7 @@ namespace CSVRender
{
if (mDragMode == DragMode_Move)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection(Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection(SceneUtil::Mask_Pathgrid);
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
{
@ -233,7 +233,7 @@ namespace CSVRender
{
if (mDragMode == DragMode_Move)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
{
if (PathgridTag* tag = dynamic_cast<PathgridTag*>(it->get()))
@ -272,11 +272,11 @@ namespace CSVRender
}
mDragMode = DragMode_None;
getWorldspaceWidget().reset(Mask_Pathgrid);
getWorldspaceWidget().reset(SceneUtil::Mask_Pathgrid);
}
void PathgridMode::dragAborted()
{
getWorldspaceWidget().reset(Mask_Pathgrid);
getWorldspaceWidget().reset(SceneUtil::Mask_Pathgrid);
}
}

@ -13,7 +13,7 @@
namespace CSVRender
{
PathgridSelectionMode::PathgridSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget)
: SelectionMode(parent, worldspaceWidget, Mask_Pathgrid)
: SelectionMode(parent, worldspaceWidget, SceneUtil::Mask_Pathgrid)
{
mRemoveSelectedNodes = new QAction("Remove selected nodes", this);
mRemoveSelectedEdges = new QAction("Remove edges between selected nodes", this);
@ -37,7 +37,7 @@ namespace CSVRender
void PathgridSelectionMode::removeSelectedNodes()
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
{
@ -54,7 +54,7 @@ namespace CSVRender
void PathgridSelectionMode::removeSelectedEdges()
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
{

@ -17,6 +17,7 @@
#include <components/resource/scenemanager.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../widget/scenetoolmode.hpp"
@ -25,7 +26,6 @@
#include "../../model/prefs/shortcuteventhandler.hpp"
#include "lighting.hpp"
#include "mask.hpp"
#include "cameracontroller.hpp"
namespace CSVRender
@ -71,7 +71,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager;
lightMgr->setStartLight(1);
lightMgr->setLightingMask(Mask_Lighting);
lightMgr->setLightingMask(SceneUtil::Mask_Lighting);
mRootNode = lightMgr;
mView->getCamera()->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
@ -88,7 +88,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
// Add ability to signal osg to show its statistics for debugging purposes
mView->addEventHandler(new osgViewer::StatsHandler);
mView->getCamera()->setCullMask(~(Mask_UpdateVisitor));
mView->getCamera()->setCullMask(~(SceneUtil::Mask_UpdateVisitor));
viewer.addView(mView);
viewer.setDone(false);
@ -100,6 +100,14 @@ RenderWidget::~RenderWidget()
try
{
CompositeViewer::get().removeView(mView);
#if OSG_VERSION_LESS_THAN(3,6,5)
// before OSG 3.6.4, the default font was a static object, and if it wasn't attached to the scene when a graphics context was destroyed, it's program wouldn't be released.
// 3.6.4 moved it into the object cache, which meant it usually got released, but not here.
// 3.6.5 improved cleanup with osgViewer::CompositeViewer::removeView so it more reliably released associated state for objects in the object cache.
osg::ref_ptr<osg::GraphicsContext> graphicsContext = mView->getCamera()->getGraphicsContext();
osgText::Font::getDefaultFont()->releaseGLObjects(graphicsContext->getState());
#endif
}
catch(const std::exception& e)
{
@ -114,7 +122,7 @@ void RenderWidget::flagAsModified()
void RenderWidget::setVisibilityMask(int mask)
{
mView->getCamera()->setCullMask(mask | Mask_ParticleSystem | Mask_Lighting);
mView->getCamera()->setCullMask(mask | SceneUtil::Mask_ParticleSystem | SceneUtil::Mask_Lighting);
}
osg::Camera *RenderWidget::getCamera()
@ -204,7 +212,7 @@ SceneWidget::SceneWidget(std::shared_ptr<Resource::ResourceSystem> resourceSyste
mOrbitCamControl = new OrbitCameraController(this);
mCurrentCamControl = mFreeCamControl;
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
mOrbitCamControl->setPickingMask(SceneUtil::Mask_EditorReference | SceneUtil::Mask_Terrain);
mOrbitCamControl->setConstRoll( CSMPrefs::get()["3D Scene Input"]["navi-orbit-const-roll"].isTrue() );
@ -213,7 +221,7 @@ SceneWidget::SceneWidget(std::shared_ptr<Resource::ResourceSystem> resourceSyste
setLighting(&mLightingDay);
mResourceSystem->getSceneManager()->setParticleSystemMask(Mask_ParticleSystem);
mResourceSystem->getSceneManager()->setParticleSystemMask(SceneUtil::Mask_ParticleSystem);
// Recieve mouse move event even if mouse button is not pressed
setMouseTracking(true);
@ -342,7 +350,7 @@ void SceneWidget::update(double dt)
}
else
{
mCurrentCamControl->setup(mRootNode, Mask_Reference | Mask_Terrain, CameraController::WorldUp);
mCurrentCamControl->setup(mRootNode, SceneUtil::Mask_EditorReference | SceneUtil::Mask_Terrain, CameraController::WorldUp);
mCamPositionSet = true;
}
}

@ -3,8 +3,6 @@
#include "../widget/scenetoolmode.hpp"
#include "mask.hpp"
class QAction;
namespace CSVRender

@ -1,9 +1,9 @@
#include "tagbase.hpp"
CSVRender::TagBase::TagBase (Mask mask) : mMask (mask) {}
CSVRender::TagBase::TagBase (SceneUtil::VisMask mask) : mMask (mask) {}
CSVRender::Mask CSVRender::TagBase::getMask() const
SceneUtil::VisMask CSVRender::TagBase::getMask() const
{
return mMask;
}

@ -5,19 +5,19 @@
#include <QString>
#include "mask.hpp"
#include <components/sceneutil/vismask.hpp>
namespace CSVRender
{
class TagBase : public osg::Referenced
{
Mask mMask;
SceneUtil::VisMask mMask;
public:
TagBase (Mask mask);
TagBase (SceneUtil::VisMask mask);
Mask getMask() const;
SceneUtil::VisMask getMask() const;
virtual QString getToolTip (bool hideBasics) const;

@ -17,6 +17,7 @@
#include <components/esm/loadland.hpp>
#include <components/debug/debuglog.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../widget/brushshapes.hpp"
#include "../widget/modebutton.hpp"
@ -38,13 +39,12 @@
#include "editmode.hpp"
#include "pagedworldspacewidget.hpp"
#include "mask.hpp"
#include "tagbase.hpp"
#include "terrainselection.hpp"
#include "worldspacewidget.hpp"
CSVRender::TerrainShapeMode::TerrainShapeMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent)
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, Mask_Terrain | Mask_Reference, "Terrain land editing", parent),
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, SceneUtil::Mask_Terrain | SceneUtil::Mask_EditorReference, "Terrain land editing", parent),
mParentNode(parentNode)
{
}

@ -13,6 +13,7 @@
#include <osg/Group>
#include <components/esm/loadland.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../widget/modebutton.hpp"
#include "../widget/scenetoolbar.hpp"
@ -34,12 +35,11 @@
#include "editmode.hpp"
#include "pagedworldspacewidget.hpp"
#include "mask.hpp"
#include "object.hpp" // Something small needed regarding pointers from here ()
#include "worldspacewidget.hpp"
CSVRender::TerrainTextureMode::TerrainTextureMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent)
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-texture"}, Mask_Terrain | Mask_Reference, "Terrain texture editing", parent),
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-texture"}, SceneUtil::Mask_Terrain | SceneUtil::Mask_EditorReference, "Terrain texture editing", parent),
mBrushTexture("L0#0"),
mBrushSize(1),
mBrushShape(0),

@ -16,7 +16,6 @@
#include "../widget/scenetooltoggle2.hpp"
#include "cameracontroller.hpp"
#include "mask.hpp"
#include "tagbase.hpp"
void CSVRender::UnpagedWorldspaceWidget::update()
@ -304,8 +303,8 @@ void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool)
{
WorldspaceWidget::addVisibilitySelectorButtons (tool);
tool->addButton (Button_Terrain, Mask_Terrain, "Terrain", "", true);
tool->addButton (Button_Fog, Mask_Fog, "Fog");
tool->addButton (Button_Terrain, SceneUtil::Mask_Terrain, "Terrain", "", true);
//tool->addButton (Button_Fog, Mask_Fog, "Fog");
}
std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction()

@ -26,8 +26,9 @@
#include "../widget/scenetooltoggle2.hpp"
#include "../widget/scenetoolrun.hpp"
#include <components/sceneutil/vismask.hpp>
#include "object.hpp"
#include "mask.hpp"
#include "instancemode.hpp"
#include "pathgridmode.hpp"
#include "cameracontroller.hpp"
@ -138,7 +139,7 @@ void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setti
{
float alpha = setting->toDouble();
// getSelection is virtual, thus this can not be called from the constructor
auto selection = getSelection(Mask_Reference);
auto selection = getSelection(SceneUtil::Mask_EditorReference);
for (osg::ref_ptr<TagBase> tag : selection)
{
if (auto objTag = dynamic_cast<ObjectTag*>(tag.get()))
@ -345,7 +346,7 @@ unsigned int CSVRender::WorldspaceWidget::getVisibilityMask() const
void CSVRender::WorldspaceWidget::setInteractionMask (unsigned int mask)
{
mInteractionMask = mask | Mask_CellMarker | Mask_CellArrow;
mInteractionMask = mask | SceneUtil::Mask_EditorCellMarker | SceneUtil::Mask_EditorCellArrow;
}
unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const
@ -361,9 +362,9 @@ void CSVRender::WorldspaceWidget::setEditLock (bool locked)
void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool)
{
tool->addButton (Button_Reference, Mask_Reference, "Instances");
tool->addButton (Button_Water, Mask_Water, "Water");
tool->addButton (Button_Pathgrid, Mask_Pathgrid, "Pathgrid");
tool->addButton (Button_Reference, SceneUtil::Mask_EditorReference, "Instances");
tool->addButton (Button_Water, SceneUtil::Mask_Water, "Water");
tool->addButton (Button_Pathgrid, SceneUtil::Mask_Pathgrid, "Pathgrid");
}
void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool)

@ -8,7 +8,6 @@
#include "../../model/world/tablemimedata.hpp"
#include "scenewidget.hpp"
#include "mask.hpp"
namespace CSMPrefs
{

@ -18,7 +18,7 @@ set(GAME_HEADER
source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender
actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
actors objects renderingmanager animation rotatecontroller sky npcanimation
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
renderbin actoranimation landmanager navmesh actorspaths

@ -26,6 +26,7 @@
#include <components/compiler/extensions0.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/sceneutil/workqueue.hpp>
#include <components/files/configurationmanager.hpp>
@ -59,8 +60,6 @@
#include "mwworld/player.hpp"
#include "mwworld/worldimp.hpp"
#include "mwrender/vismask.hpp"
#include "mwclass/classes.hpp"
#include "mwdialogue/dialoguemanagerimp.hpp"
@ -667,7 +666,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
std::string myguiResources = (mResDir / "mygui").string();
osg::ref_ptr<osg::Group> guiRoot = new osg::Group;
guiRoot->setName("GUI Root");
guiRoot->setNodeMask(MWRender::Mask_GUI);
guiRoot->setNodeMask(SceneUtil::Mask_GUI);
rootNode->addChild(guiRoot);
MWGui::WindowManager* window = new MWGui::WindowManager(mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(),
mCfgMgr.getLogPath().string() + std::string("/"), myguiResources,

@ -3,6 +3,7 @@
#include <components/esm/loadacti.hpp>
#include <components/misc/rng.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
@ -19,7 +20,6 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/vismask.hpp"
#include "../mwgui/tooltips.hpp"
@ -34,7 +34,7 @@ namespace MWClass
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model, true);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Static);
}
}

@ -15,6 +15,7 @@
#include <components/esm/loaddoor.hpp>
#include <components/esm/doorstate.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -37,7 +38,6 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/animation.hpp"
#include "../mwrender/vismask.hpp"
#include "../mwmechanics/actorutil.hpp"
@ -70,7 +70,7 @@ namespace MWClass
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model, true);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Static);
}
}

@ -2,6 +2,7 @@
#include <components/esm/loadstat.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwphysics/physicssystem.hpp"
@ -9,7 +10,6 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/vismask.hpp"
namespace MWClass
{
@ -19,7 +19,7 @@ namespace MWClass
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Static);
}
}

@ -9,7 +9,7 @@ namespace MWGui
/**
* @brief A variant of MyGUI::ImageBox with aspect ratio correction using black bars
*/
class BackgroundImage : public MyGUI::ImageBox
class BackgroundImage final : public MyGUI::ImageBox
{
MYGUI_RTTI_DERIVED(BackgroundImage)
@ -22,8 +22,8 @@ namespace MWGui
*/
void setBackgroundImage (const std::string& image, bool fixedRatio=true, bool stretch=true);
virtual void setSize (const MyGUI::IntSize &_value);
virtual void setCoord (const MyGUI::IntCoord &_value);
void setSize (const MyGUI::IntSize &_value) final;
void setCoord (const MyGUI::IntCoord &_value) final;
private:
MyGUI::ImageBox* mChild;

@ -817,7 +817,7 @@ namespace
};
}
class PageDisplay : public MyGUI::ISubWidgetText
class PageDisplay final : public MyGUI::ISubWidgetText
{
MYGUI_RTTI_DERIVED(PageDisplay)
protected:
@ -1140,7 +1140,7 @@ public:
i->second->createDrawItem (mNode);
}
void setVisible (bool newVisible)
void setVisible (bool newVisible) final
{
if (mVisible == newVisible)
return;
@ -1162,7 +1162,7 @@ public:
}
}
void createDrawItem(MyGUI::ITexture* texture, MyGUI::ILayerNode* node)
void createDrawItem(MyGUI::ITexture* texture, MyGUI::ILayerNode* node) final
{
mNode = node;
@ -1230,9 +1230,9 @@ public:
// ISubWidget should not necessarily be a drawitem
// in this case, it is not...
void doRender() { }
void doRender() final { }
void _updateView ()
void _updateView () final
{
_checkMargin();
@ -1241,7 +1241,7 @@ public:
mNode->outOfDate (i->second->mRenderItem);
}
void _correctView()
void _correctView() final
{
_checkMargin ();
@ -1251,7 +1251,7 @@ public:
}
void destroyDrawItem()
void destroyDrawItem() final
{
for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i)
i->second->destroyDrawItem (mNode);
@ -1261,7 +1261,7 @@ public:
};
class BookPageImpl : public BookPage
class BookPageImpl final : public BookPage
{
MYGUI_RTTI_DERIVED(BookPage)
public:
@ -1271,24 +1271,24 @@ public:
{
}
void showPage (TypesetBook::Ptr book, size_t page)
void showPage (TypesetBook::Ptr book, size_t page) final
{
mPageDisplay->showPage (book, page);
}
void adviseLinkClicked (std::function <void (InteractiveId)> linkClicked)
void adviseLinkClicked (std::function <void (InteractiveId)> linkClicked) final
{
mPageDisplay->mLinkClicked = linkClicked;
}
void unadviseLinkClicked ()
void unadviseLinkClicked () final
{
mPageDisplay->mLinkClicked = std::function <void (InteractiveId)> ();
}
protected:
virtual void initialiseOverride()
void initialiseOverride() final
{
Base::initialiseOverride();
@ -1302,24 +1302,24 @@ protected:
}
}
void onMouseLostFocus(Widget* _new)
void onMouseLostFocus(Widget* _new) final
{
// NOTE: MyGUI also fires eventMouseLostFocus for widgets that are about to be destroyed (if they had focus).
// Child widgets may already be destroyed! So be careful.
mPageDisplay->onMouseLostFocus ();
}
void onMouseMove(int left, int top)
void onMouseMove(int left, int top) final
{
mPageDisplay->onMouseMove (left, top);
}
void onMouseButtonPressed (int left, int top, MyGUI::MouseButton id)
void onMouseButtonPressed (int left, int top, MyGUI::MouseButton id) final
{
mPageDisplay->onMouseButtonPressed (left, top, id);
}
void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id)
void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id) final
{
mPageDisplay->onMouseButtonReleased (left, top, id);
}

@ -14,14 +14,14 @@ namespace MWGui
namespace Controllers
{
/// Automatically positions a widget below the mouse cursor.
class ControllerFollowMouse :
class ControllerFollowMouse final :
public MyGUI::ControllerItem
{
MYGUI_RTTI_DERIVED( ControllerFollowMouse )
private:
bool addTime(MyGUI::Widget* _widget, float _time);
void prepareItem(MyGUI::Widget* _widget);
bool addTime(MyGUI::Widget* _widget, float _time) final;
void prepareItem(MyGUI::Widget* _widget) final;
};
}
}

@ -11,7 +11,7 @@ namespace MWGui
/// ResourceImageSetPointer that we need.
/// \example MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
/// MyGUI::ResourceManager::getInstance().load("core.xml");
class ResourceImageSetPointerFix :
class ResourceImageSetPointerFix final :
public MyGUI::IPointer
{
MYGUI_RTTI_DERIVED( ResourceImageSetPointerFix )
@ -20,17 +20,17 @@ namespace MWGui
ResourceImageSetPointerFix();
virtual ~ResourceImageSetPointerFix();
virtual void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version);
void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) final;
virtual void setImage(MyGUI::ImageBox* _image);
virtual void setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point);
void setImage(MyGUI::ImageBox* _image) final;
void setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point) final;
//and now for the whole point of this class, allow us to get
//the hot spot, the image and the size of the cursor.
virtual MyGUI::ResourceImageSetPtr getImageSet();
virtual MyGUI::IntPoint getHotSpot();
virtual MyGUI::IntSize getSize();
virtual int getRotation();
MyGUI::ResourceImageSetPtr getImageSet();
MyGUI::IntPoint getHotSpot();
MyGUI::IntSize getSize();
int getRotation();
private:
MyGUI::IntPoint mPoint;

@ -21,7 +21,7 @@ namespace MWGui
class ItemModel;
class ItemWidget;
class ItemChargeView : public MyGUI::Widget
class ItemChargeView final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED(ItemChargeView)
public:
@ -36,7 +36,7 @@ namespace MWGui
/// Register needed components with MyGUI's factory manager
static void registerComponents();
virtual void initialiseOverride();
void initialiseOverride() final;
/// Takes ownership of \a model
void setModel(ItemModel* model);
@ -47,8 +47,8 @@ namespace MWGui
void layoutWidgets();
void resetScrollbars();
virtual void setSize(const MyGUI::IntSize& value);
virtual void setCoord(const MyGUI::IntCoord& value);
void setSize(const MyGUI::IntSize& value) final;
void setCoord(const MyGUI::IntCoord& value) final;
MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, const MWWorld::Ptr&> eventItemClicked;

@ -8,7 +8,7 @@
namespace MWGui
{
class ItemView : public MyGUI::Widget
class ItemView final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED(ItemView)
public:
@ -33,12 +33,12 @@ namespace MWGui
void resetScrollBars();
private:
virtual void initialiseOverride();
void initialiseOverride() final;
void layoutWidgets();
virtual void setSize(const MyGUI::IntSize& _value);
virtual void setCoord(const MyGUI::IntCoord& _value);
void setSize(const MyGUI::IntSize& _value) final;
void setCoord(const MyGUI::IntCoord& _value) final;
void onSelectedItem (MyGUI::Widget* sender);
void onSelectedBackground (MyGUI::Widget* sender);

@ -41,7 +41,7 @@ namespace MWGui
void setFrame (const std::string& frame, const MyGUI::IntCoord& coord);
protected:
virtual void initialiseOverride();
void initialiseOverride() final;
MyGUI::ImageBox* mItem;
MyGUI::ImageBox* mItemShadow;

@ -14,14 +14,13 @@
#include <components/myguiplatform/myguitexture.hpp>
#include <components/settings/settings.hpp>
#include <components/vfs/manager.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/statemanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/inputmanager.hpp"
#include "../mwrender/vismask.hpp"
#include "backgroundimage.hpp"
namespace MWGui
@ -335,8 +334,8 @@ namespace MWGui
// Turn off rendering except the GUI
int oldUpdateMask = mViewer->getUpdateVisitor()->getTraversalMask();
int oldCullMask = mViewer->getCamera()->getCullMask();
mViewer->getUpdateVisitor()->setTraversalMask(MWRender::Mask_GUI|MWRender::Mask_PreCompile);
mViewer->getCamera()->setCullMask(MWRender::Mask_GUI|MWRender::Mask_PreCompile);
mViewer->getUpdateVisitor()->setTraversalMask(SceneUtil::Mask_GUI|SceneUtil::Mask_PreCompile);
mViewer->getCamera()->setCullMask(SceneUtil::Mask_GUI|SceneUtil::Mask_PreCompile);
MWBase::Environment::get().getInputManager()->update(0, true, true);

@ -65,7 +65,7 @@ namespace
/// @brief A widget that changes its color when hovered.
class MarkerWidget: public MyGUI::Widget
class MarkerWidget final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED(MarkerWidget)
@ -85,12 +85,12 @@ namespace
MyGUI::Colour mNormalColour;
MyGUI::Colour mHoverColour;
void onMouseLostFocus(MyGUI::Widget* _new)
void onMouseLostFocus(MyGUI::Widget* _new) final
{
setColour(mNormalColour);
}
void onMouseSetFocus(MyGUI::Widget* _old)
void onMouseSetFocus(MyGUI::Widget* _old) final
{
setColour(mHoverColour);
}

@ -5,12 +5,12 @@
namespace MWGui
{
class AutoSizedResourceSkin : public MyGUI::ResourceSkin
class AutoSizedResourceSkin final : public MyGUI::ResourceSkin
{
MYGUI_RTTI_DERIVED( AutoSizedResourceSkin )
public:
virtual void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version);
void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) final;
};
}

@ -19,7 +19,7 @@ namespace MWGui
class SpellModel;
///@brief Displays a SpellModel in a list widget
class SpellView : public MyGUI::Widget
class SpellView final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED(SpellView)
public:
@ -47,10 +47,10 @@ namespace MWGui
/// Fired when a spell was clicked
EventHandle_ModelIndex eventSpellClicked;
virtual void initialiseOverride();
void initialiseOverride() final;
virtual void setSize(const MyGUI::IntSize& _value);
virtual void setCoord(const MyGUI::IntCoord& _value);
void setSize(const MyGUI::IntSize& _value) final;
void setCoord(const MyGUI::IntCoord& _value) final;
void resetScrollbars();

@ -90,7 +90,7 @@ namespace MWGui
typedef std::vector<SpellEffectParams> SpellEffectList;
class MWSkill : public MyGUI::Widget
class MWSkill final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED( MWSkill )
public:
@ -116,7 +116,7 @@ namespace MWGui
protected:
virtual ~MWSkill();
virtual void initialiseOverride();
void initialiseOverride() final;
void onClicked(MyGUI::Widget* _sender);
@ -131,7 +131,7 @@ namespace MWGui
};
typedef MWSkill* MWSkillPtr;
class MWAttribute : public MyGUI::Widget
class MWAttribute final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED( MWAttribute )
public:
@ -156,7 +156,7 @@ namespace MWGui
protected:
virtual ~MWAttribute();
virtual void initialiseOverride();
void initialiseOverride() final;
void onClicked(MyGUI::Widget* _sender);
@ -175,7 +175,7 @@ namespace MWGui
* @todo remove this class and use MWEffectList instead
*/
class MWSpellEffect;
class MWSpell : public MyGUI::Widget
class MWSpell final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED( MWSpell )
public:
@ -199,7 +199,7 @@ namespace MWGui
protected:
virtual ~MWSpell();
virtual void initialiseOverride();
void initialiseOverride() final;
private:
void updateWidgets();
@ -209,7 +209,7 @@ namespace MWGui
};
typedef MWSpell* MWSpellPtr;
class MWEffectList : public MyGUI::Widget
class MWEffectList final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED( MWEffectList )
public:
@ -241,7 +241,7 @@ namespace MWGui
protected:
virtual ~MWEffectList();
virtual void initialiseOverride();
void initialiseOverride() final;
private:
void updateWidgets();
@ -250,7 +250,7 @@ namespace MWGui
};
typedef MWEffectList* MWEffectListPtr;
class MWSpellEffect : public MyGUI::Widget
class MWSpellEffect final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED( MWSpellEffect )
public:
@ -265,7 +265,7 @@ namespace MWGui
protected:
virtual ~MWSpellEffect();
virtual void initialiseOverride();
void initialiseOverride() final;
private:
static const int sIconOffset = 24;
@ -279,7 +279,7 @@ namespace MWGui
};
typedef MWSpellEffect* MWSpellEffectPtr;
class MWDynamicStat : public MyGUI::Widget
class MWDynamicStat final : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED( MWDynamicStat )
public:
@ -294,7 +294,7 @@ namespace MWGui
protected:
virtual ~MWDynamicStat();
virtual void initialiseOverride();
void initialiseOverride() final;
private:

@ -42,6 +42,7 @@
#include <components/resource/resourcesystem.hpp>
#include <components/resource/imagemanager.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/sceneutil/workqueue.hpp>
#include <components/translation/translation.hpp>
@ -62,8 +63,6 @@
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwrender/vismask.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/cellstore.hpp"
@ -2012,8 +2011,8 @@ namespace MWGui
// Turn off all rendering except for the GUI
int oldUpdateMask = mViewer->getUpdateVisitor()->getTraversalMask();
int oldCullMask = mViewer->getCamera()->getCullMask();
mViewer->getUpdateVisitor()->setTraversalMask(MWRender::Mask_GUI);
mViewer->getCamera()->setCullMask(MWRender::Mask_GUI);
mViewer->getUpdateVisitor()->setTraversalMask(SceneUtil::Mask_GUI);
mViewer->getCamera()->setCullMask(SceneUtil::Mask_GUI);
MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize();
sizeVideo(screenSize.width, screenSize.height);

@ -4,6 +4,7 @@
#include <components/esm/esmwriter.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/debug/debuglog.hpp>
#include <components/misc/rng.hpp>
#include <components/settings/settings.hpp>
@ -43,8 +44,6 @@
#include "../mwmechanics/aibreathe.hpp"
#include "../mwrender/vismask.hpp"
#include "spellcasting.hpp"
#include "steering.hpp"
#include "npcstats.hpp"
@ -1535,11 +1534,11 @@ namespace MWMechanics
const float dist = (player.getRefData().getPosition().asVec3() - ptr.getRefData().getPosition().asVec3()).length();
if (dist > mActorsProcessingRange)
{
ptr.getRefData().getBaseNode()->setNodeMask(0);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Disabled);
return;
}
else
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Actor);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Actor);
// Fade away actors on large distance (>90% of actor's processing distance)
float visibilityRatio = 1.0;
@ -1917,12 +1916,12 @@ namespace MWMechanics
if (!inRange)
{
iter->first.getRefData().getBaseNode()->setNodeMask(0);
iter->first.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Disabled);
world->setActorCollisionMode(iter->first, false, false);
continue;
}
else if (!isPlayer)
iter->first.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Actor);
iter->first.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Actor);
const bool isDead = iter->first.getClass().getCreatureStats(iter->first).isDead();
if (!isDead && iter->first.getClass().getCreatureStats(iter->first).isParalyzed())

@ -44,7 +44,7 @@ namespace MWMechanics
void fastForward(const MWWorld::Ptr& actor, AiState& state);
virtual osg::Vec3f getDestination() { return osg::Vec3f(mX, mY, mZ); }
virtual osg::Vec3f getDestination() const { return osg::Vec3f(mX, mY, mZ); }
private:
std::string mCellId;

@ -76,7 +76,7 @@ namespace MWMechanics
void fastForward(const MWWorld::Ptr& actor, AiState& state);
virtual osg::Vec3f getDestination()
virtual osg::Vec3f getDestination() const
{
MWWorld::Ptr target = getTarget();
if (target.isEmpty())

@ -102,7 +102,7 @@ namespace MWMechanics
/// Return true if this package should repeat. Currently only used for Wander packages.
virtual bool getRepeat() const;
virtual osg::Vec3f getDestination() { return osg::Vec3f(0, 0, 0); }
virtual osg::Vec3f getDestination() const { return osg::Vec3f(0, 0, 0); }
// Return true if any loaded actor with this AI package must be active.
virtual bool alwaysActive() const { return false; }

@ -36,7 +36,7 @@ namespace MWMechanics
virtual bool alwaysActive() const { return true; }
virtual osg::Vec3f getDestination() { return osg::Vec3f(mX, mY, mZ); }
virtual osg::Vec3f getDestination() const { return osg::Vec3f(mX, mY, mZ); }
private:
float mX;

@ -97,6 +97,8 @@ namespace MWMechanics
virtual int getTypeId() const;
virtual bool useVariableSpeed() const { return true;}
virtual void writeState(ESM::AiSequence::AiSequence &sequence) const;
virtual void fastForward(const MWWorld::Ptr& actor, AiState& state);
@ -105,6 +107,14 @@ namespace MWMechanics
osg::Vec3f getDestination(const MWWorld::Ptr& actor) const;
virtual osg::Vec3f getDestination() const
{
if (!mHasDestination)
return osg::Vec3f(0, 0, 0);
return mDestination;
}
private:
// NOTE: mDistance and mDuration must be set already
void init();

@ -341,21 +341,23 @@ namespace MWMechanics
const osg::Vec3f& endPoint, const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags,
std::back_insert_iterator<std::deque<osg::Vec3f>> out)
{
try
{
const auto world = MWBase::Environment::get().getWorld();
const auto stepSize = getPathStepSize(actor);
const auto navigator = world->getNavigator();
return navigator->findPath(halfExtents, stepSize, startPoint, endPoint, flags, out).is_initialized();
}
catch (const DetourNavigator::NavigatorException& exception)
const auto world = MWBase::Environment::get().getWorld();
const auto stepSize = getPathStepSize(actor);
const auto navigator = world->getNavigator();
const auto status = navigator->findPath(halfExtents, stepSize, startPoint, endPoint, flags, out);
if (status == DetourNavigator::Status::NavMeshNotFound)
return false;
if (status != DetourNavigator::Status::Success)
{
Log(Debug::Debug) << "Build path by navigator exception: \"" << exception.what()
Log(Debug::Debug) << "Build path by navigator error: \"" << DetourNavigator::getMessage(status)
<< "\" for \"" << actor.getClass().getName(actor) << "\" (" << actor.getBase()
<< ") from " << startPoint << " to " << endPoint << " with flags ("
<< DetourNavigator::WriteFlags {flags} << ")";
return true;
}
return true;
}
void PathFinder::buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
@ -370,26 +372,30 @@ namespace MWMechanics
if (sqrDistanceIgnoreZ(mPath.front(), startPoint) <= 4 * stepSize * stepSize)
return;
try
{
const auto navigator = MWBase::Environment::get().getWorld()->getNavigator();
std::deque<osg::Vec3f> prePath;
navigator->findPath(halfExtents, stepSize, startPoint, mPath.front(), flags, std::back_inserter(prePath));
const auto navigator = MWBase::Environment::get().getWorld()->getNavigator();
std::deque<osg::Vec3f> prePath;
auto prePathInserter = std::back_inserter(prePath);
const auto status = navigator->findPath(halfExtents, stepSize, startPoint, mPath.front(), flags,
prePathInserter);
while (!prePath.empty() && sqrDistanceIgnoreZ(prePath.front(), startPoint) < stepSize * stepSize)
prePath.pop_front();
while (!prePath.empty() && sqrDistanceIgnoreZ(prePath.back(), mPath.front()) < stepSize * stepSize)
prePath.pop_back();
if (status == DetourNavigator::Status::NavMeshNotFound)
return;
std::copy(prePath.rbegin(), prePath.rend(), std::front_inserter(mPath));
}
catch (const DetourNavigator::NavigatorException& exception)
if (status != DetourNavigator::Status::Success)
{
Log(Debug::Debug) << "Build path by navigator exception: \"" << exception.what()
Log(Debug::Debug) << "Build path by navigator error: \"" << DetourNavigator::getMessage(status)
<< "\" for \"" << actor.getClass().getName(actor) << "\" (" << actor.getBase()
<< ") from " << startPoint << " to " << mPath.front() << " with flags ("
<< DetourNavigator::WriteFlags {flags} << ")";
return;
}
while (!prePath.empty() && sqrDistanceIgnoreZ(prePath.front(), startPoint) < stepSize * stepSize)
prePath.pop_front();
while (!prePath.empty() && sqrDistanceIgnoreZ(prePath.back(), mPath.front()) < stepSize * stepSize)
prePath.pop_back();
std::copy(prePath.rbegin(), prePath.rend(), std::front_inserter(mPath));
}
}

@ -1334,10 +1334,10 @@ namespace MWMechanics
return false;
}
void adjustDynamicStat(CreatureStats& creatureStats, int index, float magnitude)
void adjustDynamicStat(CreatureStats& creatureStats, int index, float magnitude, bool allowDecreaseBelowZero = false)
{
DynamicStat<float> stat = creatureStats.getDynamic(index);
stat.setCurrent(stat.getCurrent() + magnitude, index == 2);
stat.setCurrent(stat.getCurrent() + magnitude, allowDecreaseBelowZero);
creatureStats.setDynamic(index, stat);
}
@ -1376,9 +1376,12 @@ namespace MWMechanics
case ESM::MagicEffect::DamageMagicka:
case ESM::MagicEffect::DamageFatigue:
adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::DamageHealth, -magnitude);
{
int index = effectKey.mId-ESM::MagicEffect::DamageHealth;
static const bool uncappedDamageFatigue = Settings::Manager::getBool("uncapped damage fatigue", "Game");
adjustDynamicStat(creatureStats, index, -magnitude, index == 2 && uncappedDamageFatigue);
break;
}
case ESM::MagicEffect::AbsorbHealth:
if (magnitude > 0.f)
receivedMagicDamage = true;

@ -15,6 +15,7 @@
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/lightutil.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/misc/stringops.hpp>
@ -31,8 +32,6 @@
#include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/weapontype.hpp"
#include "vismask.hpp"
namespace MWRender
{
@ -367,7 +366,7 @@ void ActorAnimation::updateHolsteredWeapon(bool showHolsteredWeapons)
// Otherwise add the enchanted glow to it.
if (!showHolsteredWeapons)
{
weaponNode->setNodeMask(0);
weaponNode->setNodeMask(SceneUtil::Mask_Disabled);
}
else
{
@ -541,7 +540,7 @@ void ActorAnimation::addHiddenItemLight(const MWWorld::ConstPtr& item, const ESM
bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior();
osg::Vec4f ambient(1,1,1,1);
osg::ref_ptr<SceneUtil::LightSource> lightSource = SceneUtil::createLightSource(esmLight, Mask_Lighting, exterior, ambient);
osg::ref_ptr<SceneUtil::LightSource> lightSource = SceneUtil::createLightSource(esmLight, exterior, ambient);
mInsert->addChild(lightSource);

@ -1,7 +1,7 @@
#include "actorspaths.hpp"
#include "vismask.hpp"
#include <components/sceneutil/agentpath.hpp>
#include <components/sceneutil/vismask.hpp>
#include <osg/PositionAttitudeTransform>
@ -43,7 +43,7 @@ namespace MWRender
const auto newGroup = SceneUtil::createAgentPathGroup(path, halfExtents, start, end, settings);
if (newGroup)
{
newGroup->setNodeMask(Mask_Debug);
newGroup->setNodeMask(SceneUtil::Mask_Debug);
mRootNode->addChild(newGroup);
mGroups[actor] = newGroup;
}

@ -28,6 +28,7 @@
#include <components/sceneutil/actorutil.hpp>
#include <components/sceneutil/statesetupdater.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/lightutil.hpp>
#include <components/sceneutil/skeleton.hpp>
@ -44,7 +45,6 @@
#include "../mwmechanics/character.hpp" // FIXME: for MWMechanics::Priority
#include "vismask.hpp"
#include "util.hpp"
#include "rotatecontroller.hpp"
@ -578,7 +578,7 @@ namespace MWRender
else
{
// Hide effect immediately
node->setNodeMask(0);
node->setNodeMask(SceneUtil::Mask_Disabled);
mFinished = true;
}
}
@ -1595,7 +1595,7 @@ namespace MWRender
{
bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior();
SceneUtil::addLight(parent, esmLight, Mask_ParticleSystem, Mask_Lighting, exterior);
SceneUtil::addLight(parent, esmLight, exterior);
}
void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, const std::string& texture)
@ -1647,7 +1647,7 @@ namespace MWRender
// FreezeOnCull doesn't work so well with effect particles, that tend to have moving emitters
SceneUtil::DisableFreezeOnCullVisitor disableFreezeOnCullVisitor;
node->accept(disableFreezeOnCullVisitor);
node->setNodeMask(Mask_Effect);
node->setNodeMask(SceneUtil::Mask_Effect);
params.mMaxControllerLength = findMaxLengthVisitor.getMaxLength();
params.mLoop = loop;
@ -1806,7 +1806,7 @@ namespace MWRender
SceneUtil::configureLight(light, radius, isExterior);
mGlowLight = new SceneUtil::LightSource;
mGlowLight->setNodeMask(Mask_Lighting);
mGlowLight->setNodeMask(SceneUtil::Mask_Lighting);
mInsert->addChild(mGlowLight);
mGlowLight->setLight(light);
}

@ -7,7 +7,7 @@
#include <components/debug/debuglog.hpp>
#include "vismask.hpp"
#include <components/sceneutil/vismask.hpp>
namespace
{
@ -34,7 +34,7 @@ void DebugDrawer::createGeometry()
if (!mGeometry)
{
mGeometry = new osg::Geometry;
mGeometry->setNodeMask(Mask_Debug);
mGeometry->setNodeMask(SceneUtil::Mask_Debug);
mVertices = new osg::Vec3Array;

@ -17,6 +17,7 @@
#include <components/fallback/fallback.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/shadow.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -27,7 +28,6 @@
#include "../mwmechanics/weapontype.hpp"
#include "npcanimation.hpp"
#include "vismask.hpp"
namespace MWRender
{
@ -61,7 +61,7 @@ namespace MWRender
}
else
{
node->setNodeMask(0);
node->setNodeMask(SceneUtil::Mask_Disabled);
}
}
@ -138,9 +138,9 @@ namespace MWRender
mCamera->attach(osg::Camera::COLOR_BUFFER, mTexture);
mCamera->setName("CharacterPreview");
mCamera->setComputeNearFarMode(osg::Camera::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES);
mCamera->setCullMask(~(Mask_UpdateVisitor));
mCamera->setCullMask(~(SceneUtil::Mask_UpdateVisitor));
mCamera->setNodeMask(Mask_RenderToTexture);
mCamera->setNodeMask(SceneUtil::Mask_RenderToTexture);
osg::ref_ptr<SceneUtil::LightManager> lightManager = new SceneUtil::LightManager;
lightManager->setStartLight(1);
@ -255,7 +255,7 @@ namespace MWRender
void CharacterPreview::redraw()
{
mCamera->setNodeMask(Mask_RenderToTexture);
mCamera->setNodeMask(SceneUtil::Mask_RenderToTexture);
mDrawOnceCallback->redrawNextFrame();
}
@ -364,7 +364,7 @@ namespace MWRender
visitor.setTraversalNumber(mDrawOnceCallback->getLastRenderedFrame());
osg::Node::NodeMask nodeMask = mCamera->getNodeMask();
mCamera->setNodeMask(~0);
mCamera->setNodeMask(SceneUtil::Mask_Default);
mCamera->accept(visitor);
mCamera->setNodeMask(nodeMask);

@ -6,9 +6,9 @@
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/controller.hpp>
#include <components/sceneutil/vismask.hpp>
#include "animation.hpp"
#include "vismask.hpp"
#include "util.hpp"
namespace MWRender
@ -29,7 +29,7 @@ void EffectManager::addEffect(const std::string &model, const std::string& textu
{
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(model);
node->setNodeMask(Mask_Effect);
node->setNodeMask(SceneUtil::Mask_Effect);
Effect effect;
effect.mAnimTime.reset(new EffectAnimationTime);

@ -16,6 +16,7 @@
#include <components/debug/debuglog.hpp>
#include <components/sceneutil/workqueue.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/esm/globalmap.hpp>
@ -37,8 +38,6 @@
#include "../mwworld/esmstore.hpp"
#include "vismask.hpp"
namespace
{
@ -89,7 +88,7 @@ namespace
{
if (mParent->copyResult(static_cast<osg::Camera*>(node), nv->getTraversalNumber()))
{
node->setNodeMask(0);
node->setNodeMask(SceneUtil::Mask_Disabled);
mParent->markForRemoval(static_cast<osg::Camera*>(node));
}
return;
@ -324,7 +323,7 @@ namespace MWRender
float srcLeft, float srcTop, float srcRight, float srcBottom)
{
osg::ref_ptr<osg::Camera> camera (new osg::Camera);
camera->setNodeMask(Mask_RenderToTexture);
camera->setNodeMask(SceneUtil::Mask_RenderToTexture);
camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
camera->setViewMatrix(osg::Matrix::identity());
camera->setProjectionMatrix(osg::Matrix::identity());

@ -18,6 +18,7 @@
#include <components/settings/settings.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/shadow.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/files/memorystream.hpp>
#include "../mwbase/environment.hpp"
@ -25,8 +26,6 @@
#include "../mwworld/cellstore.hpp"
#include "vismask.hpp"
namespace
{
@ -42,7 +41,7 @@ namespace
virtual void operator()(osg::Node* node, osg::NodeVisitor*)
{
if (mRendered)
node->setNodeMask(0);
node->setNodeMask(SceneUtil::Mask_Disabled);
if (!mRendered)
{
@ -178,8 +177,8 @@ osg::ref_ptr<osg::Camera> LocalMap::createOrthographicCamera(float x, float y, f
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setCullMask(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object | Mask_Static);
camera->setNodeMask(Mask_RenderToTexture);
camera->setCullMask(SceneUtil::Mask_Scene | SceneUtil::Mask_SimpleWater | SceneUtil::Mask_Terrain | SceneUtil::Mask_Object | SceneUtil::Mask_Static);
camera->setNodeMask(SceneUtil::Mask_RenderToTexture);
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
stateset->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), osg::StateAttribute::OVERRIDE);
@ -376,7 +375,7 @@ void LocalMap::requestExteriorMap(const MWWorld::CellStore* cell)
void LocalMap::requestInteriorMap(const MWWorld::CellStore* cell)
{
osg::ComputeBoundsVisitor computeBoundsVisitor;
computeBoundsVisitor.setTraversalMask(Mask_Scene | Mask_Terrain | Mask_Object | Mask_Static);
computeBoundsVisitor.setTraversalMask(SceneUtil::Mask_Scene | SceneUtil::Mask_Terrain | SceneUtil::Mask_Object | SceneUtil::Mask_Static);
mSceneRoot->accept(computeBoundsVisitor);
osg::BoundingBox bounds = computeBoundsVisitor.getBoundingBox();

@ -1,7 +1,7 @@
#include "navmesh.hpp"
#include "vismask.hpp"
#include <components/sceneutil/navmesh.hpp>
#include <components/sceneutil/vismask.hpp>
#include <osg/PositionAttitudeTransform>
@ -45,7 +45,7 @@ namespace MWRender
mGroup = SceneUtil::createNavMeshGroup(navMesh, settings);
if (mGroup)
{
mGroup->setNodeMask(Mask_Debug);
mGroup->setNodeMask(SceneUtil::Mask_Debug);
mRootNode->addChild(mGroup);
}
}

@ -18,6 +18,7 @@
#include <components/sceneutil/actorutil.hpp>
#include <components/sceneutil/attach.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/sceneutil/skeleton.hpp>
#include <components/settings/settings.hpp>
@ -43,7 +44,6 @@
#include "camera.hpp"
#include "rotatecontroller.hpp"
#include "renderbin.hpp"
#include "vismask.hpp"
namespace
{
@ -81,6 +81,34 @@ std::string getVampireHead(const std::string& race, bool female)
return "meshes\\" + bodyPart->mModel;
}
std::string getShieldBodypartMesh(const std::vector<ESM::PartReference>& bodyparts, bool female)
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
for (const auto& part : bodyparts)
{
if (part.mPart != ESM::PRT_Shield)
continue;
std::string bodypartName;
if (female && !part.mFemale.empty())
bodypartName = part.mFemale;
else if (!part.mMale.empty())
bodypartName = part.mMale;
if (!bodypartName.empty())
{
const ESM::BodyPart *bodypart = partStore.search(bodypartName);
if (bodypart == nullptr || bodypart->mData.mType != ESM::BodyPart::MT_Armor)
return std::string();
if (!bodypart->mModel.empty())
return "meshes\\" + bodypart->mModel;
}
}
return std::string();
}
}
@ -507,7 +535,7 @@ void NpcAnimation::updateNpcBase()
addAnimSource(smodel, smodel);
mObjectRoot->setNodeMask(Mask_FirstPerson);
mObjectRoot->setNodeMask(SceneUtil::Mask_FirstPerson);
mObjectRoot->addCullCallback(new OverrideFieldOfViewCallback(mFirstPersonFieldOfView));
}
@ -519,36 +547,9 @@ std::string NpcAnimation::getShieldMesh(MWWorld::ConstPtr shield) const
std::string mesh = shield.getClass().getModel(shield);
const ESM::Armor *armor = shield.get<ESM::Armor>()->mBase;
const std::vector<ESM::PartReference>& bodyparts = armor->mParts.mParts;
// Try to recover the body part model, use ground model as a fallback otherwise.
if (!bodyparts.empty())
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
// Try to get shield model from bodyparts first, with ground model as fallback
for (const auto& part : bodyparts)
{
if (part.mPart != ESM::PRT_Shield)
continue;
std::string bodypartName;
if (!mNpc->isMale() && !part.mFemale.empty())
bodypartName = part.mFemale;
else if (!part.mMale.empty())
bodypartName = part.mMale;
if (!bodypartName.empty())
{
const ESM::BodyPart *bodypart = partStore.search(bodypartName);
if (bodypart == nullptr || bodypart->mData.mType != ESM::BodyPart::MT_Armor)
return std::string();
else if (!bodypart->mModel.empty())
{
mesh = "meshes\\" + bodypart->mModel;
break;
}
}
}
}
mesh = getShieldBodypartMesh(bodyparts, !mNpc->isMale());
if (mesh.empty())
return std::string();
@ -1002,9 +1003,19 @@ void NpcAnimation::showCarriedLeft(bool show)
{
osg::Vec4f glowColor = iter->getClass().getEnchantmentColor(*iter);
std::string mesh = iter->getClass().getModel(*iter);
if (addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1,
mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor))
// For shields we must try to use the body part model
if (iter->getTypeName() == typeid(ESM::Armor).name())
{
const ESM::Armor *armor = iter->get<ESM::Armor>()->mBase;
const std::vector<ESM::PartReference>& bodyparts = armor->mParts.mParts;
if (!bodyparts.empty())
mesh = getShieldBodypartMesh(bodyparts, !mNpc->isMale());
}
if (mesh.empty() || addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1,
mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor))
{
if (mesh.empty())
reserveIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1);
if (iter->getTypeName() == typeid(ESM::Light).name() && mObjectParts[ESM::PRT_Shield])
addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), iter->get<ESM::Light>()->mBase);
}

@ -5,6 +5,7 @@
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/unrefqueue.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/class.hpp"
@ -12,8 +13,6 @@
#include "animation.hpp"
#include "npcanimation.hpp"
#include "creatureanimation.hpp"
#include "vismask.hpp"
namespace MWRender
{
@ -71,7 +70,7 @@ void Objects::insertBegin(const MWWorld::Ptr& ptr)
void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool animated, bool allowLight)
{
insertBegin(ptr);
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Object);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Object);
osg::ref_ptr<ObjectAnimation> anim (new ObjectAnimation(ptr, mesh, mResourceSystem, animated, allowLight));
@ -81,7 +80,7 @@ void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool
void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, bool weaponsShields)
{
insertBegin(ptr);
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Actor);
// CreatureAnimation
osg::ref_ptr<Animation> anim;
@ -98,7 +97,7 @@ void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, b
void Objects::insertNPC(const MWWorld::Ptr &ptr)
{
insertBegin(ptr);
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Actor);
osg::ref_ptr<NpcAnimation> anim (new NpcAnimation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), mResourceSystem));

@ -8,6 +8,7 @@
#include <components/esm/loadpgrd.hpp>
#include <components/sceneutil/pathgridutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone
#include "../mwbase/environment.hpp"
@ -17,8 +18,6 @@
#include "../mwmechanics/pathfinding.hpp"
#include "../mwmechanics/coordinateconverter.hpp"
#include "vismask.hpp"
namespace MWRender
{
@ -73,7 +72,7 @@ void Pathgrid::togglePathgrid()
{
// add path grid meshes to already loaded cells
mPathGridRoot = new osg::Group;
mPathGridRoot->setNodeMask(Mask_Debug);
mPathGridRoot->setNodeMask(SceneUtil::Mask_Pathgrid);
mRootNode->addChild(mPathGridRoot);
for(const MWWorld::CellStore* cell : mActiveCells)

@ -40,6 +40,7 @@
#include <components/sceneutil/unrefqueue.hpp>
#include <components/sceneutil/writescene.hpp>
#include <components/sceneutil/shadow.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/terrain/terraingrid.hpp>
#include <components/terrain/quadtreeworld.hpp>
@ -58,7 +59,6 @@
#include "sky.hpp"
#include "effectmanager.hpp"
#include "npcanimation.hpp"
#include "vismask.hpp"
#include "pathgrid.hpp"
#include "camera.hpp"
#include "water.hpp"
@ -215,7 +215,7 @@ namespace MWRender
, mFieldOfViewOverride(0.f)
, mBorders(false)
{
resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem);
resourceSystem->getSceneManager()->setParticleSystemMask(SceneUtil::Mask_ParticleSystem);
resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders");
resourceSystem->getSceneManager()->setForceShaders(Settings::Manager::getBool("force shaders", "Shaders") || Settings::Manager::getBool("enable shadows", "Shadows")); // Shadows have problems with fixed-function mode
// FIXME: calling dummy method because terrain needs to know whether lighting is clamped
@ -227,21 +227,21 @@ namespace MWRender
resourceSystem->getSceneManager()->setSpecularMapPattern(Settings::Manager::getString("specular map pattern", "Shaders"));
osg::ref_ptr<SceneUtil::LightManager> sceneRoot = new SceneUtil::LightManager;
sceneRoot->setLightingMask(Mask_Lighting);
sceneRoot->setLightingMask(SceneUtil::Mask_Lighting);
mSceneRoot = sceneRoot;
sceneRoot->setStartLight(1);
int shadowCastingTraversalMask = Mask_Scene;
int shadowCastingTraversalMask = SceneUtil::Mask_Scene;
if (Settings::Manager::getBool("actor shadows", "Shadows"))
shadowCastingTraversalMask |= Mask_Actor;
shadowCastingTraversalMask |= SceneUtil::Mask_Actor;
if (Settings::Manager::getBool("player shadows", "Shadows"))
shadowCastingTraversalMask |= Mask_Player;
shadowCastingTraversalMask |= SceneUtil::Mask_Player;
if (Settings::Manager::getBool("terrain shadows", "Shadows"))
shadowCastingTraversalMask |= Mask_Terrain;
shadowCastingTraversalMask |= SceneUtil::Mask_Terrain;
int indoorShadowCastingTraversalMask = shadowCastingTraversalMask;
if (Settings::Manager::getBool("object shadows", "Shadows"))
shadowCastingTraversalMask |= (Mask_Object|Mask_Static);
shadowCastingTraversalMask |= (SceneUtil::Mask_Object|SceneUtil::Mask_Static);
mShadowManager.reset(new SceneUtil::ShadowManager(sceneRoot, mRootNode, shadowCastingTraversalMask, indoorShadowCastingTraversalMask, mResourceSystem->getSceneManager()->getShaderManager()));
@ -305,11 +305,10 @@ namespace MWRender
float maxCompGeometrySize = Settings::Manager::getFloat("max composite geometry size", "Terrain");
maxCompGeometrySize = std::max(maxCompGeometrySize, 1.f);
mTerrain.reset(new Terrain::QuadTreeWorld(
sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile, Mask_Debug,
compMapResolution, compMapLevel, lodFactor, vertexLodMod, maxCompGeometrySize));
sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, compMapResolution, compMapLevel, lodFactor, vertexLodMod, maxCompGeometrySize));
}
else
mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile, Mask_Debug));
mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage));
mTerrain->setTargetFrameRate(Settings::Manager::getFloat("target framerate", "Cells"));
mTerrain->setWorkQueue(mWorkQueue.get());
@ -319,7 +318,7 @@ namespace MWRender
mViewer->setLightingMode(osgViewer::View::NO_LIGHT);
osg::ref_ptr<osg::LightSource> source = new osg::LightSource;
source->setNodeMask(Mask_Lighting);
source->setNodeMask(SceneUtil::Mask_Lighting);
mSunLight = new osg::Light;
source->setLight(mSunLight);
mSunLight->setDiffuse(osg::Vec4f(0,0,0,1));
@ -338,7 +337,7 @@ namespace MWRender
defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f));
sceneRoot->getOrCreateStateSet()->setAttribute(defaultMat);
sceneRoot->setNodeMask(Mask_Scene);
sceneRoot->setNodeMask(SceneUtil::Mask_Scene);
sceneRoot->setName("Scene Root");
mSky.reset(new SkyManager(sceneRoot, resourceSystem->getSceneManager()));
@ -366,7 +365,7 @@ namespace MWRender
mViewer->getCamera()->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
mViewer->getCamera()->setCullingMode(cullingMode);
mViewer->getCamera()->setCullMask(~(Mask_UpdateVisitor|Mask_SimpleWater));
mViewer->getCamera()->setCullMask(~(SceneUtil::Mask_UpdateVisitor|SceneUtil::Mask_SimpleWater));
mNearClip = Settings::Manager::getFloat("near clip", "Camera");
mViewDistance = Settings::Manager::getFloat("viewing distance", "Camera");
@ -568,12 +567,12 @@ namespace MWRender
else if (mode == Render_Scene)
{
int mask = mViewer->getCamera()->getCullMask();
bool enabled = mask&Mask_Scene;
bool enabled = mask & SceneUtil::Mask_Scene;
enabled = !enabled;
if (enabled)
mask |= Mask_Scene;
mask |= SceneUtil::Mask_Scene;
else
mask &= ~Mask_Scene;
mask &= ~SceneUtil::Mask_Scene;
mViewer->getCamera()->setCullMask(mask);
return enabled;
}
@ -841,7 +840,7 @@ namespace MWRender
int maskBackup = mPlayerAnimation->getObjectRoot()->getNodeMask();
if (mCamera->isFirstPerson())
mPlayerAnimation->getObjectRoot()->setNodeMask(0);
mPlayerAnimation->getObjectRoot()->setNodeMask(SceneUtil::Mask_Disabled);
for (int i = 0; i < 6; ++i) // for each cubemap side
{
@ -915,7 +914,7 @@ namespace MWRender
void RenderingManager::renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h)
{
camera->setNodeMask(Mask_RenderToTexture);
camera->setNodeMask(SceneUtil::Mask_RenderToTexture);
camera->attach(osg::Camera::COLOR_BUFFER, image);
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
@ -968,7 +967,7 @@ namespace MWRender
rttCamera->addChild(mWater->getReflectionCamera());
rttCamera->addChild(mWater->getRefractionCamera());
rttCamera->setCullMask(mViewer->getCamera()->getCullMask() & (~Mask_GUI));
rttCamera->setCullMask(mViewer->getCamera()->getCullMask() & (~SceneUtil::Mask_GUI));
rttCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -981,7 +980,7 @@ namespace MWRender
return osg::Vec4f();
osg::ComputeBoundsVisitor computeBoundsVisitor;
computeBoundsVisitor.setTraversalMask(~(Mask_ParticleSystem|Mask_Effect));
computeBoundsVisitor.setTraversalMask(~(SceneUtil::Mask_ParticleSystem|SceneUtil::Mask_Effect));
ptr.getRefData().getBaseNode()->accept(computeBoundsVisitor);
osg::Matrix viewProj = mViewer->getCamera()->getViewMatrix() * mViewer->getCamera()->getProjectionMatrix();
@ -1053,12 +1052,11 @@ namespace MWRender
mIntersectionVisitor->setTraversalNumber(mViewer->getFrameStamp()->getFrameNumber());
mIntersectionVisitor->setIntersector(intersector);
int mask = ~0;
mask &= ~(Mask_RenderToTexture|Mask_Sky|Mask_Debug|Mask_Effect|Mask_Water|Mask_SimpleWater);
int mask = ~(SceneUtil::Mask_RenderToTexture|SceneUtil::Mask_Sky|SceneUtil::Mask_Pathgrid|SceneUtil::Mask_Debug|SceneUtil::Mask_Effect|SceneUtil::Mask_Water|SceneUtil::Mask_SimpleWater);
if (ignorePlayer)
mask &= ~(Mask_Player);
mask &= ~(SceneUtil::Mask_Player);
if (ignoreActors)
mask &= ~(Mask_Actor|Mask_Player);
mask &= ~(SceneUtil::Mask_Actor|SceneUtil::Mask_Player);
mIntersectionVisitor->setTraversalMask(mask);
return mIntersectionVisitor;
@ -1108,6 +1106,7 @@ namespace MWRender
void RenderingManager::notifyWorldSpaceChanged()
{
mEffectManager->clear();
mWater->clearRipples();
}
void RenderingManager::clear()
@ -1138,7 +1137,7 @@ namespace MWRender
if (!mPlayerNode)
{
mPlayerNode = new SceneUtil::PositionAttitudeTransform;
mPlayerNode->setNodeMask(Mask_Player);
mPlayerNode->setNodeMask(SceneUtil::Mask_Player);
mPlayerNode->setName("Player Root");
mSceneRoot->addChild(mPlayerNode);
}
@ -1382,7 +1381,7 @@ namespace MWRender
osg::ref_ptr<const osg::Node> node = mResourceSystem->getSceneManager()->getTemplate(modelName);
osg::ComputeBoundsVisitor computeBoundsVisitor;
computeBoundsVisitor.setTraversalMask(~(MWRender::Mask_ParticleSystem|MWRender::Mask_Effect));
computeBoundsVisitor.setTraversalMask(~(SceneUtil::Mask_ParticleSystem|SceneUtil::Mask_Effect));
const_cast<osg::Node*>(node.get())->accept(computeBoundsVisitor);
osg::BoundingBox bounds = computeBoundsVisitor.getBoundingBox();

@ -16,8 +16,7 @@
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/fallback/fallback.hpp>
#include "vismask.hpp"
#include <components/sceneutil/vismask.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
@ -104,7 +103,7 @@ RippleSimulation::RippleSimulation(osg::Group *parent, Resource::ResourceSystem*
mParticleNode->setName("Ripple Root");
mParticleNode->addChild(updater);
mParticleNode->addChild(mParticleSystem);
mParticleNode->setNodeMask(Mask_Water);
mParticleNode->setNodeMask(SceneUtil::Mask_Water);
createWaterRippleStateSet(resourceSystem, mParticleNode);

@ -42,12 +42,12 @@
#include <components/sceneutil/statesetupdater.hpp>
#include <components/sceneutil/controller.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/sceneutil/shadow.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "vismask.hpp"
#include "renderbin.hpp"
namespace
@ -453,7 +453,7 @@ public:
void setVisible(bool visible)
{
mTransform->setNodeMask(visible ? mVisibleMask : 0);
mTransform->setNodeMask(visible ? mVisibleMask : SceneUtil::Mask_Disabled);
}
protected:
@ -469,7 +469,7 @@ class Sun : public CelestialBody
{
public:
Sun(osg::Group* parentNode, Resource::ImageManager& imageManager)
: CelestialBody(parentNode, 1.0f, 1, Mask_Sun)
: CelestialBody(parentNode, 1.0f, 1, SceneUtil::Mask_Sun)
, mUpdater(new Updater)
{
mTransform->addUpdateCallback(mUpdater);
@ -644,7 +644,7 @@ private:
camera->setProjectionMatrix(osg::Matrix::identity());
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); // add to skyRoot instead?
camera->setViewMatrix(osg::Matrix::identity());
camera->setClearMask(0);
camera->setClearMask(SceneUtil::Mask_Disabled);
camera->setRenderOrder(osg::Camera::NESTED_RENDER);
camera->setAllowEventFocus(false);
@ -1134,7 +1134,7 @@ SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneMana
skyroot->getOrCreateStateSet()->setAttributeAndModes(new osg::Program(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::PROTECTED|osg::StateAttribute::ON);
SceneUtil::ShadowManager::disableShadowsForStateSet(skyroot->getOrCreateStateSet());
skyroot->setNodeMask(Mask_Sky);
skyroot->setNodeMask(SceneUtil::Mask_Sky);
parentNode->addChild(skyroot);
mRootNode = skyroot;
@ -1166,7 +1166,7 @@ void SkyManager::create()
mAtmosphereDay->addUpdateCallback(mAtmosphereUpdater);
mAtmosphereNightNode = new osg::PositionAttitudeTransform;
mAtmosphereNightNode->setNodeMask(0);
mAtmosphereNightNode->setNodeMask(SceneUtil::Mask_Disabled);
mEarlyRenderBinRoot->addChild(mAtmosphereNightNode);
osg::ref_ptr<osg::Node> atmosphereNight;
@ -1199,7 +1199,7 @@ void SkyManager::create()
mCloudUpdater2 = new CloudUpdater;
mCloudUpdater2->setOpacity(0.f);
mCloudMesh2->addUpdateCallback(mCloudUpdater2);
mCloudMesh2->setNodeMask(0);
mCloudMesh2->setNodeMask(SceneUtil::Mask_Disabled);
osg::ref_ptr<osg::Depth> depth = new osg::Depth;
depth->setWriteMask(false);
@ -1522,7 +1522,7 @@ void SkyManager::createRain()
mRainFader = new RainFader(&mWeatherAlpha);
mRainNode->addUpdateCallback(mRainFader);
mRainNode->addCullCallback(mUnderwaterSwitch);
mRainNode->setNodeMask(Mask_WeatherParticles);
mRainNode->setNodeMask(SceneUtil::Mask_WeatherParticles);
mRootNode->addChild(mRainNode);
}
@ -1625,7 +1625,7 @@ void SkyManager::setEnabled(bool enabled)
if (enabled && !mCreated)
create();
mRootNode->setNodeMask(enabled ? Mask_Sky : 0);
mRootNode->setNodeMask(enabled ? SceneUtil::Mask_Sky : SceneUtil::Mask_Disabled);
mEnabled = enabled;
}
@ -1718,7 +1718,7 @@ void SkyManager::setWeather(const WeatherResult& weather)
{
mParticleNode = new osg::PositionAttitudeTransform;
mParticleNode->addCullCallback(mUnderwaterSwitch);
mParticleNode->setNodeMask(Mask_WeatherParticles);
mParticleNode->setNodeMask(SceneUtil::Mask_WeatherParticles);
mRootNode->addChild(mParticleNode);
}
@ -1788,7 +1788,7 @@ void SkyManager::setWeather(const WeatherResult& weather)
mCloudUpdater->setOpacity((1.f-mCloudBlendFactor));
mCloudUpdater2->setOpacity(mCloudBlendFactor);
mCloudMesh2->setNodeMask(mCloudBlendFactor > 0.f ? ~0 : 0);
mCloudMesh2->setNodeMask(mCloudBlendFactor > 0.f ? SceneUtil::Mask_Default : SceneUtil::Mask_Disabled);
}
if (mCloudColour != weather.mFogColor)
@ -1833,7 +1833,7 @@ void SkyManager::setWeather(const WeatherResult& weather)
mAtmosphereNightUpdater->setFade(mStarsOpacity);
}
mAtmosphereNightNode->setNodeMask(weather.mNight ? ~0 : 0);
mAtmosphereNightNode->setNodeMask(weather.mNight ? SceneUtil::Mask_Default : SceneUtil::Mask_Disabled);
if (mRainFader)
mRainFader->setAlpha(weather.mEffectFade * 0.6); // * Rain_Threshold?

@ -27,6 +27,7 @@
#include <components/sceneutil/shadow.hpp>
#include <components/sceneutil/waterutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/misc/constants.hpp>
@ -40,7 +41,6 @@
#include "../mwworld/cellstore.hpp"
#include "vismask.hpp"
#include "ripplesimulation.hpp"
#include "renderbin.hpp"
#include "util.hpp"
@ -243,8 +243,8 @@ public:
setName("RefractionCamera");
setCullCallback(new InheritViewPointCallback);
setCullMask(Mask_Effect|Mask_Scene|Mask_Object|Mask_Static|Mask_Terrain|Mask_Actor|Mask_ParticleSystem|Mask_Sky|Mask_Sun|Mask_Player|Mask_Lighting);
setNodeMask(Mask_RenderToTexture);
setCullMask(SceneUtil::Mask_Effect|SceneUtil::Mask_Scene|SceneUtil::Mask_Object|SceneUtil::Mask_Static|SceneUtil::Mask_Terrain|SceneUtil::Mask_Actor|SceneUtil::Mask_ParticleSystem|SceneUtil::Mask_Sky|SceneUtil::Mask_Sun|SceneUtil::Mask_Player|SceneUtil::Mask_Lighting);
setNodeMask(SceneUtil::Mask_RenderToTexture);
setViewport(0, 0, rttSize, rttSize);
// No need for Update traversal since the scene is already updated as part of the main scene graph
@ -337,7 +337,7 @@ public:
setCullCallback(new InheritViewPointCallback);
setInterior(isInterior);
setNodeMask(Mask_RenderToTexture);
setNodeMask(SceneUtil::Mask_RenderToTexture);
unsigned int rttSize = Settings::Manager::getInt("rtt size", "Water");
setViewport(0, 0, rttSize, rttSize);
@ -372,11 +372,11 @@ public:
int reflectionDetail = Settings::Manager::getInt("reflection detail", "Water");
reflectionDetail = std::min(4, std::max(isInterior ? 2 : 0, reflectionDetail));
unsigned int extraMask = 0;
if(reflectionDetail >= 1) extraMask |= Mask_Terrain;
if(reflectionDetail >= 2) extraMask |= Mask_Static;
if(reflectionDetail >= 3) extraMask |= Mask_Effect|Mask_ParticleSystem|Mask_Object;
if(reflectionDetail >= 4) extraMask |= Mask_Player|Mask_Actor;
setCullMask(Mask_Scene|Mask_Sky|Mask_Lighting|extraMask);
if(reflectionDetail >= 1) extraMask |= SceneUtil::Mask_Terrain;
if(reflectionDetail >= 2) extraMask |= SceneUtil::Mask_Static;
if(reflectionDetail >= 3) extraMask |= SceneUtil::Mask_Effect|SceneUtil::Mask_ParticleSystem|SceneUtil::Mask_Object;
if(reflectionDetail >= 4) extraMask |= SceneUtil::Mask_Player|SceneUtil::Mask_Actor;
setCullMask(SceneUtil::Mask_Scene|SceneUtil::Mask_Sky|SceneUtil::Mask_Lighting|extraMask);
}
void setWaterLevel(float waterLevel)
@ -441,7 +441,7 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem
mWaterGeom = SceneUtil::createWaterGeometry(Constants::CellSizeInUnits*150, 40, 900);
mWaterGeom->setDrawCallback(new DepthClampCallback);
mWaterGeom->setNodeMask(Mask_Water);
mWaterGeom->setNodeMask(SceneUtil::Mask_Water);
mWaterNode = new osg::PositionAttitudeTransform;
mWaterNode->setName("Water Root");
@ -451,7 +451,7 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem
// simple water fallback for the local map
osg::ref_ptr<osg::Geometry> geom2 (osg::clone(mWaterGeom.get(), osg::CopyOp::DEEP_COPY_NODES));
createSimpleWaterStateSet(geom2, Fallback::Map::getFloat("Water_Map_Alpha"));
geom2->setNodeMask(Mask_SimpleWater);
geom2->setNodeMask(SceneUtil::Mask_SimpleWater);
mWaterNode->addChild(geom2);
mSceneRoot->addChild(mWaterNode);
@ -706,11 +706,11 @@ void Water::update(float dt)
void Water::updateVisible()
{
bool visible = mEnabled && mToggled;
mWaterNode->setNodeMask(visible ? ~0 : 0);
mWaterNode->setNodeMask(visible ? SceneUtil::Mask_Default : SceneUtil::Mask_Disabled);
if (mRefraction)
mRefraction->setNodeMask(visible ? Mask_RenderToTexture : 0);
mRefraction->setNodeMask(visible ? SceneUtil::Mask_RenderToTexture : SceneUtil::Mask_Disabled);
if (mReflection)
mReflection->setNodeMask(visible ? Mask_RenderToTexture : 0);
mReflection->setNodeMask(visible ? SceneUtil::Mask_RenderToTexture : SceneUtil::Mask_Disabled);
}
bool Water::toggle()

@ -1042,31 +1042,27 @@ namespace MWScript
if (!ptr.isEmpty())
{
const std::string& script = ptr.getClass().getScript(ptr);
if (script.empty())
{
output << ptr.getCellRef().getRefId() << " has no script " << std::endl;
}
else
if (!script.empty())
{
const Compiler::Locals& locals =
MWBase::Environment::get().getScriptManager()->getLocals(script);
char type = locals.getType(var);
std::string refId = ptr.getCellRef().getRefId();
if (refId.find(' ') != std::string::npos)
refId = '"' + refId + '"';
switch (type)
{
case 'l':
case 's':
output << ptr.getCellRef().getRefId() << "." << var << ": " << ptr.getRefData().getLocals().getIntVar(script, var);
output << refId << "." << var << " = " << ptr.getRefData().getLocals().getIntVar(script, var);
break;
case 'f':
output << ptr.getCellRef().getRefId() << "." << var << ": " << ptr.getRefData().getLocals().getFloatVar(script, var);
break;
default:
output << "unknown local '" << var << "' for '" << ptr.getCellRef().getRefId() << "'";
output << refId << "." << var << " = " << ptr.getRefData().getLocals().getFloatVar(script, var);
break;
}
}
}
else
if (output.rdbuf()->in_avail() == 0)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
char type = world->getGlobalVariableType (var);
@ -1074,16 +1070,16 @@ namespace MWScript
switch (type)
{
case 's':
output << runtime.getContext().getGlobalShort (var);
output << var << " = " << runtime.getContext().getGlobalShort (var);
break;
case 'l':
output << runtime.getContext().getGlobalLong (var);
output << var << " = " << runtime.getContext().getGlobalLong (var);
break;
case 'f':
output << runtime.getContext().getGlobalFloat (var);
output << var << " = " << runtime.getContext().getGlobalFloat (var);
break;
default:
output << "unknown global variable";
output << "unknown variable";
}
}
runtime.getContext().report(output.str());

@ -349,7 +349,7 @@ namespace MWWorld
/// \attention This function also lists deleted (count 0) objects!
/// \return Iteration completed?
template<class Visitor>
bool forEach (Visitor& visitor)
bool forEach (Visitor&& visitor)
{
if (mState != State_Loaded)
return false;

@ -16,6 +16,7 @@
#include <components/sceneutil/controller.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include "../mwworld/manualref.hpp"
@ -35,7 +36,6 @@
#include "../mwmechanics/weapontype.hpp"
#include "../mwrender/animation.hpp"
#include "../mwrender/vismask.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "../mwrender/util.hpp"
@ -188,7 +188,7 @@ namespace MWWorld
bool rotate, bool createLight, osg::Vec4 lightDiffuseColor, std::string texture)
{
state.mNode = new osg::PositionAttitudeTransform;
state.mNode->setNodeMask(MWRender::Mask_Effect);
state.mNode->setNodeMask(SceneUtil::Mask_Effect);
state.mNode->setPosition(pos);
state.mNode->setAttitude(orient);
@ -228,7 +228,7 @@ namespace MWWorld
projectileLight->setPosition(osg::Vec4(pos, 1.0));
SceneUtil::LightSource* projectileLightSource = new SceneUtil::LightSource;
projectileLightSource->setNodeMask(MWRender::Mask_Lighting);
projectileLightSource->setNodeMask(SceneUtil::Mask_Lighting);
projectileLightSource->setRadius(66.f);
state.mNode->addChild(projectileLightSource);

@ -44,6 +44,7 @@
#include "../mwphysics/object.hpp"
#include "../mwphysics/heightfield.hpp"
#include "actionteleport.hpp"
#include "player.hpp"
#include "localscripts.hpp"
#include "esmstore.hpp"
@ -266,12 +267,22 @@ namespace
}
}
struct AdjustPositionVisitor
struct PositionVisitor
{
float mLowestPos = std::numeric_limits<float>::max();
bool operator() (const MWWorld::Ptr& ptr)
{
if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled())
{
if (!ptr.getClass().isActor())
{
float objectPosZ = ptr.getRefData().getPosition().pos[2];
if (objectPosZ < mLowestPos)
mLowestPos = objectPosZ;
}
ptr.getClass().adjustPosition (ptr, false);
}
return true;
}
};
@ -352,7 +363,7 @@ namespace MWWorld
End of tes3mp addition
*/
(*iter)->forEach<ListAndResetObjectsVisitor>(visitor);
(*iter)->forEach(visitor);
const auto world = MWBase::Environment::get().getWorld();
for (const auto& ptr : visitor.mObjects)
{
@ -529,6 +540,16 @@ namespace MWWorld
const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr();
navigator->update(player.getRefData().getPosition().asVec3());
const float fallThreshold = 256.f;
if (mCurrentCell && !mCurrentCell->isExterior() && pos.z() < mLowestPos - fallThreshold)
{
ESM::Position newPos;
std::string cellName = mCurrentCell->getCell()->mName;
MWBase::Environment::get().getWorld()->findInteriorPosition(cellName, newPos);
if (newPos.pos[2] >= mLowestPos)
MWWorld::ActionTeleport(cellName, newPos, false).execute(player);
}
if (!mCurrentCell || !mCurrentCell->isExterior())
return;
@ -949,8 +970,10 @@ namespace MWWorld
insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); });
// do adjustPosition (snapping actors to ground) after objects are loaded, so we don't depend on the loading order
AdjustPositionVisitor adjustPosVisitor;
cell.forEach (adjustPosVisitor);
// Also note the lowest object position in the cell to allow infinite fall fail safe to work
PositionVisitor posVisitor;
cell.forEach (posVisitor);
mLowestPos = posVisitor.mLowestPos;
}
void Scene::addObjectToScene (const Ptr& ptr)

@ -84,6 +84,7 @@ namespace MWWorld
float mPredictionTime;
osg::Vec3f mLastPlayerPos;
float mLowestPos;
void insertCell (CellStore &cell, Loading::Listener* loadingListener, bool test = false);

@ -45,6 +45,7 @@
#include <components/resource/resourcesystem.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/detournavigator/debug.hpp>
#include <components/detournavigator/navigatorimpl.hpp>
@ -68,7 +69,6 @@
#include "../mwrender/npcanimation.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "../mwrender/camera.hpp"
#include "../mwrender/vismask.hpp"
#include "../mwscript/globalscripts.hpp"
@ -2558,7 +2558,7 @@ namespace MWWorld
{
// Adjust position so the location we wanted ends up in the middle of the object bounding box
osg::ComputeBoundsVisitor computeBounds;
computeBounds.setTraversalMask(~MWRender::Mask_ParticleSystem);
computeBounds.setTraversalMask(~SceneUtil::Mask_ParticleSystem);
dropped.getRefData().getBaseNode()->accept(computeBounds);
osg::BoundingBox bounds = computeBounds.getBoundingBox();
if (bounds.valid())
@ -3242,28 +3242,15 @@ namespace MWWorld
}
}
struct ListObjectsVisitor
{
std::vector<MWWorld::Ptr> mObjects;
bool operator() (Ptr ptr)
{
if (ptr.getRefData().getBaseNode())
mObjects.push_back(ptr);
return true;
}
};
void World::getItemsOwnedBy (const MWWorld::ConstPtr& npc, std::vector<MWWorld::Ptr>& out)
{
for (CellStore* cellstore : mWorldScene->getActiveCells())
{
ListObjectsVisitor visitor;
cellstore->forEach(visitor);
for (const Ptr &object : visitor.mObjects)
if (Misc::StringUtils::ciEqual(object.getCellRef().getOwner(), npc.getCellRef().getRefId()))
out.push_back(object);
cellstore->forEach([&] (const auto& ptr) {
if (ptr.getRefData().getBaseNode() && Misc::StringUtils::ciEqual(ptr.getCellRef().getOwner(), npc.getCellRef().getRefId()))
out.push_back(ptr);
return true;
});
}
}

@ -73,14 +73,16 @@ namespace
TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_return_empty)
{
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut),
Status::NavMeshNotFound);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>());
}
TEST_F(DetourNavigatorNavigatorTest, find_path_for_existing_agent_with_no_navmesh_should_throw_exception)
{
mNavigator->addAgent(mAgentHalfExtents);
EXPECT_THROW(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), NavigatorException);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut),
Status::StartPolygonNotFound);
}
TEST_F(DetourNavigatorNavigatorTest, add_agent_should_count_each_agent)
@ -88,7 +90,8 @@ namespace
mNavigator->addAgent(mAgentHalfExtents);
mNavigator->addAgent(mAgentHalfExtents);
mNavigator->removeAgent(mAgentHalfExtents);
EXPECT_THROW(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), NavigatorException);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut),
Status::StartPolygonNotFound);
}
TEST_F(DetourNavigatorNavigatorTest, update_then_find_path_should_return_path)
@ -108,7 +111,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait();
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(-215, 215, 1.85963428020477294921875),
@ -158,7 +161,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait();
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, std::back_inserter(mPath));
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(-215, 215, 1.85963428020477294921875),
@ -191,7 +194,8 @@ namespace
mNavigator->wait();
mPath.clear();
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, std::back_inserter(mPath));
mOut = std::back_inserter(mPath);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(-215, 215, 1.87826788425445556640625),
@ -242,7 +246,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait();
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, std::back_inserter(mPath));
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(-215, 215, 1.87826788425445556640625),
@ -277,7 +281,8 @@ namespace
mNavigator->wait();
mPath.clear();
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut);
mOut = std::back_inserter(mPath);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(-215, 215, 1.85963428020477294921875),
@ -334,7 +339,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait();
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(-215, 215, 1.96328866481781005859375),
@ -390,7 +395,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait();
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(-215, 215, 1.9393787384033203125),
@ -443,7 +448,7 @@ namespace
mEnd.x() = 0;
mEnd.z() = 300;
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim, mOut);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(0, 215, 185.33331298828125),
@ -489,7 +494,8 @@ namespace
mStart.x() = 0;
mEnd.x() = 0;
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim | Flag_walk, mOut);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim | Flag_walk, mOut),
Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(0, 215, -94.75363922119140625),
@ -535,7 +541,8 @@ namespace
mStart.x() = 0;
mEnd.x() = 0;
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim | Flag_walk, mOut);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim | Flag_walk, mOut),
Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(0, 215, -94.75363922119140625),
@ -581,7 +588,7 @@ namespace
mStart.x() = 0;
mEnd.x() = 0;
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(0, 215, -94.75363922119140625),
@ -630,7 +637,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait();
mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mOut), Status::Success);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>({
osg::Vec3f(-215, 215, 1.85963428020477294921875),

@ -52,7 +52,7 @@ add_component_dir (shader
add_component_dir (sceneutil
clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller
lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil waterutil writescene serialize optimizer
actorutil detourdebugdraw navmesh agentpath shadow mwshadowtechnique
actorutil detourdebugdraw navmesh agentpath shadow mwshadowtechnique vismask
)
add_component_dir (nif

@ -2,6 +2,7 @@
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_H
#include "tilebounds.hpp"
#include "status.hpp"
#include <osg/io_utils>
@ -26,6 +27,25 @@ namespace DetourNavigator
return stream << "TileBounds {" << value.mMin << ", " << value.mMax << "}";
}
inline std::ostream& operator <<(std::ostream& stream, Status value)
{
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE(name) \
case Status::name: return stream << "DetourNavigator::Status::"#name;
switch (value)
{
OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE(Success)
OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE(NavMeshNotFound)
OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE(StartPolygonNotFound)
OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE(EndPolygonNotFound)
OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE(MoveAlongSurfaceFailed)
OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE(FindPathOverPolygonsFailed)
OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE(GetPolyHeightFailed)
OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE(InitNavMeshQueryFailed)
}
#undef OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_STATUS_MESSAGE
return stream << "DetourNavigator::Error::" << static_cast<int>(value);
}
class RecastMesh;
void writeToFile(const RecastMesh& recastMesh, const std::string& pathPrefix, const std::string& revision);

@ -14,7 +14,8 @@ namespace DetourNavigator
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const Settings& settings)
{
dtNavMeshQuery navMeshQuery;
initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes);
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes))
return boost::optional<osg::Vec3f>();
dtQueryFilter queryFilter;
queryFilter.setIncludeFlags(includeFlags);

@ -7,6 +7,7 @@
#include "settings.hpp"
#include "settingsutils.hpp"
#include "debug.hpp"
#include "status.hpp"
#include <DetourCommon.h>
#include <DetourNavMesh.h>
@ -97,11 +98,10 @@ namespace DetourNavigator
std::reference_wrapper<const Settings> mSettings;
};
inline void initNavMeshQuery(dtNavMeshQuery& value, const dtNavMesh& navMesh, const int maxNodes)
inline bool initNavMeshQuery(dtNavMeshQuery& value, const dtNavMesh& navMesh, const int maxNodes)
{
const auto status = value.init(&navMesh, maxNodes);
if (!dtStatusSucceed(status))
throw NavigatorException("Failed to init navmesh query");
return dtStatusSucceed(status);
}
struct MoveAlongSurfaceResult
@ -110,8 +110,8 @@ namespace DetourNavigator
std::vector<dtPolyRef> mVisited;
};
inline MoveAlongSurfaceResult moveAlongSurface(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef,
const osg::Vec3f& startPos, const osg::Vec3f& endPos, const dtQueryFilter& filter,
inline boost::optional<MoveAlongSurfaceResult> moveAlongSurface(const dtNavMeshQuery& navMeshQuery,
const dtPolyRef startRef, const osg::Vec3f& startPos, const osg::Vec3f& endPos, const dtQueryFilter& filter,
const std::size_t maxVisitedSize)
{
MoveAlongSurfaceResult result;
@ -120,18 +120,14 @@ namespace DetourNavigator
const auto status = navMeshQuery.moveAlongSurface(startRef, startPos.ptr(), endPos.ptr(),
&filter, result.mResultPos.ptr(), result.mVisited.data(), &visitedNumber, static_cast<int>(maxVisitedSize));
if (!dtStatusSucceed(status))
{
std::ostringstream message;
message << "Failed to move along surface from " << startPos << " to " << endPos;
throw NavigatorException(message.str());
}
return {};
assert(visitedNumber >= 0);
assert(visitedNumber <= static_cast<int>(maxVisitedSize));
result.mVisited.resize(static_cast<std::size_t>(visitedNumber));
return result;
return {std::move(result)};
}
inline std::vector<dtPolyRef> findPath(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef,
inline boost::optional<std::vector<dtPolyRef>> findPath(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef,
const dtPolyRef endRef, const osg::Vec3f& startPos, const osg::Vec3f& endPos, const dtQueryFilter& queryFilter,
const std::size_t maxSize)
{
@ -140,34 +136,26 @@ namespace DetourNavigator
const auto status = navMeshQuery.findPath(startRef, endRef, startPos.ptr(), endPos.ptr(), &queryFilter,
result.data(), &pathLen, static_cast<int>(maxSize));
if (!dtStatusSucceed(status))
{
std::ostringstream message;
message << "Failed to find path over polygons from " << startRef << " to " << endRef;
throw NavigatorException(message.str());
}
return {};
assert(pathLen >= 0);
assert(static_cast<std::size_t>(pathLen) <= maxSize);
result.resize(static_cast<std::size_t>(pathLen));
return result;
return {std::move(result)};
}
inline float getPolyHeight(const dtNavMeshQuery& navMeshQuery, const dtPolyRef ref, const osg::Vec3f& pos)
inline boost::optional<float> getPolyHeight(const dtNavMeshQuery& navMeshQuery, const dtPolyRef ref, const osg::Vec3f& pos)
{
float result = 0.0f;
const auto status = navMeshQuery.getPolyHeight(ref, pos.ptr(), &result);
if (!dtStatusSucceed(status))
{
std::ostringstream message;
message << "Failed to get polygon height ref=" << ref << " pos=" << pos;
throw NavigatorException(message.str());
}
return {};
return result;
}
template <class OutputIterator>
OutputIterator makeSmoothPath(const dtNavMesh& navMesh, const dtNavMeshQuery& navMeshQuery,
Status makeSmoothPath(const dtNavMesh& navMesh, const dtNavMeshQuery& navMeshQuery,
const dtQueryFilter& filter, const osg::Vec3f& start, const osg::Vec3f& end, const float stepSize,
std::vector<dtPolyRef> polygonPath, std::size_t maxSmoothPathSize, OutputIterator out)
std::vector<dtPolyRef> polygonPath, std::size_t maxSmoothPathSize, OutputIterator& out)
{
// Iterate over the path to find smooth path on the detail mesh surface.
osg::Vec3f iterPos;
@ -207,12 +195,15 @@ namespace DetourNavigator
const osg::Vec3f moveTgt = iterPos + delta * len;
const auto result = moveAlongSurface(navMeshQuery, polygonPath.front(), iterPos, moveTgt, filter, 16);
polygonPath = fixupCorridor(polygonPath, result.mVisited);
if (!result)
return Status::MoveAlongSurfaceFailed;
polygonPath = fixupCorridor(polygonPath, result->mVisited);
polygonPath = fixupShortcuts(polygonPath, navMeshQuery);
float h = 0;
navMeshQuery.getPolyHeight(polygonPath.front(), result.mResultPos.ptr(), &h);
iterPos = result.mResultPos;
navMeshQuery.getPolyHeight(polygonPath.front(), result->mResultPos.ptr(), &h);
iterPos = result->mResultPos;
iterPos.y() = h;
// Handle end of path and off-mesh links when close enough.
@ -259,7 +250,12 @@ namespace DetourNavigator
// Move position at the other side of the off-mesh link.
iterPos = endPos;
iterPos.y() = getPolyHeight(navMeshQuery, polygonPath.front(), iterPos);
const auto height = getPolyHeight(navMeshQuery, polygonPath.front(), iterPos);
if (!height)
return Status::GetPolyHeightFailed;
iterPos.y() = *height;
}
}
@ -268,16 +264,17 @@ namespace DetourNavigator
++smoothPathSize;
}
return out;
return Status::Success;
}
template <class OutputIterator>
OutputIterator findSmoothPath(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, const float stepSize,
Status findSmoothPath(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, const float stepSize,
const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags,
const Settings& settings, OutputIterator out)
const Settings& settings, OutputIterator& out)
{
dtNavMeshQuery navMeshQuery;
initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes);
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes))
return Status::InitNavMeshQueryFailed;
dtQueryFilter queryFilter;
queryFilter.setIncludeFlags(includeFlags);
@ -293,7 +290,7 @@ namespace DetourNavigator
}
if (startRef == 0)
throw NavigatorException("Navmesh polygon for start point is not found");
return Status::StartPolygonNotFound;
dtPolyRef endRef = 0;
osg::Vec3f endPolygonPosition;
@ -306,18 +303,20 @@ namespace DetourNavigator
}
if (endRef == 0)
throw NavigatorException("Navmesh polygon for end polygon is not found");
return Status::EndPolygonNotFound;
const auto polygonPath = findPath(navMeshQuery, startRef, endRef, start, end, queryFilter,
settings.mMaxPolygonPathSize);
if (polygonPath.empty() || polygonPath.back() != endRef)
return out;
if (!polygonPath)
return Status::FindPathOverPolygonsFailed;
makeSmoothPath(navMesh, navMeshQuery, queryFilter, start, end, stepSize, std::move(polygonPath),
settings.mMaxSmoothPathSize, OutputTransformIterator<OutputIterator>(out, settings));
if (polygonPath->empty() || polygonPath->back() != endRef)
return Status::Success;
return out;
auto outTransform = OutputTransformIterator<OutputIterator>(out, settings);
return makeSmoothPath(navMesh, navMeshQuery, queryFilter, start, end, stepSize, std::move(*polygonPath),
settings.mMaxSmoothPathSize, outTransform);
}
}

@ -1,4 +1,4 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATOR_H
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATOR_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATOR_H
#include "findsmoothpath.hpp"
@ -159,8 +159,8 @@ namespace DetourNavigator
* Equal to out if no path is found.
*/
template <class OutputIterator>
boost::optional<OutputIterator> findPath(const osg::Vec3f& agentHalfExtents, const float stepSize, const osg::Vec3f& start,
const osg::Vec3f& end, const Flags includeFlags, OutputIterator out) const
Status findPath(const osg::Vec3f& agentHalfExtents, const float stepSize, const osg::Vec3f& start,
const osg::Vec3f& end, const Flags includeFlags, OutputIterator& out) const
{
static_assert(
std::is_same<
@ -171,7 +171,7 @@ namespace DetourNavigator
);
const auto navMesh = getNavMesh(agentHalfExtents);
if (!navMesh)
return {};
return Status::NavMeshNotFound;
const auto settings = getSettings();
return findSmoothPath(navMesh->lockConst()->getImpl(), toNavMeshCoordinates(settings, agentHalfExtents),
toNavMeshCoordinates(settings, stepSize), toNavMeshCoordinates(settings, start),

@ -0,0 +1,43 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_STATUS_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_STATUS_H
namespace DetourNavigator
{
enum class Status
{
Success,
NavMeshNotFound,
StartPolygonNotFound,
EndPolygonNotFound,
MoveAlongSurfaceFailed,
FindPathOverPolygonsFailed,
GetPolyHeightFailed,
InitNavMeshQueryFailed,
};
constexpr const char* getMessage(Status value)
{
switch (value)
{
case Status::Success:
return "success";
case Status::NavMeshNotFound:
return "navmesh is not found";
case Status::StartPolygonNotFound:
return "polygon for start position is not found on navmesh";
case Status::EndPolygonNotFound:
return "polygon for end position is not found on navmesh";
case Status::MoveAlongSurfaceFailed:
return "move along surface on navmesh is failed";
case Status::FindPathOverPolygonsFailed:
return "path over navmesh polygons is not found";
case Status::GetPolyHeightFailed:
return "failed to get polygon height";
case Status::InitNavMeshQueryFailed:
return "failed to init navmesh query";
}
return "unknown error";
}
}
#endif

@ -110,6 +110,7 @@ namespace ESM
void Cell::loadCell(ESMReader &esm, bool saveContext)
{
bool isLoaded = false;
mHasAmbi = false;
while (!isLoaded && esm.hasMoreSubs())
{
esm.getSubName();
@ -127,6 +128,7 @@ namespace ESM
break;
case ESM::FourCC<'A','M','B','I'>::value:
esm.getHT(mAmbi);
mHasAmbi = true;
break;
case ESM::FourCC<'R','G','N','N'>::value:
mRegion = esm.getHString();
@ -182,7 +184,12 @@ namespace ESM
if (mData.mFlags & QuasiEx)
esm.writeHNOCString("RGNN", mRegion);
else
esm.writeHNT("AMBI", mAmbi, 16);
{
// Try to avoid saving ambient lighting information when it's unnecessary.
// This is to fix black lighting in resaved cell records that lack this information.
if (mHasAmbi)
esm.writeHNT("AMBI", mAmbi, 16);
}
}
else
{
@ -272,6 +279,7 @@ namespace ESM
mData.mX = 0;
mData.mY = 0;
mHasAmbi = true;
mAmbi.mAmbient = 0;
mAmbi.mSunlight = 0;
mAmbi.mFog = 0;

@ -90,6 +90,7 @@ struct Cell
Cell() : mName(""),
mRegion(""),
mHasAmbi(true),
mWater(0),
mWaterInt(false),
mMapColor(0),
@ -108,6 +109,7 @@ struct Cell
CellId mCellId;
AMBIstruct mAmbi;
bool mHasAmbi;
float mWater; // Water level
bool mWaterInt;
@ -152,6 +154,16 @@ struct Cell
return ((mData.mFlags&HasWater) != 0) || isExterior();
}
bool hasAmbient() const
{
return mHasAmbi;
}
void setHasAmbient(bool hasAmbi)
{
mHasAmbi = hasAmbi;
}
// Restore the given reader to the stored position. Will try to open
// the file matching the stored file name. If you want to read from
// somewhere other than the file system, you need to pre-open the

@ -14,7 +14,7 @@ namespace osgMyGUI
{
/// @brief A Layer rendering with additive blend mode.
class AdditiveLayer : public MyGUI::OverlappedLayer
class AdditiveLayer final : public MyGUI::OverlappedLayer
{
public:
MYGUI_RTTI_DERIVED( AdditiveLayer )
@ -22,7 +22,7 @@ namespace osgMyGUI
AdditiveLayer();
~AdditiveLayer();
virtual void renderToTarget(MyGUI::IRenderTarget* _target, bool _update);
void renderToTarget(MyGUI::IRenderTarget* _target, bool _update) final;
private:
osg::ref_ptr<osg::StateSet> mStateSet;

@ -8,18 +8,18 @@ namespace osgMyGUI
///@brief A Layer that lays out and renders widgets in screen-relative coordinates. The "Size" property determines the size of the virtual screen,
/// which is then upscaled to the real screen size during rendering. The aspect ratio is kept intact, adding blanks to the sides when necessary.
class ScalingLayer : public MyGUI::OverlappedLayer
class ScalingLayer final : public MyGUI::OverlappedLayer
{
public:
MYGUI_RTTI_DERIVED(ScalingLayer)
virtual void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version);
void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) final;
virtual MyGUI::ILayerItem* getLayerItemByPoint(int _left, int _top) const;
virtual MyGUI::IntPoint getPosition(int _left, int _top) const;
virtual void renderToTarget(MyGUI::IRenderTarget* _target, bool _update);
MyGUI::ILayerItem* getLayerItemByPoint(int _left, int _top) const final;
MyGUI::IntPoint getPosition(int _left, int _top) const final;
void renderToTarget(MyGUI::IRenderTarget* _target, bool _update) final;
virtual void resizeView(const MyGUI::IntSize& _viewSize);
void resizeView(const MyGUI::IntSize& _viewSize) final;
private:
void screenToLayerCoords(int& _left, int& _top) const;

@ -48,6 +48,7 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
newFactory.insert(makeEntry("NiSwitchNode", &construct <NiSwitchNode> , RC_NiSwitchNode ));
newFactory.insert(makeEntry("NiLODNode", &construct <NiLODNode> , RC_NiLODNode ));
newFactory.insert(makeEntry("AvoidNode", &construct <NiNode> , RC_AvoidNode ));
newFactory.insert(makeEntry("NiCollisionSwitch", &construct <NiNode> , RC_NiCollisionSwitch ));
newFactory.insert(makeEntry("NiBSParticleNode", &construct <NiNode> , RC_NiBSParticleNode ));
newFactory.insert(makeEntry("NiBSAnimationNode", &construct <NiNode> , RC_NiBSAnimationNode ));
newFactory.insert(makeEntry("NiBillboardNode", &construct <NiNode> , RC_NiBillboardNode ));

@ -84,7 +84,8 @@ struct NiNode : Node
enum Flags {
Flag_Hidden = 0x0001,
Flag_MeshCollision = 0x0002,
Flag_BBoxCollision = 0x0004
Flag_BBoxCollision = 0x0004,
Flag_ActiveCollision = 0x0020
};
enum BSAnimFlags {
AnimFlag_AutoPlay = 0x0020

@ -40,6 +40,7 @@ enum RecordType
RC_NiLODNode,
RC_NiBillboardNode,
RC_AvoidNode,
RC_NiCollisionSwitch,
RC_NiTriShape,
RC_NiTriStrips,
RC_NiRotatingParticles,

@ -254,6 +254,10 @@ bool BulletNifLoader::hasAutoGeneratedCollision(const Nif::Node* rootNode)
void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *node, int flags,
bool isCollisionNode, bool isAnimated, bool autogenerated, bool avoid)
{
// TODO: allow on-the fly collision switching via toggling this flag
if (node->recType == Nif::RC_NiCollisionSwitch && !(node->flags & Nif::NiNode::Flag_ActiveCollision))
return;
// Accumulate the flags from all the child nodes. This works for all
// the flags we currently use, at least.
flags |= node->flags;

@ -10,6 +10,7 @@
#include <components/nif/data.hpp>
#include <components/sceneutil/morphgeometry.hpp>
#include <components/sceneutil/vismask.hpp>
#include "userdata.hpp"
@ -304,7 +305,7 @@ void VisController::operator() (osg::Node* node, osg::NodeVisitor* nv)
{
bool vis = calculate(getInputValue(nv));
// Leave 0x1 enabled for UpdateVisitor, so we can make ourselves visible again in the future from this update callback
node->setNodeMask(vis ? ~0 : 0x1);
node->setNodeMask(vis ? SceneUtil::Mask_Default : SceneUtil::Mask_UpdateVisitor);
}
traverse(node, nv);
}

@ -16,6 +16,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/imagemanager.hpp>
#include <components/sceneutil/util.hpp>
#include <components/sceneutil/vismask.hpp>
// particle
#include <osgParticle/ParticleSystem>
@ -167,6 +168,19 @@ namespace
namespace NifOsg
{
class CollisionSwitch : public osg::Group
{
public:
CollisionSwitch(bool enabled) : osg::Group()
{
setEnabled(enabled);
}
void setEnabled(bool enabled)
{
setNodeMask(enabled ? SceneUtil::Mask_Default : SceneUtil::Mask_Effect);
}
};
bool Loader::sShowMarkers = false;
@ -460,6 +474,14 @@ namespace NifOsg
case Nif::RC_NiBillboardNode:
dataVariance = osg::Object::DYNAMIC;
break;
case Nif::RC_NiCollisionSwitch:
{
bool enabled = nifNode->flags & Nif::NiNode::Flag_ActiveCollision;
node = new CollisionSwitch(enabled);
dataVariance = osg::Object::STATIC;
break;
}
default:
// The Root node can be created as a Group if no transformation is required.
// This takes advantage of the fact root nodes can't have additional controllers
@ -553,7 +575,7 @@ namespace NifOsg
{
skipMeshes = true;
// Leave mask for UpdateVisitor enabled
node->setNodeMask(0x1);
node->setNodeMask(SceneUtil::Mask_UpdateVisitor);
}
// We can skip creating meshes for hidden nodes if they don't have a VisController that
@ -568,7 +590,7 @@ namespace NifOsg
skipMeshes = true; // skip child meshes, but still create the child node hierarchy for animating collision shapes
// now hide this node, but leave the mask for UpdateVisitor enabled so that KeyframeController works
node->setNodeMask(0x1);
node->setNodeMask(SceneUtil::Mask_UpdateVisitor);
}
if ((skipMeshes || hasMarkers) && isAnimated) // make sure the empty node is not optimized away so the physicssystem can find it.

@ -12,6 +12,7 @@
#include <osgViewer/Renderer>
#include <components/myguiplatform/myguidatamanager.hpp>
#include <components/sceneutil/vismask.hpp>
namespace Resource
{
@ -103,14 +104,14 @@ void StatsHandler::toggle(osgViewer::ViewerBase *viewer)
if (!_statsType)
{
_camera->setNodeMask(0);
_camera->setNodeMask(SceneUtil::Mask_Disabled);
_switch->setAllChildrenOff();
viewer->getViewerStats()->collectStats("resource", false);
}
else
{
_camera->setNodeMask(0xffffffff);
_camera->setNodeMask(SceneUtil::Mask_Default);
_switch->setSingleChildOn(_resourceStatsChildNum);
viewer->getViewerStats()->collectStats("resource", true);

@ -11,6 +11,7 @@
#include "lightcontroller.hpp"
#include "util.hpp"
#include "visitor.hpp"
#include "vismask.hpp"
#include "positionattitudetransform.hpp"
namespace SceneUtil
@ -58,7 +59,7 @@ namespace SceneUtil
light->setQuadraticAttenuation(quadraticAttenuation);
}
void addLight (osg::Group* node, const ESM::Light* esmLight, unsigned int partsysMask, unsigned int lightMask, bool isExterior)
void addLight (osg::Group* node, const ESM::Light* esmLight, bool isExterior)
{
SceneUtil::FindByNameVisitor visitor("AttachLight");
node->accept(visitor);
@ -71,7 +72,7 @@ namespace SceneUtil
else
{
osg::ComputeBoundsVisitor computeBound;
computeBound.setTraversalMask(~partsysMask);
computeBound.setTraversalMask(~SceneUtil::Mask_ParticleSystem);
// 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);
@ -85,15 +86,15 @@ namespace SceneUtil
attachTo = trans;
}
osg::ref_ptr<LightSource> lightSource = createLightSource(esmLight, lightMask, isExterior);
osg::ref_ptr<LightSource> lightSource = createLightSource(esmLight, isExterior);
attachTo->addChild(lightSource);
}
osg::ref_ptr<LightSource> createLightSource(const ESM::Light* esmLight, unsigned int lightMask, bool isExterior, const osg::Vec4f& ambient)
osg::ref_ptr<LightSource> createLightSource(const ESM::Light* esmLight, bool isExterior, const osg::Vec4f& ambient)
{
osg::ref_ptr<SceneUtil::LightSource> lightSource (new SceneUtil::LightSource);
osg::ref_ptr<osg::Light> light (new osg::Light);
lightSource->setNodeMask(lightMask);
lightSource->setNodeMask(SceneUtil::Mask_Lighting);
float radius = esmLight->mData.mRadius;
lightSource->setRadius(radius);

@ -32,14 +32,14 @@ namespace SceneUtil
/// @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.
void addLight (osg::Group* node, const ESM::Light* esmLight, unsigned int partsysMask, unsigned int lightMask, bool isExterior);
void addLight (osg::Group* node, const ESM::Light* esmLight, bool isExterior);
/// @brief Convert an ESM::Light to a SceneUtil::LightSource, and return it.
/// @param esmLight The light definition coming from the game files containing radius, color, flicker, etc.
/// @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.
/// @param ambient Ambient component of the light.
osg::ref_ptr<LightSource> createLightSource (const ESM::Light* esmLight, unsigned int lightMask, bool isExterior, const osg::Vec4f& ambient=osg::Vec4f(0,0,0,1));
osg::ref_ptr<LightSource> createLightSource (const ESM::Light* esmLight, bool isExterior, const osg::Vec4f& ambient=osg::Vec4f(0,0,0,1));
}

@ -22,6 +22,8 @@
#include <osg/Transform>
#include <osg/Texture2D>
#include <components/sceneutil/vismask.hpp>
//#include <osgUtil/Export>
#include <set>
@ -42,7 +44,7 @@ class BaseOptimizerVisitor : public osg::NodeVisitor
_optimizer(optimizer),
_operationType(operation)
{
setNodeMaskOverride(0xffffffff);
setNodeMaskOverride(SceneUtil::Mask_Default);
}
inline bool isOperationPermissibleForObject(const osg::StateSet* object) const;

@ -2,6 +2,7 @@
#include <osgShadow/ShadowedScene>
#include <components/sceneutil/vismask.hpp>
#include <components/settings/settings.hpp>
namespace SceneUtil
@ -21,7 +22,7 @@ namespace SceneUtil
mShadowTechnique->enableShadows();
mShadowSettings->setLightNum(0);
mShadowSettings->setReceivesShadowTraversalMask(~0u);
mShadowSettings->setReceivesShadowTraversalMask(SceneUtil::Mask_Default);
int numberOfShadowMapsPerLight = Settings::Manager::getInt("number of shadow maps", "Shadows");
numberOfShadowMapsPerLight = std::max(1, std::min(numberOfShadowMapsPerLight, 8));

@ -1,7 +1,7 @@
#ifndef OPENMW_MWRENDER_VISMASK_H
#define OPENMW_MWRENDER_VISMASK_H
#ifndef OPENMW_COMPONENTS_SCENEUTIL_VISMASK_H
#define OPENMW_COMPONENTS_SCENEUTIL_VISMASK_H
namespace MWRender
namespace SceneUtil
{
/// Node masks used for controlling visibility of game objects.
@ -21,6 +21,8 @@ namespace MWRender
/// compatibility if the enumeration values were to be changed. Feel free to change them when it makes sense.
enum VisMask
{
Mask_Disabled = 0, // For hidden nodes
Mask_UpdateVisitor = 0x1, // reserved for separating UpdateVisitors from CullVisitors
// child of Scene
@ -53,7 +55,19 @@ namespace MWRender
Mask_PreCompile = (1<<18),
// Set on a camera's cull mask to enable the LightManager
Mask_Lighting = (1<<19)
Mask_Lighting = (1<<19),
// For pathgrid nodes debugging
Mask_Pathgrid = (1<<20),
// Editor control elements
Mask_EditorCellMarker = (1<<21),
Mask_EditorCellArrow = (1<<22),
Mask_EditorCellBorder = (1<<23),
Mask_EditorReference = (1<<24),
// Default mask for OSG nodes
Mask_Default = 0xffffffff
};
}

@ -4,16 +4,17 @@
#include <osg/Geometry>
#include <osg/Geode>
#include <components/sceneutil/vismask.hpp>
#include "world.hpp"
#include "../esm/loadland.hpp"
namespace Terrain
{
CellBorder::CellBorder(Terrain::World *world, osg::Group *root, int borderMask):
CellBorder::CellBorder(Terrain::World *world, osg::Group *root):
mWorld(world),
mRoot(root),
mBorderMask(borderMask)
mRoot(root)
{
}
@ -69,7 +70,7 @@ void CellBorder::createCellBorderGeometry(int x, int y)
polygonmode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
stateSet->setAttributeAndModes(polygonmode,osg::StateAttribute::ON);
borderGeode->setNodeMask(mBorderMask);
borderGeode->setNodeMask(SceneUtil::Mask_Debug);
mRoot->addChild(borderGeode);

@ -16,7 +16,7 @@ namespace Terrain
public:
typedef std::map<std::pair<int, int>, osg::ref_ptr<osg::Node> > CellGrid;
CellBorder(Terrain::World *world, osg::Group *root, int borderMask);
CellBorder(Terrain::World *world, osg::Group *root);
void createCellBorderGeometry(int x, int y);
void destroyCellBorderGeometry(int x, int y);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save