|
|
|
@ -16,11 +16,13 @@
|
|
|
|
|
#include "worldspacewidget.hpp"
|
|
|
|
|
|
|
|
|
|
CSVRender::TerrainSelection::TerrainSelection(osg::Group* parentNode, WorldspaceWidget *worldspaceWidget, TerrainSelectionType type):
|
|
|
|
|
mParentNode(parentNode), mWorldspaceWidget (worldspaceWidget), mDraggedOperationFlag(false), mSelectionType(type)
|
|
|
|
|
mParentNode(parentNode), mWorldspaceWidget (worldspaceWidget), mSelectionType(type)
|
|
|
|
|
{
|
|
|
|
|
mGeometry = new osg::Geometry();
|
|
|
|
|
|
|
|
|
|
mSelectionNode = new osg::Group();
|
|
|
|
|
mSelectionNode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
|
|
|
|
mSelectionNode->getOrCreateStateSet()->setRenderBinDetails(11, "RenderBin");
|
|
|
|
|
mSelectionNode->addChild(mGeometry);
|
|
|
|
|
|
|
|
|
|
activate();
|
|
|
|
@ -43,19 +45,24 @@ void CSVRender::TerrainSelection::onlySelect(const std::vector<std::pair<int, in
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSVRender::TerrainSelection::addSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress)
|
|
|
|
|
void CSVRender::TerrainSelection::addSelect(const std::vector<std::pair<int, int>>& localPositions)
|
|
|
|
|
{
|
|
|
|
|
handleSelection(localPositions, toggleInProgress, SelectionMethod::AddSelect);
|
|
|
|
|
handleSelection(localPositions, SelectionMethod::AddSelect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSVRender::TerrainSelection::removeSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress)
|
|
|
|
|
void CSVRender::TerrainSelection::removeSelect(const std::vector<std::pair<int, int>>& localPositions)
|
|
|
|
|
{
|
|
|
|
|
handleSelection(localPositions, toggleInProgress, SelectionMethod::RemoveSelect);
|
|
|
|
|
handleSelection(localPositions, SelectionMethod::RemoveSelect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSVRender::TerrainSelection::toggleSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress)
|
|
|
|
|
void CSVRender::TerrainSelection::toggleSelect(const std::vector<std::pair<int, int>>& localPositions)
|
|
|
|
|
{
|
|
|
|
|
handleSelection(localPositions, toggleInProgress, SelectionMethod::ToggleSelect);
|
|
|
|
|
handleSelection(localPositions, SelectionMethod::ToggleSelect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSVRender::TerrainSelection::clearTemporarySelection()
|
|
|
|
|
{
|
|
|
|
|
mTemporarySelection.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSVRender::TerrainSelection::activate()
|
|
|
|
@ -102,26 +109,16 @@ void CSVRender::TerrainSelection::drawShapeSelection(const osg::ref_ptr<osg::Vec
|
|
|
|
|
float xWorldCoord(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x));
|
|
|
|
|
float yWorldCoord(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y));
|
|
|
|
|
|
|
|
|
|
osg::Vec3f pointXY(xWorldCoord, yWorldCoord, calculateLandHeight(x, y) + 2);
|
|
|
|
|
osg::Vec3f pointXY(xWorldCoord, yWorldCoord, calculateLandHeight(x, y));
|
|
|
|
|
|
|
|
|
|
vertices->push_back(pointXY);
|
|
|
|
|
vertices->push_back(osg::Vec3f(xWorldCoord, CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y - 1), calculateLandHeight(x, y - 1) + 2));
|
|
|
|
|
vertices->push_back(osg::Vec3f(xWorldCoord, CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y - 1), calculateLandHeight(x, y - 1)));
|
|
|
|
|
vertices->push_back(pointXY);
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x - 1), yWorldCoord, calculateLandHeight(x - 1, y) + 2));
|
|
|
|
|
|
|
|
|
|
const auto north = std::find(mSelection.begin(), mSelection.end(), std::make_pair(x, y + 1));
|
|
|
|
|
if (north == mSelection.end())
|
|
|
|
|
{
|
|
|
|
|
vertices->push_back(pointXY);
|
|
|
|
|
vertices->push_back(osg::Vec3f(xWorldCoord, CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y + 1), calculateLandHeight(x, y + 1) + 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto east = std::find(mSelection.begin(), mSelection.end(), std::make_pair(x + 1, y));
|
|
|
|
|
if (east == mSelection.end())
|
|
|
|
|
{
|
|
|
|
|
vertices->push_back(pointXY);
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x + 1), yWorldCoord, calculateLandHeight(x + 1, y) + 2));
|
|
|
|
|
}
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x - 1), yWorldCoord, calculateLandHeight(x - 1, y)));
|
|
|
|
|
vertices->push_back(pointXY);
|
|
|
|
|
vertices->push_back(osg::Vec3f(xWorldCoord, CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y + 1), calculateLandHeight(x, y + 1)));
|
|
|
|
|
vertices->push_back(pointXY);
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x + 1), yWorldCoord, calculateLandHeight(x + 1, y)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -154,8 +151,8 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
|
|
|
|
|
{
|
|
|
|
|
float drawPreviousX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
|
|
|
|
|
float drawCurrentX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
|
|
|
|
|
vertices->push_back(osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), calculateLandHeight(x1+(i-1), y2)+2));
|
|
|
|
|
vertices->push_back(osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), calculateLandHeight(x1+i, y2)+2));
|
|
|
|
|
vertices->push_back(osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), calculateLandHeight(x1+(i-1), y2)));
|
|
|
|
|
vertices->push_back(osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), calculateLandHeight(x1+i, y2)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -166,8 +163,8 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
|
|
|
|
|
{
|
|
|
|
|
float drawPreviousX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + (i - 1) *(ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
|
|
|
|
|
float drawCurrentX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
|
|
|
|
|
vertices->push_back(osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+(i-1), y1)+2));
|
|
|
|
|
vertices->push_back(osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+i, y1)+2));
|
|
|
|
|
vertices->push_back(osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+(i-1), y1)));
|
|
|
|
|
vertices->push_back(osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+i, y1)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -178,8 +175,8 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
|
|
|
|
|
{
|
|
|
|
|
float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
|
|
|
|
|
float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), drawPreviousY, calculateLandHeight(x2, y1+(i-1))+2));
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), drawCurrentY, calculateLandHeight(x2, y1+i)+2));
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), drawPreviousY, calculateLandHeight(x2, y1+(i-1))));
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), drawCurrentY, calculateLandHeight(x2, y1+i)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -190,103 +187,60 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
|
|
|
|
|
{
|
|
|
|
|
float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
|
|
|
|
|
float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), drawPreviousY, calculateLandHeight(x1, y1+(i-1))+2));
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), drawCurrentY, calculateLandHeight(x1, y1+i)+2));
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), drawPreviousY, calculateLandHeight(x1, y1+(i-1))));
|
|
|
|
|
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), drawCurrentY, calculateLandHeight(x1, y1+i)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSVRender::TerrainSelection::handleSelection(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress, SelectionMethod selectionMethod)
|
|
|
|
|
void CSVRender::TerrainSelection::handleSelection(const std::vector<std::pair<int, int>>& localPositions, SelectionMethod selectionMethod)
|
|
|
|
|
{
|
|
|
|
|
if (toggleInProgress)
|
|
|
|
|
for (auto const& localPos : localPositions)
|
|
|
|
|
{
|
|
|
|
|
for (auto const& localPos : localPositions)
|
|
|
|
|
{
|
|
|
|
|
auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos);
|
|
|
|
|
mDraggedOperationFlag = true;
|
|
|
|
|
|
|
|
|
|
if (iterTemp == mTemporarySelection.end())
|
|
|
|
|
{
|
|
|
|
|
auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
|
|
|
|
|
const auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
|
|
|
|
|
|
|
|
|
|
switch (selectionMethod)
|
|
|
|
|
{
|
|
|
|
|
case SelectionMethod::AddSelect:
|
|
|
|
|
if (iter == mSelection.end())
|
|
|
|
|
{
|
|
|
|
|
mSelection.emplace_back(localPos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case SelectionMethod::RemoveSelect:
|
|
|
|
|
if (iter != mSelection.end())
|
|
|
|
|
{
|
|
|
|
|
mSelection.erase(iter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case SelectionMethod::ToggleSelect:
|
|
|
|
|
if (iter == mSelection.end())
|
|
|
|
|
{
|
|
|
|
|
mSelection.emplace_back(localPos);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mSelection.erase(iter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mTemporarySelection.push_back(localPos);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (mDraggedOperationFlag == false)
|
|
|
|
|
{
|
|
|
|
|
for (auto const& localPos : localPositions)
|
|
|
|
|
switch (selectionMethod)
|
|
|
|
|
{
|
|
|
|
|
const auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
|
|
|
|
|
case SelectionMethod::OnlySelect:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
switch (selectionMethod)
|
|
|
|
|
{
|
|
|
|
|
case SelectionMethod::AddSelect:
|
|
|
|
|
if (iter == mSelection.end())
|
|
|
|
|
{
|
|
|
|
|
mSelection.emplace_back(localPos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SelectionMethod::RemoveSelect:
|
|
|
|
|
if (iter != mSelection.end())
|
|
|
|
|
{
|
|
|
|
|
mSelection.erase(iter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SelectionMethod::ToggleSelect:
|
|
|
|
|
if (iter == mSelection.end())
|
|
|
|
|
{
|
|
|
|
|
mSelection.emplace_back(localPos);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos);
|
|
|
|
|
if (iterTemp == mTemporarySelection.end())
|
|
|
|
|
{
|
|
|
|
|
mSelection.erase(iter);
|
|
|
|
|
if (iter == mSelection.end())
|
|
|
|
|
{
|
|
|
|
|
mSelection.emplace_back(localPos);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mSelection.erase(iter);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mTemporarySelection.emplace_back(localPos);
|
|
|
|
|
break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mDraggedOperationFlag = false;
|
|
|
|
|
|
|
|
|
|
mTemporarySelection.clear();
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update();
|
|
|
|
@ -336,11 +290,9 @@ int CSVRender::TerrainSelection::calculateLandHeight(int x, int y) // global ver
|
|
|
|
|
else if (isLandLoaded(CSMWorld::CellCoordinates::generateId(cellX, cellY)))
|
|
|
|
|
{
|
|
|
|
|
CSMDoc::Document& document = mWorldspaceWidget->getDocument();
|
|
|
|
|
CSMWorld::IdTable& landTable = dynamic_cast<CSMWorld::IdTable&> ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land));
|
|
|
|
|
std::string cellId = CSMWorld::CellCoordinates::generateId(cellX, cellY);
|
|
|
|
|
int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex);
|
|
|
|
|
const CSMWorld::LandHeightsColumn::DataType mPointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value<CSMWorld::LandHeightsColumn::DataType>();
|
|
|
|
|
return mPointer[localY*ESM::Land::LAND_SIZE + localX];
|
|
|
|
|
const ESM::Land::LandData* landData = document.getData().getLand().getRecord(cellId).get().getLandData(ESM::Land::DATA_VHGT);
|
|
|
|
|
return landData->mHeights[localY*ESM::Land::LAND_SIZE + localX];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return landHeight;
|
|
|
|
|