1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-25 09:44:02 +00:00
Aquaria/BBGE/SplineGrid.cpp

212 lines
5 KiB
C++
Raw Normal View History

2022-09-04 15:16:35 +00:00
#include "SplineGrid.h"
#include "RenderBase.h"
#include "Core.h"
SplineGridCtrlPoint *SplineGridCtrlPoint::movingPoint;
SplineGridCtrlPoint::SplineGridCtrlPoint()
{
setTexture("gui/open-menu");
setWidthHeight(16, 16);
}
Vector SplineGridCtrlPoint::getSplinePosition() const
{
SplineGridCtrlPoint *p = (SplineGridCtrlPoint*)getParent();
// always return alpha == 1
// points within the quad result in in -0.5 .. +0.5 on both axes
return Vector(position.x / p->width, position.y / p->height, 1.0f);
2022-09-04 15:16:35 +00:00
}
void SplineGridCtrlPoint::setSplinePosition(Vector pos)
{
SplineGridCtrlPoint *p = (SplineGridCtrlPoint*)getParent();
position.x = pos.x * p->width;
position.y = pos.y * p->height;
}
2022-09-04 15:16:35 +00:00
void SplineGridCtrlPoint::onUpdate(float dt)
{
const bool lmb = core->mouse.buttons.left;
// FIXME: selected point tracking should be done by the parent
Vector cur = core->mouse.position;
// bool wouldpick = isCoordinateInside(cur); // doesn't work
Vector wp = getWorldPosition();
const bool wouldpick = (cur - wp).isLength2DIn(10);
if(wouldpick)
color = Vector(1,0,0);
else
color = Vector(1,1,1);
2022-09-04 15:16:35 +00:00
if(lmb)
{
if(!movingPoint && wouldpick)
{
2022-09-04 15:16:35 +00:00
movingPoint = this;
}
2022-09-04 15:16:35 +00:00
}
else if(movingPoint)
{
movingPoint->color = Vector(1,1,1);
2022-09-04 15:16:35 +00:00
movingPoint = NULL;
}
2022-09-04 15:16:35 +00:00
if(movingPoint == this)
{
2022-09-05 15:19:34 +00:00
SplineGrid *p = (SplineGrid*)getParent();
2022-09-04 15:16:35 +00:00
const Vector parentPos = p->getWorldPosition();
const Vector invscale = Vector(1.0f / p->scale.x, 1.0f / p->scale.y);
Vector newpos = (cur - parentPos) * invscale;
if(position != newpos)
{
position = newpos;
p->recalc();
}
2022-09-04 15:16:35 +00:00
}
}
SplineGrid::SplineGrid()
2022-09-14 03:11:56 +00:00
: deg(0)
2022-09-04 15:16:35 +00:00
{
setWidthHeight(128, 128);
2022-09-05 15:19:34 +00:00
renderQuad = true;
renderBorder = true;
2022-09-04 15:16:35 +00:00
}
SplineGrid::~SplineGrid()
{
}
void SplineGrid::resize(size_t w, size_t h, size_t xres, size_t yres, unsigned degx, unsigned degy)
2022-09-04 15:16:35 +00:00
{
size_t oldcpx = bsp.ctrlX();
size_t oldcpy = bsp.ctrlY();
2022-09-04 15:16:35 +00:00
this->createGrid(xres, yres);
std::vector<SplineGridCtrlPoint*> oldp;
ctrlp.swap(oldp);
ctrlp.resize(w * h);
// move any old points over that fit within the new size
{
const size_t cw = std::min(oldcpx, w);
const size_t ch = std::min(oldcpy, h);
2022-09-04 15:16:35 +00:00
for(size_t y = 0; y < ch; ++y)
for(size_t x = 0; x < cw; ++x)
{
SplineGridCtrlPoint *& ref = oldp[y * oldcpx + x];
2022-09-04 15:16:35 +00:00
ctrlp[y * w + x] = ref;
ref = NULL;
}
}
bsp.resize(w, h, degx, degy);
2022-09-05 15:19:34 +00:00
2022-09-04 15:16:35 +00:00
// kill any excess points
for(size_t i = 0; i < oldp.size(); ++i)
if(oldp[i])
oldp[i]->safeKill();
// extend until all points are there
for(size_t y = 0; y < h; ++y)
for(size_t x = 0; x < w; ++x)
{
SplineGridCtrlPoint *& ref = ctrlp[y * w + x];
if(!ref)
ref = createControlPoint(x, y);
}
2022-09-05 15:19:34 +00:00
recalc();
2022-09-05 15:19:34 +00:00
}
void SplineGrid::recalc()
2022-09-05 15:19:34 +00:00
{
exportControlPoints(&bsp.controlpoints[0]);
2022-09-14 03:11:56 +00:00
bsp.recalc(drawGrid.data(), drawGrid.width(), drawGrid.height());
wasModified = true;
}
void SplineGrid::exportControlPoints(Vector* controlpoints)
{
for(size_t i = 0; i < ctrlp.size(); ++i)
controlpoints[i] = ctrlp[i]->getSplinePosition();
}
2022-09-14 03:11:56 +00:00
void SplineGrid::importControlPoints(const Vector* controlpoints)
{
for(size_t i = 0; i < ctrlp.size(); ++i)
ctrlp[i]->setSplinePosition(controlpoints[i]);
recalc();
2022-09-05 15:19:34 +00:00
}
2022-09-04 15:16:35 +00:00
void SplineGrid::resetControlPoints()
{
bsp.reset();
importControlPoints(&bsp.controlpoints[0]);
2022-09-04 15:16:35 +00:00
}
SplineGridCtrlPoint* SplineGrid::createControlPoint(size_t x, size_t y)
{
const size_t cpx = bsp.ctrlX();
const size_t cpy = bsp.ctrlY();
assert(x < cpx && y < cpy);
2022-09-05 15:19:34 +00:00
const Vector wh(width, height);
const Vector pos01(float(x) / float(cpx-1), float(y) / float(cpy-1));
2022-09-04 15:16:35 +00:00
SplineGridCtrlPoint *cp = new SplineGridCtrlPoint();
2022-09-05 15:19:34 +00:00
cp->position = (pos01 - Vector(0.5f, 0.5f)) * wh;
2022-09-04 15:16:35 +00:00
this->addChild(cp, PM_POINTER);
return cp;
}
void SplineGrid::onUpdate(float dt)
{
Quad::onUpdate(dt);
}
void SplineGrid::onRender(const RenderState& rs) const
{
Quad::onRender(rs);
glBindTexture(GL_TEXTURE_2D, 0);
2022-09-05 15:19:34 +00:00
const Vector wh2(width * 0.5f, height * 0.5f);
2022-09-04 15:16:35 +00:00
glLineWidth(2);
glColor4f(0.0f, 0.3f, 1.0f, 0.3f);
2022-09-04 15:16:35 +00:00
const size_t cpx = bsp.ctrlX();
const size_t cpy = bsp.ctrlY();
2022-09-04 15:16:35 +00:00
// X axis
for(size_t y = 0; y < cpy; ++y)
2022-09-04 15:16:35 +00:00
{
glBegin(GL_LINE_STRIP);
const SplineGridCtrlPoint * const *row = &ctrlp[y * cpx];
for(size_t x = 0; x < cpx; ++x)
2022-09-04 15:16:35 +00:00
{
const Vector p = row[x]->position;
glVertex2f(p.x, p.y);
}
glEnd();
}
// Y axis
for(size_t x = 0; x < cpx; ++x)
2022-09-04 15:16:35 +00:00
{
glBegin(GL_LINE_STRIP);
for(size_t y = 0; y < cpy; ++y)
2022-09-04 15:16:35 +00:00
{
const Vector p = ctrlp[y * cpx + x]->position;
2022-09-04 15:16:35 +00:00
glVertex2f(p.x, p.y);
}
glEnd();
}
}