forked from mirror/openmw-tes3mp
We don't need the delay any more because the rendering itself is part of the normal rendering traversal - so it's delayed anyway. Don't request maps that we're not actually using (i.e. with cell grid sizes higher than the default 3, we were rendering more maps than the map window could show).
160 lines
4.7 KiB
C++
160 lines
4.7 KiB
C++
#ifndef GAME_RENDER_LOCALMAP_H
|
|
#define GAME_RENDER_LOCALMAP_H
|
|
|
|
#include <set>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
#include <osg/BoundingBox>
|
|
#include <osg/Quat>
|
|
#include <osg/ref_ptr>
|
|
|
|
namespace MWWorld
|
|
{
|
|
class CellStore;
|
|
}
|
|
|
|
namespace ESM
|
|
{
|
|
struct FogTexture;
|
|
}
|
|
|
|
namespace osgViewer
|
|
{
|
|
class Viewer;
|
|
}
|
|
|
|
namespace osg
|
|
{
|
|
class Texture2D;
|
|
class Image;
|
|
class Camera;
|
|
class Group;
|
|
class Node;
|
|
}
|
|
|
|
namespace MWRender
|
|
{
|
|
///
|
|
/// \brief Local map rendering
|
|
///
|
|
class LocalMap
|
|
{
|
|
public:
|
|
LocalMap(osgViewer::Viewer* viewer);
|
|
~LocalMap();
|
|
|
|
/**
|
|
* Clear all savegame-specific data (i.e. fog of war textures)
|
|
*/
|
|
void clear();
|
|
|
|
/**
|
|
* Request a map render for the given cells. Render textures will be immediately created and can be retrieved with the getMapTexture function.
|
|
*/
|
|
void requestMap (std::set<const MWWorld::CellStore*> cells);
|
|
|
|
/**
|
|
* Remove map and fog textures for the given cell.
|
|
*/
|
|
void removeCell (MWWorld::CellStore* cell);
|
|
|
|
osg::ref_ptr<osg::Texture2D> getMapTexture (int x, int y);
|
|
|
|
osg::ref_ptr<osg::Texture2D> getFogOfWarTexture (int x, int y);
|
|
|
|
/**
|
|
* Indicates a camera has been queued for rendering and can be cleaned up in the next frame. For internal use only.
|
|
*/
|
|
void markForRemoval(osg::Camera* cam);
|
|
|
|
/**
|
|
* Removes cameras that have already been rendered. Should be called every frame to ensure that
|
|
* we do not render the same map more than once. Note, this cleanup is difficult to implement in an
|
|
* automated fashion, since we can't alter the scene graph structure from within an update callback.
|
|
*/
|
|
void cleanupCameras();
|
|
|
|
/**
|
|
* Set the position & direction of the player, and returns the position in map space through the reference parameters.
|
|
* @remarks This is used to draw a "fog of war" effect
|
|
* to hide areas on the map the player has not discovered yet.
|
|
*/
|
|
void updatePlayer (const osg::Vec3f& position, const osg::Quat& orientation,
|
|
float& u, float& v, int& x, int& y, osg::Vec3f& direction);
|
|
|
|
/**
|
|
* Save the fog of war for this cell to its CellStore.
|
|
* @remarks This should be called when unloading a cell, and for all active cells prior to saving the game.
|
|
*/
|
|
void saveFogOfWar(MWWorld::CellStore* cell);
|
|
|
|
/**
|
|
* Get the interior map texture index and normalized position on this texture, given a world position
|
|
*/
|
|
void worldToInteriorMapPosition (osg::Vec2f pos, float& nX, float& nY, int& x, int& y);
|
|
|
|
osg::Vec2f interiorMapToWorldPosition (float nX, float nY, int x, int y);
|
|
|
|
/**
|
|
* Check if a given position is explored by the player (i.e. not obscured by fog of war)
|
|
*/
|
|
bool isPositionExplored (float nX, float nY, int x, int y);
|
|
|
|
osg::Group* getRoot();
|
|
|
|
private:
|
|
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
|
|
|
osg::ref_ptr<osg::Group> mRoot;
|
|
osg::ref_ptr<osg::Node> mSceneRoot;
|
|
|
|
typedef std::vector< osg::ref_ptr<osg::Camera> > CameraVector;
|
|
|
|
CameraVector mActiveCameras;
|
|
|
|
CameraVector mCamerasPendingRemoval;
|
|
|
|
struct MapSegment
|
|
{
|
|
MapSegment();
|
|
~MapSegment();
|
|
|
|
void initFogOfWar();
|
|
void loadFogOfWar(const ESM::FogTexture& fog);
|
|
void saveFogOfWar(ESM::FogTexture& fog) const;
|
|
void createFogOfWarTexture();
|
|
|
|
osg::ref_ptr<osg::Texture2D> mMapTexture;
|
|
osg::ref_ptr<osg::Texture2D> mFogOfWarTexture;
|
|
osg::ref_ptr<osg::Image> mFogOfWarImage;
|
|
|
|
bool mHasFogState;
|
|
};
|
|
|
|
typedef std::map<std::pair<int, int>, MapSegment> SegmentMap;
|
|
SegmentMap mSegments;
|
|
|
|
int mMapResolution;
|
|
|
|
// the dynamic texture is a bottleneck, so don't set this too high
|
|
static const int sFogOfWarResolution = 32;
|
|
|
|
// size of a map segment (for exteriors, 1 cell)
|
|
float mMapWorldSize;
|
|
|
|
float mAngle;
|
|
const osg::Vec2f rotatePoint(const osg::Vec2f& point, const osg::Vec2f& center, const float angle);
|
|
|
|
void requestExteriorMap(const MWWorld::CellStore* cell);
|
|
void requestInteriorMap(const MWWorld::CellStore* cell);
|
|
|
|
osg::ref_ptr<osg::Camera> createOrthographicCamera(float left, float top, float width, float height, const osg::Vec3d& upVector, float zmin, float zmax);
|
|
void setupRenderToTexture(osg::ref_ptr<osg::Camera> camera, int x, int y);
|
|
|
|
bool mInterior;
|
|
osg::BoundingBox mBounds;
|
|
};
|
|
|
|
}
|
|
#endif
|