rogueviz:: objmodels:: OO design of the model class

This commit is contained in:
Zeno Rogue 2023-02-15 14:49:53 +01:00
parent f252456578
commit c53972c4b0
4 changed files with 101 additions and 64 deletions

View File

@ -203,7 +203,20 @@ void prepare_nilform() {
make_routes();
}
model staircase("rogueviz/nil/", "aco.obj", nilize);
struct nilmodel : model {
hyperpoint transform(hyperpoint h) override { return nilize(h).second; }
void process_triangle(vector<hyperpoint>& hys, vector<hyperpoint>& tot, bool textured, object *co) {
auto n0 = nilize(hys[0]).first;
auto n1 = nilize(hys[1]).first;
auto n2 = nilize(hys[2]).first;
auto mi = min(n0, min(n1, n2));
auto ma = max(n0, max(n1, n2));
if(ma - mi > 1) return;
model::process_triangle(hys, tot, textured, co);
}
};
nilmodel staircase;
bool draw_ply() {

View File

@ -21,20 +21,22 @@ using namespace rogueviz::objmodels;
void prepare_tf();
model city("rogueviz/models/", "emilejohansson_p2.obj", default_transformer, prepare_tf);
struct citymodel : model {
citymodel() : model("rogueviz/models/", "emilejohansson_p2.obj") {}
hyperpoint low, high;
hyperpoint low, high;
ld t;
void prepare_tf() {
for(int i=0; i<4; i++) low[i] = 100, high[i] = -100;
void prepare() override {
for(int i=0; i<4; i++) low[i] = 100, high[i] = -100;
cgi.require_basics();
hyperpoint corner = get_corner_position(cwt.at, 0);
ld t = abs(corner[0] / corner[3]);
cgi.require_basics();
hyperpoint corner = get_corner_position(cwt.at, 0);
t = abs(corner[0] / corner[3]);
}
city.tf = [=] (hyperpoint h) -> pair<int, hyperpoint> {
hyperpoint transform(hyperpoint h) override {
swap(h[1], h[2]);
h[2] = -h[2];
h[2] += 0.063;
@ -59,7 +61,7 @@ void prepare_tf() {
hx = normalize(hx);
hx = orthogonal_move(hx, h[2]*(t*(sphere ? 3 : 7)));
return {0, hx};
return hx;
}
if(nil || sol) {
@ -68,14 +70,19 @@ void prepare_tf() {
if(sol) h *= vid.binary_width;
if(nil) h *= nilv::nilwidth;
h[3] = 1;
return {0, h};
return h;
}
return {0, h};
};
println(hlog, "low = ", low);
println(hlog, "high = ", high);
}
return h;
}
void postprocess() {
println(hlog, "low = ", low);
println(hlog, "high = ", high);
}
};
citymodel city;
bool draw_city_at(cell *c, const shiftmatrix& V) {
if(nil) {

View File

@ -21,8 +21,6 @@ bool model::available() {
return false;
}
bool root = false;
string ignore_mtlname = "XXX";
void model::load_obj(model_data& md) {
@ -34,7 +32,7 @@ void model::load_obj(model_data& md) {
if(!fs.f)
throw hr_exception("failed to open model file: " + path + fname);
preparer();
prepare();
vector<hyperpoint> vertices;
vector<hyperpoint> normals;
@ -73,9 +71,7 @@ void model::load_obj(model_data& md) {
if(s == "Kd") {
ld a, b, c;
scan(fsm, a, b, c);
part(nextcol, 3) = root ? sqrt(a) * 255.99 : a * 319.99;
part(nextcol, 2) = root ? sqrt(b) * 255.99 : b * 319.99;
part(nextcol, 1) = root ? sqrt(c) * 255.99 : c * 319.99;
nextcol = read_color(a, b, c);
}
if(s == "newmtl") {
emit_material();
@ -208,44 +204,8 @@ void model::load_obj(model_data& md) {
for(auto& h: hys)
h -= ctr1;
}
hyperpoint norm = (hys[1] - hys[0]) ^ (hys[2] - hys[0]);
norm /= hypot_d(3, norm);
ld y = .5 + (.2 * norm[0] + .16 * norm[1] + .14 * norm[2]);
glvertex shade = glhr::makevertex(0, y, 0);
glvertex shadecol = glhr::makevertex(y, y, y);
auto n0 = tf(hys[0]);
auto n1 = tf(hys[1]);
auto n2 = tf(hys[2]);
auto mi = min(n0.first, min(n1.first, n2.first));
auto ma = max(n0.first, max(n1.first, n2.first));
if(ma - mi > 1) continue;
int parts = sd(hys);
auto tri = [&] (int a, int b) {
cgi.hpcpush(tf(hys[0] + (hys[1] - hys[0]) * a / parts + (hys[2] - hys[0]) * b / parts).second);
// cgi.hpcpush(tf(tot[0] + (tot[1] - tot[0]) * a / parts + (tot[2] - tot[0]) * b / parts).second);
if(textured) {
co->tv.tvertices.push_back(glhr::pointtogl(tot[0] + (tot[1] - tot[0]) * a / parts + (tot[2] - tot[0]) * b / parts));
co->tv.colors.push_back(shadecol);
}
else {
co->tv.tvertices.push_back(shade);
}
};
for(int a=0; a<parts; a++)
for(int b=0; b<parts-a; b++) {
tri(a, b);
tri(a+1, b);
tri(a, b+1);
if(a+b < parts-1) {
tri(a, b+1);
tri(a+1, b);
tri(a+1, b+1);
}
}
process_triangle(hys, tot, textured, co);
while(among(peek(fs), ' ', '\r', '\n')) scan(fs, bar);
if(isdigit(peek(fs))) { vis[1] = vis[2]; goto next_triangle; }
@ -271,6 +231,56 @@ void model::load_obj(model_data& md) {
cgi.extra_vertices();
}
hyperpoint model::transform(hyperpoint h) { return direct_exp(h); }
int model::subdivision(vector<hyperpoint>& hys) {
if(euclid) return 1;
ld maxlen = prec * max(hypot_d(3, hys[1] - hys[0]), max(hypot_d(3, hys[2] - hys[0]), hypot_d(3, hys[2] - hys[1])));
return int(ceil(maxlen));
}
color_t model::read_color(ld a, ld b, ld c) {
color_t nextcol = 0xFFFFFFFF;
part(nextcol, 3) = a * 255.99;
part(nextcol, 2) = b * 255.99;
part(nextcol, 1) = c * 255.99;
return nextcol;
}
void model::process_triangle(vector<hyperpoint>& hys, vector<hyperpoint>& tot, bool textured, object *co) {
hyperpoint norm = (hys[1] - hys[0]) ^ (hys[2] - hys[0]);
norm /= hypot_d(3, norm);
ld y = .5 + (.2 * norm[0] + .16 * norm[1] + .14 * norm[2]);
glvertex shade = glhr::makevertex(0, y, 0);
glvertex shadecol = glhr::makevertex(y, y, y);
int parts = subdivision(hys);
auto tri = [&] (int a, int b) {
cgi.hpcpush(transform(hys[0] + (hys[1] - hys[0]) * a / parts + (hys[2] - hys[0]) * b / parts));
// cgi.hpcpush(tf(tot[0] + (tot[1] - tot[0]) * a / parts + (tot[2] - tot[0]) * b / parts).second);
if(textured) {
co->tv.tvertices.push_back(glhr::pointtogl(tot[0] + (tot[1] - tot[0]) * a / parts + (tot[2] - tot[0]) * b / parts));
co->tv.colors.push_back(shadecol);
}
else {
co->tv.tvertices.push_back(shade);
}
};
for(int a=0; a<parts; a++)
for(int b=0; b<parts-a; b++) {
tri(a, b);
tri(a+1, b);
tri(a, b+1);
if(a+b < parts-1) {
tri(a, b+1);
tri(a+1, b);
tri(a+1, b+1);
}
}
}
model_data& model::get() {
auto& md = (unique_ptr<model_data>&) cgi.ext[fname];

View File

@ -23,7 +23,14 @@ namespace snow {
using rogueviz::objmodels::model;
using rogueviz::objmodels::tf_result;
vector<model> models;
struct snowmodel : model {
ld scale;
transmatrix T;
snowmodel(string s, ld scale, transmatrix T) : model("rogueviz/models", s), scale(scale), T(T) {}
hyperpoint transform(hyperpoint h) override { return direct_exp(T*h*scale); }
};
vector<snowmodel> models;
ld snow_lambda = 0;
@ -278,7 +285,7 @@ auto hchook = addHook(hooks_drawcell, 100, draw_snow)
for(int i=0; i<qty; i++) {
transmatrix T = random_spin();
println(hlog, "T = ", T);
models.emplace_back("rogueviz/models/", s, [scale,T] (hyperpoint h) { tf_result res{0, direct_exp(T*h*scale)}; return res; });
models.emplace_back(s, scale, T);
s = "/" + s;
}
}