mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
Generate WNAM upon saving terrain
This commit is contained in:
parent
7d394dd97d
commit
89055f1c6c
7 changed files with 21 additions and 101 deletions
|
@ -76,53 +76,6 @@ namespace CSMWorld
|
|||
return false;
|
||||
}
|
||||
|
||||
/* LandMapLodColumn */
|
||||
LandMapLodColumn::LandMapLodColumn()
|
||||
: Column<Land>(Columns::ColumnId_LandMapLodIndex, ColumnBase::Display_String, 0)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant LandMapLodColumn::get(const Record<Land>& record) const
|
||||
{
|
||||
const int Size = Land::LAND_GLOBAL_MAP_LOD_SIZE;
|
||||
const Land& land = record.get();
|
||||
|
||||
DataType values(Size, 0);
|
||||
|
||||
if (land.mDataTypes & Land::DATA_WNAM)
|
||||
{
|
||||
for (int i = 0; i < Size; ++i)
|
||||
values[i] = land.mWnam[i];
|
||||
}
|
||||
|
||||
QVariant variant;
|
||||
variant.setValue(values);
|
||||
return variant;
|
||||
}
|
||||
|
||||
void LandMapLodColumn::set(Record<Land>& record, const QVariant& data)
|
||||
{
|
||||
DataType values = data.value<DataType>();
|
||||
|
||||
if (values.size() != Land::LAND_GLOBAL_MAP_LOD_SIZE)
|
||||
throw std::runtime_error("invalid land map LOD data");
|
||||
|
||||
Land copy = record.get();
|
||||
copy.add(Land::DATA_WNAM);
|
||||
|
||||
for (int i = 0; i < values.size(); ++i)
|
||||
{
|
||||
copy.mWnam[i] = values[i];
|
||||
}
|
||||
|
||||
record.setModified(copy);
|
||||
}
|
||||
|
||||
bool LandMapLodColumn::isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* LandNormalsColumn */
|
||||
LandNormalsColumn::LandNormalsColumn()
|
||||
: Column<Land>(Columns::ColumnId_LandNormalsIndex, ColumnBase::Display_String, 0)
|
||||
|
|
|
@ -2461,17 +2461,6 @@ namespace CSMWorld
|
|||
bool isEditable() const override;
|
||||
};
|
||||
|
||||
struct LandMapLodColumn : public Column<Land>
|
||||
{
|
||||
using DataType = QVector<signed char>;
|
||||
|
||||
LandMapLodColumn();
|
||||
|
||||
QVariant get(const Record<Land>& record) const override;
|
||||
void set(Record<Land>& record, const QVariant& data) override;
|
||||
bool isEditable() const override;
|
||||
};
|
||||
|
||||
struct LandNormalsColumn : public Column<Land>
|
||||
{
|
||||
using DataType = QVector<signed char>;
|
||||
|
@ -2529,8 +2518,7 @@ namespace CSMWorld
|
|||
}
|
||||
|
||||
// This is required to access the type as a QVariant.
|
||||
Q_DECLARE_METATYPE(CSMWorld::LandMapLodColumn::DataType)
|
||||
//Q_DECLARE_METATYPE(CSMWorld::LandNormalsColumn::DataType) // Same as LandMapLodColumn::DataType
|
||||
Q_DECLARE_METATYPE(CSMWorld::LandNormalsColumn::DataType)
|
||||
Q_DECLARE_METATYPE(CSMWorld::LandHeightsColumn::DataType)
|
||||
Q_DECLARE_METATYPE(CSMWorld::LandColoursColumn::DataType)
|
||||
Q_DECLARE_METATYPE(CSMWorld::LandTexturesColumn::DataType)
|
||||
|
|
|
@ -443,7 +443,6 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat
|
|||
mLand.addColumn (new RecordStateColumn<Land>);
|
||||
mLand.addColumn (new FixedRecordTypeColumn<Land>(UniversalId::Type_Land));
|
||||
mLand.addColumn (new LandPluginIndexColumn);
|
||||
mLand.addColumn (new LandMapLodColumn);
|
||||
mLand.addColumn (new LandNormalsColumn);
|
||||
mLand.addColumn (new LandHeightsColumn);
|
||||
mLand.addColumn (new LandColoursColumn);
|
||||
|
|
|
@ -273,7 +273,6 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
|
|||
*document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures));
|
||||
|
||||
int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex);
|
||||
int landMapLodColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandMapLodIndex);
|
||||
int landnormalsColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandNormalsIndex);
|
||||
|
||||
QUndoStack& undoStack = document.getUndoStack();
|
||||
|
@ -287,9 +286,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
|
|||
std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY());
|
||||
undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId));
|
||||
const CSMWorld::LandHeightsColumn::DataType landShapePointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value<CSMWorld::LandHeightsColumn::DataType>();
|
||||
const CSMWorld::LandMapLodColumn::DataType landMapLodPointer = landTable.data(landTable.getModelIndex(cellId, landMapLodColumn)).value<CSMWorld::LandMapLodColumn::DataType>();
|
||||
CSMWorld::LandHeightsColumn::DataType landShapeNew(landShapePointer);
|
||||
CSMWorld::LandMapLodColumn::DataType mapLodShapeNew(landMapLodPointer);
|
||||
CSVRender::PagedWorldspaceWidget *paged = dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget());
|
||||
|
||||
// Generate land height record
|
||||
|
@ -304,26 +301,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
|
|||
}
|
||||
}
|
||||
|
||||
// Generate WNAM record
|
||||
int sqrtLandGlobalMapLodSize = sqrt(ESM::Land::LAND_GLOBAL_MAP_LOD_SIZE);
|
||||
for(int i = 0; i < sqrtLandGlobalMapLodSize; ++i)
|
||||
{
|
||||
for(int j = 0; j < sqrtLandGlobalMapLodSize; ++j)
|
||||
{
|
||||
int col = (static_cast<float>(j) / sqrtLandGlobalMapLodSize) * (ESM::Land::LAND_SIZE - 1);
|
||||
int row = (static_cast<float>(i) / sqrtLandGlobalMapLodSize) * (ESM::Land::LAND_SIZE - 1);
|
||||
signed char lodHeight = 0;
|
||||
float floatLodHeight = 0;
|
||||
if (landShapeNew[col * ESM::Land::LAND_SIZE + row] > 0) floatLodHeight = landShapeNew[col * ESM::Land::LAND_SIZE + row] / 128;
|
||||
if (landShapeNew[col * ESM::Land::LAND_SIZE + row] <= 0) floatLodHeight = landShapeNew[col * ESM::Land::LAND_SIZE + row] / 16;
|
||||
if (floatLodHeight > std::numeric_limits<signed char>::max()) lodHeight = std::numeric_limits<signed char>::max();
|
||||
else if (floatLodHeight < std::numeric_limits<signed char>::min()) lodHeight = std::numeric_limits<signed char>::min();
|
||||
else lodHeight = static_cast<signed char>(floatLodHeight);
|
||||
mapLodShapeNew[j * sqrtLandGlobalMapLodSize + i] = lodHeight;
|
||||
}
|
||||
}
|
||||
pushEditToCommand(landShapeNew, document, landTable, cellId);
|
||||
pushLodToCommand(mapLodShapeNew, document, landTable, cellId);
|
||||
}
|
||||
|
||||
for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells)
|
||||
|
@ -1136,18 +1114,6 @@ void CSVRender::TerrainShapeMode::pushNormalsEditToCommand(const CSMWorld::LandN
|
|||
undoStack.push (new CSMWorld::ModifyCommand(landTable, index, changedLand));
|
||||
}
|
||||
|
||||
void CSVRender::TerrainShapeMode::pushLodToCommand(const CSMWorld::LandMapLodColumn::DataType& newLandMapLod, CSMDoc::Document& document,
|
||||
CSMWorld::IdTable& landTable, const std::string& cellId)
|
||||
{
|
||||
QVariant changedLod;
|
||||
changedLod.setValue(newLandMapLod);
|
||||
|
||||
QModelIndex index(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandMapLodIndex)));
|
||||
|
||||
QUndoStack& undoStack = document.getUndoStack();
|
||||
undoStack.push (new CSMWorld::ModifyCommand(landTable, index, changedLod));
|
||||
}
|
||||
|
||||
bool CSVRender::TerrainShapeMode::noCell(const std::string& cellId)
|
||||
{
|
||||
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
|
||||
|
|
|
@ -148,10 +148,6 @@ namespace CSVRender
|
|||
void pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
||||
CSMWorld::IdTable& landTable, const std::string& cellId);
|
||||
|
||||
/// Generate new land map LOD
|
||||
void pushLodToCommand(const CSMWorld::LandMapLodColumn::DataType& newLandMapLod, CSMDoc::Document& document,
|
||||
CSMWorld::IdTable& landTable, const std::string& cellId);
|
||||
|
||||
bool noCell(const std::string& cellId);
|
||||
|
||||
bool noLand(const std::string& cellId);
|
||||
|
|
|
@ -158,8 +158,24 @@ namespace ESM
|
|||
}
|
||||
}
|
||||
|
||||
if (mDataTypes & Land::DATA_WNAM) {
|
||||
esm.writeHNT("WNAM", mWnam, 81);
|
||||
if (mDataTypes & Land::DATA_WNAM)
|
||||
{
|
||||
// Generate WNAM record
|
||||
signed char wnam[LAND_GLOBAL_MAP_LOD_SIZE];
|
||||
float max = std::numeric_limits<signed char>::max();
|
||||
float min = std::numeric_limits<signed char>::min();
|
||||
float vertMult = static_cast<float>(ESM::Land::LAND_SIZE - 1) / LAND_GLOBAL_MAP_LOD_SIZE_SQRT;
|
||||
for (int row = 0; row < LAND_GLOBAL_MAP_LOD_SIZE_SQRT; ++row)
|
||||
{
|
||||
for (int col = 0; col < LAND_GLOBAL_MAP_LOD_SIZE_SQRT; ++col)
|
||||
{
|
||||
float height = mLandData->mHeights[int(row * vertMult) * ESM::Land::LAND_SIZE + int(col * vertMult)];
|
||||
height /= height > 0 ? 128.f : 16.f;
|
||||
height = std::min(max, std::max(min, height));
|
||||
wnam[row * LAND_GLOBAL_MAP_LOD_SIZE_SQRT + col] = static_cast<signed char>(height);
|
||||
}
|
||||
}
|
||||
esm.writeHNT("WNAM", wnam, 81);
|
||||
}
|
||||
|
||||
if (mLandData)
|
||||
|
|
|
@ -70,6 +70,8 @@ struct Land
|
|||
|
||||
static const int LAND_GLOBAL_MAP_LOD_SIZE = 81;
|
||||
|
||||
static const int LAND_GLOBAL_MAP_LOD_SIZE_SQRT = 9;
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct VHGT
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue