1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-17 10:21:11 +00:00

Resolve merge issues.

This commit is contained in:
cc9cii 2015-12-05 17:28:32 +11:00
parent 33c0db1d9a
commit 1334091613
6 changed files with 140 additions and 51 deletions

View File

@ -127,27 +127,22 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
if (topic.isModified() || infoModified) if (topic.isModified() || infoModified)
{ {
ESM::Dialogue dialogue = topic.get(); if (infoModified && topic.mState != CSMWorld::RecordBase::State_Modified
if (infoModified && state != CSMWorld::RecordBase::State_Modified && topic.mState != CSMWorld::RecordBase::State_ModifiedOnly)
&& state != CSMWorld::RecordBase::State_ModifiedOnly)
{ {
mState.getWriter().startRecord (topic.mBase.sRecordId); mState.getWriter().startRecord (topic.mBase.sRecordId);
mState.getWriter().writeHNCString ("NAME", topic.mBase.mId); 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); mState.getWriter().endRecord (topic.mBase.sRecordId);
} }
else else
{ {
mState.getWriter().startRecord (topic.mModified.sRecordId); mState.getWriter().startRecord (topic.mModified.sRecordId);
mState.getWriter().writeHNCString ("NAME", topic.mModified.mId); 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); mState.getWriter().endRecord (topic.mModified.sRecordId);
} }
writer.startRecord (dialogue.sRecordId);
dialogue.save (writer);
writer.endRecord (dialogue.sRecordId);
// write modified selected info records // write modified selected info records
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter) 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) if (land.isModified() || land.mState == CSMWorld::RecordBase::State_Deleted)
{ {
const CSMWorld::Land& record = land.get(); CSMWorld::Land record = land.get();
writer.startRecord (record.mLand->sRecordId); writer.startRecord (record.sRecordId);
record.mLand->save (writer, land.mState == CSMWorld::RecordBase::State_Deleted); record.save (writer, land.mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.mLand->sRecordId);
if (const ESM::Land::LandData *data = record.getLandData (record.mDataTypes))
data->save (mState.getWriter());
writer.endRecord (record.sRecordId);
} }
} }

View File

