1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-06 10:15:33 +00:00

Share state sets for recast mesh tiles and actors paths

This commit is contained in:
elsid 2024-05-18 14:09:51 +02:00
parent d15be7a685
commit 98d530d8cb
No known key found for this signature in database
GPG key ID: 4DE04C198CBA7625
14 changed files with 99 additions and 72 deletions

View file

@ -1,12 +1,16 @@
#include "actorspaths.hpp" #include "actorspaths.hpp"
#include "vismask.hpp" #include "vismask.hpp"
#include <components/detournavigator/settings.hpp> #include <components/detournavigator/settings.hpp>
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/sceneutil/agentpath.hpp> #include <components/sceneutil/agentpath.hpp>
#include <components/sceneutil/detourdebugdraw.hpp>
#include <osg/Material>
#include <osg/PositionAttitudeTransform> #include <osg/PositionAttitudeTransform>
#include <osg/StateSet>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -15,9 +19,24 @@
namespace MWRender namespace MWRender
{ {
namespace
{
osg::ref_ptr<osg::StateSet> makeGroupStateSet()
{
osg::ref_ptr<osg::Material> material = new osg::Material;
material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet;
stateSet->setAttribute(material);
return stateSet;
}
}
ActorsPaths::ActorsPaths(const osg::ref_ptr<osg::Group>& root, bool enabled) ActorsPaths::ActorsPaths(const osg::ref_ptr<osg::Group>& root, bool enabled)
: mRootNode(root) : mRootNode(root)
, mEnabled(enabled) , mEnabled(enabled)
, mGroupStateSet(makeGroupStateSet())
, mDebugDrawStateSet(SceneUtil::DebugDraw::makeStateSet())
{ {
} }
@ -48,14 +67,15 @@ namespace MWRender
if (group != mGroups.end()) if (group != mGroups.end())
mRootNode->removeChild(group->second.mNode); mRootNode->removeChild(group->second.mNode);
auto newGroup = SceneUtil::createAgentPathGroup(path, agentBounds, start, end, settings.mRecast); osg::ref_ptr<osg::Group> newGroup
if (newGroup) = SceneUtil::createAgentPathGroup(path, agentBounds, start, end, settings.mRecast, mDebugDrawStateSet);
{ newGroup->setNodeMask(Mask_Debug);
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(newGroup, "debug"); newGroup->setStateSet(mGroupStateSet);
newGroup->setNodeMask(Mask_Debug);
mRootNode->addChild(newGroup); MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(newGroup, "debug");
mGroups[actor.mRef] = Group{ actor.mCell, std::move(newGroup) };
} mRootNode->addChild(newGroup);
mGroups.insert_or_assign(group, actor.mRef, Group{ actor.mCell, std::move(newGroup) });
} }
void ActorsPaths::remove(const MWWorld::ConstPtr& actor) void ActorsPaths::remove(const MWWorld::ConstPtr& actor)

View file

@ -7,11 +7,11 @@
#include <deque> #include <deque>
#include <map> #include <map>
#include <unordered_map>
namespace osg namespace osg
{ {
class Group; class Group;
class StateSet;
} }
namespace DetourNavigator namespace DetourNavigator
@ -56,6 +56,8 @@ namespace MWRender
osg::ref_ptr<osg::Group> mRootNode; osg::ref_ptr<osg::Group> mRootNode;
Groups mGroups; Groups mGroups;
bool mEnabled; bool mEnabled;
osg::ref_ptr<osg::StateSet> mGroupStateSet;
osg::ref_ptr<osg::StateSet> mDebugDrawStateSet;
}; };
} }

View file

@ -1,4 +1,5 @@
#include "navmesh.hpp" #include "navmesh.hpp"
#include "vismask.hpp" #include "vismask.hpp"
#include <components/detournavigator/guardednavmeshcacheitem.hpp> #include <components/detournavigator/guardednavmeshcacheitem.hpp>
@ -129,16 +130,17 @@ namespace MWRender
if (mAborted.load(std::memory_order_acquire)) if (mAborted.load(std::memory_order_acquire))
return; return;
group = SceneUtil::createNavMeshTileGroup(navMesh->getImpl(), *meshTile, mSettings, mGroupStateSet, group = SceneUtil::createNavMeshTileGroup(
mDebugDrawStateSet, flags, minSalt, maxSalt); navMesh->getImpl(), *meshTile, mSettings, mDebugDrawStateSet, flags, minSalt, maxSalt);
} }
if (group == nullptr) if (group == nullptr)
{ {
removedTiles.push_back(position); removedTiles.push_back(position);
continue; continue;
} }
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug");
group->setNodeMask(Mask_Debug); group->setNodeMask(Mask_Debug);
group->setStateSet(mGroupStateSet);
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug");
updatedTiles.emplace_back(position, Tile{ version, std::move(group) }); updatedTiles.emplace_back(position, Tile{ version, std::move(group) });
} }
@ -166,7 +168,7 @@ namespace MWRender
bool enabled, Settings::NavMeshRenderMode mode) bool enabled, Settings::NavMeshRenderMode mode)
: mRootNode(root) : mRootNode(root)
, mWorkQueue(workQueue) , mWorkQueue(workQueue)
, mGroupStateSet(SceneUtil::makeNavMeshTileStateSet()) , mGroupStateSet(SceneUtil::makeDetourGroupStateSet())
, mDebugDrawStateSet(SceneUtil::DebugDraw::makeStateSet()) , mDebugDrawStateSet(SceneUtil::DebugDraw::makeStateSet())
, mEnabled(enabled) , mEnabled(enabled)
, mMode(mode) , mMode(mode)

View file

@ -11,7 +11,6 @@
#include <cstddef> #include <cstddef>
#include <map> #include <map>
#include <memory> #include <memory>
#include <string_view>
#include <vector> #include <vector>
class dtNavMesh; class dtNavMesh;

View file

@ -6,6 +6,7 @@
#include <components/detournavigator/settings.hpp> #include <components/detournavigator/settings.hpp>
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/sceneutil/detourdebugdraw.hpp>
#include <components/sceneutil/recastmesh.hpp> #include <components/sceneutil/recastmesh.hpp>
#include <osg/PositionAttitudeTransform> #include <osg/PositionAttitudeTransform>
@ -19,6 +20,8 @@ namespace MWRender
RecastMesh::RecastMesh(const osg::ref_ptr<osg::Group>& root, bool enabled) RecastMesh::RecastMesh(const osg::ref_ptr<osg::Group>& root, bool enabled)
: mRootNode(root) : mRootNode(root)
, mEnabled(enabled) , mEnabled(enabled)
, mGroupStateSet(SceneUtil::makeDetourGroupStateSet())
, mDebugDrawStateSet(SceneUtil::DebugDraw::makeStateSet())
{ {
} }
@ -55,11 +58,16 @@ namespace MWRender
if (it->second.mVersion != tile->second->getVersion()) if (it->second.mVersion != tile->second->getVersion())
{ {
const auto group = SceneUtil::createRecastMeshGroup(*tile->second, settings.mRecast); const osg::ref_ptr<osg::Group> group
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug"); = SceneUtil::createRecastMeshGroup(*tile->second, settings.mRecast, mDebugDrawStateSet);
group->setNodeMask(Mask_Debug); group->setNodeMask(Mask_Debug);
group->setStateSet(mGroupStateSet);
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug");
mRootNode->removeChild(it->second.mValue); mRootNode->removeChild(it->second.mValue);
mRootNode->addChild(group); mRootNode->addChild(group);
it->second.mValue = group; it->second.mValue = group;
it->second.mVersion = tile->second->getVersion(); it->second.mVersion = tile->second->getVersion();
} }
@ -79,9 +87,13 @@ namespace MWRender
mRootNode->removeChild(it->second.mValue); mRootNode->removeChild(it->second.mValue);
} }
const auto group = SceneUtil::createRecastMeshGroup(*mesh, settings.mRecast); const osg::ref_ptr<osg::Group> group
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug"); = SceneUtil::createRecastMeshGroup(*mesh, settings.mRecast, mDebugDrawStateSet);
group->setNodeMask(Mask_Debug); group->setNodeMask(Mask_Debug);
group->setStateSet(mGroupStateSet);
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug");
mGroups.insert_or_assign(it, position, Group{ mesh->getVersion(), group }); mGroups.insert_or_assign(it, position, Group{ mesh->getVersion(), group });
mRootNode->addChild(group); mRootNode->addChild(group);
} }

View file

@ -10,6 +10,7 @@ namespace osg
{ {
class Group; class Group;
class Geometry; class Geometry;
class StateSet;
} }
namespace DetourNavigator namespace DetourNavigator
@ -47,6 +48,8 @@ namespace MWRender
osg::ref_ptr<osg::Group> mRootNode; osg::ref_ptr<osg::Group> mRootNode;
bool mEnabled; bool mEnabled;
std::map<DetourNavigator::TilePosition, Group> mGroups; std::map<DetourNavigator::TilePosition, Group> mGroups;
osg::ref_ptr<osg::StateSet> mGroupStateSet;
osg::ref_ptr<osg::StateSet> mDebugDrawStateSet;
}; };
} }

View file

@ -1,4 +1,5 @@
#include "agentpath.hpp" #include "agentpath.hpp"
#include "detourdebugdraw.hpp" #include "detourdebugdraw.hpp"
#include <osg/Material> #include <osg/Material>
@ -38,13 +39,13 @@ namespace SceneUtil
{ {
osg::ref_ptr<osg::Group> createAgentPathGroup(const std::deque<osg::Vec3f>& path, osg::ref_ptr<osg::Group> createAgentPathGroup(const std::deque<osg::Vec3f>& path,
const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end, const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end,
const DetourNavigator::RecastSettings& settings) const DetourNavigator::RecastSettings& settings, const osg::ref_ptr<osg::StateSet>& debugDrawStateSet)
{ {
using namespace DetourNavigator; using namespace DetourNavigator;
const osg::ref_ptr<osg::Group> group(new osg::Group); osg::ref_ptr<osg::Group> group(new osg::Group);
DebugDraw debugDraw(*group, DebugDraw::makeStateSet(), osg::Vec3f(0, 0, 0), 1); DebugDraw debugDraw(*group, debugDrawStateSet, osg::Vec3f(0, 0, 0), 1);
const auto agentRadius = DetourNavigator::getAgentRadius(agentBounds); const auto agentRadius = DetourNavigator::getAgentRadius(agentBounds);
const auto agentHeight = DetourNavigator::getAgentHeight(agentBounds); const auto agentHeight = DetourNavigator::getAgentHeight(agentBounds);
@ -69,10 +70,6 @@ namespace SceneUtil
debugDraw.depthMask(true); debugDraw.depthMask(true);
osg::ref_ptr<osg::Material> material = new osg::Material;
material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
group->getOrCreateStateSet()->setAttribute(material);
return group; return group;
} }
} }

View file

@ -9,6 +9,7 @@ namespace osg
{ {
class Group; class Group;
class Vec3f; class Vec3f;
class StateSet;
} }
namespace DetourNavigator namespace DetourNavigator
@ -21,7 +22,7 @@ namespace SceneUtil
{ {
osg::ref_ptr<osg::Group> createAgentPathGroup(const std::deque<osg::Vec3f>& path, osg::ref_ptr<osg::Group> createAgentPathGroup(const std::deque<osg::Vec3f>& path,
const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end, const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end,
const DetourNavigator::RecastSettings& settings); const DetourNavigator::RecastSettings& settings, const osg::ref_ptr<osg::StateSet>& debugDrawStateSet);
} }
#endif #endif

View file

