04-02-2022, 02:53 PM | #1 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,296
|
Help with gfx_rotoblit?
This is killing me. Mostly because it's probably a lot simpler than I'm making it out to be, but I just can't get it to work.
Code:
gfx_rotoblit(srcidx, angle, x, y, w, h, srcx, srcy, w, h, cliptosrcrect, centxoffs, centyoffs] ) I don't super need a lecture on linear algebra and all that matrix stuff. What I do kind of need is a function something like: Code:
sane_rotoblit (sridx, dest_cntr_x, dest_center_y, scale_x, scale_y, angle)
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika |
04-02-2022, 07:50 PM | #2 |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 690
|
I had at some point in the past understood how the rotoblit() function works but I was never able to prevent it from cutting the edges of a full image even with downsizing. The only trick I found is to rotoblit() in the middle of a temporary larger image and then blit() back to the frame buffer but you end up with some opaque black around the shape unless you allocate an temporary image with an alpha plane.
|
04-03-2022, 01:10 AM | #3 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,296
|
Well yeah see that’s what happens if you use it “as intended”. That is, it gets clipped to the destination w and h, which is why I want to leave those as the full window. It then will work for what I’m trying to do, if I can just figure out the right value for the other arguments to reliably place things.
BTW I did try your trick for allocating a transparent space, but couldn’t get it to work for some reason. Then I realized it wasn’t super necessary if only…
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika Last edited by ashcat_lt; 04-03-2022 at 01:16 AM. |
04-03-2022, 04:03 AM | #4 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 690
|
Quote:
|
|
04-03-2022, 10:32 AM | #5 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 690
|
Quote:
Code:
//Overlay: image w/non-clipping rotation //by papagirafe //@param1:zoom 'zoom %' 100 1 400 100 0.1 //@param2:rot 'rotation (deg)' 0 -180 180 0 0.1 //@param4:posx 'offset x' 0 -2 2 0 0.001 //@param5:posy 'offset y' 0 -2 2 0 0.001 //@param6:centx 'axis offset x' 0 -2 2 0 0.001 //@param7:centy 'axis offset y' 0 -2 2 0 0.001 //@param9:debug 'monitor' 0 0 1 0.5 1 function radius_max() ( zsw=floor(sw*zoom+0.5); zsh=floor(sh*zoom+0.5); zax=floor((centx+sw/2)*zoom+0.5); zay=floor((centy+sh/2)*zoom+0.5); a2tl=ceil(sqrt(abs(0-zax)^2 + abs(0-zay)^2)); a2tr=ceil(sqrt(abs(zsw-zax)^2 + abs(0-zay)^2)); a2bl=ceil(sqrt(abs(0-zax)^2 + abs(zsh-zay)^2)); a2br=ceil(sqrt(abs(zsw-zax)^2 + abs(zsh-zay)^2)); max(max(a2tl,a2tr),max(a2bl,a2br)); ); function monitor() ( sprintf(t=#,"source:%5dx%-5d\nzoomed:%5dx%-5d\n axis:%5i,%-5i\nradius max:%-6d ", sw,sh, floor(sw*zoom+0.5),floor(sh*zoom+0.5), (centx+sw/2)*zoom,(centy*zoom+sh/2)*zoom, radius_max(); ); gfx_setfont(0.05*project_h,"lucida console",'V'); gfx_set(1,1,1,1); gfx_str_draw(t); ); zoom/=100; rotation=rot/180*$pi; input_info(0,sw,sh); pw=project_w; ph=project_h; centx*=sw/2; centy*=sh/2; posx*=pw/2; posy*=ph/2; rmax = radius_max(); gfx_blit(1,1); gfx_rotoblit( 0,rotation, posx-pw*zoom+pw/2-sw*zoom/2,posy-ph*zoom+ph/2-sh*zoom/2,pw*3*zoom,ph*3*zoom, -sw,-sh,sw*3,sh*3, 1, centx,centy ); debug ? monitor(); Last edited by papagirafe; 04-03-2022 at 01:55 PM. Reason: found better code |
|
04-05-2022, 12:56 PM | #6 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,296
|
I really do appreciate you're trying to help, but honestly, you didn't give me specifically what i asked for. I'll buy you a drink next time you're in town anyway.
I think I made the whole thing a lot more complicated than I really needed to, and this first demonstration thing doesn't ultimately accomplish much different from what the built in track opacity/zoom/an does. But, I found my way through it, and now have a function with which I can interact in a way that makes sense to me. ATM it depends on a few other functions from a library I'm developing, but I intend to roll it down into a standalone thing at some point. Code:
graf_rotoblit (src, x, y, w, h, angle) src - input track or other allocated image index x, y - in "cartesian coordinates" with (0,0) in the center and (1,1) in the upper left, just like we're used to seeing in algebra class. w, h - width and height of the result as a fraction of the window size. angle - in radians. Code:
//demonstration of graf_rotoblit with supporting functions //@param1:ox 'x' -1 -1 1 0 0.1 //@param2:oy 'y' 1 -1 1 0 0.1 //@param3:x_size 'width' 1 //@param4:y_size 'height' 1 //@param5:angle 'angle' 0 //@param6:back 'background: black/input' 0 0 1 0.5 1 //@param7:src 'source track' 0 0 50 25 1 math.huge = 2^32 - 1; math.two_pi = $pi * 2; math.clamp_huge.min = -math.huge; math.clamp_huge.max = math.huge; function clamp(in) (max(this.min, min(this.max, in)); ); function lerp (o_min, o_max, t_min, t_max, o_val) local (out, o_dif) (o_dif = o_max - o_min; o_dif == 0 ? out = 0: out = t_min + ((o_val - o_min) / (o_dif)) * (t_max - t_min)); function vector (o_x, o_y, t_x, t_y) (this.origin.x = o_x; this.origin.y = o_y; this.term.x = t_x; this.term.y = t_y; this.dif.x = t_x - o_x; this.dif.y = t_y - o_y; this.cntr.x = 0.5 * (this.origin.x + this.term.x); this.cntr.y = 0.5 * (this.origin.y + this.term.y); this.dif_2.x = this.dif.x * this.dif.x; this.dif_2.y = this.dif.y * this.dif.y; this.sqr_d = this.dif_2.x + this.dif_2.y; this.distance = sqrt (this.sqr_d); this.trig.sin_d = this.dif.y / this.distance; this.trig.cos_d = this.dif.x / this.distance; this.trig.tan_d = math.clamp_huge.clamp (this.dif.y / this.dif.x); this.norm.origin.x = 0; this.norm.origin.y = 0; this.norm.dif.x = this.norm.term.x = this.trig.cos_d; this.norm.dif.y = this.norm.term.y = this.trig.sin_d;); function vector_rotate_angle (v1*, angle) local (sin_b, cos_b, sin_ab, cos_ab) (sin_b = sin (angle); cos_b = cos (angle); sin_ab = v1.distance * (v1.trig.sin_d * cos_b + sin_b * v1.trig.cos_d); cos_ab = v1.distance * (cos_b * v1.trig.cos_d - sin_b * v1.trig.sin_d); this.vector (v1.origin.x, v1.origin.y, v1.origin.x + cos_ab, v1.origin.y + sin_ab);); function graf_translate_point (p1*) (this.x = lerp (-universe.scale, universe.scale, window.origin.x, window.term.x, p1.x); this.y = lerp (-universe.scale, universe.scale, window.term.y, window.origin.y, p1.y);); function graf_rotoblit (src, x, y, w, h, angle) local (half_x, half_y, srcw, srch, cx, cy, scrx, srcy) instance (source, target) (scale_x = 1/w; scale_y = 1/h; half_x = 0.5 * scale_x; half_y = 0.5 * scale_y; srcw = this.w * scale_x; srch = this.h * scale_y; cx = -srcw * 0.5; cy = -srch * 0.5; target.vector (0, 0, x, y); target.vector_rotate_angle(target, angle); source.x = scale_x * target.dif.x - (1 - scale_x); source.y = scale_y * target.dif.y + (1 - scale_y); source.graf_translate_point (source); srcx = -source.x; srcy = -source.y; gfx_rotoblit (src, angle, 0, 0, this.w, this.h, srcx, srcy, srcw, srch, 0); ); universe.scale = 1; window.vector (0, 0, project_w, project_h); window.w = window.dif.x; window.h = window.dif.y; gfx_set (0); gfx_fillrect (window.origin.x, window.origin.y, window.w, window.h); back == 1 ? gfx_blit (0); angle = math.two_pi * angle; window.w = window.dif.x; window.h = window.dif.y; window.graf_rotoblit (src, ox, oy, x_size, y_size, angle); Gonna go buy myself a beer or 12.
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika |
Thread Tools | |
Display Modes | |
|
|