1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-30 09:45:36 +00:00

World::indexToPosition is modified to be less error prone.

This commit is contained in:
florent.teppe 2023-05-09 23:44:57 +02:00
parent 1fdecaaa34
commit f261f59809
6 changed files with 36 additions and 31 deletions

View file

@ -55,6 +55,7 @@ namespace ESM
struct ItemLevList;
struct TimeStamp;
class RefId;
struct ExteriorCellIndex;
}
namespace MWPhysics
@ -312,8 +313,7 @@ namespace MWBase
/// relative to \a referenceObject (but the object may be placed somewhere else if the wanted location is
/// obstructed).
virtual void indexToPosition(
int cellX, int cellY, float& x, float& y, bool centre = false, bool esm4Exterior = false) const = 0;
virtual osg::Vec2 indexToPosition(const ESM::ExteriorCellIndex& cellIndex, bool centre = false) const = 0;
///< Convert cell numbers to position.
virtual void queueMovement(const MWWorld::Ptr& ptr, const osg::Vec3f& velocity) = 0;

View file

@ -123,7 +123,10 @@ namespace MWScript
MWBase::World* world = MWBase::Environment::get().getWorld();
const MWWorld::Ptr playerPtr = world->getPlayerPtr();
world->indexToPosition(x, y, pos.pos[0], pos.pos[1], true);
osg::Vec2 posFromIndex
= world->indexToPosition(ESM::ExteriorCellIndex(x, y, ESM::Cell::sDefaultWorldspaceId), true);
pos.pos[0] = posFromIndex.x();
pos.pos[1] = posFromIndex.y();
pos.pos[2] = 0;
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;

View file

