1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-30 05:36:43 +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 #5241: On-self absorb spells cannot be detected
Bug #5242: ExplodeSpell behavior differs from Cast behavior
Bug #5246: Water ripples persist after cell change
Bug #5249: Wandering NPCs start walking too soon after they hello
Bug #5250: Creatures display shield ground mesh instead of shield body part
Bug #5255: "GetTarget, player" doesn't return 1 during NPC hello
Bug #5261: Creatures can sometimes become stuck playing idles and never wander again
Bug #5264: "Damage Fatigue" Magic Effect Can Bring Fatigue below 0
Bug #5269: Editor: Cell lighting in resaved cleaned content files is corrupted
Bug #5278: Console command Show doesn't fall back to global variable after local var not found
Feature #1415: Infinite fall failsafe
Feature #1774: Handle AvoidNode
Feature #2229: Improve pathfinding AI
Feature #3025: Analogue gamepad movement controls

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

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,
/// which is then upscaled to the real screen size during rendering. The aspect ratio is kept intact, adding blanks to the sides when necessary.
class ScalingLayer : public MyGUI::OverlappedLayer
class ScalingLayer final : public MyGUI::OverlappedLayer
{
public:
MYGUI_RTTI_DERIVED(ScalingLayer)
virtual void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version);
void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) final;
virtual MyGUI::ILayerItem* getLayerItemByPoint(int _left, int _top) const;
virtual MyGUI::IntPoint getPosition(int _left, int _top) const;
virtual void renderToTarget(MyGUI::IRenderTarget* _target, bool _update);
MyGUI::ILayerItem* getLayerItemByPoint(int _left, int _top) const final;
MyGUI::IntPoint getPosition(int _left, int _top) const final;
void renderToTarget(MyGUI::IRenderTarget* _target, bool _update) final;
virtual void resizeView(const MyGUI::IntSize& _viewSize);
void resizeView(const MyGUI::IntSize& _viewSize) final;
private:
void screenToLayerCoords(int& _left, int& _top) const;

View file

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

View file

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

View file

@ -40,6 +40,7 @@ enum RecordType
RC_NiLODNode,
RC_NiBillboardNode,
RC_AvoidNode,
RC_NiCollisionSwitch,
RC_NiTriShape,
RC_NiTriStrips,
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,
bool isCollisionNode, bool isAnimated, bool autogenerated, bool avoid)
{
// TODO: allow on-the fly collision switching via toggling this flag
if (node->recType == Nif::RC_NiCollisionSwitch && !(node->flags & Nif::NiNode::Flag_ActiveCollision))
return;
// Accumulate the flags from all the child nodes. This works for all
// the flags we currently use, at least.
flags |= node->flags;

View file

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

View file

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

View file

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

View file

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

View file

@ -32,14 +32,14 @@ namespace SceneUtil
/// @param partsysMask Node mask to ignore when computing the sub graph's bounding box.
/// @param lightMask Mask to assign to the newly created LightSource.
/// @param isExterior Is the light outside? May be used for deciding which attenuation settings to use.
void addLight (osg::Group* node, const ESM::Light* esmLight, unsigned int partsysMask, unsigned int lightMask, bool isExterior);
void addLight (osg::Group* node, const ESM::Light* esmLight, bool isExterior);
/// @brief Convert an ESM::Light to a SceneUtil::LightSource, and return it.
/// @param esmLight The light definition coming from the game files containing radius, color, flicker, etc.
/// @param lightMask Mask to assign to the newly created LightSource.
/// @param isExterior Is the light outside? May be used for deciding which attenuation settings to use.
/// @param ambient Ambient component of the light.
osg::ref_ptr<LightSource> createLightSource (const ESM::Light* esmLight, unsigned int lightMask, bool isExterior, const osg::Vec4f& ambient=osg::Vec4f(0,0,0,1));
osg::ref_ptr<LightSource> createLightSource (const ESM::Light* esmLight, bool isExterior, const osg::Vec4f& ambient=osg::Vec4f(0,0,0,1));
}

View file

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

View file

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

View file

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

View file

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

View file

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

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