1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-09 21:42:13 +00:00
OpenMW/components/terrain/cellborder.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

114 lines
3.7 KiB
C++
Raw Normal View History

2018-06-12 23:48:31 +00:00
#include "cellborder.hpp"
#include <osg/Geometry>
2020-06-18 05:12:56 +00:00
#include <osg/Material>
2018-06-12 23:48:31 +00:00
#include <osg/PolygonMode>
#include "world.hpp"
2022-01-22 15:20:45 +00:00
#include <components/esm3/loadland.hpp>
#include <components/resource/scenemanager.hpp>
2021-07-29 13:33:58 +00:00
#include <components/terrain/storage.hpp>
namespace Terrain
2018-06-12 23:48:31 +00:00
{
CellBorder::CellBorder(
Terrain::World* world, osg::Group* root, int borderMask, Resource::SceneManager* sceneManager)
: mWorld(world)
, mSceneManager(sceneManager)
, mRoot(root)
, mBorderMask(borderMask)
2018-06-12 23:48:31 +00:00
{
}
osg::ref_ptr<osg::Group> CellBorder::createBorderGeometry(float x, float y, float size, Terrain::Storage* terrain,
Resource::SceneManager* sceneManager, int mask, ESM::RefId worldspace, float offset, osg::Vec4f color)
2018-06-12 23:48:31 +00:00
{
2018-06-13 23:01:22 +00:00
const int cellSize = ESM::Land::REAL_SIZE;
2018-06-12 23:48:31 +00:00
const int borderSegments = 40;
osg::Vec3 cellCorner = osg::Vec3(x * cellSize, y * cellSize, 0);
2021-07-29 13:33:58 +00:00
size *= cellSize;
2018-06-12 23:48:31 +00:00
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));
2021-07-29 13:33:58 +00:00
float borderStep = size / ((float)borderSegments);
2018-06-12 23:48:31 +00:00
for (int i = 0; i <= 2 * borderSegments; ++i)
{
osg::Vec3f pos = i < borderSegments ? osg::Vec3(i * borderStep, 0.0f, 0.0f)
2021-07-29 13:33:58 +00:00
: osg::Vec3(size, (i - borderSegments) * borderStep, 0.0f);
2018-06-12 23:48:31 +00:00
pos += cellCorner;
pos += osg::Vec3f(0, 0, terrain->getHeightAt(pos, worldspace) + offset);
2018-06-12 23:48:31 +00:00
vertices->push_back(pos);
osg::Vec4f col = i % 2 == 0 ? osg::Vec4f(0, 0, 0, 1) : color;
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::Group> borderGroup = new osg::Group;
borderGroup->addChild(border.get());
2018-06-12 23:48:31 +00:00
osg::StateSet* stateSet = borderGroup->getOrCreateStateSet();
2020-06-18 05:12:56 +00:00
osg::ref_ptr<osg::Material> material(new osg::Material);
material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
stateSet->setAttribute(material);
2018-06-12 23:48:31 +00:00
osg::PolygonMode* polygonmode = new osg::PolygonMode;
polygonmode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
stateSet->setAttributeAndModes(polygonmode, osg::StateAttribute::ON);
sceneManager->recreateShaders(borderGroup, "debug");
borderGroup->setNodeMask(mask);
return borderGroup;
2021-07-29 13:33:58 +00:00
}
2018-06-14 11:18:37 +00:00
2021-07-29 13:33:58 +00:00
void CellBorder::createCellBorderGeometry(int x, int y)
{
auto borderGroup = createBorderGeometry(
x, y, 1.f, mWorld->getStorage(), mSceneManager, mBorderMask, mWorld->getWorldspace());
mRoot->addChild(borderGroup);
2018-06-12 23:48:31 +00:00
mCellBorderNodes[std::make_pair(x, y)] = borderGroup;
2018-06-12 23:48:31 +00:00
}
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;
2018-06-14 10:01:09 +00:00
mRoot->removeChild(borderNode);
2018-06-12 23:48:31 +00:00
mCellBorderNodes.erase(it);
}
2018-06-14 10:01:09 +00:00
void CellBorder::destroyCellBorderGeometry()
{
for (const auto& v : mCellBorderNodes)
mRoot->removeChild(v.second);
mCellBorderNodes.clear();
2018-06-14 10:01:09 +00:00
}
2018-06-12 23:48:31 +00:00
}