forked from mirror/openmw-tes3mp
Merge remote-tracking branch 'scrawl/terrain'
This commit is contained in:
commit
c85735abed
14 changed files with 244 additions and 8 deletions
|
@ -26,7 +26,7 @@ opencs_units (model/world
|
|||
|
||||
opencs_units_noqt (model/world
|
||||
universalid record commands columnbase scriptcontext cell refidcollection
|
||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
|
||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope landtexture land
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (model/world
|
||||
|
@ -76,7 +76,7 @@ opencs_units (view/widget
|
|||
|
||||
opencs_units (view/render
|
||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||
previewwidget
|
||||
previewwidget terrainstorage
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
|
|
|
@ -539,6 +539,16 @@ CSMWorld::IdCollection<ESM::DebugProfile>& CSMWorld::Data::getDebugProfiles()
|
|||
return mDebugProfiles;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::Land>& CSMWorld::Data::getLand() const
|
||||
{
|
||||
return mLand;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::LandTexture>& CSMWorld::Data::getLandTextures() const
|
||||
{
|
||||
return mLandTextures;
|
||||
}
|
||||
|
||||
const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id) const
|
||||
{
|
||||
return mResourcesManager.get (id.getType());
|
||||
|
@ -573,8 +583,11 @@ void CSMWorld::Data::merge()
|
|||
|
||||
int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base, bool project)
|
||||
{
|
||||
delete mReader;
|
||||
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading
|
||||
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
|
||||
mReaders.push_back(ptr);
|
||||
mReader = 0;
|
||||
|
||||
mDialogue = 0;
|
||||
mRefLoadCache.clear();
|
||||
|
||||
|
@ -598,8 +611,11 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
|||
|
||||
if (!mReader->hasMoreRecs())
|
||||
{
|
||||
delete mReader;
|
||||
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading
|
||||
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
|
||||
mReaders.push_back(ptr);
|
||||
mReader = 0;
|
||||
|
||||
mDialogue = 0;
|
||||
mRefLoadCache.clear();
|
||||
return true;
|
||||
|
@ -626,6 +642,9 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
|||
case ESM::REC_ENCH: mEnchantments.load (*mReader, mBase); break;
|
||||
case ESM::REC_BODY: mBodyParts.load (*mReader, mBase); break;
|
||||
|
||||
case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break;
|
||||
case ESM::REC_LAND: mLand.load(*mReader, mBase); break;
|
||||
|
||||
case ESM::REC_CELL:
|
||||
{
|
||||
mCells.load (*mReader, mBase);
|
||||
|
@ -775,7 +794,9 @@ bool CSMWorld::Data::hasId (const std::string& id) const
|
|||
getCells().searchId (id)!=-1 ||
|
||||
getEnchantments().searchId (id)!=-1 ||
|
||||
getBodyParts().searchId (id)!=-1 ||
|
||||
getReferenceables().searchId (id)!=-1;
|
||||
getReferenceables().searchId (id)!=-1 ||
|
||||
getLand().searchId (id) != -1 ||
|
||||
getLandTextures().searchId (id) != -1;
|
||||
}
|
||||
|
||||
int CSMWorld::Data::count (RecordBase::State state) const
|
||||
|
@ -795,7 +816,9 @@ int CSMWorld::Data::count (RecordBase::State state) const
|
|||
count (state, mCells) +
|
||||
count (state, mEnchantments) +
|
||||
count (state, mBodyParts) +
|
||||
count (state, mReferenceables);
|
||||
count (state, mReferenceables) +
|
||||
count (state, mLand) +
|
||||
count (state, mLandTextures);
|
||||
}
|
||||
|
||||
void CSMWorld::Data::setDescription (const std::string& description)
|
||||
|
@ -838,6 +861,8 @@ std::vector<std::string> CSMWorld::Data::getIds (bool listDeleted) const
|
|||
appendIds (ids, mEnchantments, listDeleted);
|
||||
appendIds (ids, mBodyParts, listDeleted);
|
||||
appendIds (ids, mReferenceables, listDeleted);
|
||||
appendIds (ids, mLand, listDeleted);
|
||||
appendIds (ids, mLandTextures, listDeleted);
|
||||
|
||||
std::sort (ids.begin(), ids.end());
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "idcollection.hpp"
|
||||
#include "universalid.hpp"
|
||||
#include "cell.hpp"
|
||||
#include "land.hpp"
|
||||
#include "landtexture.hpp"
|
||||
#include "refidcollection.hpp"
|
||||
#include "refcollection.hpp"
|
||||
#include "infocollection.hpp"
|
||||
|
@ -74,6 +76,8 @@ namespace CSMWorld
|
|||
InfoCollection mTopicInfos;
|
||||
InfoCollection mJournalInfos;
|
||||
IdCollection<Cell> mCells;
|
||||
IdCollection<LandTexture> mLandTextures;
|
||||
IdCollection<Land> mLand;
|
||||
RefIdCollection mReferenceables;
|
||||
RefCollection mRefs;
|
||||
IdCollection<ESM::Filter> mFilters;
|
||||
|
@ -88,6 +92,8 @@ namespace CSMWorld
|
|||
bool mProject;
|
||||
std::map<std::string, std::map<ESM::RefNum, std::string> > mRefLoadCache;
|
||||
|
||||
std::vector<boost::shared_ptr<ESM::ESMReader> > mReaders;
|
||||
|
||||
// not implemented
|
||||
Data (const Data&);
|
||||
Data& operator= (const Data&);
|
||||
|
@ -195,6 +201,10 @@ namespace CSMWorld
|
|||
|
||||
IdCollection<ESM::DebugProfile>& getDebugProfiles();
|
||||
|
||||
const IdCollection<CSMWorld::Land>& getLand() const;
|
||||
|
||||
const IdCollection<CSMWorld::LandTexture>& getLandTextures() const;
|
||||
|
||||
/// Throws an exception, if \a id does not match a resources list.
|
||||
const Resources& getResources (const UniversalId& id) const;
|
||||
|
||||
|
|
28
apps/opencs/model/world/land.cpp
Normal file
28
apps/opencs/model/world/land.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "land.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
|
||||
Land::Land()
|
||||
{
|
||||
mLand.reset(new ESM::Land());
|
||||
}
|
||||
|
||||
void Land::load(ESM::ESMReader &esm)
|
||||
{
|
||||
mLand->load(esm);
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "#" << mLand->mX << " " << mLand->mY;
|
||||
|
||||
mId = stream.str();
|
||||
}
|
||||
|
||||
void Land::blank()
|
||||
{
|
||||
/// \todo
|
||||
}
|
||||
|
||||
}
|
29
apps/opencs/model/world/land.hpp
Normal file
29
apps/opencs/model/world/land.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_WORLD_LAND_H
|
||||
#define CSM_WORLD_LAND_H
|
||||
|
||||
#include <string>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <components/esm/loadland.hpp>
|
||||
|
||||
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
|
||||
{
|
||||
Land();
|
||||
|
||||
boost::shared_ptr<ESM::Land> mLand;
|
||||
|
||||
std::string mId;
|
||||
|
||||
/// Loads the metadata and ID
|
||||
void load (ESM::ESMReader &esm);
|
||||
|
||||
void blank();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
21
apps/opencs/model/world/landtexture.cpp
Normal file
21
apps/opencs/model/world/landtexture.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "landtexture.hpp"
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
|
||||
void LandTexture::load(ESM::ESMReader &esm)
|
||||
{
|
||||
ESM::LandTexture::load(esm);
|
||||
|
||||
int plugin = esm.getIndex();
|
||||
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << mIndex << "_" << plugin;
|
||||
|
||||
mId = stream.str();
|
||||
}
|
||||
|
||||
}
|
22
apps/opencs/model/world/landtexture.hpp
Normal file
22
apps/opencs/model/world/landtexture.hpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef CSM_WORLD_LANDTEXTURE_H
|
||||
#define CSM_WORLD_LANDTEXTURE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <components/esm/loadltex.hpp>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
/// \brief Wrapper for LandTexture record. Encodes mIndex and the plugin index (obtained from ESMReader)
|
||||
/// in the ID.
|
||||
///
|
||||
/// \attention The mId field of the ESM::LandTexture struct is not used.
|
||||
struct LandTexture : public ESM::LandTexture
|
||||
{
|
||||
std::string mId;
|
||||
|
||||
void load (ESM::ESMReader &esm);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -10,6 +10,9 @@
|
|||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/data.hpp"
|
||||
|
||||
#include "elements.hpp"
|
||||
#include "terrainstorage.hpp"
|
||||
|
||||
bool CSVRender::Cell::removeObject (const std::string& id)
|
||||
{
|
||||
std::map<std::string, Object *>::iterator iter =
|
||||
|
@ -67,6 +70,18 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
|||
int rows = references.rowCount();
|
||||
|
||||
addObjects (0, rows-1);
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::Land>& land = mData.getLand();
|
||||
int landIndex = land.searchId(mId);
|
||||
if (landIndex != -1)
|
||||
{
|
||||
mTerrain.reset(new Terrain::TerrainGrid(sceneManager, new TerrainStorage(mData), Element_Terrain, true,
|
||||
Terrain::Align_XY));
|
||||
|
||||
const ESM::Land* esmLand = land.getRecord(mId).get().mLand.get();
|
||||
mTerrain->loadCell(esmLand->mX,
|
||||
esmLand->mY);
|
||||
}
|
||||
}
|
||||
|
||||
CSVRender::Cell::~Cell()
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
#include <components/terrain/terraingrid.hpp>
|
||||
|
||||
#include "object.hpp"
|
||||
|
||||
class QModelIndex;
|
||||
|
@ -29,6 +31,7 @@ namespace CSVRender
|
|||
std::string mId;
|
||||
Ogre::SceneNode *mCellNode;
|
||||
std::map<std::string, Object *> mObjects;
|
||||
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
||||
|
||||
/// Ignored if cell does not have an object with the given ID.
|
||||
///
|
||||
|
|
43
apps/opencs/view/render/terrainstorage.cpp
Normal file
43
apps/opencs/view/render/terrainstorage.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "terrainstorage.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
||||
TerrainStorage::TerrainStorage(const CSMWorld::Data &data)
|
||||
: mData(data)
|
||||
{
|
||||
}
|
||||
|
||||
ESM::Land* 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());
|
||||
if (index == -1)
|
||||
return NULL;
|
||||
|
||||
ESM::Land* land = mData.getLand().getRecord(index).get().mLand.get();
|
||||
int mask = ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX;
|
||||
if (!land->isDataLoaded(mask))
|
||||
land->loadData(mask);
|
||||
return land;
|
||||
}
|
||||
|
||||
const ESM::LandTexture* TerrainStorage::getLandTexture(int index, short plugin)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << index << "_" << plugin;
|
||||
|
||||
return &mData.getLandTextures().getRecord(stream.str()).get();
|
||||
}
|
||||
|
||||
void TerrainStorage::getBounds(float &minX, float &maxX, float &minY, float &maxY)
|
||||
{
|
||||
// not needed at the moment - this returns the bounds of the whole world, but we only edit individual cells
|
||||
throw std::runtime_error("getBounds not implemented");
|
||||
}
|
||||
|
||||
}
|
29
apps/opencs/view/render/terrainstorage.hpp
Normal file
29
apps/opencs/view/render/terrainstorage.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef OPENCS_RENDER_TERRAINSTORAGE_H
|
||||
#define OPENCS_RENDER_TERRAINSTORAGE_H
|
||||
|
||||
#include <components/esmterrain/storage.hpp>
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A bridge between the terrain component and OpenCS's terrain data storage.
|
||||
*/
|
||||
class TerrainStorage : public ESMTerrain::Storage
|
||||
{
|
||||
public:
|
||||
TerrainStorage(const CSMWorld::Data& data);
|
||||
private:
|
||||
const CSMWorld::Data& mData;
|
||||
|
||||
virtual ESM::Land* getLand (int cellX, int cellY);
|
||||
virtual const ESM::LandTexture* getLandTexture(int index, short plugin);
|
||||
|
||||
virtual void getBounds(float& minX, float& maxX, float& minY, float& maxY);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -98,6 +98,8 @@ struct Land
|
|||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm) const;
|
||||
|
||||
void blank() {}
|
||||
|
||||
/**
|
||||
* Actually loads data
|
||||
*/
|
||||
|
|
|
@ -19,4 +19,10 @@ void LandTexture::save(ESMWriter &esm) const
|
|||
esm.writeHNCString("DATA", mTexture);
|
||||
}
|
||||
|
||||
void LandTexture::blank()
|
||||
{
|
||||
mTexture.clear();
|
||||
mIndex = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ struct LandTexture
|
|||
std::string mId, mTexture;
|
||||
int mIndex;
|
||||
|
||||
void blank();
|
||||
///< Set record to default state (does not touch the ID).
|
||||
|
||||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm) const;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue