mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 11:53:51 +00:00
Resolve merge issues.
This commit is contained in:
parent
33c0db1d9a
commit
1334091613
6 changed files with 140 additions and 51 deletions
|
@ -127,27 +127,22 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
|
|||
|
||||
if (topic.isModified() || infoModified)
|
||||
{
|
||||
ESM::Dialogue dialogue = topic.get();
|
||||
if (infoModified && state != CSMWorld::RecordBase::State_Modified
|
||||
&& state != CSMWorld::RecordBase::State_ModifiedOnly)
|
||||
if (infoModified && topic.mState != CSMWorld::RecordBase::State_Modified
|
||||
&& topic.mState != CSMWorld::RecordBase::State_ModifiedOnly)
|
||||
{
|
||||
mState.getWriter().startRecord (topic.mBase.sRecordId);
|
||||
mState.getWriter().writeHNCString ("NAME", topic.mBase.mId);
|
||||
topic.mBase.save (mState.getWriter());
|
||||
topic.mBase.save (mState.getWriter(), topic.mState == CSMWorld::RecordBase::State_Deleted);
|
||||
mState.getWriter().endRecord (topic.mBase.sRecordId);
|
||||
}
|
||||
else
|
||||
{
|
||||
mState.getWriter().startRecord (topic.mModified.sRecordId);
|
||||
mState.getWriter().writeHNCString ("NAME", topic.mModified.mId);
|
||||
topic.mModified.save (mState.getWriter());
|
||||
topic.mModified.save (mState.getWriter(), topic.mState == CSMWorld::RecordBase::State_Deleted);
|
||||
mState.getWriter().endRecord (topic.mModified.sRecordId);
|
||||
}
|
||||
|
||||
writer.startRecord (dialogue.sRecordId);
|
||||
dialogue.save (writer);
|
||||
writer.endRecord (dialogue.sRecordId);
|
||||
|
||||
// write modified selected info records
|
||||
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter)
|
||||
{
|
||||
|
@ -398,10 +393,14 @@ void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages)
|
|||
|
||||
if (land.isModified() || land.mState == CSMWorld::RecordBase::State_Deleted)
|
||||
{
|
||||
const CSMWorld::Land& record = land.get();
|
||||
writer.startRecord (record.mLand->sRecordId);
|
||||
record.mLand->save (writer, land.mState == CSMWorld::RecordBase::State_Deleted);
|
||||
writer.endRecord (record.mLand->sRecordId);
|
||||
CSMWorld::Land record = land.get();
|
||||
writer.startRecord (record.sRecordId);
|
||||
record.save (writer, land.mState == CSMWorld::RecordBase::State_Deleted);
|
||||
|
||||
if (const ESM::Land::LandData *data = record.getLandData (record.mDataTypes))
|
||||
data->save (mState.getWriter());
|
||||
|
||||
writer.endRecord (record.sRecordId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace CSMWorld
|
|||
{
|
||||
void Land::load(ESM::ESMReader &esm, bool &isDeleted)
|
||||
{
|
||||
mLand->load(esm, isDeleted);
|
||||
ESM::Land::load(esm, isDeleted);
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "#" << mX << " " << mY;
|
||||
|
|
|
@ -10,7 +10,6 @@ namespace CSMWorld
|
|||
/// \brief Wrapper for Land record. Encodes X and Y cell index in the ID.
|
||||
///
|
||||
/// \todo Add worldspace support to the Land record.
|
||||
/// \todo Add a proper copy constructor (currently worked around using shared_ptr)
|
||||
struct Land : public ESM::Land
|
||||
{
|
||||
std::string mId;
|
||||
|
|
|
@ -7,11 +7,8 @@ namespace CSMWorld
|
|||
void LandTexture::load(ESM::ESMReader &esm, bool &isDeleted)
|
||||
{
|
||||
ESM::LandTexture::load(esm, isDeleted);
|
||||
int plugin = esm.getIndex();
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << mIndex << "_" << plugin;
|
||||
mId = stream.str();
|
||||
mPluginIndex = esm.getIndex();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,16 +55,6 @@ namespace ESM
|
|||
}
|
||||
}
|
||||
|
||||
void Land::LandData::transposeTextureData(const uint16_t *in, uint16_t *out)
|
||||
{
|
||||
int readPos = 0; //bit ugly, but it works
|
||||
for ( int y1 = 0; y1 < 4; y1++ )
|
||||
for ( int x1 = 0; x1 < 4; x1++ )
|
||||
for ( int y2 = 0; y2 < 4; y2++)
|
||||
for ( int x2 = 0; x2 < 4; x2++ )
|
||||
out[(y1*4+y2)*16+(x1*4+x2)] = in[readPos++];
|
||||
}
|
||||
|
||||
Land::Land()
|
||||
: mFlags(0)
|
||||
, mX(0)
|
||||
|
@ -77,6 +67,16 @@ namespace ESM
|
|||
{
|
||||
}
|
||||
|
||||
void Land::LandData::transposeTextureData(const uint16_t *in, uint16_t *out)
|
||||
{
|
||||
int readPos = 0; //bit ugly, but it works
|
||||
for ( int y1 = 0; y1 < 4; y1++ )
|
||||
for ( int x1 = 0; x1 < 4; x1++ )
|
||||
for ( int y2 = 0; y2 < 4; y2++)
|
||||
for ( int x2 = 0; x2 < 4; x2++ )
|
||||
out[(y1*4+y2)*16+(x1*4+x2)] = in[readPos++];
|
||||
}
|
||||
|
||||
Land::~Land()
|
||||
{
|
||||
delete mLandData;
|
||||
|
@ -256,4 +256,69 @@ namespace ESM
|
|||
return (mDataLoaded & flags) == (flags & mDataTypes);
|
||||
}
|
||||
|
||||
Land::Land (const Land& land)
|
||||
: mFlags (land.mFlags), mX (land.mX), mY (land.mY), mPlugin (land.mPlugin),
|
||||
mEsm (land.mEsm), mContext (land.mContext), mDataTypes (land.mDataTypes),
|
||||
mDataLoaded (land.mDataLoaded),
|
||||
mLandData (land.mLandData ? new LandData (*land.mLandData) : 0)
|
||||
{}
|
||||
|
||||
Land& Land::operator= (Land land)
|
||||
{
|
||||
swap (land);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Land::swap (Land& land)
|
||||
{
|
||||
std::swap (mFlags, land.mFlags);
|
||||
std::swap (mX, land.mX);
|
||||
std::swap (mY, land.mY);
|
||||
std::swap (mPlugin, land.mPlugin);
|
||||
std::swap (mEsm, land.mEsm);
|
||||
std::swap (mContext, land.mContext);
|
||||
std::swap (mDataTypes, land.mDataTypes);
|
||||
std::swap (mDataLoaded, land.mDataLoaded);
|
||||
std::swap (mLandData, land.mLandData);
|
||||
}
|
||||
|
||||
const Land::LandData *Land::getLandData (int flags) const
|
||||
{
|
||||
if (!(flags & mDataTypes))
|
||||
return 0;
|
||||
|
||||
loadData (flags);
|
||||
return mLandData;
|
||||
}
|
||||
|
||||
const Land::LandData *Land::getLandData() const
|
||||
{
|
||||
return mLandData;
|
||||
}
|
||||
|
||||
Land::LandData *Land::getLandData()
|
||||
{
|
||||
return mLandData;
|
||||
}
|
||||
|
||||
void Land::add (int flags)
|
||||
{
|
||||
if (!mLandData)
|
||||
mLandData = new LandData;
|
||||
|
||||
mDataTypes |= flags;
|
||||
mDataLoaded |= flags;
|
||||
}
|
||||
|
||||
void Land::remove (int flags)
|
||||
{
|
||||
mDataTypes &= ~flags;
|
||||
mDataLoaded &= ~flags;
|
||||
|
||||
if (!mDataLoaded)
|
||||
{
|
||||
delete mLandData;
|
||||
mLandData = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "storage.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
#include <OgreVector2.h>
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreStringConverter.h>
|
||||
|
@ -32,19 +35,22 @@ namespace ESMTerrain
|
|||
|
||||
Ogre::Vector2 origin = center - Ogre::Vector2(size/2.f, size/2.f);
|
||||
|
||||
assert(origin.x == (int) origin.x);
|
||||
assert(origin.y == (int) origin.y);
|
||||
int cellX = static_cast<int>(std::floor(origin.x));
|
||||
int cellY = static_cast<int>(std::floor(origin.y));
|
||||
|
||||
int cellX = static_cast<int>(origin.x);
|
||||
int cellY = static_cast<int>(origin.y);
|
||||
int startRow = (origin.x - cellX) * ESM::Land::LAND_SIZE;
|
||||
int startColumn = (origin.y - cellY) * ESM::Land::LAND_SIZE;
|
||||
|
||||
int endRow = startRow + size * (ESM::Land::LAND_SIZE-1) + 1;
|
||||
int endColumn = startColumn + size * (ESM::Land::LAND_SIZE-1) + 1;
|
||||
|
||||
if (const ESM::Land::LandData *data = getLandData (cellX, cellY, ESM::Land::DATA_VHGT))
|
||||
{
|
||||
min = std::numeric_limits<float>::max();
|
||||
max = -std::numeric_limits<float>::max();
|
||||
for (int row=0; row<ESM::Land::LAND_SIZE; ++row)
|
||||
for (int row=startRow; row<endRow; ++row)
|
||||
{
|
||||
for (int col=0; col<ESM::Land::LAND_SIZE; ++col)
|
||||
for (int col=startColumn; col<endColumn; ++col)
|
||||
{
|
||||
float h = data->mHeights[col*ESM::Land::LAND_SIZE+row];
|
||||
if (h > max)
|
||||
|
@ -141,17 +147,15 @@ namespace ESMTerrain
|
|||
size_t increment = 1 << lodLevel;
|
||||
|
||||
Ogre::Vector2 origin = center - Ogre::Vector2(size/2.f, size/2.f);
|
||||
assert(origin.x == (int) origin.x);
|
||||
assert(origin.y == (int) origin.y);
|
||||
|
||||
int startX = static_cast<int>(origin.x);
|
||||
int startY = static_cast<int>(origin.y);
|
||||
int startCellX = static_cast<int>(std::floor(origin.x));
|
||||
int startCellY = static_cast<int>(std::floor(origin.y));
|
||||
|
||||
size_t numVerts = static_cast<size_t>(size*(ESM::Land::LAND_SIZE - 1) / increment + 1);
|
||||
|
||||
colours.resize(numVerts*numVerts*4);
|
||||
positions.resize(numVerts*numVerts*3);
|
||||
normals.resize(numVerts*numVerts*3);
|
||||
colours.resize(numVerts*numVerts*4);
|
||||
|
||||
Ogre::Vector3 normal;
|
||||
Ogre::ColourValue color;
|
||||
|
@ -160,10 +164,10 @@ namespace ESMTerrain
|
|||
float vertX = 0;
|
||||
|
||||
float vertY_ = 0; // of current cell corner
|
||||
for (int cellY = startY; cellY < startY + std::ceil(size); ++cellY)
|
||||
for (int cellY = startCellY; cellY < startCellY + std::ceil(size); ++cellY)
|
||||
{
|
||||
float vertX_ = 0; // of current cell corner
|
||||
for (int cellX = startX; cellX < startX + std::ceil(size); ++cellX)
|
||||
for (int cellX = startCellX; cellX < startCellX + std::ceil(size); ++cellX)
|
||||
{
|
||||
const ESM::Land::LandData *heightData = getLandData (cellX, cellY, ESM::Land::DATA_VHGT);
|
||||
const ESM::Land::LandData *normalData = getLandData (cellX, cellY, ESM::Land::DATA_VNML);
|
||||
|
@ -173,20 +177,33 @@ namespace ESMTerrain
|
|||
int colStart = 0;
|
||||
// Skip the first row / column unless we're at a chunk edge,
|
||||
// since this row / column is already contained in a previous cell
|
||||
// This is only relevant if we're creating a chunk spanning multiple cells
|
||||
if (colStart == 0 && vertY_ != 0)
|
||||
colStart += increment;
|
||||
if (rowStart == 0 && vertX_ != 0)
|
||||
rowStart += increment;
|
||||
|
||||
// Only relevant for chunks smaller than (contained in) one cell
|
||||
rowStart += (origin.x - startCellX) * ESM::Land::LAND_SIZE;
|
||||
colStart += (origin.y - startCellY) * ESM::Land::LAND_SIZE;
|
||||
int rowEnd = rowStart + std::min(1.f, size) * (ESM::Land::LAND_SIZE-1) + 1;
|
||||
int colEnd = colStart + std::min(1.f, size) * (ESM::Land::LAND_SIZE-1) + 1;
|
||||
|
||||
vertY = vertY_;
|
||||
for (int col=colStart; col<ESM::Land::LAND_SIZE; col += increment)
|
||||
for (int col=colStart; col<colEnd; col += increment)
|
||||
{
|
||||
vertX = vertX_;
|
||||
for (int row=rowStart; row<ESM::Land::LAND_SIZE; row += increment)
|
||||
for (int row=rowStart; row<rowEnd; row += increment)
|
||||
{
|
||||
positions[static_cast<unsigned int>(vertX*numVerts * 3 + vertY * 3)] = ((vertX / float(numVerts - 1) - 0.5f) * size * 8192);
|
||||
positions[static_cast<unsigned int>(vertX*numVerts * 3 + vertY * 3 + 1)] = ((vertY / float(numVerts - 1) - 0.5f) * size * 8192);
|
||||
|
||||
assert(row >= 0 && row < ESM::Land::LAND_SIZE);
|
||||
assert(col >= 0 && col < ESM::Land::LAND_SIZE);
|
||||
|
||||
assert (vertX < numVerts);
|
||||
assert (vertY < numVerts);
|
||||
|
||||
float height = -2048;
|
||||
if (heightData)
|
||||
height = heightData->mHeights[col*ESM::Land::LAND_SIZE + row];
|
||||
|
@ -290,7 +307,7 @@ namespace ESMTerrain
|
|||
// NB: All vtex ids are +1 compared to the ltex ids
|
||||
const ESM::LandTexture* ltex = getLandTexture(id.first-1, id.second);
|
||||
|
||||
//TODO this is needed due to MWs messed up texture handling
|
||||
// this is needed due to MWs messed up texture handling
|
||||
std::string texture = Misc::ResourceHelpers::correctTexturePath(ltex->mTexture);
|
||||
|
||||
return texture;
|
||||
|
@ -320,8 +337,19 @@ namespace ESMTerrain
|
|||
// and interpolate the rest of the cell by hand? :/
|
||||
|
||||
Ogre::Vector2 origin = chunkCenter - Ogre::Vector2(chunkSize/2.f, chunkSize/2.f);
|
||||
int cellX = static_cast<int>(origin.x);
|
||||
int cellY = static_cast<int>(origin.y);
|
||||
int cellX = static_cast<int>(std::floor(origin.x));
|
||||
int cellY = static_cast<int>(std::floor(origin.y));
|
||||
|
||||
int realTextureSize = ESM::Land::LAND_TEXTURE_SIZE+1; // add 1 to wrap around next cell
|
||||
|
||||
int rowStart = (origin.x - cellX) * realTextureSize;
|
||||
int colStart = (origin.y - cellY) * realTextureSize;
|
||||
int rowEnd = rowStart + chunkSize * (realTextureSize-1) + 1;
|
||||
int colEnd = colStart + chunkSize * (realTextureSize-1) + 1;
|
||||
|
||||
assert (rowStart >= 0 && colStart >= 0);
|
||||
assert (rowEnd <= realTextureSize);
|
||||
assert (colEnd <= realTextureSize);
|
||||
|
||||
// Save the used texture indices so we know the total number of textures
|
||||
// and number of required blend maps
|
||||
|
@ -332,8 +360,8 @@ namespace ESMTerrain
|
|||
// So we're always adding _land_default.dds as the base layer here, even if it's not referenced in this cell.
|
||||
textureIndices.insert(std::make_pair(0,0));
|
||||
|
||||
for (int y=0; y<ESM::Land::LAND_TEXTURE_SIZE+1; ++y)
|
||||
for (int x=0; x<ESM::Land::LAND_TEXTURE_SIZE+1; ++x)
|
||||
for (int y=colStart; y<colEnd; ++y)
|
||||
for (int x=rowStart; x<rowEnd; ++x)
|
||||
{
|
||||
UniqueTextureId id = getVtexIndexAt(cellX, cellY, x, y);
|
||||
textureIndices.insert(id);
|
||||
|
@ -357,7 +385,7 @@ namespace ESMTerrain
|
|||
int channels = pack ? 4 : 1;
|
||||
|
||||
// Second iteration - create and fill in the blend maps
|
||||
const int blendmapSize = ESM::Land::LAND_TEXTURE_SIZE+1;
|
||||
const int blendmapSize = (realTextureSize-1) * chunkSize + 1;
|
||||
|
||||
for (int i=0; i<numBlendmaps; ++i)
|
||||
{
|
||||
|
@ -371,7 +399,8 @@ namespace ESMTerrain
|
|||
{
|
||||
for (int x=0; x<blendmapSize; ++x)
|
||||
{
|
||||
UniqueTextureId id = getVtexIndexAt(cellX, cellY, x, y);
|
||||
UniqueTextureId id = getVtexIndexAt(cellX, cellY, x+rowStart, y+colStart);
|
||||
assert(textureIndicesMap.find(id) != textureIndicesMap.end());
|
||||
int layerIndex = textureIndicesMap.find(id)->second;
|
||||
int blendIndex = (pack ? static_cast<int>(std::floor((layerIndex - 1) / 4.f)) : layerIndex - 1);
|
||||
int channel = pack ? std::max(0, (layerIndex-1) % 4) : 0;
|
||||
|
|
Loading…
Reference in a new issue