Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- in vec2 texCoord;
- out vec2 newPosition;
- uniform int quads_x;
- uniform int quads_y;
- uniform GridMatrix{
- vec2 grid[400];
- } g;
- float distToLine(vec2 pt1, vec2 pt2, vec2 testPt){
- vec2 lineDir = pt2 - pt1;
- vec2 perpDir = vec2(lineDir.y, -lineDir.x);
- vec2 dirToPt1 = pt1 - testPt;
- return abs(dot(normalize(perpDir), dirToPt1));
- }
- bool pointInTriangle(vec2 A, vec2 B, vec2 C, vec2 X){
- float alpha, beta;
- // Calculate barycentric coordinates
- float det = ((B.y-C.y)*(A.x-C.x)+(C.x-B.x)*(A.y-C.y));
- alpha = ((B.y-C.y)*(X.x-C.x)+(C.x-B.x)*(X.y-C.y))/det;
- beta = ((C.y-A.y)*(X.x-C.x)+(A.x-C.x)*(X.y-C.y))/det;
- if(alpha+beta >= 0.0 && alpha+beta <= 1.0 && alpha >= 0.0 && alpha <= 1.0 && beta >= 0.0 && beta <= 1.0)
- return true;
- return false;
- }
- vec2 bilinearInterpolation(vec2 point, vec2 local_bl, vec2 local_br, vec2 local_tl, vec2 local_tr, bool vert_parallel, bool hori_parallel){
- float s, t;
- bool vert_parallel = cross(vec3((local_tl-local_bl), 0), vec3(local_tr-local_br, 0)).z == 0.0;
- bool hori_parallel = cross(vec3((local_tl-local_tr), 0), vec3(local_bl-local_br, 0)).z == 0.0;
- vec3 A = vec3(local_bl.x, local_bl.y, 0);
- vec3 B = vec3(local_br.x, local_br.y, 0);
- vec3 C = vec3(local_tr.x, local_tr.y, 0);
- vec3 D = vec3(local_tl.x, local_tl.y, 0);
- vec3 M = vec3(point, 0);
- if(!vert_parallel && !hori_parallel){
- float a = (cross(C,D)+cross(D,B)+cross(A,C)+cross(B,A)).z;
- float b = (cross(M,C)+cross(D,M)+cross(B,M)+cross(M,A)+cross(C,A)+cross(B,D)+2.0*cross(A,B)).z;
- float c = (cross(M,B)+cross(A,M)+cross(B,A)).z;
- float t1 = (-b+sqrt(pow(b,2.0)-4.0*a*c))/(2.0*a);
- float t2 = (-b-sqrt(pow(b,2.0)-4.0*a*c))/(2.0*a);
- t = t1;
- if(t1 < 0.0 || t1 > 1.0)
- if(abs(t1) > abs(t2))
- t = t2;
- s = (M.x-A.x-t *(D.x-A.x))/(B.x-A.x+t*(C.x-D.x-B.x+A.x));
- }
- else if(vert_parallel && !hori_parallel){ // vertical edges parallel
- float dist1 = distToLine(local_tl, local_bl, point);
- float dist2 = distToLine(local_tr, local_br, point);
- s = dist1/(dist1+dist2);
- t = (M.y-A.y-s *(B.y-A.y))/(D.y-A.y+s*(C.y-D.y-B.y+A.y));
- }
- else if(!vert_parallel && hori_parallel){// horizontal edges parallel
- float dist1 = distToLine(local_bl, local_br, point);
- float dist2 = distToLine(local_tl, local_tr, point);
- t = dist1/(dist1+dist2);
- s = (M.x-A.x-t *(D.x-A.x))/(B.x-A.x+t*(C.x-D.x-B.x+A.x));
- }
- else{
- float dist1 = distToLine(local_bl, local_br, point);
- float dist2 = distToLine(local_tl, local_tr, point);
- t = dist1/(dist1+dist2);
- dist1 = distToLine(local_bl, local_tl, point);
- dist2 = distToLine(local_br, local_tr, point);
- s = dist1/(dist1+dist2);
- }
- return vec2(s, t);
- }
- vec2 staticWarp(vec2 point){
- int x = 0;
- int y = 0;
- while(y < quads_y){
- int curr_y = y*(quads_x+1);
- int curr_y_plus1 = (y+1)*(quads_x+1);
- vec2 bl = g.grid[curr_y_plus1+x]; // bottom left
- vec2 br = g.grid[curr_y_plus1+x+1]; // bottom right
- vec2 tl = g.grid[curr_y+x]; // top left
- vec2 tr = g.grid[curr_y+x+1]; // top right
- if(pointInTriangle(bl, br, tl, point) || pointInTriangle(tl, tr, br, point)){
- point = bilinearInterpolation(point, bl, br, tl, tr);
- point = vec2((x + point.x)/quads_x, (quads_y - y - 1 + point.y)/quads_y);
- return point;
- }
- x = x + 1;
- if ( x == quads_x){
- x = 0;
- y = y + 1;
- }
- }
- return vec2(-1.0, -1.0);
- }
- void main()
- {
- vec2 point = texCoord;
- point = staticWarp(point);
- newPosition = point;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement