mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-29 21:45:33 +00:00
Store the min/max height in LandData
This commit is contained in:
parent
051c17a184
commit
0fc465da59
6 changed files with 21 additions and 20 deletions
|
@ -516,21 +516,11 @@ namespace MWPhysics
|
|||
class HeightField
|
||||
{
|
||||
public:
|
||||
HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, const osg::Object* holdObject)
|
||||
HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject)
|
||||
{
|
||||
// find the minimum and maximum heights (needed for bullet)
|
||||
float minh = heights[0];
|
||||
float maxh = heights[0];
|
||||
for(int i = 1;i < sqrtVerts*sqrtVerts;++i)
|
||||
{
|
||||
float h = heights[i];
|
||||
if(h > maxh) maxh = h;
|
||||
if(h < minh) minh = h;
|
||||
}
|
||||
|
||||
mShape = new btHeightfieldTerrainShape(
|
||||
sqrtVerts, sqrtVerts, heights, 1,
|
||||
minh, maxh, 2,
|
||||
minH, maxH, 2,
|
||||
PHY_FLOAT, false
|
||||
);
|
||||
mShape->setUseDiamondSubdivision(true);
|
||||
|
@ -539,7 +529,7 @@ namespace MWPhysics
|
|||
btTransform transform(btQuaternion::getIdentity(),
|
||||
btVector3((x+0.5f) * triSize * (sqrtVerts-1),
|
||||
(y+0.5f) * triSize * (sqrtVerts-1),
|
||||
(maxh+minh)*0.5f));
|
||||
(maxH+minH)*0.5f));
|
||||
|
||||
mCollisionObject = new btCollisionObject;
|
||||
mCollisionObject->setCollisionShape(mShape);
|
||||
|
@ -1143,9 +1133,9 @@ namespace MWPhysics
|
|||
return MovementSolver::traceDown(ptr, position, found->second, mCollisionWorld, maxHeight);
|
||||
}
|
||||
|
||||
void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, const osg::Object* holdObject)
|
||||
void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject)
|
||||
{
|
||||
HeightField *heightfield = new HeightField(heights, x, y, triSize, sqrtVerts, holdObject);
|
||||
HeightField *heightfield = new HeightField(heights, x, y, triSize, sqrtVerts, minH, maxH, holdObject);
|
||||
mHeightFields[std::make_pair(x,y)] = heightfield;
|
||||
|
||||
mCollisionWorld->addCollisionObject(heightfield->getCollisionObject(), CollisionType_HeightMap,
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace MWPhysics
|
|||
void updatePosition (const MWWorld::Ptr& ptr);
|
||||
|
||||
|
||||
void addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, const osg::Object* holdObject);
|
||||
void addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject);
|
||||
|
||||
void removeHeightField (int x, int y);
|
||||
|
||||
|
|
|
@ -278,13 +278,13 @@ namespace MWWorld
|
|||
const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : 0;
|
||||
if (data)
|
||||
{
|
||||
mPhysics->addHeightField (data->mHeights, cellX, cell->getCell()->getGridY(), worldsize / (verts-1), verts, land.get());
|
||||
mPhysics->addHeightField (data->mHeights, cellX, cell->getCell()->getGridY(), worldsize / (verts-1), verts, data->mMinHeight, data->mMaxHeight, land.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
static std::vector<float> defaultHeight;
|
||||
defaultHeight.resize(verts*verts, ESM::Land::DEFAULT_HEIGHT);
|
||||
mPhysics->addHeightField (&defaultHeight[0], cell->getCell()->getGridX(), cell->getCell()->getGridY(), worldsize / (verts-1), verts, land.get());
|
||||
mPhysics->addHeightField (&defaultHeight[0], cell->getCell()->getGridX(), cell->getCell()->getGridY(), worldsize / (verts-1), verts, ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -203,16 +203,27 @@ namespace ESM
|
|||
if (reader.isNextSub("VHGT")) {
|
||||
VHGT vhgt;
|
||||
if (condLoad(reader, flags, target->mDataLoaded, DATA_VHGT, &vhgt, sizeof(vhgt))) {
|
||||
target->mMinHeight = FLT_MAX;
|
||||
target->mMaxHeight = -FLT_MAX;
|
||||
float rowOffset = vhgt.mHeightOffset;
|
||||
for (int y = 0; y < LAND_SIZE; y++) {
|
||||
rowOffset += vhgt.mHeightData[y * LAND_SIZE];
|
||||
|
||||
target->mHeights[y * LAND_SIZE] = rowOffset * HEIGHT_SCALE;
|
||||
if (rowOffset * HEIGHT_SCALE > target->mMaxHeight)
|
||||
target->mMaxHeight = rowOffset * HEIGHT_SCALE;
|
||||
if (rowOffset * HEIGHT_SCALE < target->mMinHeight)
|
||||
target->mMinHeight = rowOffset * HEIGHT_SCALE;
|
||||
|
||||
float colOffset = rowOffset;
|
||||
for (int x = 1; x < LAND_SIZE; x++) {
|
||||
colOffset += vhgt.mHeightData[y * LAND_SIZE + x];
|
||||
target->mHeights[x + y * LAND_SIZE] = colOffset * HEIGHT_SCALE;
|
||||
|
||||
if (colOffset * HEIGHT_SCALE > target->mMaxHeight)
|
||||
target->mMaxHeight = colOffset * HEIGHT_SCALE;
|
||||
if (colOffset * HEIGHT_SCALE < target->mMinHeight)
|
||||
target->mMinHeight = colOffset * HEIGHT_SCALE;
|
||||
}
|
||||
}
|
||||
target->mUnk1 = vhgt.mUnk1;
|
||||
|
|
|
@ -87,6 +87,8 @@ struct Land
|
|||
float mHeightOffset;
|
||||
// Height in world space for each vertex
|
||||
float mHeights[LAND_NUM_VERTS];
|
||||
float mMinHeight;
|
||||
float mMaxHeight;
|
||||
|
||||
// 24-bit normals, these aren't always correct though. Edge and corner normals may be garbage.
|
||||
VNML mNormals[LAND_NUM_VERTS * 3];
|
||||
|
|
|
@ -65,8 +65,6 @@ namespace ESMTerrain
|
|||
{
|
||||
assert (size <= 1 && "Storage::getMinMaxHeights, chunk size should be <= 1 cell");
|
||||
|
||||
/// \todo investigate if min/max heights should be stored at load time in ESM::Land instead
|
||||
|
||||
osg::Vec2f origin = center - osg::Vec2f(size/2.f, size/2.f);
|
||||
|
||||
int cellX = static_cast<int>(std::floor(origin.x()));
|
||||
|
|
Loading…
Reference in a new issue