mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-12 13:13:27 +00:00
Land::loadData rework
This commit is contained in:
parent
bd94f257bf
commit
2d5ddd104b
@ -99,9 +99,10 @@ namespace MWRender
|
|||||||
if (land == NULL) // no land data means we're not going to create any terrain.
|
if (land == NULL) // no land data means we're not going to create any terrain.
|
||||||
return;
|
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
|
//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);
|
ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().lands.search(cellX, cellY);
|
||||||
if ( land != NULL )
|
if ( land != NULL )
|
||||||
{
|
{
|
||||||
if (!land->mDataLoaded)
|
if (!land->isDataLoaded(ESM::Land::DATA_VTEX))
|
||||||
{
|
{
|
||||||
land->loadData();
|
land->loadData(ESM::Land::DATA_VTEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
return land->mLandData
|
return land->mLandData
|
||||||
|
@ -12,7 +12,7 @@ void Land::LandData::save(ESMWriter &esm)
|
|||||||
esm.writeHNT("VNML", mNormals, sizeof(VNML));
|
esm.writeHNT("VNML", mNormals, sizeof(VNML));
|
||||||
}
|
}
|
||||||
if (mDataTypes & Land::DATA_VHGT) {
|
if (mDataTypes & Land::DATA_VHGT) {
|
||||||
VHGT offsets;
|
static VHGT offsets;
|
||||||
offsets.mHeightOffset = mHeights[0] / HEIGHT_SCALE;
|
offsets.mHeightOffset = mHeights[0] / HEIGHT_SCALE;
|
||||||
offsets.mUnk1 = mUnk1;
|
offsets.mUnk1 = mUnk1;
|
||||||
offsets.mUnk2 = mUnk2;
|
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
|
// 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)
|
// 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;
|
mLandData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,10 +141,10 @@ void Land::save(ESMWriter &esm)
|
|||||||
|
|
||||||
// TODO: Land!
|
// TODO: Land!
|
||||||
bool wasLoaded = mDataLoaded;
|
bool wasLoaded = mDataLoaded;
|
||||||
if (mHasData)
|
if (mDataTypes) {
|
||||||
loadData(); // I think it might be a good idea to have
|
// Try to load all available data before saving
|
||||||
// the data loaded before trying to save it
|
loadData(mDataTypes);
|
||||||
|
}
|
||||||
if (mDataLoaded)
|
if (mDataLoaded)
|
||||||
mLandData->save(esm);
|
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
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
// Create storage if nothing is loaded
|
||||||
|
if (mLandData == NULL) {
|
||||||
|
mLandData = new LandData;
|
||||||
|
mLandData->mDataTypes = mDataTypes;
|
||||||
|
}
|
||||||
|
mEsm->restoreContext(mContext);
|
||||||
|
|
||||||
mLandData = new LandData;
|
memset(mLandData->mNormals, 0, LAND_NUM_VERTS * 3);
|
||||||
|
|
||||||
if (mHasData)
|
|
||||||
{
|
|
||||||
mEsm->restoreContext(mContext);
|
|
||||||
|
|
||||||
memset(mLandData->mNormals, 0, LAND_NUM_VERTS * 3);
|
|
||||||
|
|
||||||
if (mEsm->isNextSub("VNML")) {
|
if (mEsm->isNextSub("VNML")) {
|
||||||
mEsm->getHExact(mLandData->mNormals, sizeof(VNML));
|
condLoad(actual, DATA_VNML, mLandData->mNormals, sizeof(VNML));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEsm->isNextSub("VHGT")) {
|
if (mEsm->isNextSub("VHGT")) {
|
||||||
VHGT rawHeights;
|
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));
|
mLandData->mHeights[y * LAND_SIZE] = rowOffset * HEIGHT_SCALE;
|
||||||
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;
|
|
||||||
|
|
||||||
float tempOffset = currentHeightOffset;
|
float colOffset = rowOffset;
|
||||||
for (int x = 1; x < LAND_SIZE; x++)
|
for (int x = 1; x < LAND_SIZE; x++) {
|
||||||
{
|
colOffset += vhgt.mHeightData[y * LAND_SIZE + x];
|
||||||
tempOffset += rawHeights.mHeightData[y * LAND_SIZE + x];
|
mLandData->mHeights[x + y * LAND_SIZE] = colOffset * HEIGHT_SCALE;
|
||||||
mLandData->mHeights[x + y * LAND_SIZE] = tempOffset * HEIGHT_SCALE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mLandData->mUnk1 = rawHeights.mUnk1;
|
mLandData->mUnk1 = vhgt.mUnk1;
|
||||||
mLandData->mUnk2 = rawHeights.mUnk2;
|
mLandData->mUnk2 = vhgt.mUnk2;
|
||||||
}
|
}
|
||||||
|
} else if ((flags & DATA_VHGT) && (mDataLoaded & DATA_VHGT) == 0) {
|
||||||
if (mEsm->isNextSub("WNAM")) {
|
for (int i = 0; i < LAND_NUM_VERTS; ++i) {
|
||||||
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++)
|
|
||||||
{
|
|
||||||
mLandData->mHeights[i] = -256.0f * HEIGHT_SCALE;
|
mLandData->mHeights[i] = -256.0f * HEIGHT_SCALE;
|
||||||
}
|
}
|
||||||
|
mDataLoaded |= DATA_VHGT;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLandData->mDataTypes = mDataTypes;
|
if (mEsm->isNextSub("WNAM")) {
|
||||||
mDataLoaded = true;
|
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()
|
void Land::unloadData()
|
||||||
@ -227,8 +225,22 @@ void Land::unloadData()
|
|||||||
{
|
{
|
||||||
delete mLandData;
|
delete mLandData;
|
||||||
mLandData = NULL;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ struct Land : public Record
|
|||||||
|
|
||||||
bool mHasData;
|
bool mHasData;
|
||||||
int mDataTypes;
|
int mDataTypes;
|
||||||
bool mDataLoaded;
|
int mDataLoaded;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -97,16 +97,27 @@ struct Land : public Record
|
|||||||
/**
|
/**
|
||||||
* Actually loads data
|
* Actually loads data
|
||||||
*/
|
*/
|
||||||
void loadData();
|
void loadData(int flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees memory allocated for land data
|
* Frees memory allocated for land data
|
||||||
*/
|
*/
|
||||||
void unloadData();
|
void unloadData();
|
||||||
|
|
||||||
|
/// Check if given data type is loaded
|
||||||
|
/// \todo reimplement this
|
||||||
|
bool isDataLoaded(int flags) {
|
||||||
|
return (mDataLoaded & flags) == flags;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Land(const Land& land);
|
Land(const Land& land);
|
||||||
Land& operator=(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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user