1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-29 18:32:36 +00:00
OpenMW/apps/openmw/mwrender/renderingmanager.hpp
elsid 1a12c453d6
Support different agent collision shape type for pathfinding
Actors may have different collision shapes. Currently there are axis-aligned
bounding boxes and rotating bounding boxes. With AABB it's required to use
bounding cylinder for navmesh agent to avoid providing paths where actor can't
pass. But for rotating bounding boxes cylinder with diameter equal to the front
face width should be used to not reduce of available paths. For example rats
have rotating bounding box as collision shape because of the difference between
front and side faces width.

* Add agent bounds to navmesh tile db cache key. This is required to distinguish
  tiles for agents with different bounds.
* Increase navmesh version because navmesh tile db cache key and data has changed.
* Move navmesh version to the code to avoid misconfiguration by users.
* Fix all places where wrong half extents were used for pathfinding.
2022-06-21 12:57:32 +02:00

332 lines
10 KiB
C++

#ifndef OPENMW_MWRENDER_RENDERINGMANAGER_H
#define OPENMW_MWRENDER_RENDERINGMANAGER_H
#include <osg/ref_ptr>
#include <osg/Light>
#include <osg/Camera>
#include <components/settings/settings.hpp>
#include <osgUtil/IncrementalCompileOperation>
#include "objects.hpp"
#include "navmeshmode.hpp"
#include "renderinginterface.hpp"
#include "rendermode.hpp"
#include <deque>
#include <memory>
namespace osg
{
class Group;
class PositionAttitudeTransform;
}
namespace osgUtil
{
class IntersectionVisitor;
class Intersector;
}
namespace Resource
{
class ResourceSystem;
}
namespace osgViewer
{
class Viewer;
}
namespace ESM
{
struct Cell;
struct RefNum;
}
namespace Terrain
{
class World;
}
namespace Fallback
{
class Map;
}
namespace SceneUtil
{
class ShadowManager;
class WorkQueue;
class LightManager;
}
namespace DetourNavigator
{
struct Navigator;
struct Settings;
struct AgentBounds;
}
namespace MWWorld
{
class GroundcoverStore;
}
namespace MWRender
{
class StateUpdater;
class SharedUniformStateUpdater;
class PerViewUniformStateUpdater;
class EffectManager;
class ScreenshotManager;
class FogManager;
class SkyManager;
class NpcAnimation;
class Pathgrid;
class Camera;
class Water;
class TerrainStorage;
class LandManager;
class NavMesh;
class ActorsPaths;
class RecastMesh;
class ObjectPaging;
class Groundcover;
class PostProcessor;
class RenderingManager : public MWRender::RenderingInterface
{
public:
RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
const std::string& resourcePath, DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore);
~RenderingManager();
osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation();
MWRender::Objects& getObjects() override;
Resource::ResourceSystem* getResourceSystem();
SceneUtil::WorkQueue* getWorkQueue();
Terrain::World* getTerrain();
void preloadCommonAssets();
double getReferenceTime() const;
SceneUtil::LightManager* getLightRoot();
void setNightEyeFactor(float factor);
void setAmbientColour(const osg::Vec4f& colour);
void skySetDate(int day, int month);
int skyGetMasserPhase() const;
int skyGetSecundaPhase() const;
void skySetMoonColour(bool red);
void setSunDirection(const osg::Vec3f& direction);
void setSunColour(const osg::Vec4f& diffuse, const osg::Vec4f& specular, float sunVis);
void setNight(bool isNight) { mNight = isNight; }
void configureAmbient(const ESM::Cell* cell);
void configureFog(const ESM::Cell* cell);
void configureFog(float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f& colour);
void addCell(const MWWorld::CellStore* store);
void removeCell(const MWWorld::CellStore* store);
void enableTerrain(bool enable);
void updatePtr(const MWWorld::Ptr& old, const MWWorld::Ptr& updated);
void rotateObject(const MWWorld::Ptr& ptr, const osg::Quat& rot);
void moveObject(const MWWorld::Ptr& ptr, const osg::Vec3f& pos);
void scaleObject(const MWWorld::Ptr& ptr, const osg::Vec3f& scale);
void removeObject(const MWWorld::Ptr& ptr);
void setWaterEnabled(bool enabled);
void setWaterHeight(float level);
/// Take a screenshot of w*h onto the given image, not including the GUI.
void screenshot(osg::Image* image, int w, int h);
bool screenshot360(osg::Image* image);
struct RayResult
{
bool mHit;
osg::Vec3f mHitNormalWorld;
osg::Vec3f mHitPointWorld;
MWWorld::Ptr mHitObject;
ESM::RefNum mHitRefnum;
float mRatio;
};
RayResult castRay(const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors=false);
/// Return the object under the mouse cursor / crosshair position, given by nX and nY normalized screen coordinates,
/// where (0,0) is the top left corner.
RayResult castCameraToViewportRay(const float nX, const float nY, float maxDistance, bool ignorePlayer, bool ignoreActors=false);
/// Get the bounding box of the given object in screen coordinates as (minX, minY, maxX, maxY), with (0,0) being the top left corner.
osg::Vec4f getScreenBounds(const osg::BoundingBox &worldbb);
void setSkyEnabled(bool enabled);
bool toggleRenderMode(RenderMode mode);
SkyManager* getSkyManager();
void spawnEffect(const std::string &model, const std::string &texture, const osg::Vec3f &worldPosition, float scale = 1.f, bool isMagicVFX = true);
/// Clear all savegame-specific data
void clear();
/// Clear all worldspace-specific data
void notifyWorldSpaceChanged();
void update(float dt, bool paused);
Animation* getAnimation(const MWWorld::Ptr& ptr);
const Animation* getAnimation(const MWWorld::ConstPtr& ptr) const;
PostProcessor* getPostProcessor();
void addWaterRippleEmitter(const MWWorld::Ptr& ptr);
void removeWaterRippleEmitter(const MWWorld::Ptr& ptr);
void emitWaterRipple(const osg::Vec3f& pos);
void updatePlayerPtr(const MWWorld::Ptr &ptr);
void removePlayer(const MWWorld::Ptr& player);
void setupPlayer(const MWWorld::Ptr& player);
void renderPlayer(const MWWorld::Ptr& player);
void rebuildPtr(const MWWorld::Ptr& ptr);
void processChangedSettings(const Settings::CategorySettingVector& settings);
float getNearClipDistance() const { return mNearClip; }
float getViewDistance() const { return mViewDistance; }
void setViewDistance(float distance, bool delay = false);
float getTerrainHeightAt(const osg::Vec3f& pos);
// camera stuff
Camera* getCamera() { return mCamera.get(); }
/// temporarily override the field of view with given value.
void overrideFieldOfView(float val);
void setFieldOfView(float val);
float getFieldOfView() const;
/// reset a previous overrideFieldOfView() call, i.e. revert to field of view specified in the settings file.
void resetFieldOfView();
osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& object) const;
void exportSceneGraph(const MWWorld::Ptr& ptr, const std::string& filename, const std::string& format);
LandManager* getLandManager() const;
bool toggleBorders();
void updateActorPath(const MWWorld::ConstPtr& actor, const std::deque<osg::Vec3f>& path,
const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end) const;
void removeActorPath(const MWWorld::ConstPtr& actor) const;
void setNavMeshNumber(const std::size_t value);
void setActiveGrid(const osg::Vec4i &grid);
bool pagingEnableObject(int type, const MWWorld::ConstPtr& ptr, bool enabled);
void pagingBlacklistObject(int type, const MWWorld::ConstPtr &ptr);
bool pagingUnlockCache();
void getPagedRefnums(const osg::Vec4i &activeGrid, std::set<ESM::RefNum> &out);
void updateProjectionMatrix();
void setScreenRes(int width, int height);
void setNavMeshMode(NavMeshMode value);
private:
void updateTextureFiltering();
void updateAmbient();
void setFogColor(const osg::Vec4f& color);
void updateThirdPersonViewMode();
void reportStats() const;
void updateNavMesh();
void updateRecastMesh();
const bool mSkyBlending;
osg::ref_ptr<osgUtil::IntersectionVisitor> getIntersectionVisitor(osgUtil::Intersector* intersector, bool ignorePlayer, bool ignoreActors);
osg::ref_ptr<osgUtil::IntersectionVisitor> mIntersectionVisitor;
osg::ref_ptr<osgViewer::Viewer> mViewer;
osg::ref_ptr<osg::Group> mRootNode;
osg::ref_ptr<SceneUtil::LightManager> mSceneRoot;
Resource::ResourceSystem* mResourceSystem;
osg::ref_ptr<SceneUtil::WorkQueue> mWorkQueue;
osg::ref_ptr<osg::Light> mSunLight;
DetourNavigator::Navigator& mNavigator;
std::unique_ptr<NavMesh> mNavMesh;
std::size_t mNavMeshNumber = 0;
std::unique_ptr<ActorsPaths> mActorsPaths;
std::unique_ptr<RecastMesh> mRecastMesh;
std::unique_ptr<Pathgrid> mPathgrid;
std::unique_ptr<Objects> mObjects;
std::unique_ptr<Water> mWater;
std::unique_ptr<Terrain::World> mTerrain;
std::unique_ptr<TerrainStorage> mTerrainStorage;
std::unique_ptr<ObjectPaging> mObjectPaging;
std::unique_ptr<Groundcover> mGroundcover;
std::unique_ptr<SkyManager> mSky;
std::unique_ptr<FogManager> mFog;
std::unique_ptr<ScreenshotManager> mScreenshotManager;
std::unique_ptr<EffectManager> mEffectManager;
std::unique_ptr<SceneUtil::ShadowManager> mShadowManager;
osg::ref_ptr<PostProcessor> mPostProcessor;
osg::ref_ptr<NpcAnimation> mPlayerAnimation;
osg::ref_ptr<SceneUtil::PositionAttitudeTransform> mPlayerNode;
std::unique_ptr<Camera> mCamera;
osg::ref_ptr<StateUpdater> mStateUpdater;
osg::ref_ptr<SharedUniformStateUpdater> mSharedUniformStateUpdater;
osg::ref_ptr<PerViewUniformStateUpdater> mPerViewUniformStateUpdater;
osg::Vec4f mAmbientColor;
float mMinimumAmbientLuminance;
float mNightEyeFactor;
float mNearClip;
float mViewDistance;
bool mFieldOfViewOverridden;
float mFieldOfViewOverride;
float mFieldOfView;
float mFirstPersonFieldOfView;
bool mUpdateProjectionMatrix = false;
bool mNight = false;
void operator = (const RenderingManager&);
RenderingManager(const RenderingManager&);
};
}
#endif