Start cell border debug drawing

pull/1764/head
Miloslav Číž 7 years ago
parent 36f4f0ef85
commit db8aaa74d6

@ -120,6 +120,7 @@ namespace MWBase
virtual bool toggleWater() = 0;
virtual bool toggleWorld() = 0;
virtual bool toggleBorders() = 0;
virtual void adjustSky() = 0;

@ -181,6 +181,7 @@ namespace MWRender
, mNightEyeFactor(0.f)
, mFieldOfViewOverride(0.f)
, mFieldOfViewOverridden(false)
, mBorders(false)
{
resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem);
resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders");
@ -219,9 +220,10 @@ namespace MWRender
Settings::Manager::getBool("auto use terrain specular maps", "Shaders"));
if (distantTerrain)
mTerrain.reset(new Terrain::QuadTreeWorld(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile));
mTerrain.reset(new Terrain::QuadTreeWorld(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile, Mask_Debug));
else
mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile));
mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile, Mask_Debug));
mTerrain->setDefaultViewer(mViewer->getCamera());
mCamera.reset(new Camera(mViewer->getCamera()));
@ -441,6 +443,13 @@ namespace MWRender
{
mSky->setEnabled(enabled);
}
bool RenderingManager::toggleBorders()
{
mBorders = !mBorders;
mTerrain->setBordersVisible(mBorders);
return mBorders;
}
bool RenderingManager::toggleRenderMode(RenderMode mode)
{

@ -205,6 +205,8 @@ namespace MWRender
LandManager* getLandManager() const;
bool toggleBorders();
private:
void updateProjectionMatrix();
void updateTextureFiltering();
@ -257,6 +259,7 @@ namespace MWRender
bool mFieldOfViewOverridden;
float mFieldOfView;
float mFirstPersonFieldOfView;
bool mBorders;
void operator = (const RenderingManager&);
RenderingManager(const RenderingManager&);

@ -454,5 +454,6 @@ op 0x2000303: Fixme, explicit
op 0x2000304: Show
op 0x2000305: Show, explicit
op 0x2000306: OnActivate, explicit
op 0x2000307: ToggleBorders, tb
opcodes 0x2000307-0x3ffffff unused
opcodes 0x2000308-0x3ffffff unused

@ -254,6 +254,20 @@ namespace MWScript
}
};
class OpToggleBorders : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
bool enabled =
MWBase::Environment::get().getWorld()->toggleBorders();
runtime.getContext().report (enabled ?
"Border Rendering -> On" : "Border Rendering -> Off");
}
};
class OpTogglePathgrid : public Interpreter::Opcode0
{
public:
@ -1374,6 +1388,7 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Misc::opcodeRemoveFromLevItem, new OpRemoveFromLevItem);
interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraph, new OpShowSceneGraph<ImplicitRef>);
interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraphExplicit, new OpShowSceneGraph<ExplicitRef>);
interpreter.installSegment5 (Compiler::Misc::opcodeToggleBorders, new OpToggleBorders);
}
}
}

@ -1919,6 +1919,11 @@ namespace MWWorld
return mRendering->toggleRenderMode(MWRender::Render_Scene);
}
bool World::toggleBorders()
{
return mRendering->toggleBorders();
}
void World::PCDropped (const Ptr& item)
{
std::string script = item.getClass().getScript(item);

@ -217,6 +217,7 @@ namespace MWWorld
bool toggleWater() override;
bool toggleWorld() override;
bool toggleBorders() override;
void adjustSky() override;

@ -120,7 +120,7 @@ add_component_dir (translation
)
add_component_dir (terrain
storage world buffercache defs terraingrid material terraindrawable texturemanager chunkmanager compositemaprenderer quadtreeworld quadtreenode viewdata
storage world buffercache defs terraingrid material terraindrawable texturemanager chunkmanager compositemaprenderer quadtreeworld quadtreenode viewdata cellborder
)
add_component_dir (loadinglistener

@ -318,6 +318,8 @@ namespace Compiler
extensions.registerInstruction ("removefromlevcreature", "ccl", opcodeRemoveFromLevCreature);
extensions.registerInstruction ("addtolevitem", "ccl", opcodeAddToLevItem);
extensions.registerInstruction ("removefromlevitem", "ccl", opcodeRemoveFromLevItem);
extensions.registerInstruction ("tb", "", opcodeToggleBorders);
extensions.registerInstruction ("toggleborders", "", opcodeToggleBorders);
}
}

@ -295,6 +295,7 @@ namespace Compiler
const int opcodeRemoveFromLevItem = 0x20002fe;
const int opcodeShowSceneGraph = 0x2002f;
const int opcodeShowSceneGraphExplicit = 0x20030;
const int opcodeToggleBorders = 0x2000307;
}
namespace Sky

