mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-10-20 13:29:30 +00:00
new tbsp version; working spline control point generation prototype
This commit is contained in:
parent
753718c7ad
commit
fc3580ca64
5 changed files with 876 additions and 87 deletions
|
@ -1,6 +1,5 @@
|
|||
#include "Interpolators.h"
|
||||
#include <math.h>
|
||||
#include "tbsp.hh"
|
||||
|
||||
// usually one would expect that a bspline goes from t=0 to t=1.
|
||||
// here, splines eval between these -0.5 .. +0.5.
|
||||
|
@ -79,7 +78,24 @@ tail:
|
|||
}
|
||||
|
||||
BSpline2D::BSpline2D()
|
||||
: _cpx(0), _cpy(0), _degx(0), _degy(0), _tmin(0), _tmax(0)
|
||||
: _cpx(0), _cpy(0), _degx(0), _degy(0), _tmin(0), _tmax(0), _ext(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
BSpline2D::~BSpline2D()
|
||||
{
|
||||
if(_ext)
|
||||
{
|
||||
_ext->~Extended();
|
||||
free(_ext);
|
||||
}
|
||||
}
|
||||
|
||||
BSpline2D::BSpline2D(const BSpline2D& o)
|
||||
: _cpx(o._cpx), _cpy(o._cpy), _degx(o._degx), _degy(o._degy)
|
||||
, _tmin(o._tmin), _tmax(o._tmax)
|
||||
, knotsX(o.knotsX), knotsY(o.knotsY)
|
||||
, _ext(NULL) // VERY important
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -97,13 +113,83 @@ void BSpline2D::resize(size_t cx, size_t cy, unsigned degx, unsigned degy)
|
|||
_degy = degy;
|
||||
_tmin = tmin;
|
||||
_tmax = tmax;
|
||||
|
||||
|
||||
const size_t maxCp = std::max(cx, cy);
|
||||
|
||||
const size_t interpStorageSizeX = tbsp__getInterpolatorStorageSize(cx, cx);
|
||||
const size_t interpStorageSizeY = tbsp__getInterpolatorStorageSize(cy, cy);
|
||||
const size_t interpInitTempSize = tbsp__getInterpolatorInitTempSize(maxCp, maxCp);
|
||||
const size_t interpStorageNeeded = interpStorageSizeX + interpStorageSizeY;
|
||||
|
||||
if(_ext && _ext->capacity < interpStorageNeeded)
|
||||
{
|
||||
free(_ext);
|
||||
_ext = NULL;
|
||||
}
|
||||
|
||||
if(!_ext)
|
||||
{
|
||||
void *extmem = malloc(sizeof(Extended) + sizeof(float) * interpStorageNeeded);
|
||||
Extended *ext = new (extmem) Extended;
|
||||
ext->capacity = interpStorageNeeded;
|
||||
_ext = ext;
|
||||
}
|
||||
|
||||
if(_ext)
|
||||
{
|
||||
// Some extra temp memory is required during init, but can be discarded right afterward
|
||||
std::vector<float> interptmp(interpInitTempSize);
|
||||
|
||||
float *mx = _ext->floats();
|
||||
float *my = mx + interpStorageSizeX;
|
||||
|
||||
_ext->interp.x = tbsp::initInterpolator(mx, &interptmp[0], degx, cx, cx, &knotsX[0]);
|
||||
_ext->interp.y = tbsp::initInterpolator(my, &interptmp[0], degy, cy, cy, &knotsY[0]);
|
||||
_ext->tmp2d.init(cx, cy);
|
||||
}
|
||||
}
|
||||
|
||||
void BSpline2D::recalc(Vector* dst, size_t xres, size_t yres, const Vector *controlpoints)
|
||||
{
|
||||
if(_ext)
|
||||
{
|
||||
const size_t maxCp = std::max(_cpx, _cpy);
|
||||
|
||||
Array2d<Vector>& tmp2d = _ext->tmp2d;
|
||||
std::vector<Vector> tmpcp(maxCp), tmpin(maxCp);
|
||||
|
||||
// FIXME: should have in/out stride in the generator function
|
||||
|
||||
// y direction first
|
||||
for(size_t x = 0; x < _cpx; ++x)
|
||||
{
|
||||
const Vector *src = &controlpoints[x];
|
||||
for(size_t i = 0; i < _cpy; ++i, src += _cpx)
|
||||
tmpin[i] = *src;
|
||||
|
||||
tbsp::generateControlPoints<Vector>(&tmpcp[0], NULL, _ext->interp.y, &tmpin[0]);
|
||||
|
||||
for(size_t y = 0; y < _cpy; ++y)
|
||||
tmp2d(x, y) = tmpcp[y];
|
||||
}
|
||||
|
||||
// x direction
|
||||
for(size_t y = 0; y < _cpy; ++y)
|
||||
{
|
||||
Vector *row = tmp2d.row(y);
|
||||
memcpy(&tmpin[0], row, sizeof(Vector) * _cpx);
|
||||
tbsp::generateControlPoints<Vector>(row, NULL, _ext->interp.x, &tmpin[0]);
|
||||
}
|
||||
|
||||
controlpoints = tmp2d.data();
|
||||
}
|
||||
|
||||
|
||||
const unsigned maxDeg = std::max(_degx, _degy);
|
||||
|
||||
std::vector<Vector> tmpv;
|
||||
size_t degn = std::max(_degx, _degy);
|
||||
size_t tmpn = (yres * _cpx) + degn;
|
||||
size_t tmpn = (yres * _cpx) + maxDeg;
|
||||
size_t tmpsz = tmpn * sizeof(Vector);
|
||||
Vector *tmp;
|
||||
if(tmpsz < 17*1024)
|
||||
|
@ -113,7 +199,7 @@ void BSpline2D::recalc(Vector* dst, size_t xres, size_t yres, const Vector *cont
|
|||
tmpv.resize(tmpn);
|
||||
tmp = &tmpv[0];
|
||||
}
|
||||
Vector *work = tmp + (tmpn - degn);
|
||||
Vector *work = tmp + (tmpn - maxDeg);
|
||||
|
||||
// Each column -> Y-axis interpolation
|
||||
for(size_t x = 0; x < _cpx; ++x)
|
||||
|
|
|
@ -4,6 +4,15 @@
|
|||
#include <algorithm> // std::pair
|
||||
#include <vector>
|
||||
#include "Vector.h"
|
||||
#include "tbsp.hh"
|
||||
#include "DataStructures.h"
|
||||
|
||||
enum SplineType
|
||||
{
|
||||
INTERPOLATOR_BSPLINE,
|
||||
INTERPOLATOR_COSINE,
|
||||
INTERPOLATOR_BSPLINE_EXT
|
||||
};
|
||||
|
||||
class CosineInterpolator
|
||||
{
|
||||
|
@ -23,6 +32,9 @@ class BSpline2D
|
|||
{
|
||||
public:
|
||||
BSpline2D();
|
||||
BSpline2D(const BSpline2D&);
|
||||
~BSpline2D();
|
||||
|
||||
|
||||
// # of control points on each axis
|
||||
void resize(size_t cx, size_t cy, unsigned degx, unsigned degy);
|
||||
|
@ -37,10 +49,26 @@ public:
|
|||
inline unsigned degY() const { return _degy; }
|
||||
|
||||
private:
|
||||
|
||||
size_t _cpx, _cpy; // # of control points
|
||||
unsigned _degx, _degy;
|
||||
float _tmin, _tmax;
|
||||
std::vector<float> knotsX, knotsY;
|
||||
|
||||
// always allocated on heap, with extra space at the end
|
||||
struct Extended
|
||||
{
|
||||
Array2d<Vector> tmp2d;
|
||||
struct
|
||||
{
|
||||
tbsp::Interpolator<float> x, y;
|
||||
} interp;
|
||||
size_t capacity;
|
||||
float *floats() { return reinterpret_cast<float*>(this + 1); }
|
||||
// space for n floats follows
|
||||
};
|
||||
|
||||
Extended *_ext;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1660,7 +1660,9 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
|||
XMLElement *animation = animations->FirstChildElement("Animation");
|
||||
while(animation)
|
||||
{
|
||||
Animation newAnimation;
|
||||
this->animations.push_back(Animation());
|
||||
Animation& newAnimation = this->animations.back();
|
||||
|
||||
newAnimation.name = animation->Attribute("name");
|
||||
if(animation->Attribute("resetOnEnd"))
|
||||
newAnimation.resetOnEnd = animation->BoolAttribute("resetOnEnd");
|
||||
|
@ -1786,8 +1788,15 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
|||
}
|
||||
|
||||
// <Interpolator bone="name or idx" type="TYPE config and params" data="controlpoints; aded by editor" />
|
||||
size_t numInterp = 0;
|
||||
XMLElement *interp = animation->FirstChildElement("Interpolator");
|
||||
for( ; interp; interp = interp->NextSiblingElement("Interpolator"))
|
||||
++numInterp;
|
||||
|
||||
newAnimation.interpolators.resize(numInterp);
|
||||
|
||||
interp = animation->FirstChildElement("Interpolator");
|
||||
for(numInterp = 0 ; interp; interp = interp->NextSiblingElement("Interpolator"), ++numInterp)
|
||||
{
|
||||
Bone *bi = NULL;
|
||||
const char *sbone = interp->Attribute("bone");
|
||||
|
@ -1817,17 +1826,16 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
|||
continue;
|
||||
}
|
||||
|
||||
SplineType spline = SPLINE_BSPLINE;
|
||||
SplineType spline = INTERPOLATOR_BSPLINE;
|
||||
unsigned cx = 3, cy = 3, degx = 3, degy = 3;
|
||||
if(const char *stype = interp->Attribute("type"))
|
||||
{
|
||||
SimpleIStringStream is(stype, SimpleIStringStream::REUSE);
|
||||
std::string ty;
|
||||
is >> ty;
|
||||
BoneGridInterpolator bgip;
|
||||
if(ty == "bspline")
|
||||
{
|
||||
spline = SPLINE_BSPLINE;
|
||||
spline = INTERPOLATOR_BSPLINE;
|
||||
if(!(is >> cx >> cy >> degx >> degy))
|
||||
{
|
||||
if(!degx)
|
||||
|
@ -1851,9 +1859,7 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
|||
// bone grid should have been created via <Bone grid=... /> earlier
|
||||
|
||||
const char *idata = interp->Attribute("data");
|
||||
newAnimation.interpolators.push_back(BoneGridInterpolator());
|
||||
BoneGridInterpolator& bgip = newAnimation.interpolators.back();
|
||||
//bgip.type = spline;
|
||||
BoneGridInterpolator& bgip = newAnimation.interpolators[numInterp];
|
||||
bgip.idx = bi->boneIdx;
|
||||
bgip.storeBoneByIdx = boneByIdx;
|
||||
|
||||
|
@ -1895,7 +1901,6 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
|||
}
|
||||
|
||||
animation = animation->NextSiblingElement("Animation");
|
||||
this->animations.push_back(newAnimation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,6 @@
|
|||
#include "Quad.h"
|
||||
#include "Interpolators.h"
|
||||
|
||||
enum SplineType
|
||||
{
|
||||
SPLINE_BSPLINE,
|
||||
SPLINE_COSINE,
|
||||
};
|
||||
|
||||
class SplineGridCtrlPoint : public Quad
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue