matrix editor and saver are now transmatrix, not trans23

This commit is contained in:
Zeno Rogue 2023-08-10 14:38:59 +02:00
parent fe6d7abec2
commit 5cc7a4e527
4 changed files with 51 additions and 35 deletions

View File

@ -131,6 +131,17 @@ namespace anims {
extern void animate_setting(setting*, string); extern void animate_setting(setting*, string);
} }
/** transmatrix with equality, so we can construct val_setting<matrix_eq> */
struct matrix_eq : transmatrix {
bool operator == (const transmatrix& t) const {
for(int i=0; i<MAXMDIM; i++) for(int j=0; j<MAXMDIM; j++) if(self[i][j] != t[i][j]) return false;
return true;
}
bool operator != (const transmatrix& t) const {
return ! (self == t);
}
};
template<class T> struct val_setting : public setting { template<class T> struct val_setting : public setting {
T *value, last_value, anim_value, dft; T *value, last_value, anim_value, dft;
@ -237,7 +248,8 @@ struct color_setting : public val_setting<color_t> {
void load_from_raw(const string& s) override { sscanf(s.c_str(), "%x", value); } void load_from_raw(const string& s) override { sscanf(s.c_str(), "%x", value); }
}; };
struct matrix_setting : public val_setting<trans23> { struct matrix_setting : public val_setting<matrix_eq> {
int dim;
supersaver *make_saver() override; supersaver *make_saver() override;
void show_edit_option(int key) override; void show_edit_option(int key) override;
matrix_setting *editable(string menu_item_name, string help_text, char key) { matrix_setting *editable(string menu_item_name, string help_text, char key) {
@ -248,7 +260,7 @@ struct matrix_setting : public val_setting<trans23> {
return this; return this;
} }
void load_from_raw(const string& s) override { *value = parsematrix23(s); } void load_from_raw(const string& s) override { (transmatrix&)*value = parsematrix(s); }
}; };
struct char_setting : public val_setting<char> { struct char_setting : public val_setting<char> {
@ -405,32 +417,30 @@ template<> struct saver<string> : dsaver<string> {
virtual void swap_with(supersaver *s) { swap(val, ((saver<string>*)s)->val); } virtual void swap_with(supersaver *s) { swap(val, ((saver<string>*)s)->val); }
}; };
template<> struct saver<trans23> : supersaver { template<> struct saver<matrix_eq> : supersaver {
trans23& val; matrix_eq& val;
trans23 dft; matrix_eq dft;
explicit saver(trans23& _val) : val(_val) { } explicit saver(matrix_eq& _val) : val(_val) { }
void reset() override { val = dft; } void reset() override { val = dft; }
bool affects(void* v) override { return v == &val; } bool affects(void* v) override { return v == &val; }
void set_default() override { dft = val; } void set_default() override { dft = val; }
bool dosave() override { return !eqmatrix(val.v2, dft.v2) || !eqmatrix(val.v3, dft.v3); } bool dosave() override { return !eqmatrix(val, dft); }
string save() override { string save() override {
shstream ss; shstream ss;
for(int a=0; a<4; a++) for(int b=0; b<4; b++) print(ss, val.v2[a][b], " "); for(int a=0; a<4; a++) for(int b=0; b<4; b++) print(ss, val[a][b], " ");
for(int a=0; a<4; a++) for(int b=0; b<4; b++) print(ss, val.v3[a][b], " ");
return ss.s; return ss.s;
} }
void load(const string& s) override { void load(const string& s) override {
shstream ss; shstream ss;
ss.s = s; ss.s = s;
for(int a=0; a<4; a++) for(int b=0; b<4; b++) scan(ss, val.v2[a][b]); for(int a=0; a<4; a++) for(int b=0; b<4; b++) scan(ss, val[a][b]);
for(int a=0; a<4; a++) for(int b=0; b<4; b++) scan(ss, val.v3[a][b]);
} }
virtual void clone(struct local_parameter_set& lps, void *value) override { addsaver(*(trans23*) value, lps.label + name); } virtual void clone(struct local_parameter_set& lps, void *value) override { addsaver(*(matrix_eq*) value, lps.label + name); }
virtual void swap_with(supersaver *s) override { swap(val, ((saver<trans23>*)s)->val); } virtual void swap_with(supersaver *s) override { swap(val, ((saver<matrix_eq>*)s)->val); }
}; };
template<> struct saver<ld> : dsaver<ld> { template<> struct saver<ld> : dsaver<ld> {
@ -564,7 +574,7 @@ void color_setting::show_edit_option(int key) {
void matrix_setting::show_edit_option(int key) { void matrix_setting::show_edit_option(int key) {
dialog::addMatrixItem(XLAT(menu_item_name), *value, key); dialog::addMatrixItem(XLAT(menu_item_name), *value, key);
dialog::add_action([this] () { dialog::add_action([this] () {
dialog::editMatrix(*value, XLAT(menu_item_name), help_text); dialog::editMatrix(*value, XLAT(menu_item_name), help_text, dim);
}); });
} }
@ -682,7 +692,8 @@ EX color_setting *param_color(color_t& val, const string s, bool has_alpha, colo
return f; return f;
} }
EX matrix_setting *param_matrix(trans23& val, const string s) { EX matrix_setting *param_matrix(transmatrix& val0, const string s, int dim) {
matrix_eq& val = (matrix_eq&) val0;
unique_ptr<matrix_setting> u ( new matrix_setting ); unique_ptr<matrix_setting> u ( new matrix_setting );
u->parameter_name = param_esc(s); u->parameter_name = param_esc(s);
u->config_name = s; u->config_name = s;
@ -690,6 +701,7 @@ EX matrix_setting *param_matrix(trans23& val, const string s) {
u->value = &val; u->value = &val;
u->last_value = val; u->last_value = val;
u->dft = val; u->dft = val;
u->dim = dim;
u->register_saver(); u->register_saver();
auto f = &*u; auto f = &*u;
params[u->parameter_name] = std::move(u); params[u->parameter_name] = std::move(u);

View File

@ -305,12 +305,13 @@ EX namespace dialog {
return alpha / degree; return alpha / degree;
} }
EX void addMatrixItem(string body, trans23& value, int key) { EX void addMatrixItem(string body, transmatrix& value, int key, int dim IS(GDIM)) {
addSelItem(body, COLORBAR, key); addSelItem(body, COLORBAR, key);
auto& it = items.back(); auto& it = items.back();
it.type = diMatrixItem; it.type = diMatrixItem;
it.ptr = &value; it.ptr = &value;
it.value = fts(as_degrees(value.get())) + "°"; it.value = fts(as_degrees(value)) + "°";
it.p1 = dim;
} }
EX void addHelp(string body) { EX void addHelp(string body) {
@ -586,13 +587,12 @@ EX namespace dialog {
} }
} }
EX void visualize_matrix(const trans23& T, ld x, ld y, ld r) { EX void visualize_matrix(const trans23& T, ld x, ld y, ld r, int dim) {
vector<hyperpoint> pts; vector<hyperpoint> pts;
for(int a=0; a<MDIM-1; a++) { for(int a=0; a<dim; a++) {
hyperpoint h = C0; h[a] = r; hyperpoint h = C0; h[a] = r;
pts.push_back(rot_inverse(T.get()) * h); pts.push_back(rot_inverse(T.get()) * h);
} }
int dim = MDIM;
flat_model_enabler fme; flat_model_enabler fme;
initquickqueue(); initquickqueue();
@ -604,14 +604,14 @@ EX namespace dialog {
queuecurve(V, 0xFFFFFFFF, 0x202020FF, PPR::LINE); queuecurve(V, 0xFFFFFFFF, 0x202020FF, PPR::LINE);
color_t cols[3] = {0xFF0000FF, 0x00FF00FF, 0x0000FFFF}; color_t cols[3] = {0xFF0000FF, 0x00FF00FF, 0x0000FFFF};
for(int a=0; a<dim-1; a++) { for(int a=0; a<dim; a++) {
auto pt = pts[a]; pt[2] = 1; pt[3] = 1; auto pt = pts[a]; pt[2] = 1; pt[3] = 1;
curvepoint(hyperpoint(0,0,1,1)); curvepoint(hyperpoint(0,0,1,1));
curvepoint(pt); curvepoint(pt);
// queueline(V * hyperpoint(0,0,1,1), V * pt, cols[a], 0); // queueline(V * hyperpoint(0,0,1,1), V * pt, cols[a], 0);
queuecurve(V, cols[a], 0, PPR::LINE); queuecurve(V, cols[a], 0, PPR::LINE);
} }
if(dim == 4) for(int a=0; a<dim-1; a++) { if(dim == 4) for(int a=0; a<dim; a++) {
auto pt = pts[a]; ld val = pt[2] * vid.fsize / r / 5; pt[2] = 1; pt[3] = 1; auto pt = pts[a]; ld val = pt[2] * vid.fsize / r / 5; pt[2] = 1; pt[3] = 1;
curvepoint(hyperpoint(0, val, 1, 1)); curvepoint(hyperpoint(0, val, 1, 1));
curvepoint(hyperpoint(-val, -val*sqrt(3)/2, 1, 1)); curvepoint(hyperpoint(-val, -val*sqrt(3)/2, 1, 1));
@ -832,7 +832,7 @@ EX namespace dialog {
while(siz > 6 && textwidth(siz, I.value) + (I.type == diMatrixItem ? siz : 0) >= vid.xres - valuex) siz--; while(siz > 6 && textwidth(siz, I.value) + (I.type == diMatrixItem ? siz : 0) >= vid.xres - valuex) siz--;
displayfr(valuex, mid, 2, siz, I.value, I.colorv, 0); displayfr(valuex, mid, 2, siz, I.value, I.colorv, 0);
if(I.type == diMatrixItem) visualize_matrix(*((trans23*)I.ptr), valuex + textwidth(siz, "-359.999o") + siz/2, mid, siz/2); if(I.type == diMatrixItem) visualize_matrix(*((transmatrix*)I.ptr), valuex + textwidth(siz, "-359.999o") + siz/2, mid, siz/2, I.p1);
} }
} }
if(xthis) getcstat = I.key; if(xthis) getcstat = I.key;
@ -1121,7 +1121,8 @@ EX namespace dialog {
#if HDR #if HDR
struct matrix_dialog : extdialog { struct matrix_dialog : extdialog {
trans23 *edit_matrix; transmatrix *edit_matrix;
int dim;
void draw() override; void draw() override;
}; };
#endif #endif
@ -1134,12 +1135,12 @@ EX namespace dialog {
addCustom(500, [this] { addCustom(500, [this] {
int siz = dfsize * 5; int siz = dfsize * 5;
int mid = (top + tothei) / 2; int mid = (top + tothei) / 2;
visualize_matrix(*edit_matrix, dcenter, mid, siz/2); visualize_matrix(*edit_matrix, dcenter, mid, siz/2, dim);
}); });
addBreak(100); addBreak(100);
addItem("enter angle", 'a'); addItem("enter angle", 'a');
dialog::add_action([this] { dialog::add_action([this] {
static ld angle = as_degrees(edit_matrix->get()); static ld angle = as_degrees(*edit_matrix);
editNumber(angle, -180, 180, 90, 0, title, help); editNumber(angle, -180, 180, 90, 0, title, help);
auto& ne = get_ne(); auto& ne = get_ne();
auto re = reaction; auto re = reaction;
@ -1151,11 +1152,12 @@ EX namespace dialog {
display(); display();
} }
EX void editMatrix(trans23& T, string t, string h) { EX void editMatrix(transmatrix& T, string t, string h, int dim) {
matrix_dialog m; matrix_dialog m;
m.edit_matrix = &T; m.edit_matrix = &T;
m.title = t; m.title = t;
m.help = h; m.help = h;
m.dim = dim;
pushScreen(m); pushScreen(m);
} }

View File

@ -468,16 +468,16 @@ EX namespace models {
} }
if(has_orientation(vpmodel)) { if(has_orientation(vpmodel)) {
dialog::addMatrixItem(XLAT("model orientation"), vpconf.mori(), 'l'); dialog::addMatrixItem(XLAT("model orientation"), vpconf.mori().get(), 'l');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editMatrix(vpconf.mori(), XLAT("model orientation"), ""); dialog::editMatrix(vpconf.mori().get(), XLAT("model orientation"), "", GDIM);
}); });
} }
if(among(vpmodel, mdPerspective, mdHorocyclic) && nil) { if(among(vpmodel, mdPerspective, mdHorocyclic) && nil) {
dialog::addMatrixItem(XLAT("model orientation"), vpconf.mori(), 'l'); dialog::addMatrixItem(XLAT("model orientation"), vpconf.mori().get(), 'l');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editMatrix(vpconf.mori(), XLAT("model orientation"), ""); dialog::editMatrix(vpconf.mori().get(), XLAT("model orientation"), "", GDIM);
}); });
dialog::addSelItem(XLAT("rotational or Heisenberg"), fts(vpconf.rotational_nil), 'L'); dialog::addSelItem(XLAT("rotational or Heisenberg"), fts(vpconf.rotational_nil), 'L');
dialog::add_action([] () { dialog::add_action([] () {
@ -965,7 +965,8 @@ EX namespace models {
addsaverenum(p.model, pp+"used model", mdDisk); addsaverenum(p.model, pp+"used model", mdDisk);
if(&p.model == &pmodel) param_custom(pmodel, "projection|Poincare|Klein|half-plane|perspective", menuitem_projection, '1'); if(&p.model == &pmodel) param_custom(pmodel, "projection|Poincare|Klein|half-plane|perspective", menuitem_projection, '1');
param_matrix(p.mori(), pp+"mori"); param_matrix(p.mori().v2, pp+"mori", 2);
param_matrix(p.mori().v3, pp+"mori3", 3);
param_f(p.top_z, sp+"topz", 5) param_f(p.top_z, sp+"topz", 5)
-> editable(1, 20, .25, "maximum z coordinate to show", "maximum z coordinate to show", 'l'); -> editable(1, 20, .25, "maximum z coordinate to show", "maximum z coordinate to show", 'l');

View File

@ -846,7 +846,8 @@ auto hook =
}) })
+ addHook(hooks_configfile, 100, [] { + addHook(hooks_configfile, 100, [] {
param_f(racing::race_advance, "race_advance"); param_f(racing::race_advance, "race_advance");
param_matrix(racing::race_angle, "race_angle"); param_matrix(racing::race_angle.v2, "race_angle", 2);
param_matrix(racing::race_angle.v3, "race_angle3", 3);
param_i(racing::ghosts_to_show, "race_ghosts_to_show"); param_i(racing::ghosts_to_show, "race_ghosts_to_show");
param_i(racing::ghosts_to_save, "race_ghosts_to_save"); param_i(racing::ghosts_to_save, "race_ghosts_to_save");
param_b(racing::guiding, "race_guiding"); param_b(racing::guiding, "race_guiding");
@ -1035,9 +1036,9 @@ void race_projection() {
else dialog::addBreak(100); else dialog::addBreak(100);
if(GDIM == 2) { if(GDIM == 2) {
dialog::addMatrixItem(XLAT("race angle"), race_angle, 'a'); dialog::addMatrixItem(XLAT("race angle"), race_angle.get(), 'a');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editMatrix(race_angle, XLAT("model orientation"), ""); dialog::editMatrix(race_angle.get(), XLAT("model orientation"), "", GDIM);
auto q = rot_inverse(race_angle) * pconf.mori(); auto q = rot_inverse(race_angle) * pconf.mori();
auto last = dialog::get_ne().reaction; auto last = dialog::get_ne().reaction;
dialog::get_ne().reaction = [q, last] () { last(); pconf.mori() = race_angle * q; }; dialog::get_ne().reaction = [q, last] () { last(); pconf.mori() = race_angle * q; };