mirror of
https://github.com/OpenMW/openmw.git
synced 2025-12-13 06:43:06 +00:00
Merge branch 'terrainselectionoptimize' into 'master'
Terrain selection optimizations See merge request OpenMW/openmw!1261
This commit is contained in:
commit
ac3c02496c
9 changed files with 121 additions and 156 deletions
|
|
@ -48,6 +48,7 @@
|
||||||
Bug #6273: Respawning NPCs rotation is inconsistent
|
Bug #6273: Respawning NPCs rotation is inconsistent
|
||||||
Bug #6282: Laura craft doesn't follow the player character
|
Bug #6282: Laura craft doesn't follow the player character
|
||||||
Bug #6283: Avis Dorsey follows you after her death
|
Bug #6283: Avis Dorsey follows you after her death
|
||||||
|
Bug #6285: Brush template drawing and terrain selection drawing performance is very bad
|
||||||
Bug #6289: Keyword search in dialogues expected the text to be all ASCII characters
|
Bug #6289: Keyword search in dialogues expected the text to be all ASCII characters
|
||||||
Bug #6291: Can't pickup the dead mage's journal from the mysterious hunter mod
|
Bug #6291: Can't pickup the dead mage's journal from the mysterious hunter mod
|
||||||
Bug #6302: Teleporting disabled actor breaks its disabled state
|
Bug #6302: Teleporting disabled actor breaks its disabled state
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,13 @@
|
||||||
#include "worldspacewidget.hpp"
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
CSVRender::TerrainSelection::TerrainSelection(osg::Group* parentNode, WorldspaceWidget *worldspaceWidget, TerrainSelectionType type):
|
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();
|
mGeometry = new osg::Geometry();
|
||||||
|
|
||||||
mSelectionNode = new osg::Group();
|
mSelectionNode = new osg::Group();
|
||||||
|
mSelectionNode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
||||||
|
mSelectionNode->getOrCreateStateSet()->setRenderBinDetails(11, "RenderBin");
|
||||||
mSelectionNode->addChild(mGeometry);
|
mSelectionNode->addChild(mGeometry);
|
||||||
|
|
||||||
activate();
|
activate();
|
||||||
|
|
@ -43,19 +45,24 @@ void CSVRender::TerrainSelection::onlySelect(const std::vector<std::pair<int, in
|
||||||
update();
|
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()
|
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 xWorldCoord(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x));
|
||||||
float yWorldCoord(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y));
|
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(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(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);
|
||||||
const auto north = std::find(mSelection.begin(), mSelection.end(), std::make_pair(x, y + 1));
|
vertices->push_back(osg::Vec3f(xWorldCoord, CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y + 1), calculateLandHeight(x, y + 1)));
|
||||||
if (north == mSelection.end())
|
vertices->push_back(pointXY);
|
||||||
{
|
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) + 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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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 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));
|
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(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)+2));
|
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 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));
|
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(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+(i-1), y1)));
|
||||||
vertices->push_back(osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+i, y1)+2));
|
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 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));
|
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), drawPreviousY, calculateLandHeight(x2, y1+(i-1))));
|
||||||
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), drawCurrentY, calculateLandHeight(x2, y1+i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,44 +187,44 @@ 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 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));
|
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), drawPreviousY, calculateLandHeight(x1, y1+(i-1))));
|
||||||
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), drawCurrentY, calculateLandHeight(x1, y1+i)+2));
|
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)
|
const auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
|
||||||
|
|
||||||
|
switch (selectionMethod)
|
||||||
{
|
{
|
||||||
auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos);
|
case SelectionMethod::OnlySelect:
|
||||||
mDraggedOperationFlag = true;
|
break;
|
||||||
|
|
||||||
if (iterTemp == mTemporarySelection.end())
|
case SelectionMethod::AddSelect:
|
||||||
{
|
if (iter == mSelection.end())
|
||||||
auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
|
|
||||||
|
|
||||||
switch (selectionMethod)
|
|
||||||
{
|
{
|
||||||
case SelectionMethod::AddSelect:
|
mSelection.emplace_back(localPos);
|
||||||
if (iter == mSelection.end())
|
}
|
||||||
{
|
break;
|
||||||
mSelection.emplace_back(localPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
case SelectionMethod::RemoveSelect:
|
||||||
case SelectionMethod::RemoveSelect:
|
if (iter != mSelection.end())
|
||||||
if (iter != mSelection.end())
|
{
|
||||||
{
|
mSelection.erase(iter);
|
||||||
mSelection.erase(iter);
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
break;
|
case SelectionMethod::ToggleSelect:
|
||||||
case SelectionMethod::ToggleSelect:
|
{
|
||||||
|
const auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos);
|
||||||
|
if (iterTemp == mTemporarySelection.end())
|
||||||
|
{
|
||||||
if (iter == mSelection.end())
|
if (iter == mSelection.end())
|
||||||
{
|
{
|
||||||
mSelection.emplace_back(localPos);
|
mSelection.emplace_back(localPos);
|
||||||
|
|
@ -236,58 +233,15 @@ void CSVRender::TerrainSelection::handleSelection(const std::vector<std::pair<in
|
||||||
{
|
{
|
||||||
mSelection.erase(iter);
|
mSelection.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
|
mTemporarySelection.emplace_back(localPos);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTemporarySelection.push_back(localPos);
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mDraggedOperationFlag == false)
|
|
||||||
{
|
|
||||||
for (auto const& localPos : localPositions)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mDraggedOperationFlag = false;
|
|
||||||
|
|
||||||
mTemporarySelection.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
@ -336,11 +290,9 @@ int CSVRender::TerrainSelection::calculateLandHeight(int x, int y) // global ver
|
||||||
else if (isLandLoaded(CSMWorld::CellCoordinates::generateId(cellX, cellY)))
|
else if (isLandLoaded(CSMWorld::CellCoordinates::generateId(cellX, cellY)))
|
||||||
{
|
{
|
||||||
CSMDoc::Document& document = mWorldspaceWidget->getDocument();
|
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);
|
std::string cellId = CSMWorld::CellCoordinates::generateId(cellX, cellY);
|
||||||
int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex);
|
const ESM::Land::LandData* landData = document.getData().getLand().getRecord(cellId).get().getLandData(ESM::Land::DATA_VHGT);
|
||||||
const CSMWorld::LandHeightsColumn::DataType mPointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value<CSMWorld::LandHeightsColumn::DataType>();
|
return landData->mHeights[localY*ESM::Land::LAND_SIZE + localX];
|
||||||
return mPointer[localY*ESM::Land::LAND_SIZE + localX];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return landHeight;
|
return landHeight;
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,10 @@ namespace CSVRender
|
||||||
~TerrainSelection();
|
~TerrainSelection();
|
||||||
|
|
||||||
void onlySelect(const std::vector<std::pair<int, int>> &localPositions);
|
void onlySelect(const std::vector<std::pair<int, int>> &localPositions);
|
||||||
void addSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress);
|
void addSelect(const std::vector<std::pair<int, int>>& localPositions);
|
||||||
void removeSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress);
|
void removeSelect(const std::vector<std::pair<int, int>>& localPositions);
|
||||||
void toggleSelect(const std::vector<std::pair<int, int>> &localPositions, bool toggleInProgress);
|
void toggleSelect(const std::vector<std::pair<int, int>> &localPositions);
|
||||||
|
void clearTemporarySelection();
|
||||||
|
|
||||||
void activate();
|
void activate();
|
||||||
void deactivate();
|
void deactivate();
|
||||||
|
|
@ -64,7 +65,7 @@ namespace CSVRender
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void handleSelection(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress, SelectionMethod selectionMethod);
|
void handleSelection(const std::vector<std::pair<int, int>>& localPositions, SelectionMethod selectionMethod);
|
||||||
|
|
||||||
bool noCell(const std::string& cellId);
|
bool noCell(const std::string& cellId);
|
||||||
|
|
||||||
|
|
@ -73,7 +74,7 @@ namespace CSVRender
|
||||||
bool noLandLoaded(const std::string& cellId);
|
bool noLandLoaded(const std::string& cellId);
|
||||||
|
|
||||||
bool isLandLoaded(const std::string& cellId);
|
bool isLandLoaded(const std::string& cellId);
|
||||||
|
|
||||||
osg::Group* mParentNode;
|
osg::Group* mParentNode;
|
||||||
WorldspaceWidget *mWorldspaceWidget;
|
WorldspaceWidget *mWorldspaceWidget;
|
||||||
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||||
|
|
@ -81,7 +82,6 @@ namespace CSVRender
|
||||||
osg::ref_ptr<osg::Group> mSelectionNode;
|
osg::ref_ptr<osg::Group> mSelectionNode;
|
||||||
std::vector<std::pair<int, int>> mSelection; // Global terrain selection coordinate in either vertex or texture units
|
std::vector<std::pair<int, int>> mSelection; // Global terrain selection coordinate in either vertex or texture units
|
||||||
std::vector<std::pair<int, int>> mTemporarySelection; // Used during toggle to compare the most recent drag operation
|
std::vector<std::pair<int, int>> mTemporarySelection; // Used during toggle to compare the most recent drag operation
|
||||||
bool mDraggedOperationFlag; //true during drag operation, false when click-operation
|
|
||||||
TerrainSelectionType mSelectionType;
|
TerrainSelectionType mSelectionType;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,16 +106,6 @@ void CSVRender::TerrainShapeMode::primaryEditPressed(const WorldspaceHitResult&
|
||||||
editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), true);
|
editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), true);
|
||||||
applyTerrainEditChanges();
|
applyTerrainEditChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDragMode == InteractionType_PrimarySelect)
|
|
||||||
{
|
|
||||||
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mDragMode == InteractionType_SecondarySelect)
|
|
||||||
{
|
|
||||||
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
clearTransientEdits();
|
clearTransientEdits();
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +114,8 @@ void CSVRender::TerrainShapeMode::primarySelectPressed(const WorldspaceHitResult
|
||||||
{
|
{
|
||||||
if(hit.hit && hit.tag == nullptr)
|
if(hit.hit && hit.tag == nullptr)
|
||||||
{
|
{
|
||||||
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, false);
|
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0);
|
||||||
|
mTerrainShapeSelection->clearTemporarySelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,7 +123,8 @@ void CSVRender::TerrainShapeMode::secondarySelectPressed(const WorldspaceHitResu
|
||||||
{
|
{
|
||||||
if(hit.hit && hit.tag == nullptr)
|
if(hit.hit && hit.tag == nullptr)
|
||||||
{
|
{
|
||||||
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, false);
|
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1);
|
||||||
|
mTerrainShapeSelection->clearTemporarySelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,8 +159,8 @@ bool CSVRender::TerrainShapeMode::primarySelectStartDrag (const QPoint& pos)
|
||||||
mDragMode = InteractionType_None;
|
mDragMode = InteractionType_None;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, true);
|
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSVRender::TerrainShapeMode::secondarySelectStartDrag (const QPoint& pos)
|
bool CSVRender::TerrainShapeMode::secondarySelectStartDrag (const QPoint& pos)
|
||||||
|
|
@ -180,8 +172,8 @@ bool CSVRender::TerrainShapeMode::secondarySelectStartDrag (const QPoint& pos)
|
||||||
mDragMode = InteractionType_None;
|
mDragMode = InteractionType_None;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, true);
|
selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::TerrainShapeMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor)
|
void CSVRender::TerrainShapeMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor)
|
||||||
|
|
@ -200,13 +192,13 @@ void CSVRender::TerrainShapeMode::drag (const QPoint& pos, int diffX, int diffY,
|
||||||
if (mDragMode == InteractionType_PrimarySelect)
|
if (mDragMode == InteractionType_PrimarySelect)
|
||||||
{
|
{
|
||||||
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
|
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
|
||||||
if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, true);
|
if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDragMode == InteractionType_SecondarySelect)
|
if (mDragMode == InteractionType_SecondarySelect)
|
||||||
{
|
{
|
||||||
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
|
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
|
||||||
if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, true);
|
if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,12 +209,17 @@ void CSVRender::TerrainShapeMode::dragCompleted(const QPoint& pos)
|
||||||
applyTerrainEditChanges();
|
applyTerrainEditChanges();
|
||||||
clearTransientEdits();
|
clearTransientEdits();
|
||||||
}
|
}
|
||||||
|
if (mDragMode == InteractionType_PrimarySelect || mDragMode == InteractionType_SecondarySelect)
|
||||||
|
{
|
||||||
|
mTerrainShapeSelection->clearTemporarySelection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CSVRender::TerrainShapeMode::dragAborted()
|
void CSVRender::TerrainShapeMode::dragAborted()
|
||||||
{
|
{
|
||||||
clearTransientEdits();
|
clearTransientEdits();
|
||||||
|
mDragMode = InteractionType_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::TerrainShapeMode::dragWheel (int diff, double speedFactor)
|
void CSVRender::TerrainShapeMode::dragWheel (int diff, double speedFactor)
|
||||||
|
|
@ -1076,7 +1073,7 @@ void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int glob
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>& vertexCoords, unsigned char selectMode, bool dragOperation)
|
void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>& vertexCoords, unsigned char selectMode)
|
||||||
{
|
{
|
||||||
int r = mBrushSize / 2;
|
int r = mBrushSize / 2;
|
||||||
std::vector<std::pair<int, int>> selections;
|
std::vector<std::pair<int, int>> selections;
|
||||||
|
|
@ -1136,11 +1133,11 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
|
||||||
if (selectAction == "Select only")
|
if (selectAction == "Select only")
|
||||||
mTerrainShapeSelection->onlySelect(selections);
|
mTerrainShapeSelection->onlySelect(selections);
|
||||||
else if (selectAction == "Add to selection")
|
else if (selectAction == "Add to selection")
|
||||||
mTerrainShapeSelection->addSelect(selections, dragOperation);
|
mTerrainShapeSelection->addSelect(selections);
|
||||||
else if (selectAction == "Remove from selection")
|
else if (selectAction == "Remove from selection")
|
||||||
mTerrainShapeSelection->removeSelect(selections, dragOperation);
|
mTerrainShapeSelection->removeSelect(selections);
|
||||||
else if (selectAction == "Invert selection")
|
else if (selectAction == "Invert selection")
|
||||||
mTerrainShapeSelection->toggleSelect(selections, dragOperation);
|
mTerrainShapeSelection->toggleSelect(selections);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ namespace CSVRender
|
||||||
void handleSelection(int globalSelectionX, int globalSelectionY, std::vector<std::pair<int, int>>* selections);
|
void handleSelection(int globalSelectionX, int globalSelectionY, std::vector<std::pair<int, int>>* selections);
|
||||||
|
|
||||||
/// Handle brush mechanics for terrain shape selection
|
/// Handle brush mechanics for terrain shape selection
|
||||||
void selectTerrainShapes (const std::pair<int, int>& vertexCoords, unsigned char selectMode, bool dragOperation);
|
void selectTerrainShapes (const std::pair<int, int>& vertexCoords, unsigned char selectMode);
|
||||||
|
|
||||||
/// Push terrain shape edits to command macro
|
/// Push terrain shape edits to command macro
|
||||||
void pushEditToCommand (const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
void pushEditToCommand (const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
||||||
|
|
|
||||||
|
|
@ -48,15 +48,14 @@ namespace CSVRender
|
||||||
float TerrainStorage::getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY)
|
float TerrainStorage::getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY)
|
||||||
{
|
{
|
||||||
float height = 0.f;
|
float height = 0.f;
|
||||||
osg::ref_ptr<const ESMTerrain::LandObject> land = getLand (cellX, cellY);
|
|
||||||
if (land)
|
|
||||||
{
|
|
||||||
const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr;
|
|
||||||
if (data) height = getVertexHeight(data, inCellX, inCellY);
|
|
||||||
}
|
|
||||||
else return height;
|
|
||||||
return mAlteredHeight[inCellY*ESM::Land::LAND_SIZE + inCellX] + height;
|
|
||||||
|
|
||||||
|
int index = mData.getLand().searchId(CSMWorld::Land::createUniqueRecordId(cellX, cellY));
|
||||||
|
if (index == -1) // no land!
|
||||||
|
return height;
|
||||||
|
|
||||||
|
const ESM::Land::LandData* landData = mData.getLand().getRecord(index).get().getLandData(ESM::Land::DATA_VHGT);
|
||||||
|
height = landData->mHeights[inCellY*ESM::Land::LAND_SIZE + inCellX];
|
||||||
|
return mAlteredHeight[inCellY*ESM::Land::LAND_SIZE + inCellX] + height;
|
||||||
}
|
}
|
||||||
|
|
||||||
float* TerrainStorage::getAlteredHeight(int inCellX, int inCellY)
|
float* TerrainStorage::getAlteredHeight(int inCellX, int inCellY)
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,8 @@ void CSVRender::TerrainTextureMode::primarySelectPressed(const WorldspaceHitResu
|
||||||
{
|
{
|
||||||
if(hit.hit && hit.tag == nullptr)
|
if(hit.hit && hit.tag == nullptr)
|
||||||
{
|
{
|
||||||
selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0, false);
|
selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0);
|
||||||
|
mTerrainTextureSelection->clearTemporarySelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,7 +138,8 @@ void CSVRender::TerrainTextureMode::secondarySelectPressed(const WorldspaceHitRe
|
||||||
{
|
{
|
||||||
if(hit.hit && hit.tag == nullptr)
|
if(hit.hit && hit.tag == nullptr)
|
||||||
{
|
{
|
||||||
selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1, false);
|
selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1);
|
||||||
|
mTerrainTextureSelection->clearTemporarySelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,8 +190,8 @@ bool CSVRender::TerrainTextureMode::primarySelectStartDrag (const QPoint& pos)
|
||||||
mDragMode = InteractionType_None;
|
mDragMode = InteractionType_None;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0, true);
|
selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSVRender::TerrainTextureMode::secondarySelectStartDrag (const QPoint& pos)
|
bool CSVRender::TerrainTextureMode::secondarySelectStartDrag (const QPoint& pos)
|
||||||
|
|
@ -201,8 +203,8 @@ bool CSVRender::TerrainTextureMode::secondarySelectStartDrag (const QPoint& pos)
|
||||||
mDragMode = InteractionType_None;
|
mDragMode = InteractionType_None;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1, true);
|
selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor)
|
void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor)
|
||||||
|
|
@ -225,13 +227,13 @@ void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diff
|
||||||
if (mDragMode == InteractionType_PrimarySelect)
|
if (mDragMode == InteractionType_PrimarySelect)
|
||||||
{
|
{
|
||||||
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
|
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
|
||||||
if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0, true);
|
if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDragMode == InteractionType_SecondarySelect)
|
if (mDragMode == InteractionType_SecondarySelect)
|
||||||
{
|
{
|
||||||
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
|
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
|
||||||
if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1, true);
|
if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,6 +253,8 @@ void CSVRender::TerrainTextureMode::dragCompleted(const QPoint& pos)
|
||||||
mIsEditing = false;
|
mIsEditing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTerrainTextureSelection->clearTemporarySelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::TerrainTextureMode::dragAborted()
|
void CSVRender::TerrainTextureMode::dragAborted()
|
||||||
|
|
@ -496,7 +500,7 @@ bool CSVRender::TerrainTextureMode::isInCellSelection(int globalSelectionX, int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair<int, int>& texCoords, unsigned char selectMode, bool dragOperation)
|
void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair<int, int>& texCoords, unsigned char selectMode)
|
||||||
{
|
{
|
||||||
int r = mBrushSize / 2;
|
int r = mBrushSize / 2;
|
||||||
std::vector<std::pair<int, int>> selections;
|
std::vector<std::pair<int, int>> selections;
|
||||||
|
|
@ -559,8 +563,21 @@ void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair<int, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(selectMode == 0) mTerrainTextureSelection->onlySelect(selections);
|
std::string selectAction;
|
||||||
if(selectMode == 1) mTerrainTextureSelection->toggleSelect(selections, dragOperation);
|
|
||||||
|
if (selectMode == 0)
|
||||||
|
selectAction = CSMPrefs::get()["3D Scene Editing"]["primary-select-action"].toString();
|
||||||
|
else
|
||||||
|
selectAction = CSMPrefs::get()["3D Scene Editing"]["secondary-select-action"].toString();
|
||||||
|
|
||||||
|
if (selectAction == "Select only")
|
||||||
|
mTerrainTextureSelection->onlySelect(selections);
|
||||||
|
else if (selectAction == "Add to selection")
|
||||||
|
mTerrainTextureSelection->addSelect(selections);
|
||||||
|
else if (selectAction == "Remove from selection")
|
||||||
|
mTerrainTextureSelection->removeSelect(selections);
|
||||||
|
else if (selectAction == "Invert selection")
|
||||||
|
mTerrainTextureSelection->toggleSelect(selections);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::TerrainTextureMode::pushEditToCommand(CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
void CSVRender::TerrainTextureMode::pushEditToCommand(CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ namespace CSVRender
|
||||||
bool isInCellSelection(int globalSelectionX, int globalSelectionY);
|
bool isInCellSelection(int globalSelectionX, int globalSelectionY);
|
||||||
|
|
||||||
/// \brief Handle brush mechanics for texture selection
|
/// \brief Handle brush mechanics for texture selection
|
||||||
void selectTerrainTextures (const std::pair<int, int>& texCoords, unsigned char selectMode, bool dragOperation);
|
void selectTerrainTextures (const std::pair<int, int>& texCoords, unsigned char selectMode);
|
||||||
|
|
||||||
/// \brief Push texture edits to command macro
|
/// \brief Push texture edits to command macro
|
||||||
void pushEditToCommand (CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
void pushEditToCommand (CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
||||||
|
|
|
||||||
|
|
@ -464,7 +464,6 @@ void CSVRender::WorldspaceWidget::abortDrag()
|
||||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||||
|
|
||||||
editMode.dragAborted();
|
editMode.dragAborted();
|
||||||
mDragging = false;
|
|
||||||
mDragMode = InteractionType_None;
|
mDragMode = InteractionType_None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue