Use more explicit vector math via method overloads

This commit is contained in:
Jonas Kulla 2015-02-10 16:42:32 +01:00
parent a4b1be1da5
commit 87462fd7b0
11 changed files with 148 additions and 122 deletions

View File

@ -79,19 +79,68 @@ struct Vec2i
: x(x), y(y) : x(x), y(y)
{} {}
explicit Vec2i(int xy)
: x(xy), y(xy)
{}
bool operator==(const Vec2i &other) const bool operator==(const Vec2i &other) const
{ {
return x == other.x && y == other.y; return x == other.x && y == other.y;
} }
Vec2i &operator+=(const Vec2i &other) Vec2i &operator+=(const Vec2i &value)
{ {
x += other.x; x += value.x;
y += other.y; y += value.y;
return *this; return *this;
} }
Vec2i &operator-=(const Vec2i &value)
{
x -= value.x;
y -= value.y;
return *this;
}
Vec2i operator+(const Vec2i &value) const
{
return Vec2i(x + value.x, y + value.y);
}
Vec2i operator-(const Vec2i &value) const
{
return Vec2i(x - value.x, y - value.y);
}
template<typename T>
Vec2i operator*(T value) const
{
return Vec2i(x * value, y * value);
}
template<typename T>
Vec2i operator/(T value) const
{
return Vec2i(x / value, y / value);
}
Vec2i operator%(int value) const
{
return Vec2i(x % value, y % value);
}
Vec2i operator-() const
{
return Vec2i(-x, -y);
}
Vec2i operator!() const
{
return Vec2i(!x, !y);
}
operator Vec2() const operator Vec2() const
{ {
return Vec2(x, y); return Vec2(x, y);
@ -113,6 +162,14 @@ struct IntRect : SDL_Rect
this->h = h; this->h = h;
} }
IntRect(const Vec2i &pos, const Vec2i &size)
{
x = pos.x;
y = pos.y;
w = size.x;
h = size.y;
}
bool operator==(const IntRect &other) const bool operator==(const IntRect &other) const
{ {
return (x == other.x && y == other.y && return (x == other.x && y == other.y &&
@ -129,10 +186,16 @@ struct IntRect : SDL_Rect
return Vec2i(w, h); return Vec2i(w, h);
} }
operator SDL_Rect() const void setPos(const Vec2i &value)
{ {
SDL_Rect r = { x, y, w, h }; x = value.x;
return r; y = value.y;
}
void setSize(const Vec2i &value)
{
w = value.x;
h = value.y;
} }
bool encloses(const IntRect &o) const bool encloses(const IntRect &o) const
@ -176,35 +239,10 @@ struct FloatRect
Vec2 topRight() const { return Vec2(x+w, y); } Vec2 topRight() const { return Vec2(x+w, y); }
Vec2 bottomRight() const { return Vec2(x+w, y+h); } Vec2 bottomRight() const { return Vec2(x+w, y+h); }
void shrinkHalf()
{
x += 0.5;
y += 0.5;
w -= 1.0;
h -= 1.0;
}
FloatRect vFlipped() const
{
return FloatRect(x, y+h, w, -h);
}
FloatRect hFlipped() const FloatRect hFlipped() const
{ {
return FloatRect(x+w, y, -w, h); return FloatRect(x+w, y, -w, h);
} }
Vec2 corner(int i) const
{
switch (i)
{
case 0 : return topLeft();
case 1 : return topRight();
case 2 : return bottomRight();
case 3 : return bottomLeft();
default : return Vec2();
}
}
}; };
/* Value between 0 and 255 with internal /* Value between 0 and 255 with internal

View File

@ -90,8 +90,8 @@ struct PlanePrivate
if (gl.npot_repeat) if (gl.npot_repeat)
{ {
FloatRect srcRect; FloatRect srcRect;
srcRect.x = (sceneGeo.xOrigin + ox) / zoomX; srcRect.x = (sceneGeo.orig.x + ox) / zoomX;
srcRect.y = (sceneGeo.yOrigin + oy) / zoomY; srcRect.y = (sceneGeo.orig.y + oy) / zoomY;
srcRect.w = sceneGeo.rect.w / zoomX; srcRect.w = sceneGeo.rect.w / zoomX;
srcRect.h = sceneGeo.rect.h / zoomY; srcRect.h = sceneGeo.rect.h / zoomY;

View File

@ -23,10 +23,7 @@
#include "sharedstate.h" #include "sharedstate.h"
Scene::Scene() Scene::Scene()
{ {}
geometry.xOrigin = geometry.yOrigin = 0;
geometry.rect = IntRect();
}
Scene::~Scene() Scene::~Scene()
{ {

View File

@ -39,8 +39,16 @@ class Scene
public: public:
struct Geometry struct Geometry
{ {
int xOrigin, yOrigin; /* Position and size relative to parent */
IntRect rect; IntRect rect;
/* Origin of contents */
Vec2i orig;
Vec2i offset() const
{
return rect.pos() - orig;
}
}; };
Scene(); Scene();

View File

@ -57,7 +57,7 @@ struct SpritePrivate
NormValue opacity; NormValue opacity;
BlendType blendType; BlendType blendType;
SDL_Rect sceneRect; IntRect sceneRect;
Vec2i sceneOrig; Vec2i sceneOrig;
/* Would this sprite be visible on /* Would this sprite be visible on
@ -183,9 +183,8 @@ struct SpritePrivate
return; return;
} }
SDL_Rect self; IntRect self;
self.x = trans.getPosition().x - (trans.getOrigin().x + sceneOrig.x); self.setPos(trans.getPositionI() - (trans.getOriginI() + sceneOrig));
self.y = trans.getPosition().y - (trans.getOrigin().y + sceneOrig.y);
self.w = bitmap->width(); self.w = bitmap->width();
self.h = bitmap->height(); self.h = bitmap->height();
@ -577,15 +576,10 @@ void Sprite::onGeometryChange(const Scene::Geometry &geo)
{ {
/* Offset at which the sprite will be drawn /* Offset at which the sprite will be drawn
* relative to screen origin */ * relative to screen origin */
int xOffset = geo.rect.x - geo.xOrigin; p->trans.setGlobalOffset(geo.offset());
int yOffset = geo.rect.y - geo.yOrigin;
p->trans.setGlobalOffset(xOffset, yOffset); p->sceneRect.setSize(geo.rect.size());
p->sceneOrig = geo.orig;
p->sceneRect.w = geo.rect.w;
p->sceneRect.h = geo.rect.h;
p->sceneOrig.x = geo.xOrigin;
p->sceneOrig.y = geo.yOrigin;
} }
void Sprite::releaseResources() void Sprite::releaseResources()

View File

@ -442,15 +442,13 @@ struct TilemapPrivate
void updateSceneGeometry(const Scene::Geometry &geo) void updateSceneGeometry(const Scene::Geometry &geo)
{ {
elem.sceneOffset.x = geo.rect.x - geo.xOrigin; elem.sceneOffset = geo.offset();
elem.sceneOffset.y = geo.rect.y - geo.yOrigin;
elem.sceneGeo = geo; elem.sceneGeo = geo;
} }
void updatePosition() void updatePosition()
{ {
dispPos.x = -(offset.x - viewpPos.x * 32) + elem.sceneOffset.x; dispPos = -(offset - viewpPos * 32) + elem.sceneOffset;
dispPos.y = -(offset.y - viewpPos.y * 32) + elem.sceneOffset.y;
} }
void invalidateAtlasSize() void invalidateAtlasSize()

View File

@ -366,11 +366,10 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
void onGeometryChange(const Scene::Geometry &geo) void onGeometryChange(const Scene::Geometry &geo)
{ {
mapViewp.w = (geo.rect.w / 32) + !!(geo.rect.w % 32) + 1; const Vec2i geoSize = geo.rect.size();
mapViewp.h = (geo.rect.h / 32) + !!(geo.rect.h % 32) + 1; mapViewp.setSize((geoSize / 32) + !!(geoSize % 32) + Vec2i(1));
sceneOffset.x = geo.rect.x - geo.xOrigin; sceneOffset = geo.offset();
sceneOffset.y = geo.rect.y - geo.yOrigin;
sceneGeo = geo; sceneGeo = geo;
buffersDirty = true; buffersDirty = true;

View File

@ -58,7 +58,6 @@ public:
Transform() Transform()
: scale(1, 1), : scale(1, 1),
rotation(0), rotation(0),
xOffset(0), yOffset(0),
dirty(true) dirty(true)
{ {
memset(matrix, 0, sizeof(matrix)); memset(matrix, 0, sizeof(matrix));
@ -68,38 +67,47 @@ public:
} }
Vec2 &getPosition() { return position; } Vec2 &getPosition() { return position; }
Vec2 &getScale() { return scale; }
Vec2 &getOrigin() { return origin; } Vec2 &getOrigin() { return origin; }
Vec2 &getScale() { return scale; }
float getRotation() { return rotation; } float getRotation() { return rotation; }
Vec2i getPositionI() const
{
return Vec2i(position.x, position.y);
}
Vec2i getOriginI() const
{
return Vec2i(origin.x, origin.y);
}
void setPosition(const Vec2 &value) void setPosition(const Vec2 &value)
{ {
position = value; position = value;
dirty = true; dirty = true;
} }
void setScale(const Vec2 &value)
{
scale = value;
dirty = true;
}
void setOrigin(const Vec2 &value) void setOrigin(const Vec2 &value)
{ {
origin = value; origin = value;
dirty = true; dirty = true;
} }
void setScale(const Vec2 &value)
{
scale = value;
dirty = true;
}
void setRotation(float value) void setRotation(float value)
{ {
rotation = value; rotation = value;
dirty = true; dirty = true;
} }
void setGlobalOffset(int x, int y) void setGlobalOffset(const Vec2i &value)
{ {
xOffset = x; offset = value;
yOffset = y;
dirty = true; dirty = true;
} }
@ -129,8 +137,8 @@ private:
float syc = scale.y * cosine; float syc = scale.y * cosine;
float sxs = scale.x * sine; float sxs = scale.x * sine;
float sys = scale.y * sine; float sys = scale.y * sine;
float tx = -origin.x * sxc - origin.y * sys + position.x + xOffset; float tx = -origin.x * sxc - origin.y * sys + position.x + offset.x;
float ty = origin.x * sxs - origin.y * syc + position.y + yOffset; float ty = origin.x * sxs - origin.y * syc + position.y + offset.y;
matrix[0] = sxc; matrix[0] = sxc;
matrix[1] = -sxs; matrix[1] = -sxs;
@ -146,7 +154,7 @@ private:
float rotation; float rotation;
/* Silently added to position */ /* Silently added to position */
int xOffset, yOffset; Vec2i offset;
float matrix[16]; float matrix[16];

View File

@ -144,8 +144,8 @@ void Viewport::update()
Flashable::update(); Flashable::update();
} }
DEF_ATTR_RD_SIMPLE(Viewport, OX, int, geometry.xOrigin) DEF_ATTR_RD_SIMPLE(Viewport, OX, int, geometry.orig.x)
DEF_ATTR_RD_SIMPLE(Viewport, OY, int, geometry.yOrigin) DEF_ATTR_RD_SIMPLE(Viewport, OY, int, geometry.orig.y)
DEF_ATTR_SIMPLE(Viewport, Rect, Rect&, *p->rect) DEF_ATTR_SIMPLE(Viewport, Rect, Rect&, *p->rect)
DEF_ATTR_SIMPLE(Viewport, Color, Color&, *p->color) DEF_ATTR_SIMPLE(Viewport, Color, Color&, *p->color)
@ -155,10 +155,10 @@ void Viewport::setOX(int value)
{ {
guardDisposed(); guardDisposed();
if (geometry.xOrigin == value) if (geometry.orig.x == value)
return; return;
geometry.xOrigin = value; geometry.orig.x = value;
notifyGeometryChange(); notifyGeometryChange();
} }
@ -166,10 +166,10 @@ void Viewport::setOY(int value)
{ {
guardDisposed(); guardDisposed();
if (geometry.yOrigin == value) if (geometry.orig.y == value)
return; return;
geometry.yOrigin = value; geometry.orig.y = value;
notifyGeometryChange(); notifyGeometryChange();
} }

View File

@ -471,16 +471,15 @@ struct WindowPrivate
i += TileQuads::buildFrame(effectRect, cursorVert.vert); i += TileQuads::buildFrame(effectRect, cursorVert.vert);
} }
/* Scroll arrows */ /* Scroll arrow position: Top Bottom X, Left Right Y */
int scrollLRY = (size.y - 16) / 2; const Vec2i scroll = (size - Vec2i(16)) / 2;
int scrollTBX = (size.x - 16) / 2;
Sides<IntRect> scrollArrows; Sides<IntRect> scrollArrows;
scrollArrows.l = IntRect(4, scrollLRY, 8, 16); scrollArrows.l = IntRect(4, scroll.y, 8, 16);
scrollArrows.r = IntRect(size.x - 12, scrollLRY, 8, 16); scrollArrows.r = IntRect(size.x - 12, scroll.y, 8, 16);
scrollArrows.t = IntRect(scrollTBX, 4, 16, 8); scrollArrows.t = IntRect(scroll.x, 4, 16, 8);
scrollArrows.b = IntRect(scrollTBX, size.y - 12, 16, 8); scrollArrows.b = IntRect(scroll.x, size.y - 12, 16, 8);
if (contents) if (contents)
{ {
@ -557,13 +556,10 @@ struct WindowPrivate
if (size == Vec2i(0, 0)) if (size == Vec2i(0, 0))
return; return;
Vec2i trans(position.x + sceneOffset.x,
position.y + sceneOffset.y);
SimpleAlphaShader &shader = shState->shaders().simpleAlpha; SimpleAlphaShader &shader = shState->shaders().simpleAlpha;
shader.bind(); shader.bind();
shader.applyViewportProj(); shader.applyViewportProj();
shader.setTranslation(trans); shader.setTranslation(position + sceneOffset);
if (useBaseTex) if (useBaseTex)
{ {
@ -598,12 +594,11 @@ struct WindowPrivate
controlsVertDirty = false; controlsVertDirty = false;
} }
/* Actual on screen coordinates */ /* Effective on screen coordinates */
int effectX = position.x + sceneOffset.x; const Vec2i efPos = position + sceneOffset;
int effectY = position.y + sceneOffset.y;
IntRect windowRect(effectX, effectY, size.x, size.y); const IntRect windowRect(efPos, size);
IntRect contentsRect(effectX+16, effectY+16, size.x-32, size.y-32); const IntRect contentsRect(efPos + Vec2i(16), size - Vec2i(32));
glState.scissorTest.pushSet(true); glState.scissorTest.pushSet(true);
glState.scissorBox.push(); glState.scissorBox.push();
@ -615,7 +610,7 @@ struct WindowPrivate
if (!nullOrDisposed(windowskin)) if (!nullOrDisposed(windowskin))
{ {
shader.setTranslation(Vec2i(effectX, effectY)); shader.setTranslation(efPos);
/* Draw arrows / cursors */ /* Draw arrows / cursors */
windowskin->bindTex(shader); windowskin->bindTex(shader);
@ -631,9 +626,7 @@ struct WindowPrivate
/* Draw contents bitmap */ /* Draw contents bitmap */
glState.scissorBox.setIntersect(contentsRect); glState.scissorBox.setIntersect(contentsRect);
effectX += 16-contentsOffset.x; shader.setTranslation(efPos + (Vec2i(16) - contentsOffset));
effectY += 16-contentsOffset.y;
shader.setTranslation(Vec2i(effectX, effectY));
contents->bindTex(shader); contents->bindTex(shader);
contentsQuad.draw(); contentsQuad.draw();
@ -876,8 +869,7 @@ void Window::draw()
void Window::onGeometryChange(const Scene::Geometry &geo) void Window::onGeometryChange(const Scene::Geometry &geo)
{ {
p->sceneOffset.x = geo.rect.x - geo.xOrigin; p->sceneOffset = geo.offset();
p->sceneOffset.y = geo.rect.y - geo.yOrigin;
} }
void Window::setZ(int value) void Window::setZ(int value)

View File

@ -506,15 +506,15 @@ struct WindowVXPrivate
void rebuildCtrlVert() void rebuildCtrlVert()
{ {
const int arrowTBX = (geo.w - 16) / 2; /* Scroll arrow position: Top Bottom X, Left Right Y */
const int arrowLRY = (geo.h - 16) / 2; const Vec2i arrow = (geo.size() - Vec2i(16)) / 2;
const Sides<FloatRect> arrowPos = const Sides<FloatRect> arrowPos =
{ {
FloatRect( 4, arrowLRY, 8, 16 ), /* Left */ FloatRect( 4, arrow.y, 8, 16 ), /* Left */
FloatRect( geo.w - 12, arrowLRY, 8, 16 ), /* Right */ FloatRect( geo.w - 12, arrow.y, 8, 16 ), /* Right */
FloatRect( arrowTBX, 4, 16, 8 ), /* Top */ FloatRect( arrow.x, 4, 16, 8 ), /* Top */
FloatRect( arrowTBX, geo.h - 12, 16, 8 ) /* Bottom */ FloatRect( arrow.x, geo.h - 12, 16, 8 ) /* Bottom */
}; };
size_t i = 0; size_t i = 0;
@ -538,7 +538,7 @@ struct WindowVXPrivate
if (pause) if (pause)
{ {
const FloatRect pausePos(arrowTBX, geo.h - 16, 16, 16); const FloatRect pausePos(arrow.x, geo.h - 16, 16, 16);
pauseVert = &vert[i*4]; pauseVert = &vert[i*4];
i += Quad::setTexPosRect(&vert[i*4], pauseSrc[0], pausePos); i += Quad::setTexPosRect(&vert[i*4], pauseSrc[0], pausePos);
@ -730,8 +730,7 @@ struct WindowVXPrivate
bool windowskinValid = !nullOrDisposed(windowskin); bool windowskinValid = !nullOrDisposed(windowskin);
bool contentsValid = !nullOrDisposed(contents); bool contentsValid = !nullOrDisposed(contents);
Vec2i trans(geo.x + sceneOffset.x, Vec2i trans = geo.pos() + sceneOffset;
geo.y + sceneOffset.y);
SimpleAlphaShader &shader = shState->shaders().simpleAlpha; SimpleAlphaShader &shader = shState->shaders().simpleAlpha;
shader.bind(); shader.bind();
@ -764,8 +763,7 @@ struct WindowVXPrivate
{ {
/* Translate cliprect from local into screen space */ /* Translate cliprect from local into screen space */
IntRect clip = clipRect; IntRect clip = clipRect;
clip.x += trans.x; clip.setPos(clip.pos() + trans);
clip.y += trans.y;
glState.scissorBox.push(); glState.scissorBox.push();
glState.scissorTest.pushSet(true); glState.scissorTest.pushSet(true);
@ -773,11 +771,10 @@ struct WindowVXPrivate
if (rgssVer >= 3) if (rgssVer >= 3)
glState.scissorBox.setIntersect(clip); glState.scissorBox.setIntersect(clip);
else else
glState.scissorBox.setIntersect(IntRect(trans.x, trans.y, geo.w, geo.h)); glState.scissorBox.setIntersect(IntRect(trans, geo.size()));
IntRect pad = padRect; IntRect pad = padRect;
pad.x += trans.x; pad.setPos(pad.pos() + trans);
pad.y += trans.y;
if (drawCursor) if (drawCursor)
{ {
@ -786,10 +783,7 @@ struct WindowVXPrivate
contTrans.y += cursorRect->y; contTrans.y += cursorRect->y;
if (rgssVer >= 3) if (rgssVer >= 3)
{ contTrans -= contentsOff;
contTrans.x -= contentsOff.x;
contTrans.y -= contentsOff.y;
}
shader.setTranslation(contTrans); shader.setTranslation(contTrans);
@ -804,8 +798,7 @@ struct WindowVXPrivate
glState.scissorBox.setIntersect(clip); glState.scissorBox.setIntersect(clip);
Vec2i contTrans = pad.pos(); Vec2i contTrans = pad.pos();
contTrans.x -= contentsOff.x; contTrans -= contentsOff;
contTrans.y -= contentsOff.y;
shader.setTranslation(contTrans); shader.setTranslation(contTrans);
TEX::setSmooth(false); // XXX TEX::setSmooth(false); // XXX
@ -1105,8 +1098,7 @@ void WindowVX::draw()
void WindowVX::onGeometryChange(const Scene::Geometry &geo) void WindowVX::onGeometryChange(const Scene::Geometry &geo)
{ {
p->sceneOffset.x = geo.rect.x - geo.xOrigin; p->sceneOffset = geo.offset();
p->sceneOffset.y = geo.rect.y - geo.yOrigin;
} }
void WindowVX::releaseResources() void WindowVX::releaseResources()