diff --git a/apps/opencs/view/render/terrainstorage.cpp b/apps/opencs/view/render/terrainstorage.cpp index c63d41be3..51c9dd009 100644 --- a/apps/opencs/view/render/terrainstorage.cpp +++ b/apps/opencs/view/render/terrainstorage.cpp @@ -1,5 +1,8 @@ #include "terrainstorage.hpp" +#include "../../model/world/land.hpp" +#include "../../model/world/landtexture.hpp" + namespace CSVRender { @@ -11,12 +14,9 @@ namespace CSVRender osg::ref_ptr TerrainStorage::getLand(int cellX, int cellY) { - std::ostringstream stream; - stream << "#" << cellX << " " << cellY; - // The cell isn't guaranteed to have Land. This is because the terrain implementation // has to wrap the vertices of the last row and column to the next cell, which may be a nonexisting cell - int index = mData.getLand().searchId(stream.str()); + int index = mData.getLand().searchId(CSMWorld::Land::createUniqueRecordId(cellX, cellY)); if (index == -1) return NULL; @@ -26,16 +26,11 @@ namespace CSVRender const ESM::LandTexture* TerrainStorage::getLandTexture(int index, short plugin) { - int numRecords = mData.getLandTextures().getSize(); - - for (int i=0; imIndex == index && ltex->mPluginIndex == plugin) - return ltex; - } + int row = mData.getLandTextures().searchId(CSMWorld::LandTexture::createUniqueRecordId(plugin, index)); + if (row == -1) + return nullptr; - return NULL; + return &mData.getLandTextures().getRecord(row).get(); } void TerrainStorage::getBounds(float &minX, float &maxX, float &minY, float &maxY) diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index 72c3eb98d..7d48dd037 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -15,6 +15,7 @@ namespace ESM , mX(0) , mY(0) , mPlugin(0) + , mNoFile(false) , mDataTypes(0) , mLandData(NULL) { @@ -175,6 +176,47 @@ namespace ESM } + void Land::blank() + { + if (mLandData) + { + delete mLandData; + } + + mPlugin = 0; + + for (int i = 0; i < LAND_GLOBAL_MAP_LOD_SIZE; ++i) + mWnam[0] = 0; + + mLandData = new LandData; + mLandData->mHeightOffset = 0; + for (int i = 0; i < LAND_NUM_VERTS; ++i) + mLandData->mHeights[i] = 0; + mLandData->mMinHeight = 0; + mLandData->mMaxHeight = 0; + for (int i = 0; i < LAND_NUM_VERTS; ++i) + { + mLandData->mNormals[i*3+0] = 0; + mLandData->mNormals[i*3+1] = -1; + mLandData->mNormals[i*3+2] = 0; + } + for (int i = 0; i < LAND_NUM_TEXTURES; ++i) + mLandData->mTextures[i] = 0; + for (int i = 0; i < LAND_NUM_VERTS; ++i) + { + mLandData->mColours[i*3+0] = -1; + mLandData->mColours[i*3+1] = -1; + mLandData->mColours[i*3+2] = -1; + } + mLandData->mUnk1 = 0; + mLandData->mUnk2 = 0; + mLandData->mDataLoaded = Land::DATA_VNML | Land::DATA_VHGT | Land::DATA_WNAM | + Land::DATA_VCLR | Land::DATA_VTEX; + mDataTypes = mLandData->mDataLoaded; + + mNoFile = true; + } + void Land::loadData(int flags, LandData* target) const { // Create storage if nothing is loaded @@ -193,6 +235,13 @@ namespace ESM return; } + // Copy data to target if no file + if (mNoFile) + { + *target = *mLandData; + return; + } + ESM::ESMReader reader; reader.restoreContext(mContext); @@ -271,7 +320,7 @@ namespace ESM Land::Land (const Land& land) : mFlags (land.mFlags), mX (land.mX), mY (land.mY), mPlugin (land.mPlugin), - mContext (land.mContext), mDataTypes (land.mDataTypes), + mContext (land.mContext), mNoFile(land.mNoFile), mDataTypes (land.mDataTypes), mLandData (land.mLandData ? new LandData (*land.mLandData) : 0) {} @@ -288,6 +337,7 @@ namespace ESM std::swap (mY, land.mY); std::swap (mPlugin, land.mPlugin); std::swap (mContext, land.mContext); + std::swap (mNoFile, land.mNoFile); std::swap (mDataTypes, land.mDataTypes); std::swap (mLandData, land.mLandData); } diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index a7b97a465..223b7975a 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -33,6 +33,10 @@ struct Land // location later when we are ready to load the full data set. ESM_Context mContext; + // In the editor, a new Land is not associated with a file, thus mContext should not be accessed + // when land data is being requested. Instead simply copy over the data. + bool mNoFile; + int mDataTypes; enum @@ -116,7 +120,7 @@ struct Land void load(ESMReader &esm, bool &isDeleted); void save(ESMWriter &esm, bool isDeleted = false) const; - void blank() {} + void blank(); /** * Actually loads data into target