Add command to enable NavMesh render

togglenavmesh or tnm
pull/541/head
elsid 7 years ago
parent 1caa18bb4f
commit 70a369f70e
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40

@ -21,7 +21,7 @@ add_openmw_dir (mwrender
actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
renderbin actoranimation landmanager
renderbin actoranimation landmanager navmesh
)
add_openmw_dir (mwinput
@ -117,7 +117,7 @@ include_directories(
${FFmpeg_INCLUDE_DIRS}
)
find_package(RecastNavigation COMPONENTS Detour Recast REQUIRED)
find_package(RecastNavigation COMPONENTS DebugUtils Detour Recast REQUIRED)
include_directories(SYSTEM ${RecastNavigation_INCLUDE_DIRS})

@ -0,0 +1,63 @@
#include "navmesh.hpp"
#include "vismask.hpp"
#include <components/sceneutil/navmesh.hpp>
#include <osg/PositionAttitudeTransform>
namespace MWRender
{
NavMesh::NavMesh(const osg::ref_ptr<osg::Group>& root)
: mRootNode(root)
, mEnabled(false)
, mRevision(0)
{
}
NavMesh::~NavMesh()
{
if (mEnabled)
disable();
}
bool NavMesh::toggle()
{
if (mEnabled)
disable();
else
enable();
return mEnabled;
}
void NavMesh::update(const DetourNavigator::SharedNavMesh& sharedNavMesh, std::size_t revision,
const DetourNavigator::Settings& settings)
{
if (!mEnabled || mRevision >= revision)
return;
mRevision = revision;
if (mGroup)
mRootNode->removeChild(mGroup);
mGroup = SceneUtil::createNavMeshGroup(*sharedNavMesh.lock(), settings);
if (mGroup)
{
mGroup->setNodeMask(Mask_Debug);
mRootNode->addChild(mGroup);
}
}
void NavMesh::enable()
{
if (mGroup)
mRootNode->addChild(mGroup);
mEnabled = true;
}
void NavMesh::disable()
{
if (mGroup)
mRootNode->removeChild(mGroup);
mEnabled = false;
}
}

@ -0,0 +1,39 @@
#ifndef OPENMW_MWRENDER_NAVMESH_H
#define OPENMW_MWRENDER_NAVMESH_H
#include <components/detournavigator/navigator.hpp>
#include <osg/ref_ptr>
namespace osg
{
class Group;
class Geometry;
}
namespace MWRender
{
class NavMesh
{
public:
NavMesh(const osg::ref_ptr<osg::Group>& root);
~NavMesh();
bool toggle();
void update(const DetourNavigator::SharedNavMesh& sharedNavMesh, std::size_t revision,
const DetourNavigator::Settings& settings);
void enable();
void disable();
private:
osg::ref_ptr<osg::Group> mRootNode;
bool mEnabled;
std::size_t mRevision;
osg::ref_ptr<osg::Group> mGroup;
};
}
#endif

@ -46,6 +46,8 @@
#include <components/esm/loadcell.hpp>
#include <components/fallback/fallback.hpp>
#include <components/detournavigator/navigator.hpp>
#include <boost/algorithm/string.hpp>
#include "../mwworld/cellstore.hpp"
@ -63,6 +65,7 @@
#include "water.hpp"
#include "terrainstorage.hpp"
#include "util.hpp"
#include "navmesh.hpp"
namespace
{
@ -189,13 +192,16 @@ namespace MWRender
Resource::ResourceSystem* mResourceSystem;
};
RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
const Fallback::Map* fallback, const std::string& resourcePath)
RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
const Fallback::Map* fallback, const std::string& resourcePath,
DetourNavigator::Navigator& navigator)
: mViewer(viewer)
, mRootNode(rootNode)
, mResourceSystem(resourceSystem)
, mWorkQueue(workQueue)
, mUnrefQueue(new SceneUtil::UnrefQueue)
, mNavigator(navigator)
, mLandFogStart(0.f)
, mLandFogEnd(std::numeric_limits<float>::max())
, mUnderwaterFogStart(0.f)
@ -228,6 +234,7 @@ namespace MWRender
mRootNode->addChild(mSceneRoot);
mNavMesh.reset(new NavMesh(mRootNode));
mPathgrid.reset(new Pathgrid(mRootNode));
mObjects.reset(new Objects(mResourceSystem, sceneRoot, mUnrefQueue.get()));
@ -482,7 +489,7 @@ namespace MWRender
{
mSky->setEnabled(enabled);
}
bool RenderingManager::toggleBorders()
{
mBorders = !mBorders;
@ -516,6 +523,10 @@ namespace MWRender
mViewer->getCamera()->setCullMask(mask);
return enabled;
}
else if (mode == Render_NavMesh)
{
return mNavMesh->toggle();
}
return false;
}
@ -581,6 +592,19 @@ namespace MWRender
mWater->update(dt);
}
const auto navMeshes = mNavigator.getNavMeshes();
if (!navMeshes.empty())
{
try
{
mNavMesh->update(navMeshes.begin()->second->mValue, navMeshes.begin()->second->mNavMeshRevision,
mNavigator.getSettings());
}
catch (const std::exception& e)
{
Log(Debug::Error) << "NavMesh render update exception: " << e.what();
}
}
mCamera->update(dt, paused);
osg::Vec3f focal, cameraPos;
@ -749,8 +773,8 @@ namespace MWRender
osg::Vec3 directions[6] = {
rawCubemap ? osg::Vec3(1,0,0) : osg::Vec3(0,0,1),
osg::Vec3(0,0,-1),
osg::Vec3(-1,0,0),
osg::Vec3(0,0,-1),
osg::Vec3(-1,0,0),
rawCubemap ? osg::Vec3(0,0,1) : osg::Vec3(1,0,0),
osg::Vec3(0,1,0),
osg::Vec3(0,-1,0)};
@ -789,7 +813,7 @@ namespace MWRender
mFieldOfView = fovBackup;
if (rawCubemap) // for raw cubemap don't run on GPU, just merge the images
{
{
image->allocateImage(cubeSize * 6,cubeSize,images[0]->r(),images[0]->getPixelFormat(),images[0]->getDataType());
for (int i = 0; i < 6; ++i)
@ -797,7 +821,7 @@ namespace MWRender
return true;
}
// run on GPU now:
osg::ref_ptr<osg::TextureCubeMap> cubeTexture (new osg::TextureCubeMap);

@ -55,6 +55,11 @@ namespace SceneUtil
class UnrefQueue;
}
namespace DetourNavigator
{
class Navigator;
}
namespace MWRender
{
@ -68,12 +73,15 @@ namespace MWRender
class Water;
class TerrainStorage;
class LandManager;
class NavMesh;
class RenderingManager : public MWRender::RenderingInterface
{
public:
RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
const Fallback::Map* fallback, const std::string& resourcePath);
RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
const Fallback::Map* fallback, const std::string& resourcePath,
DetourNavigator::Navigator& navigator);
~RenderingManager();
MWRender::Objects& getObjects();
@ -235,6 +243,8 @@ namespace MWRender
osg::ref_ptr<osg::Light> mSunLight;
DetourNavigator::Navigator& mNavigator;
std::unique_ptr<NavMesh> mNavMesh;
std::unique_ptr<Pathgrid> mPathgrid;
std::unique_ptr<Objects> mObjects;
std::unique_ptr<Water> mWater;

@ -10,7 +10,8 @@ namespace MWRender
Render_Wireframe,
Render_Pathgrid,
Render_Water,
Render_Scene
Render_Scene,
Render_NavMesh,
};
}

@ -455,5 +455,6 @@ op 0x2000304: Show
op 0x2000305: Show, explicit
op 0x2000306: OnActivate, explicit
op 0x2000307: ToggleBorders, tb
op 0x2000308: ToggleNavMesh
opcodes 0x2000308-0x3ffffff unused
opcodes 0x2000309-0x3ffffff unused

@ -1317,6 +1317,20 @@ namespace MWScript
}
};
class OpToggleNavMesh : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
bool enabled =
MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_NavMesh);
runtime.getContext().report (enabled ?
"Navigation Mesh Rendering -> On" : "Navigation Mesh Rendering -> Off");
}
};
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (Compiler::Misc::opcodeXBox, new OpXBox);
@ -1417,6 +1431,7 @@ namespace MWScript
interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraph, new OpShowSceneGraph<ImplicitRef>);
interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraphExplicit, new OpShowSceneGraph<ExplicitRef>);
interpreter.installSegment5 (Compiler::Misc::opcodeToggleBorders, new OpToggleBorders);
interpreter.installSegment5 (Compiler::Misc::opcodeToggleNavMesh, new OpToggleNavMesh);
}
}
}

@ -164,8 +164,6 @@ namespace MWWorld
mPlayerTraveling(false), mPlayerInJail(false), mSpellPreloadTimer(0.f)
{
mPhysics.reset(new MWPhysics::PhysicsSystem(resourceSystem, rootNode));
mRendering.reset(new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, &mFallback, resourcePath));
mProjectileManager.reset(new ProjectileManager(mRendering->getLightRoot(), resourceSystem, mRendering.get(), mPhysics.get()));
DetourNavigator::Settings navigatorSettings;
navigatorSettings.mCellHeight = Settings::Manager::getFloat("cell height", "Navigator");
@ -194,6 +192,8 @@ namespace MWWorld
DetourNavigator::Log::instance().setEnabled(Settings::Manager::getBool("enable log", "Navigator"));
mNavigator.reset(new DetourNavigator::Navigator(navigatorSettings));
mRendering.reset(new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, &mFallback, resourcePath, *mNavigator));
mProjectileManager.reset(new ProjectileManager(mRendering->getLightRoot(), resourceSystem, mRendering.get(), mPhysics.get()));
mRendering->preloadCommonAssets();
mEsm.resize(contentFiles.size());

@ -94,11 +94,11 @@ namespace MWWorld
std::unique_ptr<MWWorld::Player> mPlayer;
std::unique_ptr<MWPhysics::PhysicsSystem> mPhysics;
std::unique_ptr<DetourNavigator::Navigator> mNavigator;
std::unique_ptr<MWRender::RenderingManager> mRendering;
std::unique_ptr<MWWorld::Scene> mWorldScene;
std::unique_ptr<MWWorld::WeatherManager> mWeatherManager;
std::shared_ptr<ProjectileManager> mProjectileManager;
std::unique_ptr<DetourNavigator::Navigator> mNavigator;
bool mGodMode;
bool mScriptsEnabled;

@ -51,7 +51,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
actorutil detourdebugdraw navmesh
)
add_component_dir (nif
@ -210,7 +210,7 @@ include_directories(${Bullet_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR})
find_package(RecastNavigation COMPONENTS Detour Recast REQUIRED)
find_package(RecastNavigation COMPONENTS DebugUtils Detour Recast REQUIRED)
include_directories(SYSTEM ${RecastNavigation_INCLUDE_DIRS})

@ -320,6 +320,8 @@ namespace Compiler
extensions.registerInstruction ("removefromlevitem", "ccl", opcodeRemoveFromLevItem);
extensions.registerInstruction ("tb", "", opcodeToggleBorders);
extensions.registerInstruction ("toggleborders", "", opcodeToggleBorders);
extensions.registerInstruction ("togglenavmesh", "", opcodeToggleNavMesh);
extensions.registerInstruction ("tnm", "", opcodeToggleNavMesh);
}
}

@ -296,6 +296,7 @@ namespace Compiler
const int opcodeShowSceneGraph = 0x2002f;
const int opcodeShowSceneGraphExplicit = 0x20030;
const int opcodeToggleBorders = 0x2000307;
const int opcodeToggleNavMesh = 0x2000308;
}
namespace Sky

@ -94,6 +94,8 @@ namespace DetourNavigator
updateNavMesh(job.mAgentHalfExtents, *recastMesh, job.mChangedTile, mSettings,
job.mNavMeshCacheItem->mValue);
++job.mNavMeshCacheItem->mNavMeshRevision;
const auto finish = std::chrono::steady_clock::now();
writeDebugFiles(job, *recastMesh);

@ -25,7 +25,11 @@ namespace DetourNavigator
struct NavMeshCacheItem
{
SharedNavMesh mValue;
std::size_t mRevision;
std::size_t mRecastMeshRevision;
std::atomic_size_t mNavMeshRevision;
NavMeshCacheItem(const NavMeshPtr& value, std::size_t revision)
: mValue(value), mRecastMeshRevision(revision), mNavMeshRevision(0) {}
};
class AsyncNavMeshUpdater

@ -45,4 +45,14 @@ namespace DetourNavigator
{
mNavMeshManager.wait();
}
std::map<osg::Vec3f, std::shared_ptr<NavMeshCacheItem>> Navigator::getNavMeshes() const
{
return mNavMeshManager.getNavMeshes();
}
const Settings& Navigator::getSettings() const
{
return mSettings;
}
}

@ -34,6 +34,10 @@ namespace DetourNavigator
toNavMeshCoordinates(mSettings, start), toNavMeshCoordinates(mSettings, end), mSettings, out);
}
std::map<osg::Vec3f, std::shared_ptr<NavMeshCacheItem>> getNavMeshes() const;
const Settings& getSettings() const;
private:
Settings mSettings;
NavMeshManager mNavMeshManager;

