1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-19 17:39:48 +00:00

Land::loadData rework

This commit is contained in:
greye 2012-09-21 12:12:16 +04:00
parent bd94f257bf
commit 2d5ddd104b
3 changed files with 90 additions and 66 deletions

View file

@ -99,9 +99,10 @@ namespace MWRender
if (land == NULL) // no land data means we're not going to create any terrain.
return;
if (!land->mDataLoaded)
int dataRequired = ESM::Land::DATA_VHGT | ESM::Land::DATA_VCLR;
if (!land->isDataLoaded(dataRequired))
{
land->loadData();
land->loadData(dataRequired);
}
//split the cell terrain into four segments
@ -413,9 +414,9 @@ namespace MWRender
ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().lands.search(cellX, cellY);
if ( land != NULL )
{
if (!land->mDataLoaded)
if (!land->isDataLoaded(ESM::Land::DATA_VTEX))
{
land->loadData();
land->loadData(ESM::Land::DATA_VTEX);
}
return land->mLandData

View file

@ -12,7 +12,7 @@ void Land::LandData::save(ESMWriter &esm)
esm.writeHNT("VNML", mNormals, sizeof(VNML));
}
if (mDataTypes & Land::DATA_VHGT) {
VHGT offsets;
static VHGT offsets;
offsets.mHeightOffset = mHeights[0] / HEIGHT_SCALE;
offsets.mUnk1 = mUnk1;
offsets.mUnk2 = mUnk2;
@ -124,9 +124,9 @@ void Land::load(ESMReader &esm)
// We need all three of VNML, VHGT and VTEX in order to use the
// landscape. (Though Morrowind seems to accept terrain without VTEX/VCLR entries)
mHasData = mDataTypes & (DATA_VNML|DATA_VHGT|DATA_WNAM|DATA_VTEX|DATA_VCLR);
mHasData = mDataTypes & (DATA_VNML|DATA_VHGT|DATA_WNAM);
mDataLoaded = false;
mDataLoaded = 0;
mLandData = NULL;
}
@ -141,10 +141,10 @@ void Land::save(ESMWriter &esm)
// TODO: Land!
bool wasLoaded = mDataLoaded;
if (mHasData)
loadData(); // I think it might be a good idea to have
// the data loaded before trying to save it
if (mDataTypes) {
// Try to load all available data before saving
loadData(mDataTypes);
}
if (mDataLoaded)
mLandData->save(esm);
@ -152,73 +152,71 @@ void Land::save(ESMWriter &esm)
unloadData(); // Don't need to keep the data loaded if it wasn't already
}
void Land::loadData()
/// \todo remove memory allocation when only defaults needed
void Land::loadData(int flags)
{
if (mDataLoaded)
{
// Try to load only available data
int actual = flags & mDataTypes;
// Return if all required data is loaded
if (flags == 0 || (actual != 0 && (mDataLoaded & actual) == actual)) {
return;
}
// Create storage if nothing is loaded
if (mLandData == NULL) {
mLandData = new LandData;
mLandData->mDataTypes = mDataTypes;
}
mEsm->restoreContext(mContext);
mLandData = new LandData;
if (mHasData)
{
mEsm->restoreContext(mContext);
memset(mLandData->mNormals, 0, LAND_NUM_VERTS * 3);
memset(mLandData->mNormals, 0, LAND_NUM_VERTS * 3);
if (mEsm->isNextSub("VNML")) {
mEsm->getHExact(mLandData->mNormals, sizeof(VNML));
}
if (mEsm->isNextSub("VNML")) {
condLoad(actual, DATA_VNML, mLandData->mNormals, sizeof(VNML));
}
if (mEsm->isNextSub("VHGT")) {
VHGT rawHeights;
if (mEsm->isNextSub("VHGT")) {
static VHGT vhgt;
if (condLoad(actual, DATA_VHGT, &vhgt, sizeof(vhgt))) {
float rowOffset = vhgt.mHeightOffset;
for (int y = 0; y < LAND_SIZE; y++) {
rowOffset += vhgt.mHeightData[y * LAND_SIZE];
mEsm->getHExact(&rawHeights, sizeof(VHGT));
float currentHeightOffset = rawHeights.mHeightOffset;
for (int y = 0; y < LAND_SIZE; y++)
{
currentHeightOffset += rawHeights.mHeightData[y * LAND_SIZE];
mLandData->mHeights[y * LAND_SIZE] = currentHeightOffset * HEIGHT_SCALE;
mLandData->mHeights[y * LAND_SIZE] = rowOffset * HEIGHT_SCALE;
float tempOffset = currentHeightOffset;
for (int x = 1; x < LAND_SIZE; x++)
{
tempOffset += rawHeights.mHeightData[y * LAND_SIZE + x];
mLandData->mHeights[x + y * LAND_SIZE] = tempOffset * HEIGHT_SCALE;
float colOffset = rowOffset;
for (int x = 1; x < LAND_SIZE; x++) {
colOffset += vhgt.mHeightData[y * LAND_SIZE + x];
mLandData->mHeights[x + y * LAND_SIZE] = colOffset * HEIGHT_SCALE;
}
}
mLandData->mUnk1 = rawHeights.mUnk1;
mLandData->mUnk2 = rawHeights.mUnk2;
mLandData->mUnk1 = vhgt.mUnk1;
mLandData->mUnk2 = vhgt.mUnk2;
}
if (mEsm->isNextSub("WNAM")) {
mEsm->getHExact(mLandData->mWnam, 81);
}
if (mEsm->isNextSub("VCLR")) {
mLandData->mUsingColours = true;
mEsm->getHExact(&mLandData->mColours, 3*LAND_NUM_VERTS);
} else {
mLandData->mUsingColours = false;
}
if (mEsm->isNextSub("VTEX")) {
static uint16_t vtex[LAND_NUM_TEXTURES];
mEsm->getHExact(&vtex, sizeof(vtex));
LandData::transposeTextureData(vtex, mLandData->mTextures);
}
}
else
{
mLandData->mUsingColours = false;
memset(mLandData->mTextures, 0, sizeof(mLandData->mTextures));
for (int i = 0; i < LAND_NUM_VERTS; i++)
{
} else if ((flags & DATA_VHGT) && (mDataLoaded & DATA_VHGT) == 0) {
for (int i = 0; i < LAND_NUM_VERTS; ++i) {
mLandData->mHeights[i] = -256.0f * HEIGHT_SCALE;
}
mDataLoaded |= DATA_VHGT;
}
mLandData->mDataTypes = mDataTypes;
mDataLoaded = true;
if (mEsm->isNextSub("WNAM")) {
condLoad(actual, DATA_WNAM, mLandData->mWnam, 81);
}
if (mEsm->isNextSub("VCLR")) {
mLandData->mUsingColours = true;
condLoad(actual, DATA_VCLR, mLandData->mColours, 3 * LAND_NUM_VERTS);
} else {
mLandData->mUsingColours = false;
}
if (mEsm->isNextSub("VTEX")) {
static uint16_t vtex[LAND_NUM_TEXTURES];
if (condLoad(actual, DATA_VTEX, vtex, sizeof(vtex))) {
LandData::transposeTextureData(vtex, mLandData->mTextures);
}
} else if ((flags & DATA_VTEX) && (mDataLoaded & DATA_VTEX) == 0) {
memset(mLandData->mTextures, 0, sizeof(mLandData->mTextures));
mDataLoaded |= DATA_VTEX;
}
}
void Land::unloadData()
@ -227,8 +225,22 @@ void Land::unloadData()
{
delete mLandData;
mLandData = NULL;
mDataLoaded = false;
mDataLoaded = 0;
}
}
bool Land::condLoad(int flags, int dataFlag, void *ptr, unsigned int size)
{
if ((mDataLoaded & dataFlag) != 0) {
return false;
}
if (flags & dataFlag) {
mEsm->getHExact(ptr, size);
mDataLoaded |= dataFlag;
return true;
}
mEsm->skipHSubSize(size);
return false;
}
}

View file

@ -28,7 +28,7 @@ struct Land : public Record
bool mHasData;
int mDataTypes;
bool mDataLoaded;
int mDataLoaded;
enum
{
@ -97,16 +97,27 @@ struct Land : public Record
/**
* Actually loads data
*/
void loadData();
void loadData(int flags);
/**
* Frees memory allocated for land data
*/
void unloadData();
/// Check if given data type is loaded
/// \todo reimplement this
bool isDataLoaded(int flags) {
return (mDataLoaded & flags) == flags;
}
private:
Land(const Land& land);
Land& operator=(const Land& land);
/// Loads data and marks it as loaded
/// \return true if data is actually loaded from file, false otherwise
/// including the case when data is already loaded
bool condLoad(int flags, int dataFlag, void *ptr, unsigned int size);
};
}