mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	texture editing improved
This commit is contained in:
		
							
								
								
									
										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; | ||||||
|       } |       } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue