105 lines
2.8 KiB
C++
105 lines
2.8 KiB
C++
#ifndef SCALER_H
|
|
#define SCALER_H
|
|
|
|
#include <Indoor/geo/Point3.h>
|
|
|
|
#include <QRectF>
|
|
|
|
struct Rect {
|
|
float x0;
|
|
float y0;
|
|
float x1;
|
|
float y1;
|
|
};
|
|
|
|
/**
|
|
* - scale between map- and screen-space.
|
|
* - inverts y-axis (for openGL)
|
|
*/
|
|
class Scaler {
|
|
|
|
private:
|
|
|
|
int w;
|
|
int h;
|
|
float _scale = 50;
|
|
float _snap = 0.1;
|
|
Point3 _offset;
|
|
|
|
public:
|
|
|
|
/** map->screen (no offset) */
|
|
float ms(const float m) const {return m*_scale;}
|
|
/** x map->screen */
|
|
float xms(const float x) const {return w/2+(x+_offset.x)*_scale;}
|
|
/** x map->screen */
|
|
float yms(const float y) const {return h/2-(y-_offset.y)*_scale;}
|
|
|
|
|
|
/** screen->map (no offset) */
|
|
float sm(const float s) const {return (s/_scale);}
|
|
/** x screen->map */
|
|
float xsm(const float x) const {return ((x-w/2)/_scale)-_offset.x;}
|
|
/** y screen->map */
|
|
float ysm(const float y) const {return ((h/2-y)/_scale)+_offset.y;}
|
|
|
|
void setScale(const float s) {_scale = s;}
|
|
float getScale() const {return _scale;}
|
|
|
|
void setOffset(Point3 p) {_offset = p;}
|
|
Point3 getOffset() const {return _offset;}
|
|
void addOffset(int px, int py) {_offset.x += sm(px); _offset.y += sm(py);}
|
|
|
|
float getLODstep() const {
|
|
float step = 0.01;
|
|
if (_scale <= 1000) {step = 0.1;}
|
|
if (_scale <= 500) {step = 0.5;}
|
|
if (_scale <= 100) {step = 1.0;}
|
|
if (_scale <= 50) {step = 5.0;}
|
|
if (_scale <= 10) {step = 10.0;}
|
|
if (_scale <= 1) {step = 100.0;}
|
|
return step;
|
|
}
|
|
|
|
/** get the currently visible map-region given the provided screen-size */
|
|
Rect getMapVisible(const int screenW, const int screenH) const {
|
|
Rect r;
|
|
r.x0 = xsm(0);
|
|
r.x1 = xsm(screenW);
|
|
r.y0 = ysm(screenH);
|
|
r.y1 = ysm(0);
|
|
return r;
|
|
}
|
|
|
|
/** get the currently visible map-region given the provided screen-size, SNAPED to the given grid-size */
|
|
Rect getMapVisible(const int screenW, const int screenH, const float mapGridSize) const {
|
|
Rect r = getMapVisible(screenW, screenH);
|
|
r.x0 = snapFloor(r.x0, mapGridSize);
|
|
r.y0 = snapFloor(r.y0, mapGridSize);
|
|
r.x1 = snapCeil(r.x1, mapGridSize);
|
|
r.y1 = snapCeil(r.y1, mapGridSize);
|
|
return r;
|
|
}
|
|
|
|
//Point2 getOffset() const {return _offset.xy();}
|
|
Point2 getCenter() const {return Point2(-_offset.x, _offset.y);}
|
|
|
|
void setScreenSize(const int w, const int h) {this->w = w; this->h = h;}
|
|
|
|
public:
|
|
|
|
static float snap(const float v, const float grid) { return std::round(v/grid)*grid; }
|
|
static Point2 snap(const Point2 p, const float grid) { return Point2(snap(p.x, grid), snap(p.y, grid)); }
|
|
static Point3 snap(const Point3 p, const float grid) { return Point3(snap(p.x, grid), snap(p.y, grid), snap(p.z, grid)); }
|
|
|
|
static float snapCeil(const float v, const float grid) { return std::ceil(v/grid) * grid; }
|
|
static float snapFloor(const float v, const float grid) { return std::floor(v/grid) * grid; }
|
|
|
|
//float snap(const float v) const { return v; }
|
|
|
|
};
|
|
|
|
#endif // SCALER_H
|
|
|
|
|