mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-03 04:13:24 +00:00
Fixes bug in terrain loading + collision heightmap works
although terrain rendering is 100% broken right now
This commit is contained in:
parent
c35c7b3640
commit
d0211acf9e
@ -767,7 +767,14 @@ namespace MWRender
|
||||
if (!enable)
|
||||
mWater->setCullCallback(nullptr);
|
||||
else
|
||||
mTerrain = getWorldspaceTerrain(worldspace);
|
||||
{
|
||||
Terrain::World* newTerrain = getWorldspaceTerrain(worldspace);
|
||||
if (newTerrain != mTerrain)
|
||||
{
|
||||
mTerrain->enable(false);
|
||||
mTerrain = newTerrain;
|
||||
}
|
||||
}
|
||||
mTerrain->enable(enable);
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,6 @@ namespace MWWorld
|
||||
{
|
||||
auto visitorRec = [this](ESM4::Reader& reader) { return ESMStoreImp::readRecord(reader, *this); };
|
||||
ESM4::ReaderUtils::readAll(reader, visitorRec, [](ESM4::Reader&) {});
|
||||
getWritable<ESM4::Land>().updateLandPositions(get<ESM4::Cell>());
|
||||
}
|
||||
|
||||
void ESMStore::setIdType(const ESM::RefId& id, ESM::RecNameInts type)
|
||||
@ -449,6 +448,7 @@ namespace MWWorld
|
||||
getWritable<ESM::Skill>().setUp();
|
||||
getWritable<ESM::MagicEffect>().setUp();
|
||||
getWritable<ESM::Attribute>().setUp();
|
||||
getWritable<ESM4::Land>().updateLandPositions(get<ESM4::Cell>());
|
||||
getWritable<ESM4::Reference>().preprocessReferences(get<ESM4::Cell>());
|
||||
}
|
||||
|
||||
|
@ -398,8 +398,9 @@ namespace MWWorld
|
||||
{
|
||||
osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellIndex);
|
||||
const ESM::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr;
|
||||
const int verts = data->getLandSize();
|
||||
const int worldsize = data->getSize();
|
||||
const int verts = ESM::getLandSize(worldspace);
|
||||
const int worldsize = ESM::getCellSize(worldspace);
|
||||
|
||||
if (data)
|
||||
{
|
||||
mPhysics->addHeightField(data->getHeights().data(), cellX, cellY, worldsize, verts,
|
||||
|
@ -1194,12 +1194,12 @@ namespace MWWorld
|
||||
|
||||
void Store<ESM4::Land>::updateLandPositions(const Store<ESM4::Cell>& cells)
|
||||
{
|
||||
for (auto it : mStatic)
|
||||
for (auto& it : mStatic)
|
||||
{
|
||||
const ESM4::Cell* cell = cells.find(it.second.mCell);
|
||||
mLands[cell->getExteriorCellLocation()] = &it.second;
|
||||
}
|
||||
for (auto it : mDynamic)
|
||||
for (auto& it : mDynamic)
|
||||
{
|
||||
const ESM4::Cell* cell = cells.find(it.second.mCell);
|
||||
mLands[cell->getExteriorCellLocation()] = &it.second;
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "util.hpp"
|
||||
#include <components/esm3/loadland.hpp>
|
||||
#include <components/esm4/loadland.hpp>
|
||||
|
||||
osg::Vec2 ESM::indexToPosition(const ESM::ExteriorCellLocation& cellIndex, bool centre)
|
||||
{
|
||||
@ -14,3 +16,8 @@ osg::Vec2 ESM::indexToPosition(const ESM::ExteriorCellLocation& cellIndex, bool
|
||||
}
|
||||
return osg::Vec2(x, y);
|
||||
}
|
||||
|
||||
int ESM::getLandSize(ESM::RefId worldspaceId)
|
||||
{
|
||||
return isEsm4Ext(worldspaceId) ? ESM4::Land::VERTS_PER_SIDE : ESM::Land::LAND_SIZE;
|
||||
}
|
||||
|
@ -89,6 +89,9 @@ namespace ESM
|
||||
return isEsm4Ext(worldspaceId) ? Constants::ESM4CellSizeInUnits : Constants::CellSizeInUnits;
|
||||
}
|
||||
|
||||
// Vertex count of a side of a land record
|
||||
int getLandSize(ESM::RefId worldspaceId);
|
||||
|
||||
inline ESM::ExteriorCellLocation positionToExteriorCellLocation(
|
||||
float x, float y, ESM::RefId worldspaceId = ESM::Cell::sDefaultWorldspaceId)
|
||||
{
|
||||
|
@ -76,12 +76,12 @@ namespace ESMTerrain
|
||||
int cellY = static_cast<int>(std::floor(origin.y()));
|
||||
osg::ref_ptr<const LandObject> land = getLand(ESM::ExteriorCellLocation(cellX, cellY, worldspace));
|
||||
const ESM::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr;
|
||||
const int landSize = ESM::getLandSize(worldspace);
|
||||
int startRow = (origin.x() - cellX) * landSize;
|
||||
int startColumn = (origin.y() - cellY) * landSize;
|
||||
|
||||
int startRow = (origin.x() - cellX) * data->getLandSize();
|
||||
int startColumn = (origin.y() - cellY) * data->getLandSize();
|
||||
|
||||
int endRow = startRow + size * (data->getLandSize() - 1) + 1;
|
||||
int endColumn = startColumn + size * (data->getLandSize() - 1) + 1;
|
||||
int endRow = startRow + size * (landSize - 1) + 1;
|
||||
int endColumn = startColumn + size * (landSize - 1) + 1;
|
||||
|
||||
if (data)
|
||||
{
|
||||
@ -91,7 +91,7 @@ namespace ESMTerrain
|
||||
{
|
||||
for (int col = startColumn; col < endColumn; ++col)
|
||||
{
|
||||
float h = data->getHeights()[col * data->getLandSize() + row];
|
||||
float h = data->getHeights()[col * landSize + row];
|
||||
if (h > max)
|
||||
max = h;
|
||||
if (h < min)
|
||||
@ -112,7 +112,7 @@ namespace ESMTerrain
|
||||
|
||||
const LandObject* land = getLand(cellLocation, cache);
|
||||
const ESM::LandData* data = land ? land->getData(ESM::Land::DATA_VNML) : nullptr;
|
||||
const int landSize = data ? data->getLandSize() : ESM::Land::LAND_SIZE;
|
||||
const int landSize = ESM::getLandSize(cellLocation.mWorldspace);
|
||||
|
||||
while (col >= landSize - 1)
|
||||
{
|
||||
@ -163,7 +163,7 @@ namespace ESMTerrain
|
||||
{
|
||||
const LandObject* land = getLand(cellLocation, cache);
|
||||
const ESM::LandData* data = land ? land->getData(ESM::Land::DATA_VCLR) : nullptr;
|
||||
const int landSize = data ? data->getLandSize() : ESM::Land::LAND_SIZE;
|
||||
const int landSize = ESM::getLandSize(cellLocation.mWorldspace);
|
||||
|
||||
if (col == landSize - 1)
|
||||
{
|
||||
@ -201,8 +201,9 @@ namespace ESMTerrain
|
||||
|
||||
int startCellX = static_cast<int>(std::floor(origin.x()));
|
||||
int startCellY = static_cast<int>(std::floor(origin.y()));
|
||||
const int LandSize = ESM::getLandSize(worldspace);
|
||||
|
||||
size_t numVerts = static_cast<size_t>(size * (ESM::Land::LAND_SIZE - 1) / increment + 1);
|
||||
size_t numVerts = static_cast<size_t>(size * (LandSize - 1) / increment + 1);
|
||||
|
||||
positions->resize(numVerts * numVerts);
|
||||
normals->resize(numVerts * numVerts);
|
||||
@ -229,7 +230,6 @@ namespace ESMTerrain
|
||||
const ESM::LandData* heightData = nullptr;
|
||||
const ESM::LandData* normalData = nullptr;
|
||||
const ESM::LandData* colourData = nullptr;
|
||||
const int LandSize = land ? land->getLandSize() : ESM::Land::LAND_SIZE;
|
||||
const int LandSizeInUnits = land ? land->getRealSize() : Constants::CellSizeInUnits;
|
||||
if (land)
|
||||
{
|
||||
@ -615,14 +615,14 @@ namespace ESMTerrain
|
||||
return info;
|
||||
}
|
||||
|
||||
float Storage::getCellWorldSize()
|
||||
float Storage::getCellWorldSize(ESM::RefId worldspace)
|
||||
{
|
||||
return static_cast<float>(ESM::Land::REAL_SIZE);
|
||||
return static_cast<float>(ESM::getCellSize(worldspace));
|
||||
}
|
||||
|
||||
int Storage::getCellVertices()
|
||||
int Storage::getCellVertices(ESM::RefId worldspace)
|
||||
{
|
||||
return ESM::Land::LAND_SIZE;
|
||||
return ESM::getLandSize(worldspace);
|
||||
}
|
||||
|
||||
int Storage::getBlendmapScale(float chunkSize)
|
||||
|
@ -113,10 +113,10 @@ namespace ESMTerrain
|
||||
float getHeightAt(const osg::Vec3f& worldPos, ESM::RefId worldspace) override;
|
||||
|
||||
/// Get the transformation factor for mapping cell units to world units.
|
||||
float getCellWorldSize() override;
|
||||
float getCellWorldSize(ESM::RefId worldspace) override;
|
||||
|
||||
/// Get the number of vertices on one side for each cell. Should be (power of two)+1
|
||||
int getCellVertices() override;
|
||||
int getCellVertices(ESM::RefId worldspace) override;
|
||||
|
||||
int getBlendmapScale(float chunkSize) override;
|
||||
|
||||
|
@ -234,21 +234,27 @@ void ESM4::Land::load(ESM4::Reader& reader)
|
||||
if (!missing)
|
||||
mDataTypes |= LAND_VTEX;
|
||||
|
||||
mMinHeight = -200000.f;
|
||||
mMaxHeight = 200000.f;
|
||||
mMinHeight = std::numeric_limits<float>::max();
|
||||
mMaxHeight = std::numeric_limits<float>::lowest();
|
||||
|
||||
float row_offset = mHeightMap.heightOffset;
|
||||
for (int y = 0; y < VERTS_PER_SIDE; y++)
|
||||
{
|
||||
row_offset += mHeightMap.gradientData[y * VERTS_PER_SIDE];
|
||||
|
||||
mHeights[y * VERTS_PER_SIDE] = row_offset * HEIGHT_SCALE;
|
||||
const float heightY = row_offset * HEIGHT_SCALE;
|
||||
mHeights[y * VERTS_PER_SIDE] = heightY;
|
||||
mMinHeight = std::min(mMinHeight, heightY);
|
||||
mMaxHeight = std::max(mMaxHeight, heightY);
|
||||
|
||||
float colOffset = row_offset;
|
||||
for (int x = 1; x < VERTS_PER_SIDE; x++)
|
||||
{
|
||||
colOffset += mHeightMap.gradientData[y * VERTS_PER_SIDE + x];
|
||||
mHeights[x + y * VERTS_PER_SIDE] = colOffset * HEIGHT_SCALE;
|
||||
const float heightX = colOffset * HEIGHT_SCALE;
|
||||
mMinHeight = std::min(mMinHeight, heightX);
|
||||
mMaxHeight = std::max(mMaxHeight, heightX);
|
||||
mHeights[x + y * VERTS_PER_SIDE] = heightX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,10 +27,10 @@
|
||||
#include "loadwrld.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
//#include <iostream> // FIXME: debug only
|
||||
// #include <iostream> // FIXME: debug only
|
||||
|
||||
#include "reader.hpp"
|
||||
//#include "writer.hpp"
|
||||
// #include "writer.hpp"
|
||||
|
||||
void ESM4::World::load(ESM4::Reader& reader)
|
||||
{
|
||||
|
@ -250,7 +250,7 @@ namespace Terrain
|
||||
if (chunkSize <= 1.f)
|
||||
geometry->setLightListCallback(new SceneUtil::LightListCallback);
|
||||
|
||||
unsigned int numVerts = (mStorage->getCellVertices() - 1) * chunkSize / (1 << lod) + 1;
|
||||
unsigned int numVerts = (mStorage->getCellVertices(mWorldspace) - 1) * chunkSize / (1 << lod) + 1;
|
||||
|
||||
geometry->addPrimitiveSet(mBufferCache.getIndexBuffer(numVerts, lodFlags));
|
||||
|
||||
@ -300,7 +300,7 @@ namespace Terrain
|
||||
}
|
||||
}
|
||||
|
||||
geometry->setupWaterBoundingBox(-1, chunkSize * mStorage->getCellWorldSize() / numVerts);
|
||||
geometry->setupWaterBoundingBox(-1, chunkSize * mStorage->getCellWorldSize(mWorldspace) / numVerts);
|
||||
|
||||
if (!templateGeometry && compile && mSceneManager->getIncrementalCompileOperation())
|
||||
{
|
||||
|
@ -145,7 +145,7 @@ namespace Terrain
|
||||
addChildren(mRootNode);
|
||||
|
||||
mRootNode->initNeighbours();
|
||||
float cellWorldSize = mStorage->getCellWorldSize();
|
||||
float cellWorldSize = mStorage->getCellWorldSize(mWorldspace);
|
||||
mRootNode->setInitialBound(
|
||||
osg::BoundingSphere(osg::BoundingBox(osg::Vec3(mMinX * cellWorldSize, mMinY * cellWorldSize, 0),
|
||||
osg::Vec3(mMaxX * cellWorldSize, mMaxY * cellWorldSize, 0))));
|
||||
@ -218,7 +218,7 @@ namespace Terrain
|
||||
// height data here.
|
||||
constexpr float minZ = -std::numeric_limits<float>::max();
|
||||
constexpr float maxZ = std::numeric_limits<float>::max();
|
||||
float cellWorldSize = mStorage->getCellWorldSize();
|
||||
float cellWorldSize = mStorage->getCellWorldSize(mWorldspace);
|
||||
osg::BoundingBox boundingBox(
|
||||
osg::Vec3f((center.x() - halfSize) * cellWorldSize, (center.y() - halfSize) * cellWorldSize, minZ),
|
||||
osg::Vec3f((center.x() + halfSize) * cellWorldSize, (center.y() + halfSize) * cellWorldSize, maxZ));
|
||||
@ -475,7 +475,7 @@ namespace Terrain
|
||||
mRootNode->traverseNodes(vd, viewPoint, &lodCallback);
|
||||
}
|
||||
|
||||
const float cellWorldSize = mStorage->getCellWorldSize();
|
||||
const float cellWorldSize = ESM::getLandSize(mWorldspace);
|
||||
|
||||
for (unsigned int i = 0; i < vd->getNumEntries(); ++i)
|
||||
{
|
||||
@ -486,7 +486,7 @@ namespace Terrain
|
||||
|
||||
if (mHeightCullCallback && isCullVisitor)
|
||||
updateWaterCullingView(mHeightCullCallback, vd, static_cast<osgUtil::CullVisitor*>(&nv),
|
||||
mStorage->getCellWorldSize(), !isGridEmpty());
|
||||
mStorage->getCellWorldSize(mWorldspace), !isGridEmpty());
|
||||
|
||||
vd->resetChanged();
|
||||
|
||||
@ -534,7 +534,7 @@ namespace Terrain
|
||||
std::atomic<bool>& abort, Loading::Reporter& reporter)
|
||||
{
|
||||
ensureQuadTreeBuilt();
|
||||
const float cellWorldSize = mStorage->getCellWorldSize();
|
||||
const float cellWorldSize = mStorage->getCellWorldSize(mWorldspace);
|
||||
|
||||
ViewData* vd = static_cast<ViewData*>(view);
|
||||
vd->setViewPoint(viewPoint);
|
||||
|
@ -84,10 +84,10 @@ namespace Terrain
|
||||
virtual float getHeightAt(const osg::Vec3f& worldPos, ESM::RefId worldspace) = 0;
|
||||
|
||||
/// Get the transformation factor for mapping cell units to world units.
|
||||
virtual float getCellWorldSize() = 0;
|
||||
virtual float getCellWorldSize(ESM::RefId worldspace) = 0;
|
||||
|
||||
/// Get the number of vertices on one side for each cell. Should be (power of two)+1
|
||||
virtual int getCellVertices() = 0;
|
||||
virtual int getCellVertices(ESM::RefId worldspace) = 0;
|
||||
|
||||
virtual int getBlendmapScale(float chunkSize) = 0;
|
||||
};
|
||||
|
@ -74,7 +74,7 @@ namespace Terrain
|
||||
if (!node)
|
||||
return nullptr;
|
||||
|
||||
const float cellWorldSize = mStorage->getCellWorldSize();
|
||||
const float cellWorldSize = mStorage->getCellWorldSize(mWorldspace);
|
||||
osg::ref_ptr<SceneUtil::PositionAttitudeTransform> pat = new SceneUtil::PositionAttitudeTransform;
|
||||
pat->setPosition(osg::Vec3f(chunkCenter.x() * cellWorldSize, chunkCenter.y() * cellWorldSize, 0.f));
|
||||
pat->addChild(node);
|
||||
|
Loading…
x
Reference in New Issue
Block a user