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 actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
renderbin actoranimation landmanager renderbin actoranimation landmanager navmesh
) )
add_openmw_dir (mwinput add_openmw_dir (mwinput
@ -117,7 +117,7 @@ include_directories(
${FFmpeg_INCLUDE_DIRS} ${FFmpeg_INCLUDE_DIRS}
) )
find_package(RecastNavigation COMPONENTS Detour Recast REQUIRED) find_package(RecastNavigation COMPONENTS DebugUtils Detour Recast REQUIRED)
include_directories(SYSTEM ${RecastNavigation_INCLUDE_DIRS}) 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/esm/loadcell.hpp>
#include <components/fallback/fallback.hpp> #include <components/fallback/fallback.hpp>
#include <components/detournavigator/navigator.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
@ -63,6 +65,7 @@
#include "water.hpp" #include "water.hpp"
#include "terrainstorage.hpp" #include "terrainstorage.hpp"
#include "util.hpp" #include "util.hpp"
#include "navmesh.hpp"
namespace namespace
{ {
@ -189,13 +192,16 @@ namespace MWRender
Resource::ResourceSystem* mResourceSystem; Resource::ResourceSystem* mResourceSystem;
}; };
RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
const Fallback::Map* fallback, const std::string& resourcePath) Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
const Fallback::Map* fallback, const std::string& resourcePath,
DetourNavigator::Navigator& navigator)
: mViewer(viewer) : mViewer(viewer)
, mRootNode(rootNode) , mRootNode(rootNode)
, mResourceSystem(resourceSystem) , mResourceSystem(resourceSystem)
, mWorkQueue(workQueue) , mWorkQueue(workQueue)
, mUnrefQueue(new SceneUtil::UnrefQueue) , mUnrefQueue(new SceneUtil::UnrefQueue)
, mNavigator(navigator)
, mLandFogStart(0.f) , mLandFogStart(0.f)
, mLandFogEnd(std::numeric_limits<float>::max()) , mLandFogEnd(std::numeric_limits<float>::max())
, mUnderwaterFogStart(0.f) , mUnderwaterFogStart(0.f)
@ -228,6 +234,7 @@ namespace MWRender
mRootNode->addChild(mSceneRoot); mRootNode->addChild(mSceneRoot);
mNavMesh.reset(new NavMesh(mRootNode));
mPathgrid.reset(new Pathgrid(mRootNode)); mPathgrid.reset(new Pathgrid(mRootNode));
mObjects.reset(new Objects(mResourceSystem, sceneRoot, mUnrefQueue.get())); mObjects.reset(new Objects(mResourceSystem, sceneRoot, mUnrefQueue.get()));
@ -482,7 +489,7 @@ namespace MWRender
{ {
mSky->setEnabled(enabled); mSky->setEnabled(enabled);
} }
bool RenderingManager::toggleBorders() bool RenderingManager::toggleBorders()
{ {
mBorders = !mBorders; mBorders = !mBorders;
@ -516,6 +523,10 @@ namespace MWRender
mViewer->getCamera()->setCullMask(mask); mViewer->getCamera()->setCullMask(mask);
return enabled; return enabled;
} }
else if (mode == Render_NavMesh)
{
return mNavMesh->toggle();
}
return false; return false;
} }
@ -581,6 +592,19 @@ namespace MWRender
mWater->update(dt); 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); mCamera->update(dt, paused);
osg::Vec3f focal, cameraPos; osg::Vec3f focal, cameraPos;
@ -749,8 +773,8 @@ namespace MWRender
osg::Vec3 directions[6] = { osg::Vec3 directions[6] = {
rawCubemap ? osg::Vec3(1,0,0) : osg::Vec3(0,0,1), rawCubemap ? osg::Vec3(1,0,0) : osg::Vec3(0,0,1),
osg::Vec3(0,0,-1), osg::Vec3(0,0,-1),
osg::Vec3(-1,0,0), osg::Vec3(-1,0,0),
rawCubemap ? 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),
osg::Vec3(0,-1,0)}; osg::Vec3(0,-1,0)};
@ -789,7 +813,7 @@ namespace MWRender
mFieldOfView = fovBackup; mFieldOfView = fovBackup;
if (rawCubemap) // for raw cubemap don't run on GPU, just merge the images 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()); image->allocateImage(cubeSize * 6,cubeSize,images[0]->r(),images[0]->getPixelFormat(),images[0]->getDataType());
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
@ -797,7 +821,7 @@ namespace MWRender
return true; return true;
} }
// run on GPU now: // run on GPU now:
osg::ref_ptr<osg::TextureCubeMap> cubeTexture (new osg::TextureCubeMap); osg::ref_ptr<osg::TextureCubeMap> cubeTexture (new osg::TextureCubeMap);

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

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

@ -455,5 +455,6 @@ op 0x2000304: Show
op 0x2000305: Show, explicit op 0x2000305: Show, explicit
op 0x2000306: OnActivate, explicit op 0x2000306: OnActivate, explicit
op 0x2000307: ToggleBorders, tb 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) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (Compiler::Misc::opcodeXBox, new OpXBox); 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::opcodeShowSceneGraph, new OpShowSceneGraph<ImplicitRef>);
interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraphExplicit, new OpShowSceneGraph<ExplicitRef>); interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraphExplicit, new OpShowSceneGraph<ExplicitRef>);
interpreter.installSegment5 (Compiler::Misc::opcodeToggleBorders, new OpToggleBorders); 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) mPlayerTraveling(false), mPlayerInJail(false), mSpellPreloadTimer(0.f)
{ {
mPhysics.reset(new MWPhysics::PhysicsSystem(resourceSystem, rootNode)); 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; DetourNavigator::Settings navigatorSettings;
navigatorSettings.mCellHeight = Settings::Manager::getFloat("cell height", "Navigator"); navigatorSettings.mCellHeight = Settings::Manager::getFloat("cell height", "Navigator");
@ -194,6 +192,8 @@ namespace MWWorld
DetourNavigator::Log::instance().setEnabled(Settings::Manager::getBool("enable log", "Navigator")); DetourNavigator::Log::instance().setEnabled(Settings::Manager::getBool("enable log", "Navigator"));
mNavigator.reset(new DetourNavigator::Navigator(navigatorSettings)); 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(); mRendering->preloadCommonAssets();
mEsm.resize(contentFiles.size()); mEsm.resize(contentFiles.size());

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

@ -51,7 +51,7 @@ add_component_dir (shader
add_component_dir (sceneutil add_component_dir (sceneutil
clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller
lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil waterutil writescene serialize optimizer lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil waterutil writescene serialize optimizer
actorutil actorutil detourdebugdraw navmesh
) )
add_component_dir (nif 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}) 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}) include_directories(SYSTEM ${RecastNavigation_INCLUDE_DIRS})

@ -320,6 +320,8 @@ namespace Compiler
extensions.registerInstruction ("removefromlevitem", "ccl", opcodeRemoveFromLevItem); extensions.registerInstruction ("removefromlevitem", "ccl", opcodeRemoveFromLevItem);
extensions.registerInstruction ("tb", "", opcodeToggleBorders); extensions.registerInstruction ("tb", "", opcodeToggleBorders);
extensions.registerInstruction ("toggleborders", "", 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 opcodeShowSceneGraph = 0x2002f;
const int opcodeShowSceneGraphExplicit = 0x20030; const int opcodeShowSceneGraphExplicit = 0x20030;
const int opcodeToggleBorders = 0x2000307; const int opcodeToggleBorders = 0x2000307;
const int opcodeToggleNavMesh = 0x2000308;
} }
namespace Sky namespace Sky

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

@ -25,7 +25,11 @@ namespace DetourNavigator
struct NavMeshCacheItem struct NavMeshCacheItem
{ {
SharedNavMesh mValue; 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 class AsyncNavMeshUpdater

@ -45,4 +45,14 @@ namespace DetourNavigator
{ {
mNavMeshManager.wait(); 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); toNavMeshCoordinates(mSettings, start), toNavMeshCoordinates(mSettings, end), mSettings, out);
} }
std::map<osg::Vec3f, std::shared_ptr<NavMeshCacheItem>> getNavMeshes() const;
const Settings& getSettings() const;
private: private:
Settings mSettings; Settings mSettings;
NavMeshManager mNavMeshManager; NavMeshManager mNavMeshManager;

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

@ -37,6 +37,8 @@ namespace DetourNavigator
SharedNavMesh getNavMesh(const osg::Vec3f& agentHalfExtents) const; SharedNavMesh getNavMesh(const osg::Vec3f& agentHalfExtents) const;
std::map<osg::Vec3f, std::shared_ptr<NavMeshCacheItem>> getNavMeshes() const;
private: private:
std::size_t mRevision = 0; std::size_t mRevision = 0;
const Settings& mSettings; 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; 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 colourFromRGB (unsigned int clr);
osg::Vec4f colourFromRGBA (unsigned int value);
float makeOsgColorComponent (unsigned int value, unsigned int shift);
} }
#endif #endif

Loading…
Cancel
Save