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