mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 17:29:55 +00:00
Add command to enable NavMesh render
togglenavmesh or tnm
This commit is contained in:
parent
1caa18bb4f
commit
70a369f70e
25 changed files with 436 additions and 22 deletions
|
@ -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})
|
||||
|
||||
|
|
63
apps/openmw/mwrender/navmesh.cpp
Normal file
63
apps/openmw/mwrender/navmesh.cpp
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
39
apps/openmw/mwrender/navmesh.hpp
Normal file
39
apps/openmw/mwrender/navmesh.hpp
Normal file
|
@ -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;
|
||||
|
|
123
components/sceneutil/detourdebugdraw.cpp
Normal file
123
components/sceneutil/detourdebugdraw.cpp
Normal file
|
@ -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
|
48
components/sceneutil/detourdebugdraw.hpp
Normal file
48
components/sceneutil/detourdebugdraw.hpp
Normal file
|
@ -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);
|
||||
};
|
||||
}
|
22
components/sceneutil/navmesh.cpp
Normal file
22
components/sceneutil/navmesh.cpp
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
23
components/sceneutil/navmesh.hpp
Normal file
23
components/sceneutil/navmesh.hpp
Normal file
|
@ -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…
Reference in a new issue