Rev 1479 |
Rev 1712 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* morpher.cc
* DIN Is Noise is copyright (c) 2006-2020 Jagannathan Sampath
* For more information, please visit https://dinisnoise.org/
*/
#include "morpher.h"
#include "ui_list.h"
#include <fstream>
using namespace std;
extern ui_list uis;
extern ofstream dlog;
extern int MILLION;
morpher::morpher () : sl_amount (164, 12), sl_src_start (64, 12), sl_tar_start (64, 12), source ("morph_source.crv"), target ("morph_target.crv") {
name = "Morpher";
amount = 0.0f;
src_start = tar_start = 0;
load_params ();
}
morpher::~morpher () {
widget_save ("d_morpher", ctrls);
source.save ("morph_source.crv");
target.save ("morph_target.crv");
save_params ();
}
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};
for (int i = 0; i < 8 /*10*/; ++i) {
widget* ci = _ctrls[i];
ctrls.push_back (ci);
}
num_ctrls = ctrls.size ();
l_source.set_text ("From:");
l_target.set_text ("To:");
b_source.set_text ("Get");
b_target.set_text ("Get");
b_source.set_listener (this);
b_target.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_moveable (1);
sl->set_listener (this);
}
sp_points.set ("Points", 1, 1, MILLION, this, 0);
sp_points.set_value (num_points);
const int sx = 64, sy = 64;
cd_source.set_size (sx, sy);
cd_target.set_size (sx, sy);
widget_load ("d_morpher", ctrls);
assign_curve (source, source_sol, cd_source);
assign_curve (target, target_sol, cd_target);
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 (amount == 0.0f || amount == 1.0f) return;
shapeform = source.shapeform;
int last_point = num_points - 1;
src_start = sl_src_start () * last_point;
tar_start = sl_tar_start () * last_point;
int src_cur = src_start, tar_cur = tar_start;
points.resize (num_points);
for (int i = 0; i < num_points; ++i) {
point<float>& psrc = source_pts[src_cur];
point<float>& ptar = target_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 (amount == 0.0f) {
crv = source;
} else if (amount == 1.0f) {
crv = target;
} else return plugin::apply (crv);
return 1;
}
void morpher::make_points () {
int source_total = source.get_total_points ();
int target_total = target.get_total_points ();
if (source_total < 2 || target_total < 2) return;
num_points = max (max (source_total, target_total), int (sp_points.f_value));
if (source.shapeform) make_shapeform_pts (source_pts, source_sol, source); else make_classic_pts (source_pts, source_sol);
if (target.shapeform) make_shapeform_pts (target_pts, target_sol, target); else make_classic_pts (target_pts, target_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 == &b_source) {
source = *uis.crved->get_picked_curve ();
assign_curve (source, source_sol, cd_source);
sl_amount.set_val (0.0f);
changed (sp_points.f_value);
} else if (&b == &b_target) {
target = *uis.crved->get_picked_curve ();
assign_curve (target, target_sol, cd_target);
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);
}