@ -0,0 +1,91 @@
#include "cellborder.hpp"
#include <osg/PolygonMode>
#include <osg/Geometry>
#include <osg/Geode>
#include "world.hpp"
namespace MWRender
{
CellBorder::CellBorder(Terrain::World *world, osg::Group *root):
mWorld(world),
mRoot(root),
mBorderRoot(0)
{
}
void CellBorder::createCellBorderGeometry(int x, int y)
{
const int cellSize = 8192;
const int borderSegments = 40;
const float offset = 10.0;
osg::Vec3 cellCorner = osg::Vec3(x * cellSize,y * cellSize,0);
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0f,-1.0f, 0.0f));
float borderStep = cellSize / ((float) borderSegments);
for (int i = 0; i <= 2 * borderSegments; ++i)
{
osg::Vec3f pos = i < borderSegments ?
osg::Vec3(i * borderStep,0.0f,0.0f) :
osg::Vec3(cellSize,(i - borderSegments) * borderStep,0.0f);
pos += cellCorner;
pos += osg::Vec3f(0,0,mWorld->getHeightAt(pos) + offset);
vertices->push_back(pos);
osg::Vec4f col = i % 2 == 0 ?
osg::Vec4f(0,0,0,1) :
osg::Vec4f(1,1,0,1);
colors->push_back(col);
}
osg::ref_ptr<osg::Geometry> border = new osg::Geometry;
border->setVertexArray(vertices.get());
border->setNormalArray(normals.get());
border->setNormalBinding(osg::Geometry::BIND_OVERALL);
border->setColorArray(colors.get());
border->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
border->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size()));
osg::ref_ptr<osg::Geode> borderGeode = new osg::Geode;
borderGeode->addDrawable(border.get());
osg::StateSet *stateSet = borderGeode->getOrCreateStateSet();
osg::PolygonMode* polygonmode = new osg::PolygonMode;
polygonmode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
stateSet->setAttributeAndModes(polygonmode,osg::StateAttribute::ON);
mRoot->addChild(borderGeode);
mBorderRoot = borderGeode;
mCellBorderNodes[std::make_pair(x,y)] = borderGeode;
}
void CellBorder::destroyCellBorderGeometry(int x, int y)
{
CellGrid::iterator it = mCellBorderNodes.find(std::make_pair(x,y));
if (it == mCellBorderNodes.end())
return;
osg::ref_ptr<osg::Node> borderNode = it->second;
mBorderRoot->removeChild(borderNode);
mCellBorderNodes.erase(it);
}
}

@ -0,0 +1,36 @@
#ifndef GAME_RENDER_CELLBORDER
#define GAME_RENDER_CELLBORDER
#include <map>
#include <osg/Group>
namespace Terrain
{
class World;
}
namespace MWRender
{
/**
* @Brief Handles the debug cell borders.
*/
class CellBorder
{
public:
typedef std::map<std::pair<int, int>, osg::ref_ptr<osg::Node> > CellGrid;
CellBorder(Terrain::World *world, osg::Group *root);
void createCellBorderGeometry(int x, int y);
void destroyCellBorderGeometry(int x, int y);
protected:
Terrain::World *mWorld;
osg::Group *mRoot;
osg::Group *mBorderRoot;
CellGrid mCellBorderNodes;
};
}
#endif

@ -235,8 +235,8 @@ private:
osg::ref_ptr<RootNode> mRootNode;
};
QuadTreeWorld::QuadTreeWorld(osg::Group *parent, osg::Group *compileRoot, Resource::ResourceSystem *resourceSystem, Storage *storage, int nodeMask, int preCompileMask)
: World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask)
QuadTreeWorld::QuadTreeWorld(osg::Group *parent, osg::Group *compileRoot, Resource::ResourceSystem *resourceSystem, Storage *storage, int nodeMask, int preCompileMask, int borderMask)
: World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask, borderMask)
, mViewDataMap(new ViewDataMap)
, mQuadTreeBuilt(false)
{

@ -19,7 +19,7 @@ namespace Terrain
class QuadTreeWorld : public Terrain::World
{
public:
QuadTreeWorld(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask=~0);
QuadTreeWorld(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask=~0, int borderMask=0);
~QuadTreeWorld();
void accept(osg::NodeVisitor& nv);

@ -17,8 +17,8 @@ public:
virtual void reset(unsigned int frame) {}
};
TerrainGrid::TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask)
: Terrain::World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask)
TerrainGrid::TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask, int borderMask)
: Terrain::World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask, borderMask)
, mNumSplits(4)
{
}
@ -75,6 +75,8 @@ void TerrainGrid::loadCell(int x, int y)
if (!terrainNode)
return; // no terrain defined
Terrain::World::loadCell(x,y);
mTerrainRoot->addChild(terrainNode);
mGrid[std::make_pair(x,y)] = terrainNode;
@ -82,7 +84,9 @@ void TerrainGrid::loadCell(int x, int y)
void TerrainGrid::unloadCell(int x, int y)
{
Grid::iterator it = mGrid.find(std::make_pair(x,y));
World::unloadCell(x,y);
MWRender::CellBorder::CellGrid::iterator it = mGrid.find(std::make_pair(x,y));
if (it == mGrid.end())
return;

@ -7,6 +7,8 @@
#include "world.hpp"
#include "cellborder.hpp"
namespace Terrain
{
@ -14,7 +16,7 @@ namespace Terrain
class TerrainGrid : public Terrain::World
{
public:
TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask=~0);
TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask=~0, int borderMask=0);
~TerrainGrid();
virtual void cacheCell(View* view, int x, int y);
@ -33,8 +35,7 @@ namespace Terrain
// split each ESM::Cell into mNumSplits*mNumSplits terrain chunks
unsigned int mNumSplits;
typedef std::map<std::pair<int, int>, osg::ref_ptr<osg::Node> > Grid;
Grid mGrid;
MWRender::CellBorder::CellGrid mGrid;
};
}

@ -14,7 +14,7 @@
namespace Terrain
{
World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask)
World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask, int borderMask)
: mStorage(storage)
, mParent(parent)
, mResourceSystem(resourceSystem)
@ -28,6 +28,12 @@ World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSyst
mTerrainRoot->setName("Terrain Root");
mBorderRoot = new osg::Switch;
mBorderRoot->setName("Border Root");
mBorderRoot->setNodeMask(borderMask);
mTerrainRoot->addChild(mBorderRoot);
osg::ref_ptr<osg::Camera> compositeCam = new osg::Camera;
compositeCam->setRenderOrder(osg::Camera::PRE_RENDER, -1);
compositeCam->setProjectionMatrix(osg::Matrix::identity());
@ -39,7 +45,6 @@ World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSyst
compileRoot->addChild(compositeCam);
mCompositeMapRenderer = new CompositeMapRenderer;
compositeCam->addChild(mCompositeMapRenderer);
@ -48,8 +53,30 @@ World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSyst
mTextureManager.reset(new TextureManager(mResourceSystem->getSceneManager()));
mChunkManager.reset(new ChunkManager(mStorage, mResourceSystem->getSceneManager(), mTextureManager.get(), mCompositeMapRenderer));
mCellBorder.reset(new MWRender::CellBorder(this,mTerrainRoot.get()));
mResourceSystem->addResourceManager(mChunkManager.get());
mResourceSystem->addResourceManager(mTextureManager.get());
setBordersVisible(false);
}
void World::setBordersVisible(bool visible)
{
if (visible)
mBorderRoot->setAllChildrenOn();
else
mBorderRoot->setAllChildrenOff();
}
void World::loadCell(int x, int y)
{
mCellBorder->createCellBorderGeometry(x,y);
}
void World::unloadCell(int x, int y)
{
mCellBorder->destroyCellBorderGeometry(x,y);
}
World::~World()

@ -4,11 +4,14 @@
#include <osg/ref_ptr>
#include <osg/Referenced>
#include <osg/Vec3f>
#include <osg/Switch>
#include <memory>
#include "defs.hpp"
#include "cellborder.hpp"
namespace osg
{
class Group;
@ -54,7 +57,7 @@ namespace Terrain
/// @param storage Storage instance to get terrain data from (heights, normals, colors, textures..)
/// @param nodeMask mask for the terrain root
/// @param preCompileMask mask for pre compiling textures
World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask);
World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask, int borderMask);
virtual ~World();
/// Apply the scene manager's texture filtering settings to all cached textures.
@ -73,16 +76,16 @@ namespace Terrain
/// Load the cell into the scene graph.
/// @note Not thread safe.
/// @note May be ignored by derived implementations that don't organize the terrain into cells.
virtual void loadCell(int x, int y) {}
virtual void loadCell(int x, int y);
/// Remove the cell from the scene graph.
/// @note Not thread safe.
/// @note May be ignored by derived implementations that don't organize the terrain into cells.
virtual void unloadCell(int x, int y) {}
virtual void unloadCell(int x, int y);
virtual void enable(bool enabled) {}
void setBordersVisible(bool visible);
/// Create a View to use with preload feature. The caller is responsible for deleting the view.
/// @note Thread safe.
virtual View* createView() { return NULL; }
@ -98,10 +101,14 @@ namespace Terrain
Storage* getStorage() { return mStorage; }
protected:
void createCellBorderGeometry(int x, int y);
void destroyCellBorderGeometry(int x, int y);
Storage* mStorage;
osg::ref_ptr<osg::Group> mParent;
osg::ref_ptr<osg::Group> mTerrainRoot;
osg::ref_ptr<osg::Switch> mBorderRoot;
osg::ref_ptr<osg::Group> mCompositeMapCamera;
osg::ref_ptr<CompositeMapRenderer> mCompositeMapRenderer;
@ -110,8 +117,9 @@ namespace Terrain
std::unique_ptr<TextureManager> mTextureManager;
std::unique_ptr<ChunkManager> mChunkManager;
};
std::unique_ptr<MWRender::CellBorder> mCellBorder;
};
}
#endif

Loading…
Cancel
Save