mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
added CellCoordinates and CellSelection classes
This commit is contained in:
parent
324b2743d4
commit
67965ec10c
@ -24,7 +24,7 @@ opencs_units (model/world
|
|||||||
|
|
||||||
opencs_units_noqt (model/world
|
opencs_units_noqt (model/world
|
||||||
universalid record commands columnbase scriptcontext cell refidcollection
|
universalid record commands columnbase scriptcontext cell refidcollection
|
||||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata
|
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/world
|
opencs_hdrs_noqt (model/world
|
||||||
|
60
apps/opencs/model/world/cellcoordinates.cpp
Normal file
60
apps/opencs/model/world/cellcoordinates.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
|
||||||
|
#include "cellcoordinates.hpp"
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates::CellCoordinates() : mX (0), mY (0) {}
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates::CellCoordinates (int x, int y) : mX (x), mY (y) {}
|
||||||
|
|
||||||
|
int CSMWorld::CellCoordinates::getX() const
|
||||||
|
{
|
||||||
|
return mX;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSMWorld::CellCoordinates::getY() const
|
||||||
|
{
|
||||||
|
return mY;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates CSMWorld::CellCoordinates::move (int x, int y) const
|
||||||
|
{
|
||||||
|
return CellCoordinates (mX + x, mY + y);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSMWorld::CellCoordinates::getId (const std::string& worldspace) const
|
||||||
|
{
|
||||||
|
// we ignore the worldspace for now, since there is only one (will change in 1.1)
|
||||||
|
std::ostringstream stream;
|
||||||
|
|
||||||
|
stream << "#" << mX << " " << mY;
|
||||||
|
|
||||||
|
return stream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right)
|
||||||
|
{
|
||||||
|
return left.getX()==right.getX() && left.getY()==right.getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::operator!= (const CellCoordinates& left, const CellCoordinates& right)
|
||||||
|
{
|
||||||
|
return !(left==right);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::operator< (const CellCoordinates& left, const CellCoordinates& right)
|
||||||
|
{
|
||||||
|
if (left.getX()<right.getX())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (left.getX()>right.getX())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return left.getY()<right.getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& CSMWorld::operator<< (std::ostream& stream, const CellCoordinates& coordiantes)
|
||||||
|
{
|
||||||
|
return stream << coordiantes.getX() << ", " << coordiantes.getY();
|
||||||
|
}
|
42
apps/opencs/model/world/cellcoordinates.hpp
Normal file
42
apps/opencs/model/world/cellcoordinates.hpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef CSM_WOLRD_CELLCOORDINATES_H
|
||||||
|
#define CSM_WOLRD_CELLCOORDINATES_H
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class CellCoordinates
|
||||||
|
{
|
||||||
|
int mX;
|
||||||
|
int mY;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CellCoordinates();
|
||||||
|
|
||||||
|
CellCoordinates (int x, int y);
|
||||||
|
|
||||||
|
int getX() const;
|
||||||
|
|
||||||
|
int getY() const;
|
||||||
|
|
||||||
|
CellCoordinates move (int x, int y) const;
|
||||||
|
///< Return a copy of *this, moved by the given offset.
|
||||||
|
|
||||||
|
std::string getId (const std::string& worldspace) const;
|
||||||
|
///< Return the ID for the cell at these coordinates.
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator== (const CellCoordinates& left, const CellCoordinates& right);
|
||||||
|
bool operator!= (const CellCoordinates& left, const CellCoordinates& right);
|
||||||
|
bool operator< (const CellCoordinates& left, const CellCoordinates& right);
|
||||||
|
|
||||||
|
std::ostream& operator<< (std::ostream& stream, const CellCoordinates& coordiantes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE (CSMWorld::CellCoordinates)
|
||||||
|
|
||||||
|
#endif
|
83
apps/opencs/model/world/cellselection.cpp
Normal file
83
apps/opencs/model/world/cellselection.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
#include "cellselection.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::begin() const
|
||||||
|
{
|
||||||
|
return mCells.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::end() const
|
||||||
|
{
|
||||||
|
return mCells.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::CellSelection::add (const CellCoordinates& coordinates)
|
||||||
|
{
|
||||||
|
return mCells.insert (coordinates).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CellSelection::remove (const CellCoordinates& coordinates)
|
||||||
|
{
|
||||||
|
mCells.erase (coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::CellSelection::has (const CellCoordinates& coordinates) const
|
||||||
|
{
|
||||||
|
return mCells.find (coordinates)!=end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSMWorld::CellSelection::getSize() const
|
||||||
|
{
|
||||||
|
return mCells.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates CSMWorld::CellSelection::getCentre() const
|
||||||
|
{
|
||||||
|
if (mCells.empty())
|
||||||
|
throw std::logic_error ("call of getCentre on empty cell selection");
|
||||||
|
|
||||||
|
double x = 0;
|
||||||
|
double y = 0;
|
||||||
|
|
||||||
|
for (Iterator iter = begin(); iter!=end(); ++iter)
|
||||||
|
{
|
||||||
|
x += iter->getX();
|
||||||
|
y += iter->getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
x /= mCells.size();
|
||||||
|
y /= mCells.size();
|
||||||
|
|
||||||
|
Iterator closest = begin();
|
||||||
|
double distance = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
|
for (Iterator iter (begin()); iter!=end(); ++iter)
|
||||||
|
{
|
||||||
|
double deltaX = x - iter->getX();
|
||||||
|
double deltaY = y - iter->getY();
|
||||||
|
|
||||||
|
double delta = std::sqrt (deltaX * deltaX + deltaY * deltaY);
|
||||||
|
|
||||||
|
if (delta<distance)
|
||||||
|
{
|
||||||
|
distance = delta;
|
||||||
|
closest = iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *closest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CellSelection::move (int x, int y)
|
||||||
|
{
|
||||||
|
Container moved;
|
||||||
|
|
||||||
|
for (Iterator iter = begin(); iter!=end(); ++iter)
|
||||||
|
moved.insert (iter->move (x, y));
|
||||||
|
|
||||||
|
mCells.swap (moved);
|
||||||
|
}
|
57
apps/opencs/model/world/cellselection.hpp
Normal file
57
apps/opencs/model/world/cellselection.hpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef CSM_WOLRD_CELLSELECTION_H
|
||||||
|
#define CSM_WOLRD_CELLSELECTION_H
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
|
#include "cellcoordinates.hpp"
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
/// \brief Selection of cells in a paged worldspace
|
||||||
|
///
|
||||||
|
/// \note The CellSelection does not specify the worldspace it applies to.
|
||||||
|
class CellSelection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::set<CellCoordinates> Container;
|
||||||
|
typedef Container::const_iterator Iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Container mCells;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Iterator begin() const;
|
||||||
|
|
||||||
|
Iterator end() const;
|
||||||
|
|
||||||
|
bool add (const CellCoordinates& coordinates);
|
||||||
|
///< Ignored if the cell specified by \a coordinates is already part of the selection.
|
||||||
|
///
|
||||||
|
/// \return Was a cell added to the collection?
|
||||||
|
|
||||||
|
void remove (const CellCoordinates& coordinates);
|
||||||
|
///< ignored if the cell specified by \a coordinates is not part of the selection.
|
||||||
|
|
||||||
|
bool has (const CellCoordinates& coordinates) const;
|
||||||
|
///< \return Is the cell specified by \a coordinates part of the selection?
|
||||||
|
|
||||||
|
int getSize() const;
|
||||||
|
///< Return number of cells.
|
||||||
|
|
||||||
|
CellCoordinates getCentre() const;
|
||||||
|
///< Return the selected cell that is closest to the geometric centre of the selection.
|
||||||
|
///
|
||||||
|
/// \attention This function must not be called on selections that are empty.
|
||||||
|
|
||||||
|
void move (int x, int y);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE (CSMWorld::CellSelection)
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user