mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 15:15:37 +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
|
class HeightField
|
||||||
{
|
{
|
||||||
public:
|
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(
|
mShape = new btHeightfieldTerrainShape(
|
||||||
sqrtVerts, sqrtVerts, heights, 1,
|
sqrtVerts, sqrtVerts, heights, 1,
|
||||||
minh, maxh, 2,
|
minH, maxH, 2,
|
||||||
PHY_FLOAT, false
|
PHY_FLOAT, false
|
||||||
);
|
);
|
||||||
mShape->setUseDiamondSubdivision(true);
|
mShape->setUseDiamondSubdivision(true);
|
||||||
|
@ -539,7 +529,7 @@ namespace MWPhysics
|
||||||
btTransform transform(btQuaternion::getIdentity(),
|
btTransform transform(btQuaternion::getIdentity(),
|
||||||
btVector3((x+0.5f) * triSize * (sqrtVerts-1),
|
btVector3((x+0.5f) * triSize * (sqrtVerts-1),
|
||||||
(y+0.5f) * triSize * (sqrtVerts-1),
|
(y+0.5f) * triSize * (sqrtVerts-1),
|
||||||
(maxh+minh)*0.5f));
|
(maxH+minH)*0.5f));
|
||||||
|
|
||||||
mCollisionObject = new btCollisionObject;
|
mCollisionObject = new btCollisionObject;
|
||||||
mCollisionObject->setCollisionShape(mShape);
|
mCollisionObject->setCollisionShape(mShape);
|
||||||
|
@ -1143,9 +1133,9 @@ namespace MWPhysics
|
||||||
return MovementSolver::traceDown(ptr, position, found->second, mCollisionWorld, maxHeight);
|
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;
|
mHeightFields[std::make_pair(x,y)] = heightfield;
|
||||||
|
|
||||||
mCollisionWorld->addCollisionObject(heightfield->getCollisionObject(), CollisionType_HeightMap,
|
mCollisionWorld->addCollisionObject(heightfield->getCollisionObject(), CollisionType_HeightMap,
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace MWPhysics
|
||||||
void updatePosition (const MWWorld::Ptr& ptr);
|
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);
|
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;
|
const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : 0;
|
||||||
if (data)
|
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
|
else
|
||||||
{
|
{
|
||||||
static std::vector<float> defaultHeight;
|
static std::vector<float> defaultHeight;
|
||||||
defaultHeight.resize(verts*verts, ESM::Land::DEFAULT_HEIGHT);
|
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")) {
|
if (reader.isNextSub("VHGT")) {
|
||||||
VHGT vhgt;
|
VHGT vhgt;
|
||||||
if (condLoad(reader, flags, target->mDataLoaded, DATA_VHGT, &vhgt, sizeof(vhgt))) {
|
if (condLoad(reader, flags, target->mDataLoaded, DATA_VHGT, &vhgt, sizeof(vhgt))) {
|
||||||
|
target->mMinHeight = FLT_MAX;
|
||||||
|
target->mMaxHeight = -FLT_MAX;
|
||||||
float rowOffset = vhgt.mHeightOffset;
|
float rowOffset = vhgt.mHeightOffset;
|
||||||
for (int y = 0; y < LAND_SIZE; y++) {
|
for (int y = 0; y < LAND_SIZE; y++) {
|
||||||
rowOffset += vhgt.mHeightData[y * LAND_SIZE];
|
rowOffset += vhgt.mHeightData[y * LAND_SIZE];
|
||||||
|
|
||||||
target->mHeights[y * LAND_SIZE] = rowOffset * HEIGHT_SCALE;
|
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;
|
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];
|
colOffset += vhgt.mHeightData[y * LAND_SIZE + x];
|
||||||
target->mHeights[x + y * LAND_SIZE] = colOffset * HEIGHT_SCALE;
|
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;
|
target->mUnk1 = vhgt.mUnk1;
|
||||||
|
|
|
@ -87,6 +87,8 @@ struct Land
|
||||||
float mHeightOffset;
|
float mHeightOffset;
|
||||||
// Height in world space for each vertex
|
// Height in world space for each vertex
|
||||||
float mHeights[LAND_NUM_VERTS];
|
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.
|
// 24-bit normals, these aren't always correct though. Edge and corner normals may be garbage.
|
||||||
VNML mNormals[LAND_NUM_VERTS * 3];
|
VNML mNormals[LAND_NUM_VERTS * 3];
|
||||||
|
|
|
@ -65,8 +65,6 @@ namespace ESMTerrain
|
||||||
{
|
{
|
||||||
assert (size <= 1 && "Storage::getMinMaxHeights, chunk size should be <= 1 cell");
|
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);
|
osg::Vec2f origin = center - osg::Vec2f(size/2.f, size/2.f);
|
||||||
|
|
||||||
int cellX = static_cast<int>(std::floor(origin.x()));
|
int cellX = static_cast<int>(std::floor(origin.x()));
|
||||||
|
|
Loading…
Reference in a new issue