1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 22:23:51 +00:00

Add OpenMW commits up to 19 Feb 2020

# Conflicts:
#	apps/openmw/mwworld/scene.cpp
This commit is contained in:
David Cernat 2020-02-20 01:51:47 +02:00
commit 85fb1d1a0b
117 changed files with 807 additions and 599 deletions

View file

@ -192,10 +192,15 @@
Bug #5239: OpenMW-CS does not support non-ASCII characters in path names Bug #5239: OpenMW-CS does not support non-ASCII characters in path names
Bug #5241: On-self absorb spells cannot be detected Bug #5241: On-self absorb spells cannot be detected
Bug #5242: ExplodeSpell behavior differs from Cast behavior 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 #5249: Wandering NPCs start walking too soon after they hello
Bug #5250: Creatures display shield ground mesh instead of shield body part Bug #5250: Creatures display shield ground mesh instead of shield body part
Bug #5255: "GetTarget, player" doesn't return 1 during NPC hello 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 #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 #1774: Handle AvoidNode
Feature #2229: Improve pathfinding AI Feature #2229: Improve pathfinding AI
Feature #3025: Analogue gamepad movement controls Feature #3025: Analogue gamepad movement controls

View file

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

View file

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

View file

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

View file

@ -867,6 +867,8 @@ namespace CSMWorld
switch (subColIndex) switch (subColIndex)
{ {
case 0: return isInterior; 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) ? case 1: return (isInterior && !behaveLikeExterior) ?
cell.mAmbi.mAmbient : QVariant(QVariant::UserType); cell.mAmbi.mAmbient : QVariant(QVariant::UserType);
case 2: return (isInterior && !behaveLikeExterior) ? case 2: return (isInterior && !behaveLikeExterior) ?
@ -912,7 +914,10 @@ namespace CSMWorld
case 1: case 1:
{ {
if (isInterior && !behaveLikeExterior) if (isInterior && !behaveLikeExterior)
{
cell.mAmbi.mAmbient = static_cast<int32_t>(value.toInt()); cell.mAmbi.mAmbient = static_cast<int32_t>(value.toInt());
cell.setHasAmbient(true);
}
else else
return; // return without saving return; // return without saving
break; break;
@ -920,7 +925,10 @@ namespace CSMWorld
case 2: case 2:
{ {
if (isInterior && !behaveLikeExterior) if (isInterior && !behaveLikeExterior)
{
cell.mAmbi.mSunlight = static_cast<int32_t>(value.toInt()); cell.mAmbi.mSunlight = static_cast<int32_t>(value.toInt());
cell.setHasAmbient(true);
}
else else
return; // return without saving return; // return without saving
break; break;
@ -928,7 +936,10 @@ namespace CSMWorld
case 3: case 3:
{ {
if (isInterior && !behaveLikeExterior) if (isInterior && !behaveLikeExterior)
{
cell.mAmbi.mFog = static_cast<int32_t>(value.toInt()); cell.mAmbi.mFog = static_cast<int32_t>(value.toInt());
cell.setHasAmbient(true);
}
else else
return; // return without saving return; // return without saving
break; break;
@ -936,7 +947,10 @@ namespace CSMWorld
case 4: case 4:
{ {
if (isInterior && !behaveLikeExterior) if (isInterior && !behaveLikeExterior)
{
cell.mAmbi.mFogDensity = value.toFloat(); cell.mAmbi.mFogDensity = value.toFloat();
cell.setHasAmbient(true);
}
else else
return; // return without saving return; // return without saving
break; break;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -17,6 +17,7 @@
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/sceneutil/lightmanager.hpp> #include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../widget/scenetoolmode.hpp" #include "../widget/scenetoolmode.hpp"
@ -25,7 +26,6 @@
#include "../../model/prefs/shortcuteventhandler.hpp" #include "../../model/prefs/shortcuteventhandler.hpp"
#include "lighting.hpp" #include "lighting.hpp"
#include "mask.hpp"
#include "cameracontroller.hpp" #include "cameracontroller.hpp"
namespace CSVRender namespace CSVRender
@ -71,7 +71,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager; SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager;
lightMgr->setStartLight(1); lightMgr->setStartLight(1);
lightMgr->setLightingMask(Mask_Lighting); lightMgr->setLightingMask(SceneUtil::Mask_Lighting);
mRootNode = lightMgr; mRootNode = lightMgr;
mView->getCamera()->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); 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 // Add ability to signal osg to show its statistics for debugging purposes
mView->addEventHandler(new osgViewer::StatsHandler); mView->addEventHandler(new osgViewer::StatsHandler);
mView->getCamera()->setCullMask(~(Mask_UpdateVisitor)); mView->getCamera()->setCullMask(~(SceneUtil::Mask_UpdateVisitor));
viewer.addView(mView); viewer.addView(mView);
viewer.setDone(false); viewer.setDone(false);
@ -100,6 +100,14 @@ RenderWidget::~RenderWidget()
try try
{ {
CompositeViewer::get().removeView(mView); 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) catch(const std::exception& e)
{ {
@ -114,7 +122,7 @@ void RenderWidget::flagAsModified()
void RenderWidget::setVisibilityMask(int mask) 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() osg::Camera *RenderWidget::getCamera()
@ -204,7 +212,7 @@ SceneWidget::SceneWidget(std::shared_ptr<Resource::ResourceSystem> resourceSyste
mOrbitCamControl = new OrbitCameraController(this); mOrbitCamControl = new OrbitCameraController(this);
mCurrentCamControl = mFreeCamControl; 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() ); 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); setLighting(&mLightingDay);
mResourceSystem->getSceneManager()->setParticleSystemMask(Mask_ParticleSystem); mResourceSystem->getSceneManager()->setParticleSystemMask(SceneUtil::Mask_ParticleSystem);
// Recieve mouse move event even if mouse button is not pressed // Recieve mouse move event even if mouse button is not pressed
setMouseTracking(true); setMouseTracking(true);
@ -342,7 +350,7 @@ void SceneWidget::update(double dt)
} }
else else
{ {
mCurrentCamControl->setup(mRootNode, Mask_Reference | Mask_Terrain, CameraController::WorldUp); mCurrentCamControl->setup(mRootNode, SceneUtil::Mask_EditorReference | SceneUtil::Mask_Terrain, CameraController::WorldUp);
mCamPositionSet = true; mCamPositionSet = true;
} }
} }

View file

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

View file

@ -1,9 +1,9 @@
#include "tagbase.hpp" #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; return mMask;
} }

View file

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

View file

@ -17,6 +17,7 @@
#include <components/esm/loadland.hpp> #include <components/esm/loadland.hpp>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../widget/brushshapes.hpp" #include "../widget/brushshapes.hpp"
#include "../widget/modebutton.hpp" #include "../widget/modebutton.hpp"
@ -38,13 +39,12 @@
#include "editmode.hpp" #include "editmode.hpp"
#include "pagedworldspacewidget.hpp" #include "pagedworldspacewidget.hpp"
#include "mask.hpp"
#include "tagbase.hpp" #include "tagbase.hpp"
#include "terrainselection.hpp" #include "terrainselection.hpp"
#include "worldspacewidget.hpp" #include "worldspacewidget.hpp"
CSVRender::TerrainShapeMode::TerrainShapeMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent) 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) mParentNode(parentNode)
{ {
} }

View file

@ -13,6 +13,7 @@
#include <osg/Group> #include <osg/Group>
#include <components/esm/loadland.hpp> #include <components/esm/loadland.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../widget/modebutton.hpp" #include "../widget/modebutton.hpp"
#include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolbar.hpp"
@ -34,12 +35,11 @@
#include "editmode.hpp" #include "editmode.hpp"
#include "pagedworldspacewidget.hpp" #include "pagedworldspacewidget.hpp"
#include "mask.hpp"
#include "object.hpp" // Something small needed regarding pointers from here () #include "object.hpp" // Something small needed regarding pointers from here ()
#include "worldspacewidget.hpp" #include "worldspacewidget.hpp"
CSVRender::TerrainTextureMode::TerrainTextureMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent) 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"), mBrushTexture("L0#0"),
mBrushSize(1), mBrushSize(1),
mBrushShape(0), mBrushShape(0),

View file

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

View file

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

View file

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

View file

@ -18,7 +18,7 @@ set(GAME_HEADER
source_group(game FILES ${GAME} ${GAME_HEADER}) source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender 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 creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
renderbin actoranimation landmanager navmesh actorspaths renderbin actoranimation landmanager navmesh actorspaths

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -817,7 +817,7 @@ namespace
}; };
} }
class PageDisplay : public MyGUI::ISubWidgetText class PageDisplay final : public MyGUI::ISubWidgetText
{ {
MYGUI_RTTI_DERIVED(PageDisplay) MYGUI_RTTI_DERIVED(PageDisplay)
protected: protected:
@ -1140,7 +1140,7 @@ public:
i->second->createDrawItem (mNode); i->second->createDrawItem (mNode);
} }
void setVisible (bool newVisible) void setVisible (bool newVisible) final
{ {
if (mVisible == newVisible) if (mVisible == newVisible)
return; 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; mNode = node;
@ -1230,9 +1230,9 @@ public:
// ISubWidget should not necessarily be a drawitem // ISubWidget should not necessarily be a drawitem
// in this case, it is not... // in this case, it is not...
void doRender() { } void doRender() final { }
void _updateView () void _updateView () final
{ {
_checkMargin(); _checkMargin();
@ -1241,7 +1241,7 @@ public:
mNode->outOfDate (i->second->mRenderItem); mNode->outOfDate (i->second->mRenderItem);
} }
void _correctView() void _correctView() final
{ {
_checkMargin (); _checkMargin ();
@ -1251,7 +1251,7 @@ public:
} }
void destroyDrawItem() void destroyDrawItem() final
{ {
for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i)
i->second->destroyDrawItem (mNode); i->second->destroyDrawItem (mNode);
@ -1261,7 +1261,7 @@ public:
}; };
class BookPageImpl : public BookPage class BookPageImpl final : public BookPage
{ {
MYGUI_RTTI_DERIVED(BookPage) MYGUI_RTTI_DERIVED(BookPage)
public: 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); mPageDisplay->showPage (book, page);
} }
void adviseLinkClicked (std::function <void (InteractiveId)> linkClicked) void adviseLinkClicked (std::function <void (InteractiveId)> linkClicked) final
{ {
mPageDisplay->mLinkClicked = linkClicked; mPageDisplay->mLinkClicked = linkClicked;
} }
void unadviseLinkClicked () void unadviseLinkClicked () final
{ {
mPageDisplay->mLinkClicked = std::function <void (InteractiveId)> (); mPageDisplay->mLinkClicked = std::function <void (InteractiveId)> ();
} }
protected: protected:
virtual void initialiseOverride() void initialiseOverride() final
{ {
Base::initialiseOverride(); 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). // 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. // Child widgets may already be destroyed! So be careful.
mPageDisplay->onMouseLostFocus (); mPageDisplay->onMouseLostFocus ();
} }
void onMouseMove(int left, int top) void onMouseMove(int left, int top) final
{ {
mPageDisplay->onMouseMove (left, top); 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); 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); mPageDisplay->onMouseButtonReleased (left, top, id);
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -44,7 +44,7 @@ namespace MWMechanics
void fastForward(const MWWorld::Ptr& actor, AiState& state); 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: private:
std::string mCellId; std::string mCellId;

View file

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

View file

@ -102,7 +102,7 @@ namespace MWMechanics
/// Return true if this package should repeat. Currently only used for Wander packages. /// Return true if this package should repeat. Currently only used for Wander packages.
virtual bool getRepeat() const; 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. // Return true if any loaded actor with this AI package must be active.
virtual bool alwaysActive() const { return false; } virtual bool alwaysActive() const { return false; }

View file

@ -36,7 +36,7 @@ namespace MWMechanics
virtual bool alwaysActive() const { return true; } 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: private:
float mX; float mX;

View file

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

View file

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

View file

@ -1334,10 +1334,10 @@ namespace MWMechanics
return false; 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); DynamicStat<float> stat = creatureStats.getDynamic(index);
stat.setCurrent(stat.getCurrent() + magnitude, index == 2); stat.setCurrent(stat.getCurrent() + magnitude, allowDecreaseBelowZero);
creatureStats.setDynamic(index, stat); creatureStats.setDynamic(index, stat);
} }
@ -1376,9 +1376,12 @@ namespace MWMechanics
case ESM::MagicEffect::DamageMagicka: case ESM::MagicEffect::DamageMagicka:
case ESM::MagicEffect::DamageFatigue: 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; break;
}
case ESM::MagicEffect::AbsorbHealth: case ESM::MagicEffect::AbsorbHealth:
if (magnitude > 0.f) if (magnitude > 0.f)
receivedMagicDamage = true; receivedMagicDamage = true;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -6,9 +6,9 @@
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/sceneutil/controller.hpp> #include <components/sceneutil/controller.hpp>
#include <components/sceneutil/vismask.hpp>
#include "animation.hpp" #include "animation.hpp"
#include "vismask.hpp"
#include "util.hpp" #include "util.hpp"
namespace MWRender 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); osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(model);
node->setNodeMask(Mask_Effect); node->setNodeMask(SceneUtil::Mask_Effect);
Effect effect; Effect effect;
effect.mAnimTime.reset(new EffectAnimationTime); effect.mAnimTime.reset(new EffectAnimationTime);

View file

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

View file

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

View file

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

View file

@ -18,6 +18,7 @@
#include <components/sceneutil/actorutil.hpp> #include <components/sceneutil/actorutil.hpp>
#include <components/sceneutil/attach.hpp> #include <components/sceneutil/attach.hpp>
#include <components/sceneutil/visitor.hpp> #include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/sceneutil/skeleton.hpp> #include <components/sceneutil/skeleton.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -43,7 +44,6 @@
#include "camera.hpp" #include "camera.hpp"
#include "rotatecontroller.hpp" #include "rotatecontroller.hpp"
#include "renderbin.hpp" #include "renderbin.hpp"
#include "vismask.hpp"
namespace namespace
{ {
@ -81,6 +81,34 @@ std::string getVampireHead(const std::string& race, bool female)
return "meshes\\" + bodyPart->mModel; 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); addAnimSource(smodel, smodel);
mObjectRoot->setNodeMask(Mask_FirstPerson); mObjectRoot->setNodeMask(SceneUtil::Mask_FirstPerson);
mObjectRoot->addCullCallback(new OverrideFieldOfViewCallback(mFirstPersonFieldOfView)); mObjectRoot->addCullCallback(new OverrideFieldOfViewCallback(mFirstPersonFieldOfView));
} }
@ -519,36 +547,9 @@ std::string NpcAnimation::getShieldMesh(MWWorld::ConstPtr shield) const
std::string mesh = shield.getClass().getModel(shield); std::string mesh = shield.getClass().getModel(shield);
const ESM::Armor *armor = shield.get<ESM::Armor>()->mBase; const ESM::Armor *armor = shield.get<ESM::Armor>()->mBase;
const std::vector<ESM::PartReference>& bodyparts = armor->mParts.mParts; 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()) if (!bodyparts.empty())
{ mesh = getShieldBodypartMesh(bodyparts, !mNpc->isMale());
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;
}
}
}
}
if (mesh.empty()) if (mesh.empty())
return std::string(); return std::string();
@ -1002,9 +1003,19 @@ void NpcAnimation::showCarriedLeft(bool show)
{ {
osg::Vec4f glowColor = iter->getClass().getEnchantmentColor(*iter); osg::Vec4f glowColor = iter->getClass().getEnchantmentColor(*iter);
std::string mesh = iter->getClass().getModel(*iter); std::string mesh = iter->getClass().getModel(*iter);
if (addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, // For shields we must try to use the body part model
mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor)) 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]) if (iter->getTypeName() == typeid(ESM::Light).name() && mObjectParts[ESM::PRT_Shield])
addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), iter->get<ESM::Light>()->mBase); addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), iter->get<ESM::Light>()->mBase);
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -52,7 +52,7 @@ add_component_dir (shader
add_component_dir (sceneutil add_component_dir (sceneutil
clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller
lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil waterutil writescene serialize optimizer 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 add_component_dir (nif

View file

@ -2,6 +2,7 @@
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_DEBUG_H
#include "tilebounds.hpp" #include "tilebounds.hpp"
#include "status.hpp"
#include <osg/io_utils> #include <osg/io_utils>
@ -26,6 +27,25 @@ namespace DetourNavigator
return stream << "TileBounds {" << value.mMin << ", " << value.mMax << "}"; 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; class RecastMesh;
void writeToFile(const RecastMesh& recastMesh, const std::string& pathPrefix, const std::string& revision); void writeToFile(const RecastMesh& recastMesh, const std::string& pathPrefix, const std::string& revision);

View file

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

View file

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

View file

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

View file

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

View file

@ -110,6 +110,7 @@ namespace ESM
void Cell::loadCell(ESMReader &esm, bool saveContext) void Cell::loadCell(ESMReader &esm, bool saveContext)
{ {
bool isLoaded = false; bool isLoaded = false;
mHasAmbi = false;
while (!isLoaded && esm.hasMoreSubs()) while (!isLoaded && esm.hasMoreSubs())
{ {
esm.getSubName(); esm.getSubName();
@ -127,6 +128,7 @@ namespace ESM
break; break;
case ESM::FourCC<'A','M','B','I'>::value: case ESM::FourCC<'A','M','B','I'>::value:
esm.getHT(mAmbi); esm.getHT(mAmbi);
mHasAmbi = true;
break; break;
case ESM::FourCC<'R','G','N','N'>::value: case ESM::FourCC<'R','G','N','N'>::value:
mRegion = esm.getHString(); mRegion = esm.getHString();
@ -182,7 +184,12 @@ namespace ESM
if (mData.mFlags & QuasiEx) if (mData.mFlags & QuasiEx)
esm.writeHNOCString("RGNN", mRegion); esm.writeHNOCString("RGNN", mRegion);
else 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 else
{ {
@ -272,6 +279,7 @@ namespace ESM
mData.mX = 0; mData.mX = 0;
mData.mY = 0; mData.mY = 0;
mHasAmbi = true;
mAmbi.mAmbient = 0; mAmbi.mAmbient = 0;
mAmbi.mSunlight = 0; mAmbi.mSunlight = 0;
mAmbi.mFog = 0; mAmbi.mFog = 0;

View file

@ -90,6 +90,7 @@ struct Cell
Cell() : mName(""), Cell() : mName(""),
mRegion(""), mRegion(""),
mHasAmbi(true),
mWater(0), mWater(0),
mWaterInt(false), mWaterInt(false),
mMapColor(0), mMapColor(0),
@ -108,6 +109,7 @@ struct Cell
CellId mCellId; CellId mCellId;
AMBIstruct mAmbi; AMBIstruct mAmbi;
bool mHasAmbi;
float mWater; // Water level float mWater; // Water level
bool mWaterInt; bool mWaterInt;
@ -152,6 +154,16 @@ struct Cell
return ((mData.mFlags&HasWater) != 0) || isExterior(); 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 // 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 // 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 // somewhere other than the file system, you need to pre-open the

View file

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

View file

@ -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, ///@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. /// 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: public:
MYGUI_RTTI_DERIVED(ScalingLayer) 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; MyGUI::ILayerItem* getLayerItemByPoint(int _left, int _top) const final;
virtual MyGUI::IntPoint getPosition(int _left, int _top) const; MyGUI::IntPoint getPosition(int _left, int _top) const final;
virtual void renderToTarget(MyGUI::IRenderTarget* _target, bool _update); void renderToTarget(MyGUI::IRenderTarget* _target, bool _update) final;
virtual void resizeView(const MyGUI::IntSize& _viewSize); void resizeView(const MyGUI::IntSize& _viewSize) final;
private: private:
void screenToLayerCoords(int& _left, int& _top) const; void screenToLayerCoords(int& _left, int& _top) const;

View file

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

View file

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

View file

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

View file

@ -254,6 +254,10 @@ bool BulletNifLoader::hasAutoGeneratedCollision(const Nif::Node* rootNode)
void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *node, int flags, void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *node, int flags,
bool isCollisionNode, bool isAnimated, bool autogenerated, bool avoid) 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 // Accumulate the flags from all the child nodes. This works for all
// the flags we currently use, at least. // the flags we currently use, at least.
flags |= node->flags; flags |= node->flags;

View file

@ -10,6 +10,7 @@
#include <components/nif/data.hpp> #include <components/nif/data.hpp>
#include <components/sceneutil/morphgeometry.hpp> #include <components/sceneutil/morphgeometry.hpp>
#include <components/sceneutil/vismask.hpp>
#include "userdata.hpp" #include "userdata.hpp"
@ -304,7 +305,7 @@ void VisController::operator() (osg::Node* node, osg::NodeVisitor* nv)
{ {
bool vis = calculate(getInputValue(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 // 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); traverse(node, nv);
} }

View file

@ -16,6 +16,7 @@
#include <components/misc/resourcehelpers.hpp> #include <components/misc/resourcehelpers.hpp>
#include <components/resource/imagemanager.hpp> #include <components/resource/imagemanager.hpp>
#include <components/sceneutil/util.hpp> #include <components/sceneutil/util.hpp>
#include <components/sceneutil/vismask.hpp>
// particle // particle
#include <osgParticle/ParticleSystem> #include <osgParticle/ParticleSystem>
@ -167,6 +168,19 @@ namespace
namespace NifOsg 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; bool Loader::sShowMarkers = false;
@ -460,6 +474,14 @@ namespace NifOsg
case Nif::RC_NiBillboardNode: case Nif::RC_NiBillboardNode:
dataVariance = osg::Object::DYNAMIC; dataVariance = osg::Object::DYNAMIC;
break; break;
case Nif::RC_NiCollisionSwitch:
{
bool enabled = nifNode->flags & Nif::NiNode::Flag_ActiveCollision;
node = new CollisionSwitch(enabled);
dataVariance = osg::Object::STATIC;
break;
}
default: default:
// The Root node can be created as a Group if no transformation is required. // 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 // This takes advantage of the fact root nodes can't have additional controllers
@ -553,7 +575,7 @@ namespace NifOsg
{ {
skipMeshes = true; skipMeshes = true;
// Leave mask for UpdateVisitor enabled // 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 // 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 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 // 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. if ((skipMeshes || hasMarkers) && isAnimated) // make sure the empty node is not optimized away so the physicssystem can find it.

View file

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

View file

@ -11,6 +11,7 @@
#include "lightcontroller.hpp" #include "lightcontroller.hpp"
#include "util.hpp" #include "util.hpp"
#include "visitor.hpp" #include "visitor.hpp"
#include "vismask.hpp"
#include "positionattitudetransform.hpp" #include "positionattitudetransform.hpp"
namespace SceneUtil namespace SceneUtil
@ -58,7 +59,7 @@ namespace SceneUtil
light->setQuadraticAttenuation(quadraticAttenuation); 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"); SceneUtil::FindByNameVisitor visitor("AttachLight");
node->accept(visitor); node->accept(visitor);
@ -71,7 +72,7 @@ namespace SceneUtil
else else
{ {
osg::ComputeBoundsVisitor computeBound; 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 // We want the bounds of all children of the node, ignoring the node's local transformation
// So do a traverse(), not accept() // So do a traverse(), not accept()
computeBound.traverse(*node); computeBound.traverse(*node);
@ -85,15 +86,15 @@ namespace SceneUtil
attachTo = trans; attachTo = trans;
} }
osg::ref_ptr<LightSource> lightSource = createLightSource(esmLight, lightMask, isExterior); osg::ref_ptr<LightSource> lightSource = createLightSource(esmLight, isExterior);
attachTo->addChild(lightSource); 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<SceneUtil::LightSource> lightSource (new SceneUtil::LightSource);
osg::ref_ptr<osg::Light> light (new osg::Light); osg::ref_ptr<osg::Light> light (new osg::Light);
lightSource->setNodeMask(lightMask); lightSource->setNodeMask(SceneUtil::Mask_Lighting);
float radius = esmLight->mData.mRadius; float radius = esmLight->mData.mRadius;
lightSource->setRadius(radius); lightSource->setRadius(radius);

View file

@ -32,14 +32,14 @@ namespace SceneUtil
/// @param partsysMask Node mask to ignore when computing the sub graph's bounding box. /// @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 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 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. /// @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 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 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 isExterior Is the light outside? May be used for deciding which attenuation settings to use.
/// @param ambient Ambient component of the light. /// @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));
} }

View file

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

View file

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

View file

@ -1,7 +1,7 @@
#ifndef OPENMW_MWRENDER_VISMASK_H #ifndef OPENMW_COMPONENTS_SCENEUTIL_VISMASK_H
#define OPENMW_MWRENDER_VISMASK_H #define OPENMW_COMPONENTS_SCENEUTIL_VISMASK_H
namespace MWRender namespace SceneUtil
{ {
/// Node masks used for controlling visibility of game objects. /// 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. /// compatibility if the enumeration values were to be changed. Feel free to change them when it makes sense.
enum VisMask enum VisMask
{ {
Mask_Disabled = 0, // For hidden nodes
Mask_UpdateVisitor = 0x1, // reserved for separating UpdateVisitors from CullVisitors Mask_UpdateVisitor = 0x1, // reserved for separating UpdateVisitors from CullVisitors
// child of Scene // child of Scene
@ -53,7 +55,19 @@ namespace MWRender
Mask_PreCompile = (1<<18), Mask_PreCompile = (1<<18),
// Set on a camera's cull mask to enable the LightManager // 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
}; };
} }

View file

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

View file

@ -16,7 +16,7 @@ namespace Terrain
public: public:
typedef std::map<std::pair<int, int>, osg::ref_ptr<osg::Node> > CellGrid; 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 createCellBorderGeometry(int x, int y);
void destroyCellBorderGeometry(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