@ -6,7 +6,7 @@ namespace CSMWorld
{ {
void Land::load(ESM::ESMReader &esm, bool &isDeleted) void Land::load(ESM::ESMReader &esm, bool &isDeleted)
{ {
mLand->load(esm, isDeleted); ESM::Land::load(esm, isDeleted);
std::ostringstream stream; std::ostringstream stream;
stream << "#" << mX << " " << mY; stream << "#" << mX << " " << mY;

View File

@ -10,7 +10,6 @@ namespace CSMWorld
/// \brief Wrapper for Land record. Encodes X and Y cell index in the ID. /// \brief Wrapper for Land record. Encodes X and Y cell index in the ID.
/// ///
/// \todo Add worldspace support to the Land record. /// \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 struct Land : public ESM::Land
{ {
std::string mId; std::string mId;

View File

@ -7,11 +7,8 @@ namespace CSMWorld
void LandTexture::load(ESM::ESMReader &esm, bool &isDeleted) void LandTexture::load(ESM::ESMReader &esm, bool &isDeleted)
{ {
ESM::LandTexture::load(esm, isDeleted); ESM::LandTexture::load(esm, isDeleted);
int plugin = esm.getIndex();
std::ostringstream stream; mPluginIndex = esm.getIndex();
stream << mIndex << "_" << plugin;
mId = stream.str();
} }
} }

View File

@ -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() Land::Land()
: mFlags(0) : mFlags(0)
, mX(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() Land::~Land()
{ {
delete mLandData; delete mLandData;
@ -256,4 +256,69 @@ namespace ESM
return (mDataLoaded & flags) == (flags & mDataTypes); 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;
}
}
} }

View File

@ -1,5 +1,8 @@
#include "storage.hpp" #include "storage.hpp"
#include <set>
#include <iostream>
#include <OgreVector2.h> #include <OgreVector2.h>
#include <OgreTextureManager.h> #include <OgreTextureManager.h>
#include <OgreStringConverter.h> #include <OgreStringConverter.h>
@ -32,19 +35,22 @@ namespace ESMTerrain
Ogre::Vector2 origin = center - Ogre::Vector2(size/2.f, size/2.f); Ogre::Vector2 origin = center - Ogre::Vector2(size/2.f, size/2.f);
assert(origin.x == (int) origin.x); int cellX = static_cast<int>(std::floor(origin.x));
assert(origin.y == (int) origin.y); int cellY = static_cast<int>(std::floor(origin.y));
int cellX = static_cast<int>(origin.x); int startRow = (origin.x - cellX) * ESM::Land::LAND_SIZE;
int cellY = static_cast<int>(origin.y); 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)) if (const ESM::Land::LandData *data = getLandData (cellX, cellY, ESM::Land::DATA_VHGT))
{ {
min = std::numeric_limits<float>::max(); min = std::numeric_limits<float>::max();
max = -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]; float h = data->mHeights[col*ESM::Land::LAND_SIZE+row];
if (h > max) if (h > max)
@ -141,17 +147,15 @@ namespace ESMTerrain
size_t increment = 1 << lodLevel; size_t increment = 1 << lodLevel;
Ogre::Vector2 origin = center - Ogre::Vector2(size/2.f, size/2.f); 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 startCellX = static_cast<int>(std::floor(origin.x));
int startY = static_cast<int>(origin.y); int startCellY = static_cast<int>(std::floor(origin.y));
size_t numVerts = static_cast<size_t>(size*(ESM::Land::LAND_SIZE - 1) / increment + 1); 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); positions.resize(numVerts*numVerts*3);
normals.resize(numVerts*numVerts*3); normals.resize(numVerts*numVerts*3);
colours.resize(numVerts*numVerts*4);
Ogre::Vector3 normal; Ogre::Vector3 normal;
Ogre::ColourValue color; Ogre::ColourValue color;
@ -160,10 +164,10 @@ namespace ESMTerrain
float vertX = 0; float vertX = 0;
float vertY_ = 0; // of current cell corner 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 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 *heightData = getLandData (cellX, cellY, ESM::Land::DATA_VHGT);
const ESM::Land::LandData *normalData = getLandData (cellX, cellY, ESM::Land::DATA_VNML); const ESM::Land::LandData *normalData = getLandData (cellX, cellY, ESM::Land::DATA_VNML);
@ -173,20 +177,33 @@ namespace ESMTerrain
int colStart = 0; int colStart = 0;
// Skip the first row / column unless we're at a chunk edge, // Skip the first row / column unless we're at a chunk edge,
// since this row / column is already contained in a previous cell // 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) if (colStart == 0 && vertY_ != 0)
colStart += increment; colStart += increment;
if (rowStart == 0 && vertX_ != 0) if (rowStart == 0 && vertX_ != 0)
rowStart += increment; 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_; vertY = vertY_;
for (int col=colStart; col<ESM::Land::LAND_SIZE; col += increment) for (int col=colStart; col<colEnd; col += increment)
{ {
vertX = vertX_; 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)] = ((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); 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; float height = -2048;
if (heightData) if (heightData)
height = heightData->mHeights[col*ESM::Land::LAND_SIZE + row]; 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 // NB: All vtex ids are +1 compared to the ltex ids
const ESM::LandTexture* ltex = getLandTexture(id.first-1, id.second); 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); std::string texture = Misc::ResourceHelpers::correctTexturePath(ltex->mTexture);
return texture; return texture;
@ -320,8 +337,19 @@ namespace ESMTerrain
// and interpolate the rest of the cell by hand? :/ // and interpolate the rest of the cell by hand? :/
Ogre::Vector2 origin = chunkCenter - Ogre::Vector2(chunkSize/2.f, chunkSize/2.f); Ogre::Vector2 origin = chunkCenter - Ogre::Vector2(chunkSize/2.f, chunkSize/2.f);
int cellX = static_cast<int>(origin.x); int cellX = static_cast<int>(std::floor(origin.x));
int cellY = static_cast<int>(origin.y); 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 // Save the used texture indices so we know the total number of textures
// and number of required blend maps // 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. // 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)); textureIndices.insert(std::make_pair(0,0));
for (int y=0; y<ESM::Land::LAND_TEXTURE_SIZE+1; ++y) for (int y=colStart; y<colEnd; ++y)
for (int x=0; x<ESM::Land::LAND_TEXTURE_SIZE+1; ++x) for (int x=rowStart; x<rowEnd; ++x)
{ {
UniqueTextureId id = getVtexIndexAt(cellX, cellY, x, y); UniqueTextureId id = getVtexIndexAt(cellX, cellY, x, y);
textureIndices.insert(id); textureIndices.insert(id);
@ -357,7 +385,7 @@ namespace ESMTerrain
int channels = pack ? 4 : 1; int channels = pack ? 4 : 1;
// Second iteration - create and fill in the blend maps // 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) for (int i=0; i<numBlendmaps; ++i)
{ {
@ -371,7 +399,8 @@ namespace ESMTerrain
{ {
for (int x=0; x<blendmapSize; ++x) 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 layerIndex = textureIndicesMap.find(id)->second;
int blendIndex = (pack ? static_cast<int>(std::floor((layerIndex - 1) / 4.f)) : layerIndex - 1); int blendIndex = (pack ? static_cast<int>(std::floor((layerIndex - 1) / 4.f)) : layerIndex - 1);
int channel = pack ? std::max(0, (layerIndex-1) % 4) : 0; int channel = pack ? std::max(0, (layerIndex-1) % 4) : 0;