@ -1,9 +1,15 @@
#include "detourdebugdraw.hpp" #include "detourdebugdraw.hpp"
#include "depth.hpp"
#include "util.hpp" #include "util.hpp"
#include <osg/BlendFunc> #include <osg/BlendFunc>
#include <osg/Group> #include <osg/Group>
#include <osg/LineWidth> #include <osg/LineWidth>
#include <osg/Material>
#include <osg/PolygonOffset>
#include <algorithm>
namespace namespace
{ {
@ -113,4 +119,20 @@ namespace SceneUtil
stateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); stateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
return stateSet; return stateSet;
} }
osg::ref_ptr<osg::StateSet> makeDetourGroupStateSet()
{
osg::ref_ptr<osg::Material> material = new osg::Material;
material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
const float polygonOffsetFactor = SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0;
const float polygonOffsetUnits = SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0;
osg::ref_ptr<osg::PolygonOffset> polygonOffset
= new osg::PolygonOffset(polygonOffsetFactor, polygonOffsetUnits);
osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet;
stateSet->setAttribute(material);
stateSet->setAttributeAndModes(polygonOffset);
return stateSet;
}
} }

View file

@ -53,6 +53,8 @@ namespace SceneUtil
void addColor(osg::Vec4f&& value); void addColor(osg::Vec4f&& value);
}; };
osg::ref_ptr<osg::StateSet> makeDetourGroupStateSet();
} }
#endif #endif

View file

@ -1,5 +1,5 @@
#include "navmesh.hpp" #include "navmesh.hpp"
#include "depth.hpp"
#include "detourdebugdraw.hpp" #include "detourdebugdraw.hpp"
#include <components/detournavigator/settings.hpp> #include <components/detournavigator/settings.hpp>
@ -7,10 +7,6 @@
#include <DetourDebugDraw.h> #include <DetourDebugDraw.h>
#include <osg/Group> #include <osg/Group>
#include <osg/Material>
#include <osg/PolygonOffset>
#include <algorithm>
namespace namespace
{ {
@ -270,31 +266,14 @@ namespace
namespace SceneUtil namespace SceneUtil
{ {
osg::ref_ptr<osg::StateSet> makeNavMeshTileStateSet()
{
osg::ref_ptr<osg::Material> material = new osg::Material;
material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
const float polygonOffsetFactor = SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0;
const float polygonOffsetUnits = SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0;
osg::ref_ptr<osg::PolygonOffset> polygonOffset
= new osg::PolygonOffset(polygonOffsetFactor, polygonOffsetUnits);
osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet;
stateSet->setAttribute(material);
stateSet->setAttributeAndModes(polygonOffset);
return stateSet;
}
osg::ref_ptr<osg::Group> createNavMeshTileGroup(const dtNavMesh& navMesh, const dtMeshTile& meshTile, osg::ref_ptr<osg::Group> createNavMeshTileGroup(const dtNavMesh& navMesh, const dtMeshTile& meshTile,
const DetourNavigator::Settings& settings, const osg::ref_ptr<osg::StateSet>& groupStateSet, const DetourNavigator::Settings& settings, const osg::ref_ptr<osg::StateSet>& debugDrawStateSet,
const osg::ref_ptr<osg::StateSet>& debugDrawStateSet, unsigned char flags, unsigned minSalt, unsigned maxSalt) unsigned char flags, unsigned minSalt, unsigned maxSalt)
{ {
if (meshTile.header == nullptr) if (meshTile.header == nullptr)
return nullptr; return nullptr;
osg::ref_ptr<osg::Group> group(new osg::Group); osg::ref_ptr<osg::Group> group(new osg::Group);
group->setStateSet(groupStateSet);
constexpr float shift = 10.0f; constexpr float shift = 10.0f;
DebugDraw debugDraw( DebugDraw debugDraw(
*group, debugDrawStateSet, osg::Vec3f(0, 0, shift), 1.0f / settings.mRecast.mRecastScaleFactor); *group, debugDrawStateSet, osg::Vec3f(0, 0, shift), 1.0f / settings.mRecast.mRecastScaleFactor);

View file

@ -27,11 +27,9 @@ namespace SceneUtil
NavMeshTileDrawFlagsHeat = 1 << 3, NavMeshTileDrawFlagsHeat = 1 << 3,
}; };
osg::ref_ptr<osg::StateSet> makeNavMeshTileStateSet();
osg::ref_ptr<osg::Group> createNavMeshTileGroup(const dtNavMesh& navMesh, const dtMeshTile& meshTile, osg::ref_ptr<osg::Group> createNavMeshTileGroup(const dtNavMesh& navMesh, const dtMeshTile& meshTile,
const DetourNavigator::Settings& settings, const osg::ref_ptr<osg::StateSet>& groupStateSet, const DetourNavigator::Settings& settings, const osg::ref_ptr<osg::StateSet>& debugDrawStateSet,
const osg::ref_ptr<osg::StateSet>& debugDrawStateSet, unsigned char flags, unsigned minSalt, unsigned maxSalt); unsigned char flags, unsigned minSalt, unsigned maxSalt);
} }
#endif #endif

View file

@ -1,5 +1,5 @@
#include "recastmesh.hpp" #include "recastmesh.hpp"
#include "depth.hpp"
#include "detourdebugdraw.hpp" #include "detourdebugdraw.hpp"
#include <components/detournavigator/recastmesh.hpp> #include <components/detournavigator/recastmesh.hpp>
@ -41,13 +41,14 @@ namespace
namespace SceneUtil namespace SceneUtil
{ {
osg::ref_ptr<osg::Group> createRecastMeshGroup( osg::ref_ptr<osg::Group> createRecastMeshGroup(const DetourNavigator::RecastMesh& recastMesh,
const DetourNavigator::RecastMesh& recastMesh, const DetourNavigator::RecastSettings& settings) const DetourNavigator::RecastSettings& settings, const osg::ref_ptr<osg::StateSet>& debugDrawStateSet)
{ {
using namespace DetourNavigator; using namespace DetourNavigator;
const osg::ref_ptr<osg::Group> group(new osg::Group); const osg::ref_ptr<osg::Group> group(new osg::Group);
DebugDraw debugDraw(*group, DebugDraw::makeStateSet(), osg::Vec3f(0, 0, 0), 1.0f);
DebugDraw debugDraw(*group, debugDrawStateSet, osg::Vec3f(0, 0, 0), 1.0f);
const DetourNavigator::Mesh& mesh = recastMesh.getMesh(); const DetourNavigator::Mesh& mesh = recastMesh.getMesh();
std::vector<int> indices = mesh.getIndices(); std::vector<int> indices = mesh.getIndices();
std::vector<float> vertices = mesh.getVertices(); std::vector<float> vertices = mesh.getVertices();
@ -70,18 +71,6 @@ namespace SceneUtil
duDebugDrawTriMeshSlope(&debugDraw, vertices.data(), static_cast<int>(vertices.size() / 3), indices.data(), duDebugDrawTriMeshSlope(&debugDraw, vertices.data(), static_cast<int>(vertices.size() / 3), indices.data(),
normals.data(), static_cast<int>(indices.size() / 3), settings.mMaxSlope, texScale); normals.data(), static_cast<int>(indices.size() / 3), settings.mMaxSlope, texScale);
osg::ref_ptr<osg::Material> material = new osg::Material;
material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
const float polygonOffsetFactor = SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0;
const float polygonOffsetUnits = SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0;
osg::ref_ptr<osg::PolygonOffset> polygonOffset
= new osg::PolygonOffset(polygonOffsetFactor, polygonOffsetUnits);
osg::ref_ptr<osg::StateSet> stateSet = group->getOrCreateStateSet();
stateSet->setAttribute(material);
stateSet->setAttributeAndModes(polygonOffset);
return group; return group;
} }
} }

View file

@ -6,6 +6,7 @@
namespace osg namespace osg
{ {
class Group; class Group;
class StateSet;
} }
namespace DetourNavigator namespace DetourNavigator
@ -16,8 +17,8 @@ namespace DetourNavigator
namespace SceneUtil namespace SceneUtil
{ {
osg::ref_ptr<osg::Group> createRecastMeshGroup( osg::ref_ptr<osg::Group> createRecastMeshGroup(const DetourNavigator::RecastMesh& recastMesh,
const DetourNavigator::RecastMesh& recastMesh, const DetourNavigator::RecastSettings& settings); const DetourNavigator::RecastSettings& settings, const osg::ref_ptr<osg::StateSet>& debugDrawStateSet);
} }
#endif #endif