@ -44,7 +44,7 @@ namespace DetourNavigator
if (cached != mCache.end())
return;
mCache.insert(std::make_pair(agentHalfExtents,
std::make_shared<NavMeshCacheItem>(NavMeshCacheItem {makeEmptyNavMesh(mSettings), mRevision}))
std::make_shared<NavMeshCacheItem>(makeEmptyNavMesh(mSettings), mRevision))
);
log("cache add for agent=", agentHalfExtents);
}
@ -57,9 +57,9 @@ namespace DetourNavigator
void NavMeshManager::update(osg::Vec3f playerPosition, const osg::Vec3f& agentHalfExtents)
{
const auto& cached = getCached(agentHalfExtents);
if (cached->mRevision >= mRevision)
if (cached->mRecastMeshRevision >= mRevision)
return;
cached->mRevision = mRevision;
cached->mRecastMeshRevision = mRevision;
const auto changedTiles = mChangedTiles.find(agentHalfExtents);
if (changedTiles != mChangedTiles.end())
{
@ -84,6 +84,11 @@ namespace DetourNavigator
return getCached(agentHalfExtents)->mValue;
}
std::map<osg::Vec3f, std::shared_ptr<NavMeshCacheItem>> NavMeshManager::getNavMeshes() const
{
return mCache;
}
void NavMeshManager::addChangedTiles(const btCollisionShape& shape, const btTransform& transform)
{
btVector3 aabbMin;

@ -37,6 +37,8 @@ namespace DetourNavigator
SharedNavMesh getNavMesh(const osg::Vec3f& agentHalfExtents) const;
std::map<osg::Vec3f, std::shared_ptr<NavMeshCacheItem>> getNavMeshes() const;
private:
std::size_t mRevision = 0;
const Settings& mSettings;

@ -0,0 +1,123 @@
#include "detourdebugdraw.hpp"
#include "util.hpp"
#include <components/detournavigator/debug.hpp>
#include <osg/BlendFunc>
#include <osg/Group>
#include <osg/LineWidth>
#define OPENMW_TO_STRING(X) #X
#define OPENMW_LINE_STRING OPENMW_TO_STRING(__LINE__)
namespace
{
using DetourNavigator::operator<<;
osg::PrimitiveSet::Mode toOsgPrimitiveSetMode(duDebugDrawPrimitives value)
{
switch (value)
{
case DU_DRAW_POINTS:
return osg::PrimitiveSet::POINTS;
case DU_DRAW_LINES:
return osg::PrimitiveSet::LINES;
case DU_DRAW_TRIS:
return osg::PrimitiveSet::TRIANGLES;
case DU_DRAW_QUADS:
return osg::PrimitiveSet::QUADS;
}
throw std::logic_error("Can't convert duDebugDrawPrimitives to osg::PrimitiveSet::Mode, value="
+ std::to_string(value));
}
}
namespace SceneUtil
{
DebugDraw::DebugDraw(osg::Group& group, const osg::Vec3f& shift, float recastInvertedScaleFactor)
: mGroup(group)
, mShift(shift)
, mRecastInvertedScaleFactor(recastInvertedScaleFactor)
, mDepthMask(false)
, mMode(osg::PrimitiveSet::POINTS)
, mSize(1.0f)
{
}
void DebugDraw::depthMask(bool state)
{
mDepthMask = state;
}
void DebugDraw::texture(bool state)
{
if (state)
throw std::logic_error("DebugDraw does not support textures (at " __FILE__ ":" OPENMW_LINE_STRING ")");
}
void DebugDraw::begin(duDebugDrawPrimitives prim, float size)
{
mMode = toOsgPrimitiveSetMode(prim);
mVertices = new osg::Vec3Array;
mColors = new osg::Vec4Array;
mSize = size * mRecastInvertedScaleFactor;
}
void DebugDraw::vertex(const float* pos, unsigned color)
{
vertex(pos[0], pos[1], pos[2], color);
}
void DebugDraw::vertex(const float x, const float y, const float z, unsigned color)
{
addVertex(osg::Vec3f(x, y, z));
addColor(SceneUtil::colourFromRGBA(color));
}
void DebugDraw::vertex(const float* pos, unsigned color, const float* uv)
{
vertex(pos[0], pos[1], pos[2], color, uv[0], uv[1]);
}
void DebugDraw::vertex(const float, const float, const float, unsigned, const float, const float)
{
throw std::logic_error("Not implemented (at " __FILE__ ":" OPENMW_LINE_STRING ")");
}
void DebugDraw::end()
{
osg::ref_ptr<osg::StateSet> stateSet(new osg::StateSet);
stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateSet->setMode(GL_DEPTH, (mDepthMask ? osg::StateAttribute::ON : osg::StateAttribute::OFF));
stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateSet->setAttributeAndModes(new osg::LineWidth(mSize));
stateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
osg::ref_ptr<osg::Geometry> geometry(new osg::Geometry);
geometry->setStateSet(stateSet);
geometry->setUseDisplayList(false);
geometry->setVertexArray(mVertices);
geometry->setColorArray(mColors, osg::Array::BIND_PER_VERTEX);
geometry->addPrimitiveSet(new osg::DrawArrays(mMode, 0, static_cast<int>(mVertices->size())));
mGroup.addChild(geometry);
mColors.release();
mVertices.release();
}
void DebugDraw::addVertex(osg::Vec3f&& position)
{
std::swap(position.y(), position.z());
mVertices->push_back(position * mRecastInvertedScaleFactor + mShift);
}
void DebugDraw::addColor(osg::Vec4f&& value)
{
mColors->push_back(value);
}
}
#undef OPENMW_TO_STRING
#undef OPENMW_LINE_STRING

@ -0,0 +1,48 @@
#include <DebugDraw.h>
#include <osg/Geometry>
namespace osg
{
class Group;
}
namespace SceneUtil
{
class DebugDraw : public duDebugDraw
{
public:
DebugDraw(osg::Group& group, const osg::Vec3f& shift, float recastInvertedScaleFactor);
void depthMask(bool state) override;
void texture(bool state) override;
void begin(duDebugDrawPrimitives prim, float size) override;
void vertex(const float* pos, unsigned int color) override;
void vertex(const float x, const float y, const float z, unsigned int color) override;
void vertex(const float* pos, unsigned int color, const float* uv) override;
void vertex(const float x, const float y, const float z, unsigned int color,
const float u, const float v) override;
void end() override;
private:
osg::Group& mGroup;
osg::Vec3f mShift;
float mRecastInvertedScaleFactor;
bool mDepthMask;
osg::PrimitiveSet::Mode mMode;
float mSize;
osg::ref_ptr<osg::Vec3Array> mVertices;
osg::ref_ptr<osg::Vec4Array> mColors;
void addVertex(osg::Vec3f&& position);
void addColor(osg::Vec4f&& value);
};
}

@ -0,0 +1,22 @@
#include "navmesh.hpp"
#include "detourdebugdraw.hpp"
#include <components/detournavigator/settings.hpp>
#include <DetourDebugDraw.h>
#include <osg/Group>
namespace SceneUtil
{
osg::ref_ptr<osg::Group> createNavMeshGroup(const dtNavMesh& navMesh, const DetourNavigator::Settings& settings)
{
const osg::ref_ptr<osg::Group> group(new osg::Group);
DebugDraw debugDraw(*group, osg::Vec3f(0, 0, 10), 1.0f / settings.mRecastScaleFactor);
dtNavMeshQuery navMeshQuery;
navMeshQuery.init(&navMesh, settings.mMaxNavMeshQueryNodes);
duDebugDrawNavMeshWithClosedList(&debugDraw, navMesh, navMeshQuery,
DU_DRAWNAVMESH_OFFMESHCONS | DU_DRAWNAVMESH_CLOSEDLIST);
return group;
}
}

@ -0,0 +1,23 @@
#ifndef OPENMW_COMPONENTS_SCENEUTIL_NAVMESH_H
#define OPENMW_COMPONENTS_SCENEUTIL_NAVMESH_H
#include <osg/ref_ptr>
class dtNavMesh;
namespace osg
{
class Group;
}
namespace DetourNavigator
{
struct Settings;
}
namespace SceneUtil
{
osg::ref_ptr<osg::Group> createNavMeshGroup(const dtNavMesh& navMesh, const DetourNavigator::Settings& settings);
}
#endif

@ -42,4 +42,15 @@ osg::Vec4f colourFromRGB(unsigned int clr)
return colour;
}
osg::Vec4f colourFromRGBA(unsigned int value)
{
return osg::Vec4f(makeOsgColorComponent(value, 0), makeOsgColorComponent(value, 8),
makeOsgColorComponent(value, 16), makeOsgColorComponent(value, 24));
}
float makeOsgColorComponent(unsigned int value, unsigned int shift)
{
return float((value >> shift) & 0xFFu) / 255.0f;
}
}

@ -15,6 +15,10 @@ namespace SceneUtil
osg::Vec4f colourFromRGB (unsigned int clr);
osg::Vec4f colourFromRGBA (unsigned int value);
float makeOsgColorComponent (unsigned int value, unsigned int shift);
}
#endif

Loading…
Cancel
Save