mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 09:50:34 +00:00
texture editing improved
This commit is contained in:
parent
c003dda811
commit
e5c22834fe
5
hyper.h
5
hyper.h
@ -656,7 +656,7 @@ inline void popScreenAll() { while(size(screens)>1) popScreen(); }
|
||||
extern transmatrix View; // current rotation, relative to viewctr
|
||||
extern transmatrix cwtV; // player-relative view
|
||||
|
||||
extern cell *mouseover, *mouseover2;
|
||||
extern cell *mouseover, *mouseover2, *lmouseover;
|
||||
extern string mouseovers;
|
||||
|
||||
extern struct SDL_Surface *s;
|
||||
@ -2377,6 +2377,9 @@ namespace texture {
|
||||
};
|
||||
|
||||
extern eTextureState tstate;
|
||||
extern unsigned paint_color;
|
||||
extern ld penwidth;
|
||||
extern transmatrix itt;
|
||||
|
||||
void showMenu();
|
||||
|
||||
|
@ -933,7 +933,7 @@ namespace mapeditor {
|
||||
break;
|
||||
}
|
||||
|
||||
usershape *us =usershapes[drawcellShapeGroup()][drawcellShapeID()];
|
||||
us =usershapes[drawcellShapeGroup()][drawcellShapeID()];
|
||||
}
|
||||
|
||||
int fs = min(vid.fsize + 5, vid.yres/28);
|
||||
@ -970,6 +970,8 @@ namespace mapeditor {
|
||||
|
||||
}
|
||||
else if(texture::tstate == texture::tsActive) {
|
||||
displayButton(8, 8+fs*7, XLAT("p = color"), 'p', 0);
|
||||
displayButton(8, 8+fs*8, XLAT("w = pen size: %1", fts4(texture::penwidth)), 'w', 0);
|
||||
}
|
||||
else {
|
||||
displaymm('n', 8, 8+fs*5, 2, vid.fsize, XLAT("'n' to start"), 0);
|
||||
@ -1286,8 +1288,8 @@ namespace mapeditor {
|
||||
hyperpoint mh = inverse(drawtrans) * mouseh;
|
||||
if(uni == 'g') coldcenter = ccenter, ccenter = mh;
|
||||
|
||||
if(uni == 'z') vid.scale *= 2;
|
||||
if(uni == 'o') vid.scale /= 2;
|
||||
if(uni == 'z') vid.scale *= 2, texture::itt = xyscale(texture::itt, .5);
|
||||
if(uni == 'o') vid.scale /= 2, texture::itt = xyscale(texture::itt, 2);
|
||||
|
||||
if(uni == ' ' && cheater) {
|
||||
popScreen();
|
||||
@ -1320,9 +1322,33 @@ namespace mapeditor {
|
||||
|
||||
if(texture::tstate == texture::tsActive) {
|
||||
if(uni == '-') {
|
||||
texture::drawPixel(mouseover, mouseh, colortouse);
|
||||
texture::drawPixel(mouseover, mouseh, (texture::paint_color >> 8) | ((texture::paint_color & 0xFF) << 24));
|
||||
holdmouse = true;
|
||||
}
|
||||
|
||||
if(uni == 'p') {
|
||||
static unsigned texture_colors[] = {
|
||||
11,
|
||||
0x000000FF,
|
||||
0xFFFFFFFF,
|
||||
0xFF0000FF,
|
||||
0xFFFF00FF,
|
||||
0x00FF00FF,
|
||||
0x00FFFFFF,
|
||||
0x0000FFFF,
|
||||
0xFF00FFFF,
|
||||
0xC0C0C0FF,
|
||||
0x808080FF,
|
||||
0x404040FF,
|
||||
0x804000FF
|
||||
};
|
||||
dialog::openColorDialog(colortouse, texture_colors);
|
||||
dialog::openColorDialog(texture::paint_color);
|
||||
colorkey = true;
|
||||
}
|
||||
|
||||
if(uni == 'w')
|
||||
dialog::editNumber(texture::penwidth, 0, 0.1, 0.005, 0.02, XLAT("pen width"), XLAT("pen width"));
|
||||
}
|
||||
|
||||
else {
|
||||
@ -1430,18 +1456,23 @@ namespace mapeditor {
|
||||
}
|
||||
}
|
||||
|
||||
if(cmode & sm::DRAW) {
|
||||
if(cmode & sm::DRAW) if(!holdmouse) {
|
||||
|
||||
if(texture::tstate == texture::tsActive && mouseover && !mouseout()) {
|
||||
auto sio = patterns::getpatterninfo0(mouseover);
|
||||
if(texture::tstate == texture::tsActive && lmouseover && !mouseout()) {
|
||||
auto sio = patterns::getpatterninfo0(lmouseover);
|
||||
auto sih = patterns::getpatterninfo0(c);
|
||||
|
||||
if(sio.id == sih.id) {
|
||||
if(c == mouseover) textrans = V * applyPatterndir(mouseover, sio);
|
||||
hyperpoint mh = inverse(mapeditor::textrans) * mouseh;
|
||||
if(c == lmouseover)
|
||||
textrans = inverse(V * applyPatterndir(mouseover, sio));
|
||||
transmatrix mh = textrans * rgpushxto0(mouseh);
|
||||
for(int i=0; i<c->type; i += sih.symmetries) {
|
||||
hyperpoint P2 = V * spin(2*M_PI*i/c->type) * mh;
|
||||
queuechr(P2, 10, 'x', 0xFF00FF);
|
||||
transmatrix M2 = V * spin(2*M_PI*i/c->type) * mh;
|
||||
array<hyperpoint, 6> pts;
|
||||
for(int j=0; j<6; j++)
|
||||
pts[j] = M2 * tC0(spin(M_PI*j/3) * xpush(texture::penwidth));
|
||||
for(int j=0; j<6; j++)
|
||||
queueline(pts[j], pts[(j+1)%6], texture::paint_color, 0, PPR_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
86
textures.cpp
86
textures.cpp
@ -31,6 +31,8 @@ SDL_Surface *convertSurface(SDL_Surface* s) {
|
||||
|
||||
int twidth = 2048;
|
||||
|
||||
unsigned paint_color = 0x000000FF;
|
||||
|
||||
vector<int> expanded_data;
|
||||
|
||||
string texturename = "hyperrogue-texture.png";
|
||||
@ -275,7 +277,8 @@ void perform_mapping() {
|
||||
if(gsplits > 4) gsplits = 4;
|
||||
using namespace patterns;
|
||||
texture_map.clear();
|
||||
for(auto p: gmatrix) {
|
||||
|
||||
for(auto& p: gmatrix) {
|
||||
cell *c = p.first;
|
||||
auto si = getpatterninfo0(c);
|
||||
bool replace = false;
|
||||
@ -292,10 +295,22 @@ void perform_mapping() {
|
||||
mapTexture(c, mi, si, p.second);
|
||||
mi.texture_id = textureid;
|
||||
}
|
||||
texture_map[si.id].matrices.push_back(p.second);
|
||||
}
|
||||
|
||||
models.clear();
|
||||
for(auto& t: texture_map) models.insert(t.second.c);
|
||||
|
||||
for(auto& p: gmatrix) {
|
||||
cell *c = p.first;
|
||||
bool nearmodel = models.count(c);
|
||||
forCellEx(c2, c)
|
||||
if(models.count(c2))
|
||||
nearmodel = true;
|
||||
if(nearmodel) {
|
||||
auto si = getpatterninfo0(c);
|
||||
texture_map[si.id].matrices.push_back(p.second * applyPatterndir(c, si));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int forgeArgs() {
|
||||
@ -739,7 +754,6 @@ void showMenu() {
|
||||
if(whitetexture() && loadTextureGL()) {
|
||||
tstate = tstate_max = tsActive;
|
||||
perform_mapping();
|
||||
mapeditor::colortouse = 0xFFFF00FF;
|
||||
mapeditor::initdraw(cwt.c);
|
||||
pushScreen(mapeditor::showDrawEditor);
|
||||
}
|
||||
@ -788,13 +802,15 @@ void showMenu() {
|
||||
int lastupdate;
|
||||
|
||||
void update() {
|
||||
if(lastupdate && ticks > lastupdate + 100) {
|
||||
if(lastupdate && ticks > lastupdate + 50) {
|
||||
loadTextureGL();
|
||||
lastupdate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pair<int,int> ptc(hyperpoint h) {
|
||||
typedef pair<int,int> point;
|
||||
|
||||
point ptc(hyperpoint h) {
|
||||
hyperpoint inmodel;
|
||||
applymodel(h, inmodel);
|
||||
inmodel = itt * inmodel;
|
||||
@ -805,42 +821,72 @@ pair<int,int> ptc(hyperpoint h) {
|
||||
return make_pair(x,y);
|
||||
}
|
||||
|
||||
array<point, 3> ptc(const array<hyperpoint, 3>& h) {
|
||||
return {ptc(h[0]), ptc(h[1]), ptc(h[2])};
|
||||
}
|
||||
|
||||
ld penwidth = .02;
|
||||
|
||||
int near(pair<int, int> p1, pair<int, int> p2) {
|
||||
return max(abs(p1.first-p2.first), abs(p1.second - p2.second));
|
||||
}
|
||||
|
||||
void filltriangle(array<hyperpoint, 3> v, int col, int lev) {
|
||||
pair<int,int> p[3] = {ptc(v[0]), ptc(v[1]), ptc(v[2])};
|
||||
void filltriangle(const array<hyperpoint, 3>& v, const array<point, 3>& p, int col, int lev) {
|
||||
|
||||
if(0) for(int i=0; i<3; i++)
|
||||
printf("#%d fillt #%d %s -> %d,%d\n", lev, i, display(v[i]), p[i].first, p[i].second);
|
||||
int d2 = near(p[0], p[1]), d1 = near(p[0], p[2]), d0 = near(p[1], p[2]);
|
||||
|
||||
if((d0 <= 1 && d1 <= 1 && d2 <= 1) || lev >= 5) {
|
||||
int a, b, c;
|
||||
|
||||
if((d0 <= 1 && d1 <= 1 && d2 <= 1) || lev >= 20) {
|
||||
for(int i=0; i<3; i++)
|
||||
expanded_data[((p[i].first) & (twidth-1)) + (p[i].second & (twidth-1)) * twidth] = col;
|
||||
return;
|
||||
}
|
||||
else if(d1 >= d0 && d1 >= d2)
|
||||
swap(v[0], v[1]);
|
||||
a = 0, b = 2, c = 1;
|
||||
else if(d2 >= d0 && d2 >= d1)
|
||||
swap(v[0], v[2]);
|
||||
a = 0, b = 1, c = 2;
|
||||
else
|
||||
a = 1, b = 2, c = 0;
|
||||
|
||||
hyperpoint v3 = mid(v[1], v[2]);
|
||||
filltriangle({v[0], v[1], v3}, col, lev+1);
|
||||
filltriangle({v[0], v[2], v3}, col, lev+1);
|
||||
hyperpoint v3 = mid(v[a], v[b]);
|
||||
point p3 = ptc(v3);
|
||||
filltriangle({v[c], v[a], v3}, {p[c], p[a], p3}, col, lev+1);
|
||||
filltriangle({v[c], v[b], v3}, {p[c], p[b], p3}, col, lev+1);
|
||||
}
|
||||
|
||||
void splitseg(const transmatrix& A, const array<ld, 2>& angles, const array<hyperpoint, 2>& h, const array<point, 2>& p, int col, int lev) {
|
||||
ld newangle = (angles[0] + angles[1]) / 2;
|
||||
hyperpoint nh = A * spin(newangle) * xpush(penwidth) * C0;
|
||||
auto np = ptc(nh);
|
||||
|
||||
filltriangle({h[0],h[1],nh}, {p[0],p[1],np}, col, lev);
|
||||
if(lev < 10) {
|
||||
if(near(p[0],np) > 1)
|
||||
splitseg(A, {angles[0], newangle}, {h[0], nh}, {p[0], np}, col, lev+1);
|
||||
if(near(np,p[1]) > 1)
|
||||
splitseg(A, {newangle, angles[1]}, {nh, h[1]}, {np, p[1]}, col, lev+1);
|
||||
}
|
||||
}
|
||||
|
||||
void fillcircle(hyperpoint h, int col) {
|
||||
transmatrix A = rgpushxto0(h);
|
||||
|
||||
ld step = M_PI * 2/3;
|
||||
|
||||
array<hyperpoint, 3> mh = {A * xpush(penwidth) * C0, A * spin(step) * xpush(penwidth) * C0, A * spin(-step) * xpush(penwidth) * C0};
|
||||
auto mp = ptc(mh);
|
||||
|
||||
ld rad = .02;
|
||||
|
||||
filltriangle({A * xpush(rad) * C0, A * spin(M_PI * 2/3) * C0, A * spin(-M_PI * 2/3) * C0}, col, 0);
|
||||
filltriangle(mh, mp, col, 0);
|
||||
|
||||
for(int i=0; i<3; i++) {
|
||||
int j = (i+1) % 3;
|
||||
if(near(mp[i], mp[j]) > 1)
|
||||
splitseg(A, {step*i, step*(i+1)}, {mh[i], mh[j]}, {mp[i], mp[j]}, col, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void drawPixel(cell *c, hyperpoint h, int col) {
|
||||
printf("s = %d\n", size(gmatrix));
|
||||
|
||||
try {
|
||||
transmatrix M = gmatrix.at(c);
|
||||
@ -848,8 +894,6 @@ void drawPixel(cell *c, hyperpoint h, int col) {
|
||||
h = inverse(M * applyPatterndir(c, si)) * h;
|
||||
auto& tinf = texture_map[si.id];
|
||||
for(auto& M2: tinf.matrices) for(int i = 0; i<c->type; i += si.symmetries) {
|
||||
hyperpoint inmodel;
|
||||
|
||||
fillcircle(M2 * spin(2 * M_PI * i / c->type) * h, col);
|
||||
lastupdate = ticks;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user