mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-22 13:09:41 +00:00
Merge pull request #2669 from Capostrophic/wnam
Generate WNAM subrecord upon saving terrain instead of upon editing it
This commit is contained in:
commit
44a85795cf
7 changed files with 21 additions and 101 deletions
|
@ -76,53 +76,6 @@ namespace CSMWorld
|
||||||
return false;
|
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::LandNormalsColumn()
|
LandNormalsColumn::LandNormalsColumn()
|
||||||
: Column<Land>(Columns::ColumnId_LandNormalsIndex, ColumnBase::Display_String, 0)
|
: Column<Land>(Columns::ColumnId_LandNormalsIndex, ColumnBase::Display_String, 0)
|
||||||
|
|
|
@ -2461,17 +2461,6 @@ namespace CSMWorld
|
||||||
bool isEditable() const override;
|
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>
|
struct LandNormalsColumn : public Column<Land>
|
||||||
{
|
{
|
||||||
using DataType = QVector<signed char>;
|
using DataType = QVector<signed char>;
|
||||||
|
@ -2529,8 +2518,7 @@ namespace CSMWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is required to access the type as a QVariant.
|
// This is required to access the type as a QVariant.
|
||||||
Q_DECLARE_METATYPE(CSMWorld::LandMapLodColumn::DataType)
|
Q_DECLARE_METATYPE(CSMWorld::LandNormalsColumn::DataType)
|
||||||
//Q_DECLARE_METATYPE(CSMWorld::LandNormalsColumn::DataType) // Same as LandMapLodColumn::DataType
|
|
||||||
Q_DECLARE_METATYPE(CSMWorld::LandHeightsColumn::DataType)
|
Q_DECLARE_METATYPE(CSMWorld::LandHeightsColumn::DataType)
|
||||||
Q_DECLARE_METATYPE(CSMWorld::LandColoursColumn::DataType)
|
Q_DECLARE_METATYPE(CSMWorld::LandColoursColumn::DataType)
|
||||||
Q_DECLARE_METATYPE(CSMWorld::LandTexturesColumn::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 RecordStateColumn<Land>);
|
||||||
mLand.addColumn (new FixedRecordTypeColumn<Land>(UniversalId::Type_Land));
|
mLand.addColumn (new FixedRecordTypeColumn<Land>(UniversalId::Type_Land));
|
||||||
mLand.addColumn (new LandPluginIndexColumn);
|
mLand.addColumn (new LandPluginIndexColumn);
|
||||||
mLand.addColumn (new LandMapLodColumn);
|
|
||||||
mLand.addColumn (new LandNormalsColumn);
|
mLand.addColumn (new LandNormalsColumn);
|
||||||
mLand.addColumn (new LandHeightsColumn);
|
mLand.addColumn (new LandHeightsColumn);
|
||||||
mLand.addColumn (new LandColoursColumn);
|
mLand.addColumn (new LandColoursColumn);
|
||||||
|
|
|
@ -273,7 +273,6 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
|
||||||
*document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures));
|
*document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures));
|
||||||
|
|
||||||
int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex);
|
int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex);
|
||||||
int landMapLodColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandMapLodIndex);
|
|
||||||
int landnormalsColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandNormalsIndex);
|
int landnormalsColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandNormalsIndex);
|
||||||
|
|
||||||
QUndoStack& undoStack = document.getUndoStack();
|
QUndoStack& undoStack = document.getUndoStack();
|
||||||
|
@ -287,9 +286,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
|
||||||
std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY());
|
std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY());
|
||||||
undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId));
|
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::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::LandHeightsColumn::DataType landShapeNew(landShapePointer);
|
||||||
CSMWorld::LandMapLodColumn::DataType mapLodShapeNew(landMapLodPointer);
|
|
||||||
CSVRender::PagedWorldspaceWidget *paged = dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget());
|
CSVRender::PagedWorldspaceWidget *paged = dynamic_cast<CSVRender::PagedWorldspaceWidget *> (&getWorldspaceWidget());
|
||||||
|
|
||||||
// Generate land height record
|
// 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);
|
pushEditToCommand(landShapeNew, document, landTable, cellId);
|
||||||
pushLodToCommand(mapLodShapeNew, document, landTable, cellId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells)
|
for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells)
|
||||||
|
@ -1136,18 +1114,6 @@ void CSVRender::TerrainShapeMode::pushNormalsEditToCommand(const CSMWorld::LandN
|
||||||
undoStack.push (new CSMWorld::ModifyCommand(landTable, index, changedLand));
|
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)
|
bool CSVRender::TerrainShapeMode::noCell(const std::string& cellId)
|
||||||
{
|
{
|
||||||
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
|
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
|
||||||
|
|
|
@ -148,10 +148,6 @@ namespace CSVRender
|
||||||
void pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
void pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
||||||
CSMWorld::IdTable& landTable, const std::string& cellId);
|
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 noCell(const std::string& cellId);
|
||||||
|
|
||||||
bool noLand(const std::string& cellId);
|
bool noLand(const std::string& cellId);
|
||||||
|
|
|
@ -158,8 +158,24 @@ namespace ESM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDataTypes & Land::DATA_WNAM) {
|
if (mDataTypes & Land::DATA_WNAM)
|
||||||
esm.writeHNT("WNAM", mWnam, 81);
|
{
|
||||||
|
// 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)
|
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 = 81;
|
||||||
|
|
||||||
|
static const int LAND_GLOBAL_MAP_LOD_SIZE_SQRT = 9;
|
||||||
|
|
||||||
#pragma pack(push,1)
|
#pragma pack(push,1)
|
||||||
struct VHGT
|
struct VHGT
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue