User setting for selective cell editing or new land creation

0.6.3
Nelsson Huotari 7 years ago
parent 24977fcc0f
commit baa707b5e3

@ -222,6 +222,14 @@ void CSMPrefs::State::declare()
EnumValues insertOutsideVisibleCell; EnumValues insertOutsideVisibleCell;
insertOutsideVisibleCell.add (showAndInsert).add (dontInsert).add (insertAnyway); insertOutsideVisibleCell.add (showAndInsert).add (dontInsert).add (insertAnyway);
EnumValue createAndLandEdit ("Create cell and land, then edit");
EnumValue showAndLandEdit ("Show cell and edit");
EnumValue dontLandEdit ("Discard");
EnumValues landeditOutsideCell;
landeditOutsideCell.add (createAndLandEdit).add (dontLandEdit);
EnumValues landeditOutsideVisibleCell;
landeditOutsideVisibleCell.add (showAndLandEdit).add (dontLandEdit);
declareCategory ("Scene Drops"); declareCategory ("Scene Drops");
declareInt ("distance", "Drop Distance", 50). declareInt ("distance", "Drop Distance", 50).
setTooltip ("If an instance drop can not be placed against another object at the " setTooltip ("If an instance drop can not be placed against another object at the "
@ -230,6 +238,10 @@ void CSMPrefs::State::declare()
addValues (insertOutsideCell); addValues (insertOutsideCell);
declareEnum ("outside-visible-drop", "Handling drops outside of visible cells", showAndInsert). declareEnum ("outside-visible-drop", "Handling drops outside of visible cells", showAndInsert).
addValues (insertOutsideVisibleCell); addValues (insertOutsideVisibleCell);
declareEnum ("outside-landedit", "Handling land edit outside of cells", createAndLandEdit).
addValues (landeditOutsideCell);
declareEnum ("outside-visible-landedit", "Handling land edit outside of visible cells", showAndLandEdit).
addValues (landeditOutsideVisibleCell);
declareCategory ("Key Bindings"); declareCategory ("Key Bindings");

@ -22,11 +22,13 @@
#include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolbar.hpp"
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/prefs/state.hpp"
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"
#include "../../model/world/commandmacro.hpp" #include "../../model/world/commandmacro.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/idtree.hpp"
#include "../../model/world/land.hpp" #include "../../model/world/land.hpp"
#include "../../model/world/landtexture.hpp" #include "../../model/world/landtexture.hpp"
#include "../../model/world/resourcetable.hpp" #include "../../model/world/resourcetable.hpp"
@ -186,8 +188,11 @@ void CSVRender::TerrainTextureMode::primaryEditPressed(const WorldspaceHitResult
QUndoStack& undoStack = document.getUndoStack(); QUndoStack& undoStack = document.getUndoStack();
undoStack.beginMacro ("Edit texture records"); undoStack.beginMacro ("Edit texture records");
undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId)); if(allowLandTextureEditing(mCellId)==true)
editTerrainTextureGrid(hit); {
undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId));
editTerrainTextureGrid(hit);
}
undoStack.endMacro(); undoStack.endMacro();
} }
@ -213,8 +218,11 @@ bool CSVRender::TerrainTextureMode::primaryEditStartDrag (const QPoint& pos)
QUndoStack& undoStack = document.getUndoStack(); QUndoStack& undoStack = document.getUndoStack();
undoStack.beginMacro ("Edit texture records"); undoStack.beginMacro ("Edit texture records");
undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId)); if(allowLandTextureEditing(mCellId)==true)
editTerrainTextureGrid(hit); {
undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId));
editTerrainTextureGrid(hit);
}
return true; return true;
} }
@ -299,7 +307,12 @@ void CSVRender::TerrainTextureMode::handlePrimarySelectOnModeButton () {
void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitResult& hit) void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitResult& hit)
{ {
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
CSMWorld::IdTable& landTable = dynamic_cast<CSMWorld::IdTable&> (
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Land));
mCellId = getWorldspaceWidget().getCellId (hit.worldPos); mCellId = getWorldspaceWidget().getCellId (hit.worldPos);
if(allowLandTextureEditing(mCellId)==true) {}
std::pair<CSMWorld::CellCoordinates, bool> cellCoordinates_pair = CSMWorld::CellCoordinates::fromId (mCellId); std::pair<CSMWorld::CellCoordinates, bool> cellCoordinates_pair = CSMWorld::CellCoordinates::fromId (mCellId);
@ -321,13 +334,10 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
} }
mCellId = "#" + std::to_string(cellX) + " " + std::to_string(cellY); mCellId = "#" + std::to_string(cellX) + " " + std::to_string(cellY);
if(allowLandTextureEditing(mCellId)==true) {}
std::string iteratedCellId; std::string iteratedCellId;
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
CSMWorld::IdTable& landTable = dynamic_cast<CSMWorld::IdTable&> (
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Land));
int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex); int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex);
std::size_t hashlocation = mBrushTexture.find("#"); std::size_t hashlocation = mBrushTexture.find("#");
@ -342,8 +352,12 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
{ {
CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(mCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>(); CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(mCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>();
CSMWorld::LandTexturesColumn::DataType mNew(mPointer); CSMWorld::LandTexturesColumn::DataType mNew(mPointer);
mNew[yHitInCell*landTextureSize+xHitInCell] = brushInt;
pushEditToCommand(mNew, document, landTable, mCellId); if(allowLandTextureEditing(mCellId)==true)
{
mNew[yHitInCell*landTextureSize+xHitInCell] = brushInt;
pushEditToCommand(mNew, document, landTable, mCellId);
}
} }
if (mBrushShape == 1) if (mBrushShape == 1)
@ -363,32 +377,35 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
for(int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++) for(int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++)
{ {
iteratedCellId = "#" + std::to_string(i_cell) + " " + std::to_string(j_cell); iteratedCellId = "#" + std::to_string(i_cell) + " " + std::to_string(j_cell);
CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>(); if(allowLandTextureEditing(iteratedCellId)==true)
CSMWorld::LandTexturesColumn::DataType mNew(mPointer);
for(int i = 0; i < landTextureSize; i++)
{ {
for(int j = 0; j < landTextureSize; j++) CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>();
CSMWorld::LandTexturesColumn::DataType mNew(mPointer);
for(int i = 0; i < landTextureSize; i++)
{ {
for(int j = 0; j < landTextureSize; j++)
if (i_cell == cellX && j_cell == cellY && abs(i-xHitInCell) < r && abs(j-yHitInCell) < r)
{ {
mNew[j*landTextureSize+i] = brushInt;
} if (i_cell == cellX && j_cell == cellY && abs(i-xHitInCell) < r && abs(j-yHitInCell) < r)
else {
{ mNew[j*landTextureSize+i] = brushInt;
int distanceX(0); }
int distanceY(0); else
if (i_cell < cellX) distanceX = xHitInCell + landTextureSize * abs(i_cell-cellX) - i; {
if (j_cell < cellY) distanceY = yHitInCell + landTextureSize * abs(j_cell-cellY) - j; int distanceX(0);
if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize * abs(i_cell-cellX) + i; int distanceY(0);
if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j; if (i_cell < cellX) distanceX = xHitInCell + landTextureSize * abs(i_cell-cellX) - i;
if (i_cell == cellX) distanceX = abs(i-xHitInCell); if (j_cell < cellY) distanceY = yHitInCell + landTextureSize * abs(j_cell-cellY) - j;
if (j_cell == cellY) distanceY = abs(j-yHitInCell); if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize * abs(i_cell-cellX) + i;
if (distanceX < r && distanceY < r) mNew[j*landTextureSize+i] = brushInt; if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j;
if (i_cell == cellX) distanceX = abs(i-xHitInCell);
if (j_cell == cellY) distanceY = abs(j-yHitInCell);
if (distanceX < r && distanceY < r) mNew[j*landTextureSize+i] = brushInt;
}
} }
} }
pushEditToCommand(mNew, document, landTable, iteratedCellId);
} }
pushEditToCommand(mNew, document, landTable, iteratedCellId);
} }
} }
} }
@ -410,45 +427,49 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
for(int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++) for(int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++)
{ {
iteratedCellId = "#" + std::to_string(i_cell) + " " + std::to_string(j_cell); iteratedCellId = "#" + std::to_string(i_cell) + " " + std::to_string(j_cell);
CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>(); if(allowLandTextureEditing(iteratedCellId)==true)
CSMWorld::LandTexturesColumn::DataType mNew(mPointer);
for(int i = 0; i < landTextureSize; i++)
{ {
for(int j = 0; j < landTextureSize; j++) CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>();
CSMWorld::LandTexturesColumn::DataType mNew(mPointer);
for(int i = 0; i < landTextureSize; i++)
{ {
for(int j = 0; j < landTextureSize; j++)
if (i_cell == cellX && j_cell == cellY && abs(i-xHitInCell) < r && abs(j-yHitInCell) < r)
{ {
int distanceX(0);
int distanceY(0); if (i_cell == cellX && j_cell == cellY && abs(i-xHitInCell) < r && abs(j-yHitInCell) < r)
if (i_cell < cellX) distanceX = xHitInCell + landTextureSize * abs(i_cell-cellX) - i; {
if (j_cell < cellY) distanceY = yHitInCell + landTextureSize * abs(j_cell-cellY) - j; int distanceX(0);
if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize* abs(i_cell-cellX) + i; int distanceY(0);
if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j; if (i_cell < cellX) distanceX = xHitInCell + landTextureSize * abs(i_cell-cellX) - i;
if (i_cell == cellX) distanceX = abs(i-xHitInCell); if (j_cell < cellY) distanceY = yHitInCell + landTextureSize * abs(j_cell-cellY) - j;
if (j_cell == cellY) distanceY = abs(j-yHitInCell); if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize* abs(i_cell-cellX) + i;
distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2))); if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j;
if (distance < rf) mNew[j*landTextureSize+i] = brushInt; if (i_cell == cellX) distanceX = abs(i-xHitInCell);
} if (j_cell == cellY) distanceY = abs(j-yHitInCell);
else distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2)));
{ if (distance < rf) mNew[j*landTextureSize+i] = brushInt;
int distanceX(0); }
int distanceY(0); else
if (i_cell < cellX) distanceX = xHitInCell + landTextureSize * abs(i_cell-cellX) - i; {
if (j_cell < cellY) distanceY = yHitInCell + landTextureSize * abs(j_cell-cellY) - j; int distanceX(0);
if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize * abs(i_cell-cellX) + i; int distanceY(0);
if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j; if (i_cell < cellX) distanceX = xHitInCell + landTextureSize * abs(i_cell-cellX) - i;
if (i_cell == cellX) distanceX = abs(i-xHitInCell); if (j_cell < cellY) distanceY = yHitInCell + landTextureSize * abs(j_cell-cellY) - j;
if (j_cell == cellY) distanceY = abs(j-yHitInCell); if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize * abs(i_cell-cellX) + i;
distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2))); if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j;
if (distance < rf) mNew[j*landTextureSize+i] = brushInt; if (i_cell == cellX) distanceX = abs(i-xHitInCell);
if (j_cell == cellY) distanceY = abs(j-yHitInCell);
distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2)));
if (distance < rf) mNew[j*landTextureSize+i] = brushInt;
}
} }
} }
pushEditToCommand(mNew, document, landTable, iteratedCellId);
} }
pushEditToCommand(mNew, document, landTable, iteratedCellId);
} }
} }
} }
if (mBrushShape == 3) if (mBrushShape == 3)
{ {
// Not implemented // Not implemented
@ -510,6 +531,81 @@ void CSVRender::TerrainTextureMode::createTexture(std::string textureFileName)
undoStack.endMacro(); undoStack.endMacro();
} }
bool CSVRender::TerrainTextureMode::allowLandTextureEditing(std::string cellId)
{
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
CSMWorld::IdTable& landTable = dynamic_cast<CSMWorld::IdTable&> (
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Land));
CSMWorld::IdTree& cellTable = dynamic_cast<CSMWorld::IdTree&> (
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
bool noCell = document.getData().getCells().searchId (cellId)==-1;
bool noLand = document.getData().getLand().searchId (cellId)==-1;
if (noCell)
{
std::string mode = CSMPrefs::get()["Scene Drops"]["outside-landedit"].toString();
// target cell does not exist
if (mode=="Discard")
return false;
if (mode=="Create cell and land, then edit")
{
std::unique_ptr<CSMWorld::CreateCommand> createCommand (
new CSMWorld::CreateCommand (cellTable, cellId));
int parentIndex = cellTable.findColumnIndex (CSMWorld::Columns::ColumnId_Cell);
int index = cellTable.findNestedColumnIndex (parentIndex, CSMWorld::Columns::ColumnId_Interior);
createCommand->addNestedValue (parentIndex, index, false);
document.getUndoStack().push (createCommand.release());
if (CSVRender::PagedWorldspaceWidget *paged =
dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget()))
{
CSMWorld::CellSelection selection = paged->getCellSelection();
selection.add (CSMWorld::CellCoordinates::fromId (cellId).first);
paged->setCellSelection (selection);
}
}
}
else if (CSVRender::PagedWorldspaceWidget *paged =
dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget()))
{
CSMWorld::CellSelection selection = paged->getCellSelection();
if (!selection.has (CSMWorld::CellCoordinates::fromId (cellId).first))
{
// target cell exists, but is not shown
std::string mode =
CSMPrefs::get()["Scene Drops"]["outside-visible-landedit"].toString();
if (mode=="Discard")
return false;
if (mode=="Show cell and edit")
{
selection.add (CSMWorld::CellCoordinates::fromId (cellId).first);
paged->setCellSelection (selection);
}
}
}
if (noLand)
{
std::string mode = CSMPrefs::get()["Scene Drops"]["outside-landedit"].toString();
// target cell does not exist
if (mode=="Discard")
return false;
if (mode=="Create cell and land, then edit")
{
document.getUndoStack().push (new CSMWorld::CreateCommand (landTable, cellId));
}
}
return true;
}
void CSVRender::TerrainTextureMode::dragMoveEvent (QDragMoveEvent *event) { void CSVRender::TerrainTextureMode::dragMoveEvent (QDragMoveEvent *event) {
} }

@ -126,6 +126,9 @@ namespace CSVRender
/// \brief Create new land texture record from texture asset /// \brief Create new land texture record from texture asset
void createTexture(std::string textureFileName); void createTexture(std::string textureFileName);
/// \brief Create new cell and land if needed
bool allowLandTextureEditing(std::string textureFileName);
private: private:
TextureBrushWindow *textureBrushWindow; TextureBrushWindow *textureBrushWindow;
std::string mCellId; std::string mCellId;

Loading…
Cancel
Save