Rev 2197 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* warper.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* For more information, please visit https://dinisnoise.org/
*/
#include "warper.h"
#include "vector2d.h"
#include "ui_list.h"
#include "console.h"
#include <vector>
using namespace std;
extern ui_list uis;
warper::warper () : x ("warpx.crv"), y ("warpy.crv"), ed ("warper.ed") {
ed.add (&x, &lis);
ed.add (&y, &lis);
back_ed = 0;
name = "Warper";
}
warper::~warper () {
x.save ("warpx.crv");
y.save ("warpy.crv");
widget_save ("d_warper", ctrls);
}
void warper::setup () {
plugin::setup ();
ctrls.push_back (&b_edit);
num_ctrls = ctrls.size ();
b_edit.set_text ("Edit");
widget_load ("d_warper", ctrls);
b_edit.set_listener (this);
for (int i = 0; i < num_ctrls; ++i) {
widget* ci = ctrls[i];
if (ci != &cb_auto_apply) ci->set_color (clr.r, clr.g, clr.b);
}
solx (&x);
soly (&y);
lis.wp = this;
}
void warper::clicked (button& b) {
if (&b == &b_edit) {
if (b_edit.text == "Edit") {
b_edit.set_text ("Go back");
back_ed = uis.crved;
uis.set_current (&ed);
} else {
uis.set_current (back_ed);
b_edit.set_text ("Edit");
}
} else plugin::clicked (b);
}
void warper::warp (float& x, float& y, const box<float>& bbox) {
// normalise
float nx = (x - bbox.left) * bbox.width_1;
float ny = (y - bbox.bottom) * bbox.height_1;
// warp
float wx = solx (nx);
float wy = soly (ny);
// remap
x = bbox.left + wx * bbox.width;
y = bbox.bottom + wy * bbox.height;
}
void warper::render () {}
int warper::apply (multi_curve& in) {
// warp vertices, left and right tangents and evaluate
//
points_array& v = in.vertices;
points_array& lt = in.left_tangents;
points_array& rt = in.right_tangents;
int n = v.size ();
if (n < 2) return 0;
box<float> bbox;
in.calc_bbox (bbox);
for (int i = 0; i < n; ++i) {
point<float>& vi = v[i];
point<float>& lti = lt[i];
point<float>& rti = rt[i];
warp (vi.x, vi.y, bbox);
warp (lti.x, lti.y, bbox);
warp (rti.x, rti.y, bbox);
}
for (int i = 0, j = n - 1; i < j; ++i) in.curv[i].eval = 1;
in.evaluate ();
return 1;
}
void warper::draw (curve_editor* ed) {}
void warp_listener::edited (curve_editor* ed, int i) {
multi_curve* crv = ed->get_curve (i);
if (crv == &wp->x) wp->solx (&wp->x); else wp->soly (&wp->y);
if (wp->cb_auto_apply.state) {
multi_curve& in = *wp->back_ed->get_picked_curve ();
wp->apply (in);
}
}