Skip to content

Commit

Permalink
support additive merge, change width/height spinboxes to comboboxes, …
Browse files Browse the repository at this point in the history
…enforce width=height in overwrite mode
  • Loading branch information
Axle1975 committed Oct 19, 2019
1 parent 722d197 commit 601e9c8
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 122 deletions.
84 changes: 61 additions & 23 deletions scmp/scmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ template<typename DataT>
static void ImportImage(
const DataT *im1, int W1, int H1,
DataT *im2, int W2, int H2,
int W0, int H0, bool overwrite)
int W0, int H0, bool additive)
{
for (int col = 0u; col < W1; ++col)
{
Expand All @@ -67,13 +67,13 @@ static void ImportImage(
{
continue;
}
if (overwrite)
if (additive)
{
im2[W2*destRow + destCol] = im1[W1*row + col];
im2[W2*destRow + destCol] += im1[W1*row + col];
}
else
{
im2[W2*destRow + destCol] += im1[W1*row + col];
im2[W2*destRow + destCol] = im1[W1*row + col];
}
}
}
Expand Down Expand Up @@ -113,7 +113,7 @@ static void ImportDds(
ImportImage<std::uint8_t>(
(std::uint8_t*)srcScaled.data(), srcWScaled, srcHScaled,
(std::uint8_t*)dstDds.getMutable(imageBytes), dstDds.width(), dstDds.height(),
column0, row0, true);
column0, row0, false);
break;

case 2:
Expand All @@ -122,7 +122,7 @@ static void ImportDds(
ImportImage<std::uint16_t>(
(std::uint16_t*)srcScaled.data(), srcWScaled, srcHScaled,
(std::uint16_t*)dstDds.getMutable(imageBytes), dstDds.width(), dstDds.height(),
column0, row0, true);
column0, row0, false);
break;

case 4:
Expand All @@ -131,7 +131,7 @@ static void ImportDds(
ImportImage<std::uint32_t>(
(std::uint32_t*)srcScaled.data(), srcWScaled, srcHScaled,
(std::uint32_t*)dstDds.getMutable(imageBytes), dstDds.width(), dstDds.height(),
column0, row0, true);
column0, row0, false);
break;

case 8:
Expand All @@ -140,7 +140,7 @@ static void ImportDds(
ImportImage<std::uint64_t>(
(std::uint64_t*)srcScaled.data(), srcWScaled, srcHScaled,
(std::uint64_t*)dstDds.getMutable(imageBytes), dstDds.width(), dstDds.height(),
column0, row0, true);
column0, row0, false);
break;

default:
Expand All @@ -159,22 +159,21 @@ static void GainImage(std::vector<DataT> &im, float gain)
}


static bool isInBounds(float *pos, float xlow, float zlow, float xhigh, float zhigh)
{
return (pos[0] >= xlow && pos[0] < xhigh && pos[2] >= zlow && pos[2] < zhigh);
}


template<typename T>
static std::vector< std::shared_ptr<T> > ImportItemsInRectangle(
const std::vector<std::shared_ptr<T> > &items,
const std::vector<std::shared_ptr<T> > &otherItems,
int xlow, int zlow, int xhigh, int zhigh)
int xlow, int zlow, int xhigh, int zhigh, nfa::scmp::Scmp *scmp)
{
auto isInBounds = [xlow, zlow, xhigh, zhigh](float *pos)
{
return (pos[0] >= xlow && pos[0] < xhigh && pos[2] >= zlow && pos[2] < zhigh);
};

std::vector<std::shared_ptr<T> > newItems;
for (auto & itemPtr : items)
{
if (!isInBounds(itemPtr->position, xlow, zlow, xhigh, zhigh))
if (!isInBounds(itemPtr->position))
{
newItems.push_back(itemPtr);
}
Expand All @@ -184,8 +183,15 @@ static std::vector< std::shared_ptr<T> > ImportItemsInRectangle(
std::shared_ptr<T> itemPtr(new T(*_itemPtr));
itemPtr->position[0] += xlow;
itemPtr->position[2] += zlow;
if (isInBounds(itemPtr->position, xlow, zlow, xhigh, zhigh))

if (isInBounds(itemPtr->position))
{
if (scmp)
{
float newHeight = scmp->heightScale * scmp->HeightMapAt(itemPtr->position[0], itemPtr->position[2]);
itemPtr->position[1] = newHeight;
}

newItems.push_back(itemPtr);
}
}
Expand Down Expand Up @@ -617,6 +623,18 @@ namespace nfa {
}
}

std::int16_t Scmp::HeightMapAt(int x, int z)
{
if (x >= 0 && x <= width && z >= 0 && z <= height)
{
return heightMapData[(1 + width)*z + x];
}
else
{
return 0;
}
}

Scmp::Scmp(std::istream &is)
{
// header
Expand Down Expand Up @@ -894,6 +912,26 @@ namespace nfa {
VerifyStatus(is, true);
}

template<typename DataT>
static void SaveBufferTxt(const DataT *data, int width, int height, const char *filename, bool columnMajor)
{
std::ofstream fs(filename, std::ios::out);
for (int col = 0; col < width; ++col)
{
for (int row = 0; row < height; ++row)
{
if (columnMajor)
{
fs << col << ',' << row << data[col*width + height];
}
else
{
fs << col << ',' << row << data[row*height + col];
}
}
}
}

void Scmp::Save(std::ostream &os)
{
// header
Expand Down Expand Up @@ -1179,19 +1217,19 @@ namespace nfa {
}


void Scmp::Import(const Scmp &other, int column0, int row0)
void Scmp::Import(const Scmp &other, int column0, int row0, bool additiveTerrain)
{
// previewImageData. not important, user can update it with any map editor

ImportImage(
other.heightMapData.data(), 1 + other.width, 1 + other.height,
this->heightMapData.data(), 1 + this->width, 1 + this->height,
column0, row0, true);
column0, row0, additiveTerrain);

ImportImage(
other.terrainTypeData.data(), other.width, other.height,
this->terrainTypeData.data(), this->width, this->height,
column0, row0, true);
column0, row0, false);

for (std::size_t n = 0u; n < normalMapData.size() && n < other.normalMapData.size(); ++n)
{
Expand Down Expand Up @@ -1223,9 +1261,9 @@ namespace nfa {
int columnEnd = column0 + other.width;
int rowEnd = row0 + other.height;

waveGenerators = ImportItemsInRectangle(waveGenerators, other.waveGenerators, column0, row0, columnEnd, rowEnd);
decals = ImportItemsInRectangle(decals, other.decals, column0, row0, columnEnd, rowEnd);
props = ImportItemsInRectangle(props, other.props, column0, row0, columnEnd, rowEnd);
waveGenerators = ImportItemsInRectangle(waveGenerators, other.waveGenerators, column0, row0, columnEnd, rowEnd, this);
decals = ImportItemsInRectangle(decals, other.decals, column0, row0, columnEnd, rowEnd, this);
props = ImportItemsInRectangle(props, other.props, column0, row0, columnEnd, rowEnd, this);
}


Expand Down
3 changes: 2 additions & 1 deletion scmp/scmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ namespace nfa {
void DumpTexture(const std::string &filename, const std::vector<std::uint8_t> &data) const;
void MapInfo(std::ostream &);
void Resize(int width, int height);
void Import(const Scmp &other, int column0, int row0);
void Import(const Scmp &other, int column0, int row0, bool additiveTerrain);
std::int16_t HeightMapAt(int x, int z);

std::uint32_t magicMap1A;
std::uint32_t magicBeeffeed;
Expand Down
60 changes: 28 additions & 32 deletions scmp_rescale/scmp_rescale_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,27 @@
#include <sstream>


unsigned UpperPowerOfTwo(unsigned v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}


ScmpRescaleWindow::ScmpRescaleWindow(QWidget *parent):
QMainWindow(parent)
{
ui.setupUi(this);

for (auto pair : {
std::make_pair("1.25 km (64px)",64),
std::make_pair("2.5 km (128px)", 128),
std::make_pair("5 km (256px)", 256),
std::make_pair("10 km (512px)", 512),
std::make_pair("20 km (1024px)", 1024),
std::make_pair("40 km (2048px)", 2048),
std::make_pair("80 km (4096px)", 4096)
})
{
ui.sourceNewWidthComboBox->addItem(pair.first, QVariant(pair.second));
ui.sourceNewHeightComboBox->addItem(pair.first, QVariant(pair.second));
ui.sourceNewWidthComboBox->setCurrentIndex(3);
ui.sourceNewHeightComboBox->setCurrentIndex(3);
}

updateSourceMapInfo();
updateTargetMapInfo();
updateSaveOptions();
Expand Down Expand Up @@ -73,19 +76,6 @@ void ScmpRescaleWindow::updateSaveOptions()
{
ui.goButton->setEnabled(m_sourceScmp && m_targetScmp);
ui.mergePositionFrame->setHidden(false);

if (m_targetScmp)
{
if (getNewSourceWidth() > m_targetScmp->width)
{
ui.sourceNewWidthSpinBox->setValue(m_targetScmp->width);
}
if (getNewSourceHeight() > m_targetScmp->height)
{
ui.sourceNewHeightSpinBox->setValue(m_targetScmp->height);
}
}

}
else
{
Expand Down Expand Up @@ -155,7 +145,7 @@ void ScmpRescaleWindow::on_goButton_clicked()
if (isMergeModeSelected() && m_sourceScmp && m_targetScmp)
{
m_sourceScmp->Resize(getNewSourceWidth(), getNewSourceHeight());
m_targetScmp->Import(*m_sourceScmp, getHorzPosition(), getVertPosition());
m_targetScmp->Import(*m_sourceScmp, getHorzPosition(), getVertPosition(), isAdditiveMerge());
std::ofstream ofs(getTargetFilename().toLatin1().data(), std::ios::binary);
m_targetScmp->Save(ofs);
QMessageBox::information(this,
Expand All @@ -166,7 +156,8 @@ void ScmpRescaleWindow::on_goButton_clicked()
}
else if (!isMergeModeSelected() && m_sourceScmp)
{
m_sourceScmp->Resize(getNewSourceWidth(), getNewSourceHeight());
int newWidthHeight = std::max(getNewSourceWidth(), getNewSourceHeight());
m_sourceScmp->Resize(newWidthHeight, newWidthHeight);
std::ofstream ofs(getTargetFilename().toLatin1().data(), std::ios::binary);
m_sourceScmp->Save(ofs);
QMessageBox::information(this, "Rescale",
Expand Down Expand Up @@ -200,13 +191,13 @@ void ScmpRescaleWindow::on_exitButton_clicked()
}


void ScmpRescaleWindow::on_sourceNewWidthSpinBox_valueChanged(int)
void ScmpRescaleWindow::on_sourceNewWidthComboBox_currentIndexChanged(int)
{
updatePositionSliders();
}


void ScmpRescaleWindow::on_sourceNewHeightSpinBox_valueChanged(int)
void ScmpRescaleWindow::on_sourceNewHeightComboBox_currentIndexChanged(int)
{
updatePositionSliders();
}
Expand Down Expand Up @@ -340,12 +331,12 @@ QString ScmpRescaleWindow::getTargetFilename()

int ScmpRescaleWindow::getNewSourceWidth()
{
return ui.sourceNewWidthSpinBox->value();
return ui.sourceNewWidthComboBox->currentData().toInt();
}

int ScmpRescaleWindow::getNewSourceHeight()
{
return ui.sourceNewHeightSpinBox->value();
return ui.sourceNewHeightComboBox->currentData().toInt();
}

int ScmpRescaleWindow::getHorzPosition()
Expand All @@ -362,3 +353,8 @@ bool ScmpRescaleWindow::isMergeModeSelected()
{
return ui.mergeModeRadioButton->isChecked();
}

bool ScmpRescaleWindow::isAdditiveMerge()
{
return ui.additiveMergeCheckBox->isChecked();
}
5 changes: 3 additions & 2 deletions scmp_rescale/scmp_rescale_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ class ScmpRescaleWindow : public QMainWindow
int getHorzPosition();
int getVertPosition();
bool isMergeModeSelected();
bool isAdditiveMerge();

private slots:
void on_sourceMapButton_clicked();
void on_targetMapButton_clicked();
void on_sourceMapLineEdit_textChanged(const QString &);
void on_targetMapLineEdit_textChanged(const QString &);
void on_sourceNewWidthSpinBox_valueChanged(int);
void on_sourceNewHeightSpinBox_valueChanged(int);
void on_sourceNewWidthComboBox_currentIndexChanged(int);
void on_sourceNewHeightComboBox_currentIndexChanged(int);
void on_mergeModeRadioButton_toggled(bool);
void on_sourceHorizontalPositionSpinBox_valueChanged(int);
void on_sourceHorizontalLeftPositionSlider_valueChanged(int);
Expand Down
Loading

0 comments on commit 601e9c8

Please sign in to comment.