Rev 2097 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* morpher.cc
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/
#include "morpher.h"
#include "ui_list.h"
#include "console.h"
#include <fstream>
using namespace std;
morpher::morpher () : sl_amount (1, 192, 12), sl_src_start (0, 64, 12), sl_tar_start (0, 64, 12) {
name = "Morpher";
amount = 0.0f;
src.crv.load ("morph_source.crv");
tar.crv.load ("morph_target.crv");
load_params ();
}
morpher::~morpher () {
save_params ();
widget_save ("d_morpher", ctrls);
src.crv.save ("morph_source.crv");
tar.crv.save ("morph_target.crv");
}
void morpher::load_params () {
ifstream f (make_fname().c_str(), ios::in);
string ignore;
f >> ignore >> num_points;
}
void morpher::save_params () {
ofstream f (make_fname().c_str(), ios::out);
f << "num_points " << num_points << endl;
}
void morpher::setup () {
plugin::setup ();
/*widget* _ctrls [] = {
&l_source, &l_target, &cd_source, &cd_target, &b_source, &b_target, &sl_amount, &sp_points, &sl_src_start, &sl_tar_start};
*/
widget* _ctrls [] = {
&src.lbl, &tar.lbl, &src.cd, &tar.cd, &src.get, &tar.get, &sl_amount, &sp_points, &sl_src_start, &sl_tar_start
};
for (int i = 0; i < 10; ++i) {
widget* ci = _ctrls[i];
ctrls.push_back (ci);
}
num_ctrls = ctrls.size ();
src.lbl.set_text ("From");
tar.lbl.set_text ("To");
src.get.set_text ("Get");
tar.get.set_text ("Get");
src.get.set_listener (this);
tar.get.set_listener (this);
/*slider<float>* slr [] = {&sl_amount, &sl_src_start, &sl_tar_start};
for (int i = 0; i < 3; ++i) {
slider<float>* sl = slr[i];
sl->set_val (0.5f);
sl->set_limits (0.0f, 1.0f);
sl->set_listener (this);
}*/
sl_amount.set_limits (0.0f, 1.0f);
sl_amount.set_listener (this);
sl_src_start.set_limits (0.0f, 1.0f);
sl_tar_start.set_limits (0.0f, 1.0f);
sp_points.set ("Points", 1, 1, MILLION, this, 0);
sp_points.set_value (num_points);
const int sx = 64, sy = 64;
src.cd.set_size (sx, sy);
tar.cd.set_size (sx, sy);
sl_src_start.set_size (sx);
sl_tar_start.set_size (sx);
widget_load ("d_morpher", ctrls);
assign_curve (src.crv, src.sol, src.cd);
assign_curve (tar.crv, tar.sol, tar.cd);
make_points ();
render ();
}
void morpher::make_classic_pts (vector< point<float> >& pts, solver& sol) {
pts.clear ();
int last_point = num_points - 1;
float x = 0.0f;
float dx = 1.0f / last_point;
for (int i = 0; i < num_points; ++i) {
float y = sol (x);
pts.push_back (point<float>(x, y));
x += dx;
}
}
void morpher::make_shapeform_pts (vector< point<float> >& pts, solver& sol, multi_curve& crv) {
float px, py, dummy;
pts.clear ();
int last_point = num_points - 1;
float x = 0.0f;
float dx = 1.0f / last_point;
for (int i = 0; i < num_points; ++i) {
py = sol (x);
crv.get_xy (x, px, dummy);
pts.push_back (point<float>(px, py));
x += dx;
}
}
void morpher::render () {
amount = sl_amount ();
if (equals(amount, 0.0f) || equals(amount, 1.0f)) return;
shapeform = src.crv.shapeform;
int last_point = num_points - 1;
src.start = sl_src_start () * last_point;
tar.start = sl_tar_start () * last_point;
src.cur = src.start;
tar.cur = tar.start;
points.resize (num_points);
for (int i = 0; i < num_points; ++i) {
point<float>& psrc = src.pts[src.cur];
point<float>& ptar = tar.pts[tar.cur];
if (++src.cur > last_point) src.cur = 0;
if (++tar.cur > last_point) tar.cur = 0;
point<float> pblend ( (1 - amount) * psrc.x + amount * ptar.x, (1 - amount) * psrc.y + amount * ptar.y);
points[i] = pblend;
}
gen_pts ();
}
int morpher::apply (multi_curve& crv) {
if (equals(amount, 0.0f)) {
crv = src.crv;
} else if (equals(amount, 1.0f)) {
crv = tar.crv;
} else
return
plugin::apply (crv);
return 1;
}
void morpher::make_points () {
src.total = src.crv.get_total_points ();
tar.total = tar.crv.get_total_points ();
if (src.total < 2 || tar.total < 2) return;
num_points = max (max (src.total, tar.total), sp_points.value);
if (src.crv.shapeform) make_shapeform_pts (src.pts, src.sol, src.crv); else make_classic_pts (src.pts, src.sol);
if (tar.crv.shapeform) make_shapeform_pts (tar.pts, tar.sol, tar.crv); else make_classic_pts (tar.pts, tar.sol);
}
void morpher::assign_curve (multi_curve& crv, solver& sol, curve_display& crvdis) {
sol (&crv);
crvdis.crv = &crv;
crvdis.calc_bbox ();
}
void morpher::clicked (button& b) {
if (&b == &src.get) {
src.crv = *uis.crved->get_picked_curve ();
assign_curve (src.crv, src.sol, src.cd);
sl_amount.set_val (0.0f);
changed (sp_points.f_value);
} else if (&b == &tar.get) {
tar.crv = *uis.crved->get_picked_curve ();
assign_curve (tar.crv, tar.sol, tar.cd);
sl_amount.set_val (1.0f);
changed (sp_points.f_value);
} else plugin::clicked (b);
}
void morpher::changed (slider<float>& s) {
plugin::changed (sp_points.f_value);
}
void morpher::changed (field& f) {
make_points ();
plugin::changed (f);
}