@ -563,13 +563,12 @@ void MWState::StateManager::loadGame(const Character* character, const std::file
{
// Cell no longer exists (i.e. changed game files), choose a default cell
Log(Debug::Warning) << "Warning: Player character's cell no longer exists, changing to the default cell";
MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior(
ESM::ExteriorCellIndex(0, 0, ESM::Cell::sDefaultWorldspaceId));
float x, y;
MWBase::Environment::get().getWorld()->indexToPosition(0, 0, x, y, false);
ESM::ExteriorCellIndex cellIndex(0, 0, ESM::Cell::sDefaultWorldspaceId);
MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex);
osg::Vec2 posFromIndex = MWBase::Environment::get().getWorld()->indexToPosition(cellIndex, false);
ESM::Position pos;
pos.pos[0] = x;
pos.pos[1] = y;
pos.pos[0] = posFromIndex.x();
pos.pos[1] = posFromIndex.y();
pos.pos[2] = 0; // should be adjusted automatically (adjustPlayerPos=true)
pos.rot[0] = 0;
pos.rot[1] = 0;

View file

@ -511,12 +511,15 @@ namespace MWWorld
osg::Vec2i Scene::getNewGridCenter(const osg::Vec3f& pos, const osg::Vec2i* currentGridCenter) const
{
bool isEsm4Ext = mCurrentCell && ESM::isEsm4Ext(mCurrentCell->getCell()->getWorldSpace());
ESM::RefId worldspace
= mCurrentCell ? mCurrentCell->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId;
bool isEsm4Ext = ESM::isEsm4Ext(worldspace);
if (currentGridCenter)
{
float centerX, centerY;
mWorld.indexToPosition(currentGridCenter->x(), currentGridCenter->y(), centerX, centerY, true, isEsm4Ext);
float distance = std::max(std::abs(centerX - pos.x()), std::abs(centerY - pos.y()));
osg::Vec2 center = mWorld.indexToPosition(
ESM::ExteriorCellIndex(currentGridCenter->x(), currentGridCenter->y(), worldspace), true);
float distance = std::max(std::abs(center.x() - pos.x()), std::abs(center.y() - pos.y()));
float cellSize = ESM::getCellSize(isEsm4Ext);
const float maxDistance = cellSize / 2 + mCellLoadingThreshold; // 1/2 cell size + threshold
if (distance <= maxDistance)
@ -1163,11 +1166,10 @@ namespace MWWorld
int cellX, cellY;
cellX = mCurrentGridCenter.x();
cellY = mCurrentGridCenter.y();
float centerX, centerY;
mWorld.indexToPosition(cellX, cellY, centerX, centerY, true);
ESM::RefId extWorldspace = mWorld.getCurrentWorldspace();
osg::Vec2 center = mWorld.indexToPosition(ESM::ExteriorCellIndex(cellX, cellY, extWorldspace), true);
bool esm4Ext = ESM::isEsm4Ext(extWorldspace);
float cellSize = ESM::getCellSize(esm4Ext);
@ -1179,14 +1181,14 @@ namespace MWWorld
&& dx != -halfGridSizePlusOne)
continue; // only care about the outer (not yet loaded) part of the grid
float thisCellCenterX, thisCellCenterY;
mWorld.indexToPosition(cellX + dx, cellY + dy, thisCellCenterX, thisCellCenterY, true, esm4Ext);
osg::Vec2 thisCellCenter
= mWorld.indexToPosition(ESM::ExteriorCellIndex(cellX + dx, cellY + dy, extWorldspace), true);
float dist
= std::max(std::abs(thisCellCenterX - playerPos.x()), std::abs(thisCellCenterY - playerPos.y()));
float dist = std::max(
std::abs(thisCellCenter.x() - playerPos.x()), std::abs(thisCellCenter.y() - playerPos.y()));
dist = std::min(dist,
std::max(
std::abs(thisCellCenterX - predictedPos.x()), std::abs(thisCellCenterY - predictedPos.y())));
std::max(std::abs(thisCellCenter.x() - predictedPos.x()),
std::abs(thisCellCenter.y() - predictedPos.y())));
float loadDist = cellSize / 2 + cellSize - mCellLoadingThreshold + mPreloadDistance;
if (dist < loadDist)

View file

@ -1496,18 +1496,19 @@ namespace MWWorld
return placed;
}
void World::indexToPosition(int cellX, int cellY, float& x, float& y, bool centre, bool esm4Ext) const
osg::Vec2 World::indexToPosition(const ESM::ExteriorCellIndex& cellIndex, bool centre) const
{
const int cellSize = ESM::getCellSize(esm4Ext);
const int cellSize = ESM::getCellSize(ESM::isEsm4Ext(cellIndex.mWorldspace));
x = static_cast<float>(cellSize * cellX);
y = static_cast<float>(cellSize * cellY);
float x = static_cast<float>(cellSize * cellIndex.mX);
float y = static_cast<float>(cellSize * cellIndex.mY);
if (centre)
{
x += cellSize / 2;
y += cellSize / 2;
}
return osg::Vec2(x, y);
}
void World::queueMovement(const Ptr& ptr, const osg::Vec3f& velocity)
@ -2760,8 +2761,9 @@ namespace MWWorld
{
int x = ext->getGridX();
int y = ext->getGridY();
bool esm4Ext = ESM::isEsm4Ext(ext->getWorldSpace());
indexToPosition(x, y, pos.pos[0], pos.pos[1], true, esm4Ext);
osg::Vec2 posFromIndex = indexToPosition(ESM::ExteriorCellIndex(x, y, ext->getWorldSpace()), true);
pos.pos[0] = posFromIndex.x();
pos.pos[1] = posFromIndex.y();
// Note: Z pos will be adjusted by adjustPosition later
pos.pos[2] = 0;

View file

@ -400,8 +400,7 @@ namespace MWWorld
float getMaxActivationDistance() const override;
void indexToPosition(
int cellX, int cellY, float& x, float& y, bool centre = false, bool esm4Exterior = false) const override;
osg::Vec2 indexToPosition(const ESM::ExteriorCellIndex& cellIndex, bool centre = false) const override;
///< Convert cell numbers to position.
void queueMovement(const Ptr& ptr, const osg::Vec3f& velocity) override;