├── .gitignore ├── README.md ├── makefile ├── resource ├── canyon.png ├── fruit.png ├── imageA.png ├── imageB.png ├── meninas.png ├── miniA.png ├── miniB.png ├── shoeA.png ├── shoeB.png └── test │ ├── balloon.png │ ├── bokeh.png │ ├── child.png │ ├── city.png │ ├── cliffs.png │ ├── pier.png │ └── table.png ├── screenshots ├── interpolate.gif ├── meninas.png ├── meninas_lines.png ├── rgbd-mesh.gif ├── rgbd-pointcloud.jpg ├── rgbd-triangulation.jpg ├── shoeA.gif ├── shoeB.gif ├── warp.gif └── warp_texture.gif ├── software ├── README.md ├── rgbd │ ├── 0d.png │ ├── 0rgb.png │ ├── 1d.png │ ├── 1rgb.png │ ├── README.md │ ├── main.cpp │ ├── makefile │ └── shader │ │ ├── linestrip.fs │ │ ├── linestrip.vs │ │ ├── particle.fs │ │ ├── particle.vs │ │ ├── triangle.fs │ │ ├── triangle.vs │ │ ├── triangle3D.fs │ │ └── triangle3D.vs ├── triangulate │ ├── main.cpp │ ├── makefile │ └── shader │ │ ├── gradient.cs │ │ ├── linestrip.fs │ │ ├── linestrip.vs │ │ ├── shift.cs │ │ ├── triangle.fs │ │ └── triangle.vs ├── view │ ├── main.cpp │ ├── makefile │ └── shader │ │ ├── linestrip.fs │ │ ├── linestrip.vs │ │ ├── triangle.fs │ │ └── triangle.vs └── warp │ ├── main.cpp │ ├── makefile │ └── shader │ ├── gradient.cs │ ├── linestrip.fs │ ├── linestrip.vs │ ├── shift.cs │ ├── triangle.fs │ └── triangle.vs ├── source ├── include │ ├── delaunator-cpp │ │ ├── delaunator-header-only.hpp │ │ ├── delaunator.cpp │ │ └── delaunator.hpp │ └── poisson.hpp ├── io.hpp ├── multiview.hpp ├── tpose.hpp ├── triangulation.hpp └── utility.hpp └── tests ├── compute_fundamental_mat ├── README.md ├── imgui.ini ├── main.cpp ├── makefile ├── model.h └── shader │ ├── linestrip.fs │ ├── linestrip.vs │ ├── triangle2D.fs │ └── triangle2D.vs ├── opt_min_energy_edgeflip ├── README.md ├── main.cpp ├── makefile ├── shader │ ├── gradient.cs │ ├── image.fs │ ├── image.vs │ ├── linestrip.fs │ ├── linestrip.vs │ ├── shift.cs │ ├── triangle.fs │ └── triangle.vs └── strat │ ├── flip_delaunay.h │ ├── flip_delaunay.png │ ├── flip_delaunay.txt │ ├── flip_delaunay_dp_2.txt │ ├── flip_delaunay_lines.png │ ├── flip_max.h │ ├── flip_max.png │ ├── flip_max.txt │ ├── flip_max_lines.png │ ├── flip_set_maxangle.h │ ├── flip_set_maxangle.txt │ ├── flip_set_maxenergy.h │ ├── flip_set_maxenergy.txt │ ├── flip_set_maxenergy_dp_10.txt │ ├── flip_set_maxenergy_dp_2.txt │ ├── flip_set_maxenergy_dp_20.txt │ ├── flip_set_maxenergy_dp_3.txt │ ├── flip_set_maxenergy_dp_50.txt │ └── plot.gp ├── opt_no_geom_shader ├── fruit.png ├── main.cpp ├── makefile └── shader │ ├── gradient.cs │ ├── linestrip.fs │ ├── linestrip.vs │ ├── shift.cs │ ├── triangle.fs │ └── triangle.vs ├── opt_topology ├── fruit.png ├── main.cpp ├── makefile └── shader │ ├── average.cs │ ├── gradient.cs │ ├── image.fs │ ├── image.vs │ ├── linestrip.fs │ ├── linestrip.vs │ ├── point.fs │ ├── point.vs │ ├── reset.cs │ ├── shift.cs │ ├── triangle.fs │ ├── triangle.gs │ └── triangle.vs ├── sfm_match_test ├── README.md ├── data.txt ├── main.cpp ├── makefile └── shader │ ├── epipolarline.fs │ ├── epipolarline.gs │ ├── epipolarline.vs │ ├── image.fs │ ├── image.vs │ ├── point.fs │ ├── point.vs │ ├── point3d.fs │ └── point3d.vs ├── tri_render_direct ├── canyon.png ├── main.cpp ├── makefile ├── shader │ ├── image.fs │ ├── image.vs │ ├── point.fs │ └── point.vs └── triangulate.h └── tri_render_indirect ├── canyon.png ├── main.cpp ├── makefile ├── shader ├── image.fs ├── image.vs ├── point.fs ├── point.vs ├── triangle.fs └── triangle.vs └── triangulate.h /.gitignore: -------------------------------------------------------------------------------- 1 | *main 2 | *.tri 3 | *.tri.warp 4 | energy*.txt 5 | ./output/* 6 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | ###################################### 2 | # tpose header files installer # 3 | ###################################### 4 | 5 | # Install Location 6 | INCLUDEPATH = /usr/local/include 7 | 8 | # List of File-Names to Install 9 | FILES_INCLUDE = poisson 10 | FILES = tpose utility triangulation multiview io 11 | 12 | install: 13 | @echo "Copying t-pose Header Files ..."; 14 | @if [ ! -d "/usr/local/include/tpose" ]; then mkdir $(INCLUDEPATH)/tpose; fi; 15 | 16 | @$(foreach var,$(FILES), cp source/$(var).hpp $(INCLUDEPATH)/tpose/$(var);) 17 | 18 | #Include Files 19 | @echo "Copying Include Headers..."; 20 | @if [ ! -d "/usr/local/include/tpose/include" ]; then mkdir $(INCLUDEPATH)/tpose/include; fi; 21 | @$(foreach var,$(FILES_INCLUDE), cp source/include/$(var).hpp $(INCLUDEPATH)/tpose/include/$(var);) 22 | 23 | @echo "Done"; 24 | 25 | all: install 26 | -------------------------------------------------------------------------------- /resource/canyon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/canyon.png -------------------------------------------------------------------------------- /resource/fruit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/fruit.png -------------------------------------------------------------------------------- /resource/imageA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/imageA.png -------------------------------------------------------------------------------- /resource/imageB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/imageB.png -------------------------------------------------------------------------------- /resource/meninas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/meninas.png -------------------------------------------------------------------------------- /resource/miniA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/miniA.png -------------------------------------------------------------------------------- /resource/miniB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/miniB.png -------------------------------------------------------------------------------- /resource/shoeA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/shoeA.png -------------------------------------------------------------------------------- /resource/shoeB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/shoeB.png -------------------------------------------------------------------------------- /resource/test/balloon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/test/balloon.png -------------------------------------------------------------------------------- /resource/test/bokeh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/test/bokeh.png -------------------------------------------------------------------------------- /resource/test/child.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/test/child.png -------------------------------------------------------------------------------- /resource/test/city.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/test/city.png -------------------------------------------------------------------------------- /resource/test/cliffs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/test/cliffs.png -------------------------------------------------------------------------------- /resource/test/pier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/test/pier.png -------------------------------------------------------------------------------- /resource/test/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/resource/test/table.png -------------------------------------------------------------------------------- /screenshots/interpolate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/interpolate.gif -------------------------------------------------------------------------------- /screenshots/meninas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/meninas.png -------------------------------------------------------------------------------- /screenshots/meninas_lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/meninas_lines.png -------------------------------------------------------------------------------- /screenshots/rgbd-mesh.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/rgbd-mesh.gif -------------------------------------------------------------------------------- /screenshots/rgbd-pointcloud.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/rgbd-pointcloud.jpg -------------------------------------------------------------------------------- /screenshots/rgbd-triangulation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/rgbd-triangulation.jpg -------------------------------------------------------------------------------- /screenshots/shoeA.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/shoeA.gif -------------------------------------------------------------------------------- /screenshots/shoeB.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/shoeB.gif -------------------------------------------------------------------------------- /screenshots/warp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/warp.gif -------------------------------------------------------------------------------- /screenshots/warp_texture.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/screenshots/warp_texture.gif -------------------------------------------------------------------------------- /software/README.md: -------------------------------------------------------------------------------- 1 | # t-pose software 2 | 3 | These are programs which apply the various t-pose concepts into useable executables. 4 | 5 | ### triangulate 6 | 7 | This program will triangulate a given image. It generates an output file "out.tri" which contains the triangulations at all specified resolutions. Note that the resolutions are given in number of triangles and currently still hardcoded. 8 | 9 | ./main -i image.png 10 | 11 | ### warp 12 | 13 | Two-way consistent warping program, which takes as input two triangulation files containing various resolutions, and two corresponding images, which it warps onto each other. The resulting triangulations are written to the output same files with the warped points. 14 | 15 | ./main -ia imageA.png -ib imageB.png -ta outA.tri -tb outB.tri 16 | 17 | ### view 18 | 19 | This is a triangulation viewer, handling both multiple triangulation sets and warped triangulations. Simply specify a triangulation file and optionally an image file 20 | 21 | ./main -t out.tri [-i image.png] 22 | 23 | ### mesh 24 | 25 | This is currently being overhauled. 26 | -------------------------------------------------------------------------------- /software/rgbd/0d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/software/rgbd/0d.png -------------------------------------------------------------------------------- /software/rgbd/0rgb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/software/rgbd/0rgb.png -------------------------------------------------------------------------------- /software/rgbd/1d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/software/rgbd/1d.png -------------------------------------------------------------------------------- /software/rgbd/1rgb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/software/rgbd/1rgb.png -------------------------------------------------------------------------------- /software/rgbd/README.md: -------------------------------------------------------------------------------- 1 | # rgbd_mesh 2 | 3 | reconstruct an RGBD image / triangulation into a 3D mesh 4 | 5 | 1. Triangulate Image 6 | 2. Fit Triangles to Depth Data, Predict Vertex Positions 7 | This is the only tricky part! 8 | 3. Determine Discontinous Vertices! 9 | 4. Render 10 | -------------------------------------------------------------------------------- /software/rgbd/makefile: -------------------------------------------------------------------------------- 1 | # TinyEngine Makefile 2 | # Compiler Configuration 3 | 4 | CC = g++-10 -std=c++20 5 | CF = -Wfatal-errors -O 6 | LF = -I/usr/local/include -L/usr/local/lib 7 | 8 | # General Linking 9 | 10 | TINYLINK = -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem 11 | 12 | # OS Specific Linking 13 | 14 | UNAME := $(shell uname) 15 | ifeq ($(UNAME), Linux) #Detect GNU/Linux 16 | TINYOS = -lX11 -lGL 17 | endif 18 | ifeq ($(UNAME), Darwin) #Detext MacOS 19 | TINYOS = -framework OpenGL 20 | endif 21 | 22 | all: main.cpp 23 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine -lrealsense2 $(TINYOS) $(TINYLINK) -o main 24 | 25 | # Build Embedded Form 26 | 27 | DAT = shader #data directory to embed 28 | .PHONY: embedded 29 | embedded: CEF = $(shell c-embed $(DAT)) c-embed.o -include /usr/local/include/c-embed.h -DCEMBED_TRANSLATE 30 | embedded: 31 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 32 | rm c-embed.o 33 | -------------------------------------------------------------------------------- /software/rgbd/shader/linestrip.fs: -------------------------------------------------------------------------------- 1 | #version 430 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,1,1, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /software/rgbd/shader/linestrip.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | layout (std430, binding = 1) buffer index { 11 | ivec4 ind[]; 12 | }; 13 | 14 | uniform float RATIO; 15 | 16 | void main() { 17 | 18 | vec2 tpos = vec2(0); 19 | if (in_Position.x > 0) tpos = p[ind[gl_InstanceID].x]; 20 | if (in_Position.y > 0) tpos = p[ind[gl_InstanceID].y]; 21 | if (in_Position.z > 0) tpos = p[ind[gl_InstanceID].z]; 22 | tpos.x /= RATIO; 23 | gl_Position = vec4(tpos, -1, 1.0f); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /software/rgbd/shader/particle.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec4 ex_Color; 4 | out vec4 fragColor; 5 | 6 | void main() { 7 | fragColor = ex_Color; 8 | } 9 | -------------------------------------------------------------------------------- /software/rgbd/shader/particle.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(location = 0) in vec4 in_Position; 4 | layout(location = 1) in vec4 in_Color; 5 | layout(location = 2) in vec4 in_Normal; 6 | 7 | out vec4 ex_Color; 8 | uniform mat4 vp; 9 | 10 | void main() { 11 | 12 | ex_Color = vec4(abs(normalize(in_Normal.xyz)), 1.0f); 13 | // ex_Color = in_Color; 14 | gl_Position = vp*in_Position; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /software/rgbd/shader/triangle.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (std430, binding = 2) buffer colacc { 4 | ivec4 ca[]; 5 | }; 6 | 7 | uniform sampler2D imageTexture; 8 | uniform int mode; 9 | 10 | in VS_OUT { 11 | vec2 position; 12 | flat int index; 13 | } vs_out; 14 | 15 | out vec4 fragColor; 16 | 17 | void main(){ 18 | 19 | // Display 20 | 21 | fragColor = vec4(vec3(ca[vs_out.index].rgb)/255, 1); 22 | //fragColor = texture(imageTexture, vs_out.position); 23 | //fragColor = vec4(1,1,1,1); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /software/rgbd/shader/triangle.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | layout (std430, binding = 1) buffer index { 11 | ivec4 ind[]; 12 | }; 13 | 14 | out VS_OUT { 15 | 16 | vec2 position; 17 | flat int index; 18 | 19 | } vs_out; 20 | 21 | uniform float RATIO; 22 | uniform int KTriangles; 23 | 24 | void main() { 25 | 26 | vec2 tpos = vec2(0); 27 | float dp = 0.01f; 28 | int TDIV = gl_InstanceID/KTriangles; 29 | int TMOD = gl_InstanceID%KTriangles; 30 | vs_out.index = gl_InstanceID; 31 | 32 | if (in_Position.x > 0) tpos = p[ind[TMOD].x]; 33 | if (in_Position.y > 0) tpos = p[ind[TMOD].y]; 34 | if (in_Position.z > 0) tpos = p[ind[TMOD].z]; 35 | tpos.x /= RATIO; 36 | 37 | gl_Position = vec4(tpos, -1, 1.0f); 38 | vs_out.position = vec2(0.5*(1.0+tpos.x), 0.5*(1.0-tpos.y)); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /software/rgbd/shader/triangle3D.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (std430, binding = 5) buffer othercol { 4 | vec4 ca[]; 5 | }; 6 | 7 | uniform sampler2D imageTexture; 8 | uniform float RATIO; 9 | 10 | in VS_OUT { 11 | flat int index; 12 | vec2 opos; 13 | flat vec3 normal; 14 | } vs_out; 15 | 16 | out vec4 fragColor; 17 | 18 | void main(){ 19 | 20 | vec2 p = vs_out.opos; 21 | p.x /= RATIO; 22 | p = (p+1.0f)*0.5;///vec2(960, 540); 23 | p.y = 1.0f-p.y; 24 | // p.y = 540-p.y; 25 | // p.x = -p.x; 26 | // p = (p/vec2(960, 540)*2.0f-1.0f)*vec2(960.0/540.0, 1.0f); 27 | 28 | 29 | // Display 30 | 31 | //fragColor = vec4(vec3(ca[vs_out.index].rgb), 1.0); 32 | fragColor = texture(imageTexture, p); 33 | //fragColor = vec4(vs_out.normal, 1.0f); 34 | //fragColor = vec4(1,0,0,0.1); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /software/rgbd/shader/triangle3D.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 3) buffer points3D { 7 | vec4 p[]; 8 | }; 9 | 10 | layout (std430, binding = 4) buffer otherindex { 11 | ivec4 ind[]; 12 | }; 13 | 14 | layout (std430, binding = 6) buffer points2D { 15 | vec2 o[]; 16 | }; 17 | 18 | out VS_OUT { 19 | 20 | flat int index; 21 | vec2 opos; 22 | flat vec3 normal; 23 | 24 | } vs_out; 25 | 26 | uniform float RATIO; 27 | uniform mat4 vp; 28 | uniform mat4 model; 29 | 30 | void main() { 31 | 32 | vec4 tpos = vec4(0); 33 | int tind; 34 | if (in_Position.x > 0) tind = ind[gl_InstanceID].x; 35 | if (in_Position.y > 0) tind = ind[gl_InstanceID].y; 36 | if (in_Position.z > 0) tind = ind[gl_InstanceID].z; 37 | tpos = p[tind]; 38 | //tpos.x /= RATIO; 39 | 40 | gl_Position = vp*model*tpos; 41 | vs_out.index = gl_InstanceID; 42 | vs_out.opos = o[tind]; 43 | vs_out.normal = abs(normalize(cross(vec3(p[ind[gl_InstanceID].y] - p[ind[gl_InstanceID].x]), vec3(p[ind[gl_InstanceID].z] - p[ind[gl_InstanceID].x])))); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /software/triangulate/makefile: -------------------------------------------------------------------------------- 1 | # TinyEngine Makefile 2 | # Compiler Configuration 3 | 4 | CC = g++-10 -std=c++20 5 | CF = -Wfatal-errors -O 6 | LF = -I/usr/local/include -L/usr/local/lib 7 | 8 | # General Linking 9 | 10 | TINYLINK = -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem 11 | 12 | # OS Specific Linking 13 | 14 | UNAME := $(shell uname) 15 | ifeq ($(UNAME), Linux) #Detect GNU/Linux 16 | TINYOS = -lX11 -lGL 17 | endif 18 | ifeq ($(UNAME), Darwin) #Detext MacOS 19 | TINYOS = -framework OpenGL 20 | endif 21 | 22 | all: main.cpp 23 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 24 | 25 | # Build Embedded Form 26 | 27 | DAT = shader #data directory to embed 28 | .PHONY: embedded 29 | embedded: CEF = $(shell c-embed $(DAT)) c-embed.o -include /usr/local/include/c-embed.h -DCEMBED_TRANSLATE 30 | embedded: 31 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 32 | rm c-embed.o 33 | -------------------------------------------------------------------------------- /software/triangulate/shader/gradient.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 1) buffer index { 6 | ivec4 ind[]; 7 | }; 8 | 9 | layout (std430, binding = 4) buffer tenergy { 10 | int ten[]; 11 | }; 12 | 13 | layout (std430, binding = 6) buffer gradient { 14 | ivec2 gr[]; 15 | }; 16 | 17 | uniform int KTriangles; 18 | 19 | void main(){ 20 | 21 | const uint index = gl_GlobalInvocationID.x; 22 | if(index >= KTriangles) 23 | return; 24 | 25 | // Add the Non-Normalized Gradient to the Per-Vertex Gradients 26 | 27 | atomicAdd(gr[ind[index].x].x, ten[ 1*KTriangles + index] - ten[ 2*KTriangles + index]); 28 | atomicAdd(gr[ind[index].x].y, ten[ 3*KTriangles + index] - ten[ 4*KTriangles + index]); 29 | 30 | atomicAdd(gr[ind[index].y].x, ten[ 5*KTriangles + index] - ten[ 6*KTriangles + index]); 31 | atomicAdd(gr[ind[index].y].y, ten[ 7*KTriangles + index] - ten[ 8*KTriangles + index]); 32 | 33 | atomicAdd(gr[ind[index].z].x, ten[ 9*KTriangles + index] - ten[10*KTriangles + index]); 34 | atomicAdd(gr[ind[index].z].y, ten[11*KTriangles + index] - ten[12*KTriangles + index]); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /software/triangulate/shader/linestrip.fs: -------------------------------------------------------------------------------- 1 | #version 430 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,1,1, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /software/triangulate/shader/linestrip.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | layout (std430, binding = 1) buffer index { 11 | ivec4 ind[]; 12 | }; 13 | 14 | uniform float RATIO; 15 | 16 | void main() { 17 | 18 | vec2 tpos = vec2(0); 19 | if (in_Position.x > 0) tpos = p[ind[gl_InstanceID].x]; 20 | if (in_Position.y > 0) tpos = p[ind[gl_InstanceID].y]; 21 | if (in_Position.z > 0) tpos = p[ind[gl_InstanceID].z]; 22 | tpos.x /= RATIO; 23 | gl_Position = vec4(tpos, -1, 1.0f); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /software/triangulate/shader/shift.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 0) buffer points { 6 | vec2 p[]; 7 | }; 8 | 9 | layout (std430, binding = 6) buffer gradient { 10 | ivec2 gr[]; 11 | }; 12 | 13 | uniform int NPoints; 14 | uniform float RATIO; 15 | 16 | void main(){ 17 | 18 | const uint index = gl_GlobalInvocationID.x; 19 | 20 | if(index < 4 || index >= NPoints) 21 | return; 22 | 23 | vec2 tgr = gr[index]; 24 | 25 | if(p[index].x <= -RATIO){ 26 | p[index].x = -RATIO; 27 | tgr.x = 0; 28 | } 29 | 30 | else if(p[index].x >= RATIO){ 31 | p[index].x = RATIO; 32 | tgr.x = 0; 33 | } 34 | 35 | if(p[index].y <= -1){ 36 | p[index].y = -1; 37 | tgr.y = 0; 38 | } 39 | 40 | else if(p[index].y >= 1){ 41 | p[index].y = 1; 42 | tgr.y = 0; 43 | } 44 | 45 | p[index] -= 0.00005 * tgr / 256 / 256; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /software/triangulate/shader/triangle.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (std430, binding = 2) buffer colacc { 4 | ivec4 ca[]; 5 | }; 6 | 7 | layout (std430, binding = 3) buffer colnum { 8 | int cn[]; 9 | }; 10 | 11 | layout (std430, binding = 4) buffer tenergy { 12 | int ten[]; 13 | }; 14 | 15 | uniform sampler2D imageTexture; 16 | uniform int mode; 17 | 18 | in VS_OUT { 19 | vec2 position; 20 | flat int index; 21 | } vs_out; 22 | 23 | out vec4 fragColor; 24 | 25 | void main(){ 26 | 27 | if( mode == 0 ){ // Accumulate Color 28 | 29 | fragColor = texture(imageTexture, vs_out.position); 30 | atomicAdd(cn[vs_out.index], 1); 31 | atomicAdd(ca[vs_out.index].r, int(255*fragColor.r)); 32 | atomicAdd(ca[vs_out.index].g, int(255*fragColor.g)); 33 | atomicAdd(ca[vs_out.index].b, int(255*fragColor.b)); 34 | 35 | } 36 | 37 | if( mode == 1 ){ // Accumulate Energy 38 | 39 | vec3 d = vec3(0); 40 | if(cn[vs_out.index] > 0) d = 255*texture(imageTexture, vs_out.position).rgb - vec3(ca[vs_out.index].rgb/cn[vs_out.index]); 41 | atomicAdd(ten[vs_out.index], int(0.5*dot(d, d))); 42 | 43 | } 44 | 45 | if( mode == 2 ){ // Display 46 | 47 | // fragColor = mix(vec4(0,0,1,1), vec4(1,0,0,1), sqrt(float(en[vs_out.index]/cn[vs_out.index]))/255.0f); 48 | fragColor = vec4(vec3(ca[vs_out.index].rgb)/cn[vs_out.index]/255, 1); 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /software/triangulate/shader/triangle.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | 5 | layout (std430, binding = 0) buffer points { 6 | vec2 p[]; 7 | }; 8 | 9 | layout (std430, binding = 1) buffer index { 10 | ivec4 ind[]; 11 | }; 12 | 13 | layout (std430, binding = 2) buffer colacc { 14 | ivec4 ca[]; 15 | }; 16 | 17 | layout (std430, binding = 3) buffer colnum { 18 | int cn[]; 19 | }; 20 | 21 | layout (std430, binding = 4) buffer tenergy { 22 | int ten[]; 23 | }; 24 | 25 | 26 | layout (std430, binding = 6) buffer gradient { 27 | ivec2 gr[]; 28 | }; 29 | 30 | layout (std430, binding = 7) buffer nring { 31 | int nr[]; 32 | }; 33 | 34 | out VS_OUT { 35 | 36 | vec2 position; 37 | flat int index; 38 | 39 | } vs_out; 40 | 41 | uniform float RATIO; 42 | uniform int KTriangles; 43 | uniform int mode; 44 | 45 | void main() { 46 | 47 | const int TDIV = gl_InstanceID/KTriangles; 48 | const int TMOD = gl_InstanceID%KTriangles; 49 | vs_out.index = gl_InstanceID; 50 | 51 | int pind; // Vertex Index 52 | if (in_Position.x > 0) 53 | pind = ind[TMOD].x; 54 | if (in_Position.y > 0) 55 | pind = ind[TMOD].y; 56 | if (in_Position.z > 0) 57 | pind = ind[TMOD].z; 58 | 59 | vec2 tpos = p[pind]; // Vertex Image-Space (-RATIO, RATIO) x, (-1, 1) y 60 | float dp = 0.05f; // Image-Space Pixel Shift 61 | 62 | dp /= (1.0f + 4.0f*float(KTriangles)/3000.0f); 63 | 64 | vec2 D = vec2(dp); 65 | 66 | if(TDIV == 1 && in_Position.x > 0) D *= vec2( 1, 0); 67 | else if(TDIV == 2 && in_Position.x > 0) D *= vec2(-1, 0); 68 | else if(TDIV == 3 && in_Position.x > 0) D *= vec2( 0, 1); 69 | else if(TDIV == 4 && in_Position.x > 0) D *= vec2( 0,-1); 70 | else if(TDIV == 5 && in_Position.y > 0) D *= vec2( 1, 0); 71 | else if(TDIV == 6 && in_Position.y > 0) D *= vec2(-1, 0); 72 | else if(TDIV == 7 && in_Position.y > 0) D *= vec2( 0, 1); 73 | else if(TDIV == 8 && in_Position.y > 0) D *= vec2( 0,-1); 74 | else if(TDIV == 9 && in_Position.z > 0) D *= vec2( 1, 0); 75 | else if(TDIV == 10 && in_Position.z > 0) D *= vec2(-1, 0); 76 | else if(TDIV == 11 && in_Position.z > 0) D *= vec2( 0, 1); 77 | else if(TDIV == 12 && in_Position.z > 0) D *= vec2( 0,-1); 78 | else D *= vec2(0); 79 | 80 | tpos += D; 81 | tpos.x /= RATIO; // Position in Screen-Space (-1, 1) for x,y 82 | 83 | gl_Position = vec4(tpos, -1, 1.0f); 84 | vs_out.position = vec2(0.5*(1.0+tpos.x), 0.5*(1.0-tpos.y)); 85 | 86 | // Reset Values 87 | 88 | if(mode == 0){ 89 | cn[vs_out.index] = 0; 90 | ca[vs_out.index] = ivec4(0); 91 | } 92 | 93 | if(mode == 1){ 94 | ten[vs_out.index] = 0; 95 | gr[ind[TMOD].x] = ivec2(0); 96 | gr[ind[TMOD].y] = ivec2(0); 97 | gr[ind[TMOD].z] = ivec2(0); 98 | } 99 | 100 | //Add One-Ring Energy 101 | 102 | if( TDIV == 0 && mode == 0 ) 103 | atomicAdd(nr[TMOD], 1 ); //count the n-ring! (divided by 3) 104 | 105 | if( TDIV == 0 && mode == 1 ) { 106 | 107 | const float lambda = 0*256*256; 108 | 109 | if (in_Position.x > 0){ 110 | 111 | vec2 wva = p[pind] - p[ind[TMOD].y]; //Distance from this Vertex to Prev 112 | vec2 wvb = p[pind] - p[ind[TMOD].z]; //Distance from this Vertex to Next 113 | //Add Direct Energy Gradient 114 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[TMOD]); 115 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[TMOD]); 116 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[TMOD]); 117 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[TMOD]); 118 | 119 | } 120 | 121 | if (in_Position.y > 0){ 122 | 123 | vec2 wva = p[pind] - p[ind[TMOD].z]; //Distance from this Vertex to Prev 124 | vec2 wvb = p[pind] - p[ind[TMOD].x]; //Distance from this Vertex to Next 125 | //Add Direct Energy Gradient 126 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[TMOD]); 127 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[TMOD]); 128 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[TMOD]); 129 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[TMOD]); 130 | 131 | } 132 | 133 | if (in_Position.z > 0){ 134 | 135 | vec2 wva = p[pind] - p[ind[TMOD].x]; //Distance from this Vertex to Prev 136 | vec2 wvb = p[pind] - p[ind[TMOD].y]; //Distance from this Vertex to Next 137 | //Add Direct Energy Gradient 138 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[TMOD]); 139 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[TMOD]); 140 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[TMOD]); 141 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[TMOD]); 142 | 143 | } 144 | 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /software/view/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace glm; 11 | using namespace std; 12 | 13 | int main( int argc, char* args[] ) { 14 | 15 | parse::get(argc, args); 16 | 17 | string tri; 18 | if(!parse::option.contains("t")){ 19 | cout<<"Please specify a input triangulation with -t."<("points", tpose::pointbuf); 63 | triangleshader.bind("index", tpose::trianglebuf); 64 | triangleshader.bind("colacc", tpose::tcolaccbuf); 65 | triangleshader.bind("otherpoints", &otherpointbuf); 66 | 67 | Shader linestrip({"shader/linestrip.vs", "shader/linestrip.fs"}, {"in_Position"}, {"points", "index", "otherpoints"}); 68 | linestrip.bind("points", tpose::pointbuf); 69 | linestrip.bind("index", tpose::trianglebuf); 70 | linestrip.bind("otherpoints", &otherpointbuf); 71 | 72 | tpose::upload(&trA); 73 | otherpointbuf.fill(trA.originpoints); 74 | 75 | Tiny::event.handler = [&](){ 76 | 77 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_p) 78 | paused = !paused; 79 | 80 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_n) 81 | showlines = !showlines; 82 | 83 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_SPACE){ 84 | if(tpose::io::read(&trA, tri)){ 85 | tpose::upload(&trA); 86 | otherpointbuf.fill(trA.originpoints); 87 | } 88 | } 89 | 90 | }; 91 | 92 | // Color Accumulation Buffers 93 | 94 | float s = 0.0f; 95 | 96 | Tiny::view.pipeline = [&](){ 97 | 98 | Tiny::view.target(color::black); //Target Main Screen 99 | 100 | triangleshader.use(); 101 | 102 | if(IMG != NULL) 103 | triangleshader.texture("imageTexture", tex); //Load Texture 104 | triangleshader.uniform("mode", 2); 105 | triangleshader.uniform("KTriangles", trA.NT); 106 | triangleshader.uniform("s", s); 107 | triangleshader.uniform("RATIO", tpose::RATIO); 108 | triangleinstance.render(GL_TRIANGLE_STRIP, trA.NT); 109 | 110 | if(showlines){ 111 | 112 | linestrip.use(); 113 | linestrip.uniform("RATIO", tpose::RATIO); 114 | linestrip.uniform("s", s); 115 | linestripinstance.render(GL_LINE_STRIP, trA.NT); 116 | 117 | } 118 | 119 | }; 120 | 121 | int NN = 0; 122 | float ds = 0.001f; 123 | Tiny::loop([&](){ 124 | s += ds; 125 | if(s < 0 || s > 1) ds *= -1; 126 | }); 127 | 128 | tpose::quit(); 129 | Tiny::quit(); 130 | 131 | return 0; 132 | 133 | } 134 | -------------------------------------------------------------------------------- /software/view/makefile: -------------------------------------------------------------------------------- 1 | # TinyEngine Makefile 2 | # Compiler Configuration 3 | 4 | CC = g++-10 -std=c++20 5 | CF = -Wfatal-errors -O 6 | LF = -I/usr/local/include -L/usr/local/lib 7 | 8 | # General Linking 9 | 10 | TINYLINK = -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem 11 | 12 | # OS Specific Linking 13 | 14 | UNAME := $(shell uname) 15 | ifeq ($(UNAME), Linux) #Detect GNU/Linux 16 | TINYOS = -lX11 -lGL 17 | endif 18 | ifeq ($(UNAME), Darwin) #Detext MacOS 19 | TINYOS = -framework OpenGL 20 | endif 21 | 22 | all: main.cpp 23 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 24 | 25 | # Build Embedded Form 26 | 27 | DAT = shader #data directory to embed 28 | .PHONY: embedded 29 | embedded: CEF = $(shell c-embed $(DAT)) c-embed.o -include /usr/local/include/c-embed.h -DCEMBED_TRANSLATE 30 | embedded: 31 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 32 | rm c-embed.o 33 | -------------------------------------------------------------------------------- /software/view/shader/linestrip.fs: -------------------------------------------------------------------------------- 1 | #version 430 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,1,1, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /software/view/shader/linestrip.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | layout (std430, binding = 1) buffer index { 11 | ivec4 ind[]; 12 | }; 13 | 14 | layout (std430, binding = 3) buffer otherpoints { 15 | vec2 op[]; 16 | }; 17 | 18 | uniform float RATIO; 19 | uniform float s; 20 | 21 | void main() { 22 | 23 | vec2 tpos = vec2(0); 24 | if (in_Position.x > 0) tpos = mix(p[ind[gl_InstanceID].x], op[ind[gl_InstanceID].x], s); 25 | if (in_Position.y > 0) tpos = mix(p[ind[gl_InstanceID].y], op[ind[gl_InstanceID].y], s); 26 | if (in_Position.z > 0) tpos = mix(p[ind[gl_InstanceID].z], op[ind[gl_InstanceID].z], s); 27 | tpos.x /= RATIO; 28 | gl_Position = vec4(tpos, -1, 1.0f); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /software/view/shader/triangle.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (std430, binding = 2) buffer colacc { 4 | ivec4 ca[]; 5 | }; 6 | 7 | uniform sampler2D imageTexture; 8 | uniform int mode; 9 | 10 | in VS_OUT { 11 | vec2 position; 12 | vec2 opos; 13 | flat int index; 14 | } vs_out; 15 | 16 | out vec4 fragColor; 17 | 18 | void main(){ 19 | 20 | // Display 21 | 22 | if( mode == 2 ){ 23 | 24 | fragColor = vec4(vec3(ca[vs_out.index].rgb)/255, 1); 25 | //fragColor = texture(imageTexture, vs_out.opos); 26 | //fragColor = vec4(0,0,0,1); 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /software/view/shader/triangle.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | layout (std430, binding = 1) buffer index { 11 | ivec4 ind[]; 12 | }; 13 | 14 | layout (std430, binding = 3) buffer otherpoints { 15 | vec2 op[]; 16 | }; 17 | 18 | out VS_OUT { 19 | 20 | vec2 position; 21 | vec2 opos; 22 | flat int index; 23 | 24 | } vs_out; 25 | 26 | uniform float RATIO; 27 | uniform int KTriangles; 28 | uniform float s; 29 | 30 | void main() { 31 | 32 | vec2 tpos = vec2(0); 33 | vec2 opos = vec2(0); 34 | float dp = 0.01f; 35 | int TDIV = gl_InstanceID/KTriangles; 36 | int TMOD = gl_InstanceID%KTriangles; 37 | vs_out.index = gl_InstanceID; 38 | 39 | if (in_Position.x > 0) tpos = mix(p[ind[TMOD].x], op[ind[TMOD].x], s); 40 | if (in_Position.y > 0) tpos = mix(p[ind[TMOD].y], op[ind[TMOD].y], s); 41 | if (in_Position.z > 0) tpos = mix(p[ind[TMOD].z], op[ind[TMOD].z], s); 42 | tpos.x /= RATIO; 43 | 44 | if (in_Position.x > 0) opos = mix(p[ind[TMOD].x], op[ind[TMOD].x], 1); 45 | if (in_Position.y > 0) opos = mix(p[ind[TMOD].y], op[ind[TMOD].y], 1); 46 | if (in_Position.z > 0) opos = mix(p[ind[TMOD].z], op[ind[TMOD].z], 1); 47 | opos.x /= RATIO; 48 | 49 | gl_Position = vec4(tpos, -1, 1.0f); 50 | vs_out.position = vec2(0.5*(1.0+tpos.x), 0.5*(1.0-tpos.y)); 51 | vs_out.opos = vec2(0.5*(1.0+opos.x), 0.5*(1.0-opos.y)); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /software/warp/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | using namespace glm; 12 | 13 | int main( int argc, char* args[] ) { 14 | 15 | parse::get(argc, args); 16 | 17 | if(!parse::option.contains("ia")){ 18 | cout<<"Please specify an input image A with -ia."<w != IMGB->w || IMGA->h != IMGB->h){ 52 | cout<<"Images don't have the same dimension"<w/1.5, IMGA->h/1.5); 65 | 66 | glDisable(GL_CULL_FACE); 67 | 68 | bool paused = true; 69 | bool viewlines = false; 70 | 71 | Tiny::event.handler = [&](){ 72 | 73 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_p) 74 | paused = !paused; 75 | 76 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_n) 77 | viewlines = !viewlines; 78 | 79 | }; 80 | Tiny::view.interface = [](){}; 81 | 82 | tpose::init(); 83 | 84 | // Shaders and Buffers 85 | 86 | Shader linestrip({"shader/linestrip.vs", "shader/linestrip.fs"}, {"in_Position"}, {"points", "index"}); 87 | linestrip.bind("points", tpose::pointbuf); 88 | linestrip.bind("index", tpose::trianglebuf); 89 | 90 | Shader triangleshader({"shader/triangle.vs", "shader/triangle.fs"}, {"in_Position"}, {"points", "index", "colacc", "colnum", "tenergy", "penergy", "gradient", "nring"}); 91 | triangleshader.bind("points", tpose::pointbuf); 92 | triangleshader.bind("index", tpose::trianglebuf); 93 | triangleshader.bind("colacc", tpose::tcolaccbuf); 94 | triangleshader.bind("colnum", tpose::tcolnumbuf); 95 | triangleshader.bind("tenergy", tpose::tenergybuf); 96 | triangleshader.bind("penergy", tpose::penergybuf); 97 | triangleshader.bind("gradient", tpose::pgradbuf); 98 | triangleshader.bind("nring", tpose::tnringbuf); 99 | 100 | Compute gradient({"shader/gradient.cs"}, {"index", "tenergy", "penergy", "gradient"}); 101 | gradient.bind("index", tpose::trianglebuf); 102 | gradient.bind("tenergy", tpose::tenergybuf); 103 | gradient.bind("penergy", tpose::penergybuf); 104 | gradient.bind("gradient", tpose::pgradbuf); 105 | 106 | Compute shift({"shader/shift.cs"}, {"points", "gradient"}); 107 | shift.bind("points", tpose::pointbuf); 108 | shift.bind("gradient", tpose::pgradbuf); 109 | 110 | // Load two Triangulations 111 | 112 | bool warpA = true; 113 | 114 | tpose::triangulation trA, trB; 115 | tpose::io::read(&trA, triA); 116 | tpose::io::read(&trB, triB); 117 | 118 | Texture texA(IMGA); //Load Texture with Image A 119 | Texture texB(IMGB); //Load Texture with Image B 120 | 121 | tpose::triangulation* tr; 122 | 123 | if(warpA) tr = &trA; 124 | else tr = &trB; 125 | 126 | tpose::upload(tr); 127 | 128 | // Render Objects 129 | 130 | Square2D flat; 131 | 132 | Triangle triangle; 133 | Instance triangleinstance(&triangle); 134 | 135 | TLineStrip tlinestrip; 136 | Instance linestripinstance(&tlinestrip); 137 | 138 | // Convenience Lambdas 139 | 140 | auto doreset = [&](){ 141 | 142 | triangleshader.use(); 143 | triangleshader.texture("imageA", texA); //Load Texture 144 | triangleshader.texture("imageB", texB); //Load Texture 145 | triangleshader.uniform("warpA", warpA); 146 | triangleshader.uniform("mode", 0); 147 | triangleshader.uniform("KTriangles", tr->NT); 148 | triangleshader.uniform("RATIO", tpose::RATIO); 149 | triangleinstance.render(GL_TRIANGLE_STRIP, (13*tr->NT)); 150 | 151 | }; 152 | 153 | auto doenergy = [&](){ 154 | 155 | triangleshader.use(); 156 | triangleshader.texture("imageA", texA); //Load Texture 157 | triangleshader.texture("imageB", texB); //Load Texture 158 | triangleshader.uniform("warpA", warpA); 159 | triangleshader.uniform("mode", 1); 160 | triangleshader.uniform("KTriangles", tr->NT); 161 | triangleshader.uniform("RATIO", tpose::RATIO); 162 | triangleinstance.render(GL_TRIANGLE_STRIP, (13*tr->NT)); 163 | 164 | }; 165 | 166 | auto doshift = [&](){ 167 | 168 | gradient.use(); 169 | gradient.uniform("KTriangles", tr->NT); 170 | gradient.uniform("RATIO", tpose::RATIO); 171 | gradient.dispatch(1 + tr->NT/1024); 172 | 173 | shift.use(); 174 | shift.uniform("NPoints", tr->NP); 175 | shift.uniform("RATIO", tpose::RATIO); 176 | shift.dispatch(1 + tr->NP/1024); 177 | 178 | }; 179 | 180 | auto draw = [&](){ 181 | 182 | triangleshader.use(); 183 | triangleshader.texture("imageA", texA); //Load Texture 184 | triangleshader.texture("imageB", texB); //Load Texture 185 | triangleshader.uniform("warpA", warpA); 186 | triangleshader.uniform("mode", 2); 187 | triangleshader.uniform("KTriangles", tr->NT); 188 | triangleshader.uniform("RATIO", tpose::RATIO); 189 | triangleinstance.render(GL_TRIANGLE_STRIP, tr->NT); 190 | 191 | if(viewlines){ 192 | 193 | linestrip.use(); 194 | linestrip.uniform("RATIO", tpose::RATIO); 195 | linestripinstance.render(GL_LINE_STRIP, tr->NT); 196 | 197 | } 198 | 199 | }; 200 | 201 | // Main Functions 202 | doreset(); 203 | 204 | Tiny::view.pipeline = [&](){ 205 | 206 | Tiny::view.target(color::black); //Target Main Screen 207 | draw(); 208 | 209 | }; 210 | 211 | int NWARPA = 0; 212 | int NWARPB = 0; 213 | 214 | Tiny::loop([&](){ 215 | 216 | if(paused) return; 217 | 218 | // Compute Cost and Gradients, Shift Points 219 | 220 | doreset(); 221 | doenergy(); 222 | doshift(); 223 | 224 | // Retrieve Data from Compute Shader 225 | 226 | tpose::tenergybuf->retrieve((13*tr->NT), tpose::terr); 227 | tpose::penergybuf->retrieve(tr->NP, tpose::perr); 228 | tpose::tcolnumbuf->retrieve((13*tr->NT), tpose::cn); 229 | tpose::pointbuf->retrieve(tr->points); 230 | 231 | if( tpose::geterr(tr) < 1E-6 ){ 232 | 233 | // Flip the Warp 234 | 235 | if(warpA){ 236 | 237 | trB.points = trB.originpoints; 238 | trA.reversewarp( trB.points ); 239 | NWARPA++; 240 | 241 | } 242 | 243 | else { 244 | 245 | trA.points = trA.originpoints; 246 | trB.reversewarp( trA.points ); 247 | NWARPB++; 248 | 249 | } 250 | 251 | warpA = !warpA; 252 | 253 | if(warpA) tr = &trA; 254 | else tr = &trB; 255 | 256 | // Check for Warp Count 257 | 258 | if(NWARPA < 1 && NWARPB < 1){ 259 | tpose::upload(tr); 260 | return; 261 | } 262 | 263 | cout<<"IM HERE"<= KTriangles) 23 | return; 24 | 25 | // Add the Non-Normalized Gradient to the Per-Vertex Gradients 26 | 27 | ivec2 xgrad = ivec2( 28 | ten[ 1*KTriangles + index] - ten[ 2*KTriangles + index], 29 | ten[ 3*KTriangles + index] - ten[ 4*KTriangles + index] 30 | ); 31 | 32 | ivec2 ygrad = ivec2( 33 | ten[ 5*KTriangles + index] - ten[ 6*KTriangles + index], 34 | ten[ 7*KTriangles + index] - ten[ 8*KTriangles + index] 35 | ); 36 | 37 | ivec2 zgrad = ivec2( 38 | ten[ 9*KTriangles + index] - ten[10*KTriangles + index], 39 | ten[11*KTriangles + index] - ten[12*KTriangles + index] 40 | ); 41 | 42 | atomicAdd(gr[ind[index].x].x, xgrad.x /* + int(0.0f*ygrad.x) + int(0.0f*zgrad.x) */ ); 43 | atomicAdd(gr[ind[index].x].y, xgrad.y /* + int(0.0f*ygrad.y) + int(0.0f*zgrad.y) */ ); 44 | 45 | atomicAdd(gr[ind[index].y].x, ygrad.x /* + int(0.0f*zgrad.x) + int(0.0f*xgrad.x) */ ); 46 | atomicAdd(gr[ind[index].y].y, ygrad.y /* + int(0.0f*zgrad.y) + int(0.0f*xgrad.y) */ ); 47 | 48 | atomicAdd(gr[ind[index].z].x, zgrad.x /* + int(0.0f*xgrad.x) + int(0.0f*ygrad.x) */ ); 49 | atomicAdd(gr[ind[index].z].y, zgrad.y /* + int(0.0f*xgrad.y) + int(0.0f*ygrad.y) */ ); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /software/warp/shader/linestrip.fs: -------------------------------------------------------------------------------- 1 | #version 430 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,1,1, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /software/warp/shader/linestrip.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | layout (std430, binding = 1) buffer index { 11 | ivec4 ind[]; 12 | }; 13 | 14 | uniform float RATIO; 15 | 16 | void main() { 17 | 18 | vec2 tpos = vec2(0); 19 | if (in_Position.x > 0) tpos = p[ind[gl_InstanceID].x]; 20 | if (in_Position.y > 0) tpos = p[ind[gl_InstanceID].y]; 21 | if (in_Position.z > 0) tpos = p[ind[gl_InstanceID].z]; 22 | tpos.x /= RATIO; 23 | gl_Position = vec4(tpos, -1, 1.0f); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /software/warp/shader/shift.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 0) buffer points { 6 | vec2 p[]; 7 | }; 8 | 9 | layout (std430, binding = 6) buffer gradient { 10 | ivec2 gr[]; 11 | }; 12 | 13 | uniform int NPoints; 14 | uniform float RATIO; 15 | 16 | void main(){ 17 | 18 | const uint index = gl_GlobalInvocationID.x; 19 | 20 | if(index < 4 || index >= NPoints) 21 | return; 22 | 23 | vec2 tgr = gr[index]; 24 | 25 | if(p[index].x <= -RATIO){ 26 | p[index].x = -RATIO; 27 | tgr.x = 0; 28 | } 29 | 30 | else if(p[index].x >= RATIO){ 31 | p[index].x = RATIO; 32 | tgr.x = 0; 33 | } 34 | 35 | if(p[index].y <= -1){ 36 | p[index].y = -1; 37 | tgr.y = 0; 38 | } 39 | 40 | else if(p[index].y >= 1){ 41 | p[index].y = 1; 42 | tgr.y = 0; 43 | } 44 | 45 | p[index] -= 0.00003 * tgr / 256 / 256; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /software/warp/shader/triangle.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (std430, binding = 1) buffer index { 4 | ivec4 ind[]; 5 | }; 6 | 7 | layout (std430, binding = 2) buffer colacc { 8 | ivec4 ca[]; 9 | }; 10 | 11 | layout (std430, binding = 3) buffer colnum { 12 | int cn[]; 13 | }; 14 | 15 | layout (std430, binding = 4) buffer tenergy { 16 | int ten[]; 17 | }; 18 | 19 | layout (std430, binding = 5) buffer penergy { 20 | int pen[]; 21 | }; 22 | 23 | uniform sampler2D imageA; 24 | uniform sampler2D imageB; 25 | 26 | uniform bool warpA; 27 | uniform int mode; 28 | 29 | in VS_OUT { 30 | vec2 position; 31 | flat int index; 32 | } vs_out; 33 | 34 | out vec4 fragColor; 35 | 36 | void main(){ 37 | 38 | // Accumulate Cost Function 39 | 40 | if( mode == 0) { 41 | 42 | atomicAdd(cn[vs_out.index], 1); 43 | 44 | } 45 | 46 | if( mode == 1 ){ 47 | 48 | vec3 d = vec3(0); 49 | if(!warpA) d = 255*texture(imageA, vs_out.position).rgb - vec3(ca[vs_out.index].rgb); 50 | else d = 255*texture(imageB, vs_out.position).rgb - vec3(ca[vs_out.index].rgb); 51 | atomicAdd(ten[vs_out.index], int(0.5*dot(d, d))); 52 | 53 | } 54 | 55 | // Display 56 | 57 | if( mode == 2 ){ 58 | 59 | /* 60 | 61 | float TEN = sqrt(float(ten[vs_out.index])/cn[vs_out.index])/255.0f; 62 | float PEN = 0.0f; 63 | PEN += pen[ind[vs_out.index].x]; 64 | PEN += pen[ind[vs_out.index].y]; 65 | PEN += pen[ind[vs_out.index].z]; 66 | 67 | if(PEN == 0) fragColor = vec4(0,1,0,1); 68 | if(TEN == 0) fragColor = vec4(1,0,1,1); 69 | 70 | if(abs(TEN) < abs(PEN/200000)) fragColor = vec4(1,0,0,1); 71 | else fragColor = vec4(0,0,1,1); 72 | */ 73 | 74 | fragColor = vec4(vec3(ca[vs_out.index].rgb)/255, 1); 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /software/warp/shader/triangle.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | 5 | layout (std430, binding = 0) buffer points { 6 | vec2 p[]; 7 | }; 8 | 9 | layout (std430, binding = 1) buffer index { 10 | ivec4 ind[]; 11 | }; 12 | 13 | layout (std430, binding = 2) buffer colacc { 14 | ivec4 ca[]; 15 | }; 16 | 17 | layout (std430, binding = 3) buffer colnum { 18 | int cn[]; 19 | }; 20 | 21 | layout (std430, binding = 4) buffer tenergy { 22 | int ten[]; 23 | }; 24 | 25 | layout (std430, binding = 5) buffer penergy { 26 | int pen[]; 27 | }; 28 | 29 | layout (std430, binding = 6) buffer gradient { 30 | ivec2 gr[]; 31 | }; 32 | 33 | layout (std430, binding = 7) buffer nring { 34 | int nr[]; 35 | }; 36 | 37 | out VS_OUT { 38 | 39 | vec2 position; 40 | flat int index; 41 | 42 | } vs_out; 43 | 44 | uniform float RATIO; 45 | uniform int KTriangles; 46 | uniform int mode; 47 | 48 | void main() { 49 | 50 | const int TDIV = gl_InstanceID/KTriangles; 51 | const int TMOD = gl_InstanceID%KTriangles; 52 | vs_out.index = gl_InstanceID; 53 | 54 | int pind; // Vertex Index 55 | if (in_Position.x > 0) 56 | pind = ind[TMOD].x; 57 | if (in_Position.y > 0) 58 | pind = ind[TMOD].y; 59 | if (in_Position.z > 0) 60 | pind = ind[TMOD].z; 61 | 62 | vec2 tpos = p[pind]; // Vertex Image-Space (-RATIO, RATIO) x, (-1, 1) y 63 | float dp = 0.05f; // Image-Space Pixel Shift 64 | 65 | dp /= (1.0f + 9.0f*float(KTriangles)/1000.0f); 66 | 67 | vec2 D = vec2(dp); 68 | 69 | if(TDIV == 1 && in_Position.x > 0) D *= vec2( 1, 0); 70 | else if(TDIV == 2 && in_Position.x > 0) D *= vec2(-1, 0); 71 | else if(TDIV == 3 && in_Position.x > 0) D *= vec2( 0, 1); 72 | else if(TDIV == 4 && in_Position.x > 0) D *= vec2( 0,-1); 73 | else if(TDIV == 5 && in_Position.y > 0) D *= vec2( 1, 0); 74 | else if(TDIV == 6 && in_Position.y > 0) D *= vec2(-1, 0); 75 | else if(TDIV == 7 && in_Position.y > 0) D *= vec2( 0, 1); 76 | else if(TDIV == 8 && in_Position.y > 0) D *= vec2( 0,-1); 77 | else if(TDIV == 9 && in_Position.z > 0) D *= vec2( 1, 0); 78 | else if(TDIV == 10 && in_Position.z > 0) D *= vec2(-1, 0); 79 | else if(TDIV == 11 && in_Position.z > 0) D *= vec2( 0, 1); 80 | else if(TDIV == 12 && in_Position.z > 0) D *= vec2( 0,-1); 81 | else D *= vec2(0); 82 | 83 | tpos += D; 84 | tpos.x /= RATIO; // Position in Screen-Space (-1, 1) for x,y 85 | 86 | vs_out.position = vec2(0.5*(1.0+tpos.x), 0.5*(1.0-tpos.y)); 87 | gl_Position = vec4(tpos, -1, 1.0f); 88 | 89 | // Reset Values 90 | 91 | if(mode == 0){ 92 | cn[vs_out.index] = 0; 93 | } 94 | 95 | if(mode == 1){ 96 | ten[vs_out.index] = 0; 97 | gr[ind[TMOD].x] = ivec2(0); 98 | gr[ind[TMOD].y] = ivec2(0); 99 | gr[ind[TMOD].z] = ivec2(0); 100 | } 101 | 102 | //Add One-Ring Energy 103 | 104 | if( TDIV == 0 && mode == 0 ) 105 | atomicAdd(nr[TMOD], 1 ); //count the n-ring! (divided by 3) 106 | 107 | if( TDIV == 0 && mode == 1 ) { 108 | 109 | float lambda = 0*256*256; 110 | 111 | if (in_Position.x > 0){ 112 | 113 | vec2 wva = p[pind] - p[ind[TMOD].y]; //Distance from this Vertex to Prev 114 | vec2 wvb = p[pind] - p[ind[TMOD].z]; //Distance from this Vertex to Next 115 | //Add Direct Energy Gradient 116 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[TMOD]); 117 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[TMOD]); 118 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[TMOD]); 119 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[TMOD]); 120 | 121 | //Add Energy of Vertex 122 | atomicAdd(pen[pind], int(sqrt(lambda*0.5/3.0*dot(wva, wva))/nr[TMOD])); 123 | atomicAdd(pen[pind], int(sqrt(lambda*0.5/3.0*dot(wvb, wvb))/nr[TMOD])); 124 | 125 | } 126 | 127 | if (in_Position.y > 0){ 128 | 129 | vec2 wva = p[pind] - p[ind[TMOD].z]; //Distance from this Vertex to Prev 130 | vec2 wvb = p[pind] - p[ind[TMOD].x]; //Distance from this Vertex to Next 131 | //Add Direct Energy Gradient 132 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[TMOD]); 133 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[TMOD]); 134 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[TMOD]); 135 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[TMOD]); 136 | 137 | //Add Energy of Vertex 138 | atomicAdd(pen[pind], int(sqrt(lambda*0.5/3.0*dot(wva, wva))/nr[TMOD])); 139 | atomicAdd(pen[pind], int(sqrt(lambda*0.5/3.0*dot(wvb, wvb))/nr[TMOD])); 140 | 141 | } 142 | 143 | if (in_Position.z > 0){ 144 | 145 | vec2 wva = p[pind] - p[ind[TMOD].x]; //Distance from this Vertex to Prev 146 | vec2 wvb = p[pind] - p[ind[TMOD].y]; //Distance from this Vertex to Next 147 | //Add Direct Energy Gradient 148 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[TMOD]); 149 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[TMOD]); 150 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[TMOD]); 151 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[TMOD]); 152 | 153 | //Add Energy of Vertex 154 | atomicAdd(pen[pind], int(sqrt(lambda*0.5/3.0*dot(wva, wva))/nr[TMOD])); 155 | atomicAdd(pen[pind], int(sqrt(lambda*0.5/3.0*dot(wvb, wvb))/nr[TMOD])); 156 | 157 | } 158 | 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /source/include/delaunator-cpp/delaunator-header-only.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DELAUNATOR_HEADER_ONLY 4 | 5 | #include "delaunator.hpp" 6 | 7 | #include "delaunator.cpp" 8 | 9 | #undef DELAUNATOR_HEADER_ONLY 10 | -------------------------------------------------------------------------------- /source/include/delaunator-cpp/delaunator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef DELAUNATOR_HEADER_ONLY 4 | #define INLINE inline 5 | #else 6 | #define INLINE 7 | #endif 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace delaunator { 14 | 15 | constexpr std::size_t INVALID_INDEX = 16 | (std::numeric_limits::max)(); 17 | 18 | class Point 19 | { 20 | public: 21 | Point(double x, double y) : m_x(x), m_y(y) 22 | {} 23 | Point() : m_x(0), m_y(0) 24 | {} 25 | 26 | double x() const 27 | { return m_x; } 28 | 29 | double y() const 30 | { return m_y; } 31 | 32 | double magnitude2() const 33 | { return m_x * m_x + m_y * m_y; } 34 | 35 | static double determinant(const Point& p1, const Point& p2) 36 | { 37 | return p1.m_x * p2.m_y - p1.m_y * p2.m_x; 38 | } 39 | 40 | static Point vector(const Point& p1, const Point& p2) 41 | { 42 | return Point(p2.m_x - p1.m_x, p2.m_y - p1.m_y); 43 | } 44 | 45 | static double dist2(const Point& p1, const Point& p2) 46 | { 47 | Point vec = vector(p1, p2); 48 | return vec.m_x * vec.m_x + vec.m_y * vec.m_y; 49 | } 50 | 51 | static bool equal(const Point& p1, const Point& p2, double span) 52 | { 53 | double dist = dist2(p1, p2) / span; 54 | 55 | // ABELL - This number should be examined to figure how how 56 | // it correlates with the breakdown of calculating determinants. 57 | return dist < 1e-20; 58 | } 59 | 60 | private: 61 | double m_x; 62 | double m_y; 63 | }; 64 | 65 | inline std::ostream& operator<<(std::ostream& out, const Point& p) 66 | { 67 | out << p.x() << "/" << p.y(); 68 | return out; 69 | } 70 | 71 | 72 | class Points 73 | { 74 | public: 75 | using const_iterator = Point const *; 76 | 77 | Points(std::vector& in_coords):m_coords(in_coords){} 78 | 79 | const Point& operator[](size_t offset) 80 | { 81 | return reinterpret_cast( 82 | *(m_coords.data() + (offset * 2))); 83 | }; 84 | 85 | Points::const_iterator begin() const 86 | { return reinterpret_cast(m_coords.data()); } 87 | Points::const_iterator end() const 88 | { return reinterpret_cast( 89 | m_coords.data() + m_coords.size()); } 90 | size_t size() const 91 | { return m_coords.size() / 2; } 92 | 93 | std::vector& m_coords; 94 | }; 95 | 96 | class Delaunator { 97 | 98 | public: 99 | std::vector coords; 100 | Points m_points; 101 | 102 | void compute(std::vector& in_coords); 103 | 104 | // 'triangles' stores the indices to the 'X's of the input 105 | // 'coords'. 106 | std::vector triangles; 107 | 108 | // 'halfedges' store indices into 'triangles'. If halfedges[X] = Y, 109 | // It says that there's an edge from X to Y where a) X and Y are 110 | // both indices into triangles and b) X and Y are indices into different 111 | // triangles in the array. This allows you to get from a triangle to 112 | // its adjacent triangle. If the a triangle edge has no adjacent triangle, 113 | // its half edge will be INVALID_INDEX. 114 | std::vector halfedges; 115 | 116 | std::vector hull_prev; 117 | std::vector hull_next; 118 | 119 | // This contains indexes into the triangles array. 120 | std::vector hull_tri; 121 | std::size_t hull_start; 122 | 123 | INLINE Delaunator(std::vector& in_coords); 124 | INLINE double get_hull_area(); 125 | INLINE double get_triangle_area(); 126 | 127 | private: 128 | std::vector m_hash; 129 | Point m_center; 130 | std::size_t m_hash_size; 131 | std::vector m_edge_stack; 132 | 133 | INLINE std::size_t legalize(std::size_t a); 134 | INLINE std::size_t hash_key(double x, double y) const; 135 | INLINE std::size_t add_triangle( 136 | std::size_t i0, 137 | std::size_t i1, 138 | std::size_t i2, 139 | std::size_t a, 140 | std::size_t b, 141 | std::size_t c); 142 | INLINE void link(std::size_t a, std::size_t b); 143 | }; 144 | 145 | } //namespace delaunator 146 | 147 | #undef INLINE 148 | -------------------------------------------------------------------------------- /source/include/poisson.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace sample{ 5 | 6 | std::random_device rd; 7 | std::mt19937 gen(rd()); 8 | std::uniform_real_distribution<> dis(0.0, 1.0); 9 | 10 | float uniform(){ 11 | return dis(gen); 12 | } 13 | 14 | float uniform(float a, float b){ 15 | return dis(gen)*(a-b)+b; 16 | } 17 | 18 | //Single point at position towards p with radius R 19 | bool disc(std::vector& set, float R, glm::vec2 p, glm::vec2 a, glm::vec2 b){ 20 | 21 | if(set.empty()){ 22 | set.push_back(p); 23 | return true; 24 | } 25 | 26 | const float length = R/sqrt(2); 27 | const int NX = ceil((b.x-a.x)/length); 28 | const int NY = ceil((b.y-a.y)/length); 29 | int* grid = new int[NX*NY]; 30 | memset(grid, 0, NX*NY*sizeof(int)); 31 | 32 | std::function addGrid = [&](glm::vec2 s, int val){ 33 | glm::ivec2 ind = glm::vec2(NX, NY)*(s-a)/(b-a); //Indices 34 | grid[ind.x*NY+ind.y] = val; //Set Indices in Neighborhood 35 | }; 36 | 37 | //Set is Not Empty - Fill Grid 38 | for(unsigned int i = 0; i < set.size(); i++) 39 | addGrid(set[i], i+1); 40 | 41 | //Find the Nearest Guy - Attempt to Place Nearby 42 | int near = 0; float dist = glm::distance(a, b); 43 | for(unsigned int i = 0; i < set.size(); i++){ 44 | if(glm::distance(set[i], p) < dist){ 45 | dist = glm::distance(set[i], p); 46 | near = i; 47 | } 48 | } 49 | 50 | //Generate Nearby Point 51 | int tries = 16; 52 | while(tries > 0){ 53 | tries--; 54 | 55 | float nr = uniform(R, 2*R); 56 | float nt = uniform(0, 2*3.14159265); 57 | 58 | glm::vec2 npos = set[near]+nr*glm::vec2(cos(nt), sin(nt)); 59 | if(glm::any(glm::lessThan(npos, glm::vec2(a))) || glm::any(glm::greaterThanEqual(npos, glm::vec2(b)))) 60 | continue; 61 | 62 | glm::ivec2 ind = glm::vec2(NX, NY)*(npos-a)/(b-a); //Indices 63 | 64 | bool free = true; 65 | for(int i = ind.x-2; i <= ind.x+2 && free; i++){ 66 | for(int j = ind.y-2; j <= ind.y+2 && free; j++){ 67 | 68 | if(i < 0 || i >= NX || j < 0 || j >= NY) 69 | continue; 70 | 71 | //Non-Zero Entry,and Too Close 72 | if(grid[i*NY+j] > 0){ 73 | if(glm::distance(set[grid[i*NY+j]-1], npos) < R){ 74 | free = false; 75 | continue; 76 | } 77 | } 78 | } 79 | } 80 | 81 | if(free){ 82 | set.push_back(npos); 83 | addGrid(set.back(), set.size()); 84 | return true; 85 | } 86 | } 87 | return false; 88 | } 89 | 90 | //Sample Set of Points in Region 91 | void disc(std::vector& set, int K, glm::vec2 a, glm::vec2 b){ 92 | 93 | float r = sqrt(glm::dot(b-a, b-a)/3.14159265f/K); 94 | const float length = r/sqrt(2); //Edge Length 95 | const int NX = ceil((b.x-a.x)/length); 96 | const int NY = ceil((b.y-a.y)/length); 97 | int* grid = new int[NX*NY]; 98 | memset(grid, 0, NX*NY*sizeof(int)); 99 | 100 | //Grid Addition Function 101 | std::function addGrid = [&](glm::vec2 s, int val){ 102 | glm::ivec2 ind = glm::vec2(NX, NY)*(s-a)/(b-a); //Indices 103 | grid[ind.x*NY+ind.y] = val; //Set Indices in Neighborhood 104 | }; 105 | 106 | //Setup Grid 107 | if(set.empty()){ 108 | set.push_back(0.5f*(a+b)); //Center 109 | addGrid(set.back(), set.size()); 110 | K--; 111 | } 112 | else for(unsigned int i = 0; i < set.size(); i++) 113 | addGrid(set[i], i+1); 114 | 115 | //Now Generate New Samples by Iterating over the Set 116 | int tries = 0; 117 | 118 | while(K > 0){ 119 | 120 | if(tries > set.size()) 121 | break; 122 | 123 | //Sample Uniformly from Set 124 | int n = uniform(0, set.size()); 125 | 126 | //Generate Sample Surrounding It 127 | float nr = uniform(r, 2*r); 128 | float nt = uniform(0, 2*3.14159265); 129 | 130 | //New Sample Position, Grid Index 131 | glm::vec2 npos = set[n]+nr*glm::vec2(cos(nt), sin(nt)); 132 | if(glm::any(glm::lessThan(npos, glm::vec2(a))) || glm::any(glm::greaterThanEqual(npos, glm::vec2(b)))) 133 | continue; 134 | 135 | glm::ivec2 ind = glm::vec2(NX, NY)*(npos-a)/(b-a); //Indices 136 | 137 | bool free = true; 138 | for(int i = ind.x-2; i <= ind.x+2 && free; i++){ 139 | for(int j = ind.y-2; j <= ind.y+2 && free; j++){ 140 | 141 | if(i < 0 || i >= NX || j < 0 || j >= NY) 142 | continue; 143 | 144 | //Non-Zero Entry,and Too Close 145 | if(grid[i*NY+j] > 0){ 146 | if(glm::distance(set[grid[i*NY+j]-1], npos) < r){ 147 | free = false; 148 | continue; 149 | } 150 | } 151 | } 152 | } 153 | 154 | if(!free){ 155 | tries++; 156 | continue; 157 | } 158 | 159 | //Place Point 160 | set.push_back(npos); 161 | addGrid(set.back(), set.size()); 162 | tries = 0; 163 | K--; 164 | } 165 | delete[] grid; 166 | } 167 | 168 | void reflect(std::vector& set, glm::vec2 a, glm::vec2 b){ 169 | const size_t size = set.size(); 170 | const glm::vec2 dim = b-a; 171 | 172 | for(size_t i = 0; i < size; i++) 173 | set.push_back(set[i] + glm::vec2( dim.x, 0)); 174 | for(size_t i = 0; i < size; i++) 175 | set.push_back(set[i] + glm::vec2(-dim.x, 0)); 176 | for(size_t i = 0; i < size; i++) 177 | set.push_back(set[i] + glm::vec2(0, dim.y)); 178 | for(size_t i = 0; i < size; i++) 179 | set.push_back(set[i] + glm::vec2(0, -dim.y)); 180 | 181 | 182 | for(size_t i = 0; i < size; i++) 183 | set.push_back(set[i] + glm::vec2( dim.x, dim.y)); 184 | for(size_t i = 0; i < size; i++) 185 | set.push_back(set[i] + glm::vec2(-dim.x, dim.y)); 186 | for(size_t i = 0; i < size; i++) 187 | set.push_back(set[i] + glm::vec2( dim.x, -dim.y)); 188 | for(size_t i = 0; i < size; i++) 189 | set.push_back(set[i] + glm::vec2(-dim.x, -dim.y)); 190 | 191 | 192 | } 193 | 194 | //Those functions could probably be improved. Not sure how right now. Recursiveness? 195 | } 196 | -------------------------------------------------------------------------------- /source/io.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | ================================================================================ 3 | t-pose: io.h 4 | ================================================================================ 5 | 6 | This header file provides an interface for data io from files for various data. 7 | 8 | */ 9 | 10 | #ifndef TPOSE_IO 11 | #define TPOSE_IO 12 | 13 | #include 14 | #include 15 | 16 | namespace tpose { 17 | namespace io { 18 | 19 | using namespace std; 20 | using namespace glm; 21 | 22 | bool readmatches(string file, vector& A, vector& B){ 23 | 24 | // Load the Points 25 | 26 | cout<<"Importing from file "<in.is_open()){ 72 | tri->in.open( file, ios::binary | ios::in ); 73 | if(!tri->in.is_open()){ 74 | cout<<"failed to open file."<in.read( (char*)( &tpose::RATIO ), sizeof( float )); 82 | 83 | if(tri->in.eof()){ 84 | tri->in.close(); 85 | cout<<"end of file."<in.read( (char*)( &tri->NT ), sizeof( int )); 92 | 93 | vector ntriangles; 94 | vector nhalfedges; 95 | vector ncolors; 96 | 97 | ntriangles.resize(tri->NT); 98 | nhalfedges.resize(3*tri->NT); 99 | ncolors.resize(tri->NT); 100 | 101 | for(size_t t = 0; t < tri->NT; t++){ 102 | 103 | tri->in.read( (char*)( &ntriangles[t][0] ), sizeof( int )); 104 | tri->in.read( (char*)( &ntriangles[t][1] ), sizeof( int )); 105 | tri->in.read( (char*)( &ntriangles[t][2] ), sizeof( int )); 106 | ntriangles[t].w = 0.0f; 107 | 108 | tri->in.read( (char*)( &nhalfedges[3*t+0] ), sizeof( int )); 109 | tri->in.read( (char*)( &nhalfedges[3*t+1] ), sizeof( int )); 110 | tri->in.read( (char*)( &nhalfedges[3*t+2] ), sizeof( int )); 111 | 112 | tri->in.read( (char*)( &ncolors[t][0] ), sizeof( int )); 113 | tri->in.read( (char*)( &ncolors[t][1] ), sizeof( int )); 114 | tri->in.read( (char*)( &ncolors[t][2] ), sizeof( int )); 115 | ncolors[t].w = 1.0f; 116 | 117 | } 118 | 119 | // Per-Vertex Data 120 | 121 | tri->in.read( (char*)( &tri->NP ), sizeof( int )); 122 | 123 | vector npoints; 124 | vector noriginpoints; 125 | 126 | npoints.resize(tri->NP); 127 | noriginpoints.resize(tri->NP); 128 | 129 | for(size_t p = 0; p < tri->NP; p++){ 130 | 131 | tri->in.read( (char*)( &npoints[p][0] ), sizeof( float )); 132 | tri->in.read( (char*)( &npoints[p][1] ), sizeof( float )); 133 | 134 | tri->in.read( (char*)( &noriginpoints[p][0] ), sizeof( float )); 135 | tri->in.read( (char*)( &noriginpoints[p][1] ), sizeof( float )); 136 | 137 | } 138 | 139 | if(dowarp) tri->warp(npoints); 140 | 141 | tri->triangles = ntriangles; 142 | tri->colors = ncolors; 143 | tri->halfedges = nhalfedges; 144 | 145 | tri->points = npoints; 146 | tri->originpoints = noriginpoints; 147 | 148 | /* 149 | 150 | tri->points.resize(tri->NP); 151 | tri->originpoints.resize(tri->NP); 152 | 153 | for(size_t p = 0; p < tri->NP; p++){ 154 | 155 | tri->in.read( (char*)( &tri->points[p][0] ), sizeof( float )); 156 | tri->in.read( (char*)( &tri->points[p][1] ), sizeof( float )); 157 | 158 | tri->in.read( (char*)( &tri->originpoints[p][0] ), sizeof( float )); 159 | tri->in.read( (char*)( &tri->originpoints[p][1] ), sizeof( float )); 160 | 161 | } 162 | 163 | */ 164 | 165 | cout<<"success ("<NT<<")."<out.is_open()){ 173 | tri->out.open( file, ios::binary | ios::out ); 174 | if(!tri->out.is_open()){ 175 | cout<<"Failed to open file "<out.write( reinterpret_cast( &tpose::RATIO ), sizeof( float )); 185 | 186 | // Per-Triangle Data 187 | 188 | tri->out.write( reinterpret_cast( &tri->NT ), sizeof( int )); 189 | 190 | for(size_t t = 0; t < tri->NT; t++){ 191 | 192 | tri->out.write( reinterpret_cast( &tri->triangles[t][0] ), sizeof( int )); 193 | tri->out.write( reinterpret_cast( &tri->triangles[t][1] ), sizeof( int )); 194 | tri->out.write( reinterpret_cast( &tri->triangles[t][2] ), sizeof( int )); 195 | 196 | tri->out.write( reinterpret_cast( &tri->halfedges[3*t+0] ), sizeof( int )); 197 | tri->out.write( reinterpret_cast( &tri->halfedges[3*t+1] ), sizeof( int )); 198 | tri->out.write( reinterpret_cast( &tri->halfedges[3*t+2] ), sizeof( int )); 199 | 200 | tri->out.write( reinterpret_cast( &tri->colors[t][0] ), sizeof( int )); 201 | tri->out.write( reinterpret_cast( &tri->colors[t][1] ), sizeof( int )); 202 | tri->out.write( reinterpret_cast( &tri->colors[t][2] ), sizeof( int )); 203 | 204 | } 205 | 206 | // Per-Vertex Data 207 | 208 | tri->out.write( reinterpret_cast( &tri->NP ), sizeof( int )); 209 | 210 | for(size_t p = 0; p < tri->NP; p++){ 211 | 212 | tri->out.write( reinterpret_cast( &tri->points[p][0] ), sizeof( float )); 213 | tri->out.write( reinterpret_cast( &tri->points[p][1] ), sizeof( float )); 214 | 215 | tri->out.write( reinterpret_cast( &tri->originpoints[p][0] ), sizeof( float )); 216 | tri->out.write( reinterpret_cast( &tri->originpoints[p][1] ), sizeof( float )); 217 | 218 | } 219 | 220 | } 221 | 222 | #endif 223 | 224 | }; // End of Namespace io 225 | }; // End of Namespace tpose 226 | 227 | #endif 228 | -------------------------------------------------------------------------------- /source/tpose.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | ================================================================================ 3 | t-pose: 2D Triangulations for 3D Multiview Geometry 4 | ================================================================================ 5 | */ 6 | 7 | #ifndef TPOSE 8 | #define TPOSE 9 | 10 | namespace tpose { 11 | 12 | float RATIO = 12.0f/8.0f; 13 | 14 | } 15 | 16 | #ifdef TINYENGINE_UTILITIES 17 | 18 | /* 19 | ================================================================================ 20 | TinyEngine Rendering Interface 21 | ================================================================================ 22 | */ 23 | 24 | // Rendering Structures 25 | 26 | struct Triangle : Model { 27 | Buffer vert; 28 | Triangle():Model({"vert"}), 29 | vert({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}){ 30 | bind("vert", &vert); 31 | SIZE = 3; 32 | } 33 | }; 34 | 35 | struct TLineStrip : Model { 36 | Buffer vert; 37 | TLineStrip():Model({"vert"}), 38 | vert({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}){ 39 | bind("vert", &vert); 40 | SIZE = 4; 41 | } 42 | }; 43 | 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /source/utility.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | ================================================================================ 3 | t-pose: utility.h 4 | ================================================================================ 5 | 6 | This header defines a number of helper functions, particularly for computing 7 | roots of polynomials using companion matrices and barycentric coordinate transforms 8 | and associated queries. 9 | 10 | */ 11 | 12 | #ifndef TPOSE_UTILITY 13 | #define TPOSE_UTILITY 14 | 15 | #include 16 | #include 17 | 18 | namespace tpose { 19 | 20 | /* 21 | ================================================================================ 22 | Barycentric Coordinate Transform 23 | ================================================================================ 24 | */ 25 | 26 | // Compute the Parameters of a Point in a Triangle 27 | 28 | glm::vec3 barycentric(glm::vec2 p, glm::ivec4 t, std::vector& v){ 29 | 30 | glm::mat3 R( 31 | 1, v[t.x].x, v[t.x].y, 32 | 1, v[t.y].x, v[t.y].y, 33 | 1, v[t.z].x, v[t.z].y 34 | ); 35 | 36 | if(abs(determinant(R)) < 1E-8) return glm::vec3(1,1,1); 37 | return inverse(R)*glm::vec3(1, p.x, p.y); 38 | 39 | } 40 | 41 | // Check if a Point is in a Triangle 42 | 43 | bool intriangle( glm::vec2 p, glm::ivec4 t, std::vector& v){ 44 | 45 | if(length(v[t.x] - v[t.y]) == 0) return false; 46 | if(length(v[t.y] - v[t.z]) == 0) return false; 47 | if(length(v[t.z] - v[t.x]) == 0) return false; 48 | 49 | glm::vec3 s = barycentric(p, t, v); 50 | if(s.x <= 0 || s.x >= 1) return false; 51 | if(s.y <= 0 || s.y >= 1) return false; 52 | if(s.z <= 0 || s.z >= 1) return false; 53 | return true; 54 | 55 | } 56 | 57 | bool intriangle( glm::vec2 p, glm::ivec4 t, std::vector& vA, std::vector& vB, float warp ){ 58 | 59 | if(length(mix(vA[t.x], vB[t.x], warp) - mix(vA[t.y], vB[t.y], warp)) == 0) return false; 60 | if(length(mix(vA[t.y], vB[t.y], warp) - mix(vA[t.z], vB[t.z], warp)) == 0) return false; 61 | if(length(mix(vA[t.z], vB[t.z], warp) - mix(vA[t.x], vB[t.x], warp)) == 0) return false; 62 | 63 | glm::mat3 R( 64 | 1, mix(vA[t.x], vB[t.x], warp).x, mix(vA[t.x], vB[t.x], warp).y, 65 | 1, mix(vA[t.y], vB[t.y], warp).x, mix(vA[t.y], vB[t.y], warp).y, 66 | 1, mix(vA[t.z], vB[t.z], warp).x, mix(vA[t.z], vB[t.z], warp).y 67 | ); 68 | 69 | glm::vec3 s = inverse(R)*glm::vec3(1, p.x, p.y); 70 | if(s.x <= 0 || s.x >= 1) return false; 71 | if(s.y <= 0 || s.y >= 1) return false; 72 | if(s.z <= 0 || s.z >= 1) return false; 73 | return true; 74 | 75 | } 76 | 77 | // Map Point in Triangle 78 | 79 | glm::vec2 cartesian(glm::vec3 s, glm::ivec4 t, std::vector& v){ 80 | 81 | return s.x * v[t.x] + s.y * v[t.y] + s.z * v[t.z]; 82 | 83 | } 84 | 85 | /* 86 | ================================================================================ 87 | Polynomial Evaluation / Root-Finding 88 | ================================================================================ 89 | */ 90 | 91 | // Horner's Method Polynomial Evaluation 92 | 93 | double horner(double x, std::vector a){ 94 | 95 | double result = a[a.size()-1]; 96 | for(int i = a.size()-2; i >= 0; i--) 97 | result = result*x + a[i]; 98 | return result; 99 | 100 | } 101 | 102 | // Companion Matrix Root Computation (with complex) 103 | 104 | Eigen::VectorXcd roots(std::vector a){ 105 | 106 | const size_t K = a.size()-1; 107 | Eigen::MatrixXd C = Eigen::MatrixXd::Zero(K, K); 108 | 109 | for(size_t k = 0; k < K; k++) 110 | C(k,K-1) = -a[k]/a[K]; 111 | 112 | for(size_t k = 1; k < K; k++) 113 | C(k,k-1) = 1; 114 | 115 | Eigen::EigenSolver CS(C); 116 | return CS.eigenvalues(); 117 | 118 | } 119 | 120 | // Real Roots Only! (Iterable) 121 | 122 | std::vector realroots(std::vector a){ 123 | 124 | Eigen::VectorXcd R = roots(a); // get Complex Roots 125 | 126 | std::vector rR; 127 | for(size_t r = 0; r < a.size()-1; r++) 128 | if(R(r).imag() == 0) rR.push_back(R(r).real()); 129 | 130 | // Estimate Refinement with Newton's Method 131 | 132 | for(auto& r: rR) 133 | for(size_t n = 0; n < 25; n++) 134 | r -= horner(r, a)/horner(r, {a[1]*1.0, a[2]*2.0, a[3]*3.0, a[4]*4.0, a[5]*5.0, a[6]*6.0}); 135 | 136 | return rR; 137 | 138 | } 139 | 140 | /* 141 | ================================================================================ 142 | Eigen / GLM Matrix Conversions 143 | ================================================================================ 144 | */ 145 | 146 | glm::mat3 fromEigen3(Eigen::Matrix3f M){ 147 | glm::mat3 T; 148 | T = { M(0,0), M(0,1), M(0,2), 149 | M(1,0), M(1,1), M(1,2), 150 | M(2,0), M(2,1), M(2,2) }; 151 | //Tranpose because of Column Major Ordering 152 | return glm::transpose(T); 153 | } 154 | 155 | Eigen::Matrix3f toEigen(glm::mat3 M){ 156 | Eigen::Matrix3f T; 157 | T << M[0][0], M[0][1], M[0][2], 158 | M[1][0], M[1][1], M[1][2], 159 | M[2][0], M[2][1], M[2][2]; 160 | //Tranpose because of Row Major Ordering 161 | return T.transpose(); 162 | } 163 | 164 | glm::mat4 fromEigen(Eigen::Matrix4f M){ 165 | glm::mat4 T; 166 | T = { M(0,0), M(0,1), M(0,2), M(0,3), 167 | M(1,0), M(1,1), M(1,2), M(1,3), 168 | M(2,0), M(2,1), M(2,2), M(2,3), 169 | M(3,0), M(3,1), M(3,2), M(3,3) }; 170 | //Tranpose because of Column Major Ordering 171 | return glm::transpose(T); 172 | } 173 | 174 | Eigen::Matrix4f toEigen(glm::mat4 M){ 175 | Eigen::Matrix4f T; 176 | T << M[0][0], M[0][1], M[0][2], M[0][3], 177 | M[1][0], M[1][1], M[1][2], M[1][3], 178 | M[2][0], M[2][1], M[2][2], M[2][3], 179 | M[3][0], M[3][1], M[3][2], M[3][3]; 180 | //Tranpose because of Row Major Ordering 181 | return T.transpose(); 182 | } 183 | 184 | } 185 | 186 | #endif 187 | -------------------------------------------------------------------------------- /tests/compute_fundamental_mat/README.md: -------------------------------------------------------------------------------- 1 | # dual consisten reconstruction 2 | 3 | use the sampson energy minimization while weighting points by their warping incosistency 4 | -------------------------------------------------------------------------------- /tests/compute_fundamental_mat/imgui.ini: -------------------------------------------------------------------------------- 1 | [Window][Debug##Default] 2 | Pos=60,60 3 | Size=400,400 4 | Collapsed=0 5 | 6 | [Window][F Computer Controller] 7 | Pos=71,217 8 | Size=480,260 9 | Collapsed=0 10 | 11 | -------------------------------------------------------------------------------- /tests/compute_fundamental_mat/makefile: -------------------------------------------------------------------------------- 1 | # TinyEngine Makefile 2 | # Compiler Configuration 3 | 4 | CC = g++ -std=c++17 5 | CF = -Wfatal-errors -O3 6 | LF = -I/usr/local/include -L/usr/local/lib -I/usr/include/opencv4 7 | 8 | # General Linking 9 | 10 | TINYLINK = -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem 11 | OPENCVLINK = -lopencv_core -lopencv_calib3d 12 | 13 | # OS Specific Linking 14 | 15 | UNAME := $(shell uname) 16 | ifeq ($(UNAME), Linux) #Detect GNU/Linux 17 | TINYOS = -lX11 -lGL 18 | endif 19 | ifeq ($(UNAME), Darwin) #Detext MacOS 20 | TINYOS = -framework OpenGL 21 | endif 22 | 23 | all: main.cpp 24 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(OPENCVLINK) $(TINYOS) $(TINYLINK) -o main 25 | 26 | # Build Embedded Form 27 | 28 | DAT = shader #data directory to embed 29 | .PHONY: embedded 30 | embedded: CEF = $(shell c-embed $(DAT)) c-embed.o -include /usr/local/include/c-embed.h -DCEMBED_TRANSLATE 31 | embedded: 32 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 33 | rm c-embed.o 34 | -------------------------------------------------------------------------------- /tests/compute_fundamental_mat/model.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | // Compute the Reconstruction Set 5 | 6 | vector matchX, matchY; 7 | 8 | const mat3 T = mat3( 9 | 0.5f/tri::RATIO, 0.0, 1.0f, 10 | 0.0, -0.5f/tri::RATIO, 1.0f/tri::RATIO, 11 | 0, 0, 1 12 | ); 13 | 14 | vector tempX, tempY; 15 | vector weights; 16 | 17 | vector dist2DA, dist2DB; 18 | 19 | for(size_t i = 0; i < trA.NP; i++){ 20 | 21 | dist2DA.push_back(length(trWA.originpoints[i] - trA.points[i])); 22 | 23 | vec2 pX = trA.originpoints[i]; 24 | vec2 pY = trA.points[i]; 25 | 26 | if(dist2DA.back() > 0.0000002) 27 | continue; 28 | 29 | if( tri::triangulation::boundary(pX) 30 | || tri::triangulation::boundary(pY) ) 31 | continue; 32 | 33 | if(pX.x < -tri::RATIO/2.0) continue; 34 | if(pX.x > tri::RATIO/2.0) continue; 35 | if(pX.y < -1.0/2.0) continue; 36 | if(pX.y > 1.0/2.0) continue; 37 | if(pY.x < -tri::RATIO/2.0) continue; 38 | if(pY.x > tri::RATIO/2.0) continue; 39 | if(pY.y < -1.0/2.0) continue; 40 | if(pY.y > 1.0/2.0) continue; 41 | 42 | matchX.emplace_back(T*vec3(pX.x, pX.y, 1)); 43 | matchY.emplace_back(T*vec3(pY.x, pY.y, 1)); 44 | weights.emplace_back(1.0f/length(trWA.originpoints[i] - trA.points[i])); 45 | 46 | } 47 | 48 | for(size_t i = 0; i < trB.NP; i++){ 49 | 50 | dist2DB.push_back(length(trWB.originpoints[i] - trB.points[i])); 51 | 52 | vec2 pX = trB.points[i]; 53 | vec2 pY = trB.originpoints[i]; 54 | 55 | tempX.emplace_back(T*vec3(pX.x, pX.y, 1)); 56 | tempY.emplace_back(T*vec3(pY.x, pY.y, 1)); 57 | 58 | if(dist2DB.back() > 0.0000002) 59 | continue; 60 | 61 | if( tri::triangulation::boundary(pX) 62 | || tri::triangulation::boundary(pY) ) 63 | continue; 64 | 65 | if(pX.x < -tri::RATIO/2.0) continue; 66 | if(pX.x > tri::RATIO/2.0) continue; 67 | if(pX.y < -1.0/2.0) continue; 68 | if(pX.y > 1.0/2.0) continue; 69 | if(pY.x < -tri::RATIO/2.0) continue; 70 | if(pY.x > tri::RATIO/2.0) continue; 71 | if(pY.y < -1.0/2.0) continue; 72 | if(pY.y > 1.0/2.0) continue; 73 | 74 | matchX.emplace_back(T*vec3(pX.x, pX.y, 1)); 75 | matchY.emplace_back(T*vec3(pY.x, pY.y, 1)); 76 | weights.emplace_back(1.0f/length(trWB.originpoints[i] - trB.points[i])); 77 | 78 | // cout<<"W"< 0) tpos = p[ind[gl_InstanceID].x]; 23 | if (in_Position.y > 0) tpos = p[ind[gl_InstanceID].y]; 24 | if (in_Position.z > 0) tpos = p[ind[gl_InstanceID].z]; 25 | tpos.x /= RATIO; 26 | gl_Position = vp*model*tpos; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /tests/compute_fundamental_mat/shader/triangle2D.fs: -------------------------------------------------------------------------------- 1 | #version 430 core 2 | 3 | flat in int ex_Index; 4 | out vec4 fragColor; 5 | 6 | uniform bool docolor; 7 | 8 | layout (std430, binding = 1) buffer colacc { 9 | ivec4 col[]; 10 | }; 11 | 12 | layout (std430, binding = 4) buffer selected { 13 | int s[]; 14 | }; 15 | 16 | void main(){ 17 | 18 | if(!docolor) fragColor = vec4(1,1,1, 0.5); 19 | 20 | else if(s[ex_Index] == 1) 21 | fragColor = vec4(col[ex_Index].xyz, 255)/255.0f; 22 | 23 | else fragColor = vec4(0,0,0,1); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tests/compute_fundamental_mat/shader/triangle2D.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | 5 | layout (std430, binding = 0) buffer index { 6 | ivec4 ind[]; 7 | }; 8 | 9 | layout (std430, binding = 2) buffer points2Dfrom { 10 | vec2 p0[]; 11 | }; 12 | 13 | layout (std430, binding = 3) buffer points2Dto { 14 | vec2 p1[]; 15 | }; 16 | 17 | uniform float RATIO; 18 | uniform float warp; 19 | 20 | flat out int ex_Index; 21 | 22 | void main() { 23 | 24 | vec2 tpos = vec2(0); 25 | int pind; 26 | 27 | if (in_Position.x > 0) pind = ind[gl_InstanceID].x; 28 | if (in_Position.y > 0) pind = ind[gl_InstanceID].y; 29 | if (in_Position.z > 0) pind = ind[gl_InstanceID].z; 30 | 31 | tpos = mix(p0[pind], p1[pind], warp); 32 | tpos.x /= RATIO; 33 | ex_Index = gl_InstanceID; 34 | 35 | gl_Position = vec4(tpos, -1, 1.0f); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/README.md: -------------------------------------------------------------------------------- 1 | # Computing the Energy Descent 2 | 3 | Here I would like to test different strategies for computing the minimum energy. 4 | 5 | Potential issues: 6 | Why always max angle flip? 7 | Why only one flip? 8 | Why relate to splits?? 9 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace glm; 15 | 16 | int main( int argc, char* args[] ) { 17 | 18 | parse::get(argc, args); 19 | 20 | SDL_Surface* IMG = NULL; 21 | if(!parse::option.contains("i")){ 22 | cout<<"Please specify an input image with -i."<w/1.5f, IMG->h/1.5f); 36 | tpose::RATIO = (float)IMG->w/(float)IMG->h; 37 | 38 | bool paused = true; 39 | bool viewlines = false; 40 | 41 | Tiny::event.handler = [&](){ 42 | 43 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_p) 44 | paused = !paused; 45 | 46 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_n) 47 | viewlines = !viewlines; 48 | 49 | }; 50 | Tiny::view.interface = [](){}; 51 | 52 | Texture tex(IMG); //Load Texture with Image 53 | Square2D flat; //Create Primitive Model 54 | Shader image({"shader/image.vs", "shader/image.fs"}, {"in_Quad", "in_Tex"}); 55 | 56 | glDisable(GL_CULL_FACE); 57 | 58 | // Shaders and Buffers 59 | 60 | tpose::init(); 61 | 62 | Shader triangleshader({"shader/triangle.vs", "shader/triangle.fs"}, {"in_Position"}, {"points", "index", "colacc", "colnum", "tenergy", "penergy", "gradient", "nring"}); 63 | triangleshader.bind("points", tpose::pointbuf); 64 | triangleshader.bind("index", tpose::trianglebuf); 65 | triangleshader.bind("colacc", tpose::tcolaccbuf); 66 | triangleshader.bind("colnum", tpose::tcolnumbuf); 67 | triangleshader.bind("tenergy", tpose::tenergybuf); 68 | triangleshader.bind("penergy", tpose::penergybuf); 69 | triangleshader.bind("gradient", tpose::pgradbuf); 70 | triangleshader.bind("nring", tpose::tnringbuf); 71 | 72 | Shader linestrip({"shader/linestrip.vs", "shader/linestrip.fs"}, {"in_Position"}, {"points", "index"}); 73 | linestrip.bind("points", tpose::pointbuf); 74 | linestrip.bind("index", tpose::trianglebuf); 75 | 76 | Compute gradient({"shader/gradient.cs"}, {"index", "energy", "gradient"}); 77 | gradient.bind("index", tpose::trianglebuf); 78 | gradient.bind("energy", tpose::tenergybuf); 79 | gradient.bind("gradient", tpose::pgradbuf); 80 | 81 | Compute shift({"shader/shift.cs"}, {"points", "gradient"}); 82 | shift.bind("points", tpose::pointbuf); 83 | shift.bind("gradient", tpose::pgradbuf); 84 | 85 | // Triangulation and Models 86 | 87 | tpose::triangulation tr; 88 | tpose::upload(&tr, false); 89 | 90 | cout<<"Number of Triangles: "<("in_Position", tpose::pointbuf); 100 | 101 | // Convenience Lambdas 102 | 103 | auto computecolors = [&](){ 104 | 105 | triangleshader.use(); 106 | triangleshader.texture("imageTexture", tex); //Load Texture 107 | triangleshader.uniform("mode", 0); 108 | triangleshader.uniform("KTriangles", tr.NT); 109 | triangleshader.uniform("RATIO", tpose::RATIO); 110 | triangleinstance.render(GL_TRIANGLES, (13*tr.NT)); 111 | 112 | }; 113 | 114 | auto doenergy = [&](){ 115 | 116 | triangleshader.use(); 117 | triangleshader.texture("imageTexture", tex); 118 | triangleshader.uniform("mode", 1); 119 | triangleshader.uniform("KTriangles", tr.NT); 120 | triangleshader.uniform("RATIO", tpose::RATIO); 121 | triangleinstance.render(GL_TRIANGLE_STRIP, (13*tr.NT)); 122 | 123 | }; 124 | 125 | auto doshift = [&](){ 126 | 127 | gradient.use(); 128 | gradient.uniform("KTriangles", tr.NT); 129 | gradient.uniform("RATIO", tpose::RATIO); 130 | gradient.dispatch(1 + tr.NT/1024); 131 | 132 | shift.use(); 133 | shift.uniform("NPoints", tr.NP); 134 | shift.uniform("RATIO", tpose::RATIO); 135 | shift.dispatch(1 + tr.NP/1024); 136 | 137 | }; 138 | 139 | auto draw = [&](){ 140 | 141 | triangleshader.use(); 142 | triangleshader.texture("imageTexture", tex); //Load Texture 143 | triangleshader.uniform("mode", 2); 144 | triangleshader.uniform("KTriangles", tr.NT); 145 | triangleshader.uniform("RATIO", tpose::RATIO); 146 | triangleinstance.render(GL_TRIANGLE_STRIP, tr.NT); 147 | 148 | if(viewlines){ 149 | linestrip.use(); 150 | linestrip.uniform("RATIO", tpose::RATIO); 151 | linestripinstance.render(GL_LINE_STRIP, tr.NT); 152 | } 153 | 154 | }; 155 | 156 | computecolors(); 157 | 158 | // Main Functions 159 | 160 | Tiny::view.pipeline = [&](){ 161 | 162 | Tiny::view.target(color::black); //Target Main Screen 163 | 164 | computecolors(); 165 | draw(); 166 | 167 | }; 168 | 169 | Tiny::loop([&](){ 170 | 171 | if(paused) return; 172 | 173 | // Compute Cost and Gradients, Shift Points 174 | 175 | doenergy(); 176 | doshift(); 177 | 178 | // Retrieve Data from Compute Shader 179 | 180 | tpose::tenergybuf->retrieve((13*tr.NT), tpose::terr); 181 | // tpose::penergybuf->retrieve((13*tr.NT), tpose::perr); 182 | // tpose::tcolnumbuf->retrieve((13*tr.NT), tpose::cn); 183 | tpose::pointbuf->retrieve(tr.points); 184 | 185 | // TOPOLOGICAL OPTIMIZATIONS 186 | 187 | bool updated = false; 188 | 189 | #include "strat/flip_set_maxenergy.h" 190 | //#include "strat/flip_delaunay.h" 191 | 192 | if(updated){ 193 | if(tr.NT >= 1000) paused = true; 194 | cout<= KTriangles) 23 | return; 24 | 25 | // Add the Non-Normalized Gradient to the Per-Vertex Gradients 26 | 27 | atomicAdd(gr[ind[index].x].x, en[ 1*KTriangles + index] - en[ 2*KTriangles + index]); 28 | atomicAdd(gr[ind[index].x].y, en[ 3*KTriangles + index] - en[ 4*KTriangles + index]); 29 | 30 | atomicAdd(gr[ind[index].y].x, en[ 5*KTriangles + index] - en[ 6*KTriangles + index]); 31 | atomicAdd(gr[ind[index].y].y, en[ 7*KTriangles + index] - en[ 8*KTriangles + index]); 32 | 33 | atomicAdd(gr[ind[index].z].x, en[ 9*KTriangles + index] - en[10*KTriangles + index]); 34 | atomicAdd(gr[ind[index].z].y, en[11*KTriangles + index] - en[12*KTriangles + index]); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/shader/image.fs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 ex_Tex; 3 | out vec4 fragColor; 4 | 5 | uniform sampler2D imageTexture; 6 | 7 | void main(){ 8 | fragColor = texture(imageTexture, ex_Tex); 9 | } 10 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/shader/image.vs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 in_Quad; 3 | in vec2 in_Tex; 4 | out vec2 ex_Tex; 5 | 6 | //Position the Billboard in space! 7 | uniform mat4 model; 8 | 9 | void main(){ 10 | ex_Tex = in_Tex; 11 | gl_Position = model*vec4(in_Quad, -1.0, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/shader/linestrip.fs: -------------------------------------------------------------------------------- 1 | #version 430 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,1,1, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/shader/linestrip.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | layout (std430, binding = 1) buffer index { 11 | ivec4 ind[]; 12 | }; 13 | 14 | uniform float RATIO; 15 | 16 | void main() { 17 | 18 | vec2 tpos = vec2(0); 19 | if (in_Position.x > 0) tpos = p[ind[gl_InstanceID].x]; 20 | if (in_Position.y > 0) tpos = p[ind[gl_InstanceID].y]; 21 | if (in_Position.z > 0) tpos = p[ind[gl_InstanceID].z]; 22 | tpos.x /= RATIO; 23 | gl_Position = vec4(tpos, -1, 1.0f); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/shader/shift.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 0) buffer points { 6 | vec2 p[]; 7 | }; 8 | 9 | layout (std430, binding = 6) buffer gradient { 10 | ivec2 gr[]; 11 | }; 12 | 13 | uniform int NPoints; 14 | uniform int NTriangles; 15 | uniform float RATIO; 16 | 17 | void main(){ 18 | 19 | const uint index = gl_GlobalInvocationID.x; 20 | if(index >= NPoints) return; 21 | 22 | vec2 tgr = gr[index]; 23 | 24 | if(p[index].x <= -RATIO){ 25 | p[index].x = -RATIO; 26 | tgr.x = 0; 27 | } 28 | 29 | else if(p[index].x >= RATIO){ 30 | p[index].x = RATIO; 31 | tgr.x = 0; 32 | } 33 | 34 | if(p[index].y <= -1){ 35 | p[index].y = -1; 36 | tgr.y = 0; 37 | } 38 | 39 | else if(p[index].y >= 1){ 40 | p[index].y = 1; 41 | tgr.y = 0; 42 | } 43 | 44 | 45 | 46 | tgr = 0.00005 * vec2(tgr) / 256 / 256; 47 | // if(abs(tgr.x) < 1E-4) tgr.x = 0; 48 | // if(abs(tgr.y) < 1E-4) tgr.y = 0; 49 | 50 | // if(NTriangles >= 3){ 51 | // p[index] += vec2(1.0, 1.0); 52 | // } 53 | p[index] -= tgr; 54 | 55 | } 56 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/shader/triangle.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (std430, binding = 2) buffer colacc { 4 | ivec4 ca[]; 5 | }; 6 | 7 | layout (std430, binding = 3) buffer colnum { 8 | int cn[]; 9 | }; 10 | 11 | layout (std430, binding = 4) buffer tenergy { 12 | int ten[]; 13 | }; 14 | 15 | uniform sampler2D imageTexture; 16 | uniform int mode; 17 | 18 | in VS_OUT { 19 | vec2 position; 20 | flat int index; 21 | } vs_out; 22 | 23 | out vec4 fragColor; 24 | 25 | void main(){ 26 | 27 | if( mode == 0 ){ // Accumulate Color, Triangle Pixel Count 28 | 29 | fragColor = texture(imageTexture, vs_out.position); 30 | atomicAdd(cn[vs_out.index], 1); 31 | atomicAdd(ca[vs_out.index].r, int(255*fragColor.r)); 32 | atomicAdd(ca[vs_out.index].g, int(255*fragColor.g)); 33 | atomicAdd(ca[vs_out.index].b, int(255*fragColor.b)); 34 | 35 | } 36 | 37 | if( mode == 1 ){ // Accumulate Cost-Per-Pixel 38 | 39 | vec3 d = vec3(0); 40 | if(cn[vs_out.index] > 0) d = 255*texture(imageTexture, vs_out.position).rgb - vec3(ca[vs_out.index].rgb/cn[vs_out.index]); 41 | atomicAdd(ten[vs_out.index], int(0.5*dot(d, d))); 42 | 43 | } 44 | 45 | if( mode == 2 ){ // Draw Triangles 46 | 47 | fragColor = vec4(vec3(ca[vs_out.index].rgb)/cn[vs_out.index]/255, 1); 48 | 49 | // fragColor = mix(vec4(0,0,1,1), vec4(1,0,0,1), sqrt(float(en[vs_out.index]/cn[vs_out.index]))/255.0f); 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/shader/triangle.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | 5 | layout (std430, binding = 0) buffer points { 6 | vec2 p[]; 7 | }; 8 | 9 | layout (std430, binding = 1) buffer index { 10 | ivec4 ind[]; 11 | }; 12 | 13 | layout (std430, binding = 2) buffer colacc { 14 | ivec4 ca[]; 15 | }; 16 | 17 | layout (std430, binding = 3) buffer colnum { 18 | int cn[]; 19 | }; 20 | 21 | layout (std430, binding = 4) buffer tenergy { 22 | int ten[]; 23 | }; 24 | 25 | layout (std430, binding = 6) buffer gradient { 26 | ivec2 gr[]; 27 | }; 28 | 29 | layout (std430, binding = 7) buffer nring { 30 | int nr[]; 31 | }; 32 | 33 | out VS_OUT { 34 | 35 | vec2 position; 36 | flat int index; 37 | 38 | } vs_out; 39 | 40 | uniform float RATIO; 41 | uniform int KTriangles; 42 | uniform int mode; 43 | 44 | void main() { 45 | 46 | const int TDIV = gl_InstanceID/KTriangles; 47 | const int TMOD = gl_InstanceID%KTriangles; 48 | vs_out.index = gl_InstanceID; 49 | 50 | int pind; // Vertex Index 51 | if (in_Position.x > 0) 52 | pind = ind[TMOD].x; 53 | if (in_Position.y > 0) 54 | pind = ind[TMOD].y; 55 | if (in_Position.z > 0) 56 | pind = ind[TMOD].z; 57 | 58 | vec2 tpos = p[pind]; // Vertex Image-Space (-RATIO, RATIO) x, (-1, 1) y 59 | float dp = 0.05f; // Image-Space Pixel Shift 60 | 61 | // Cooling Regiment: 62 | 63 | // 1.: Divide by 2 as KTriangles -> 1000 64 | //dp /= (1.0f + 1.0f*float(KTriangles)/1000.0f); 65 | 66 | // 2.: Divide by 3 as KTriangles -> 1000 67 | //dp /= (1.0f + 2.0f*float(KTriangles)/1000.0f); 68 | 69 | // 3.: Divide by 10 as KTriangles -> 1000 70 | dp /= (1.0f + 9.0f*float(KTriangles)/1000.0f); 71 | 72 | // 4.: Divide by 20 as KTriangles -> 1000 73 | //dp /= (1.0f + 19.0f*float(KTriangles)/1000.0f); 74 | 75 | // 5.: Divide by 50 as KTriangles -> 1000 76 | //dp /= (1.0f + 49.0f*float(KTriangles)/1000.0f); 77 | 78 | // 6.: Scale by Size of Triangle!! 79 | //dp = 0.5*0.5*abs(determinant(mat3( 80 | // p[ind[TMOD].x].x, p[ind[TMOD].x].y, 1, 81 | // p[ind[TMOD].y].x, p[ind[TMOD].y].y, 1, 82 | // p[ind[TMOD].z].x, p[ind[TMOD].z].y, 1 83 | //))); 84 | 85 | // 7.: Scale by Eigenspace Projection 86 | 87 | /* 88 | vec2 va, vb; 89 | if(in_Position.x > 0){ 90 | va = (p[ind[TMOD].y] - p[ind[TMOD].x]); 91 | vb = (p[ind[TMOD].z] - p[ind[TMOD].x]); 92 | } 93 | if(in_Position.y > 0){ 94 | va = (p[ind[TMOD].z] - p[ind[TMOD].y]); 95 | vb = (p[ind[TMOD].x] - p[ind[TMOD].y]); 96 | } 97 | if(in_Position.z > 0){ 98 | va = (p[ind[TMOD].x] - p[ind[TMOD].z]); 99 | vb = (p[ind[TMOD].y] - p[ind[TMOD].z]); 100 | } 101 | mat2 V = transpose(mat2(normalize(va), normalize(vb))); 102 | mat2 L = mat2(length(va), 0, 0, length(vb)); 103 | 104 | vec2 D = V*L*inverse(V)*vec2(dp); 105 | 106 | */ 107 | 108 | vec2 D = vec2(dp); 109 | 110 | if(TDIV == 1 && in_Position.x > 0) D *= vec2( 1, 0); 111 | else if(TDIV == 2 && in_Position.x > 0) D *= vec2(-1, 0); 112 | else if(TDIV == 3 && in_Position.x > 0) D *= vec2( 0, 1); 113 | else if(TDIV == 4 && in_Position.x > 0) D *= vec2( 0,-1); 114 | else if(TDIV == 5 && in_Position.y > 0) D *= vec2( 1, 0); 115 | else if(TDIV == 6 && in_Position.y > 0) D *= vec2(-1, 0); 116 | else if(TDIV == 7 && in_Position.y > 0) D *= vec2( 0, 1); 117 | else if(TDIV == 8 && in_Position.y > 0) D *= vec2( 0,-1); 118 | else if(TDIV == 9 && in_Position.z > 0) D *= vec2( 1, 0); 119 | else if(TDIV == 10 && in_Position.z > 0) D *= vec2(-1, 0); 120 | else if(TDIV == 11 && in_Position.z > 0) D *= vec2( 0, 1); 121 | else if(TDIV == 12 && in_Position.z > 0) D *= vec2( 0,-1); 122 | else D *= vec2(0); 123 | 124 | tpos += D; 125 | tpos.x /= RATIO; // Position in Screen-Space (-1, 1) for x,y 126 | 127 | gl_Position = vec4(tpos, -1, 1.0f); 128 | vs_out.position = vec2(0.5*(1.0+tpos.x), 0.5*(1.0-tpos.y)); 129 | 130 | if(mode == 0){ 131 | cn[vs_out.index] = 0; 132 | ca[vs_out.index] = ivec4(0); 133 | } 134 | 135 | if(mode == 1){ 136 | ten[vs_out.index] = 0; 137 | gr[ind[TMOD].x] = ivec2(0); 138 | gr[ind[TMOD].y] = ivec2(0); 139 | gr[ind[TMOD].z] = ivec2(0); 140 | } 141 | 142 | //Add One-Ring Energy 143 | 144 | /* 145 | 146 | if( TDIV == 0 && mode == 0 ) 147 | atomicAdd(nr[TMOD], 1 ); //count the n-ring! (divided by 3) 148 | 149 | if( TDIV == 0 && mode == 1 ) { 150 | 151 | const float lambda = 0*256*256; 152 | 153 | if (in_Position.x > 0){ 154 | 155 | vec2 wva = p[pind] - p[ind[TMOD].y]; //Distance from this Vertex to Prev 156 | vec2 wvb = p[pind] - p[ind[TMOD].z]; //Distance from this Vertex to Next 157 | //Add Direct Energy Gradient 158 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[TMOD]); 159 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[TMOD]); 160 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[TMOD]); 161 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[TMOD]); 162 | 163 | } 164 | 165 | if (in_Position.y > 0){ 166 | 167 | vec2 wva = p[pind] - p[ind[TMOD].z]; //Distance from this Vertex to Prev 168 | vec2 wvb = p[pind] - p[ind[TMOD].x]; //Distance from this Vertex to Next 169 | //Add Direct Energy Gradient 170 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[TMOD]); 171 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[TMOD]); 172 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[TMOD]); 173 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[TMOD]); 174 | 175 | } 176 | 177 | if (in_Position.z > 0){ 178 | 179 | vec2 wva = p[pind] - p[ind[TMOD].x]; //Distance from this Vertex to Prev 180 | vec2 wvb = p[pind] - p[ind[TMOD].y]; //Distance from this Vertex to Next 181 | //Add Direct Energy Gradient 182 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[TMOD]); 183 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[TMOD]); 184 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[TMOD]); 185 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[TMOD]); 186 | 187 | } 188 | 189 | } 190 | 191 | */ 192 | 193 | } 194 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_delaunay.h: -------------------------------------------------------------------------------- 1 | // Delaunay Flip 2 | 3 | if( tri::geterr(&tr) < 1E-3 ){ 4 | 5 | int tta = tri::maxerrid(&tr); 6 | 7 | if(tta >= 0 && tr.split(tta)) 8 | updated = true; 9 | 10 | } 11 | 12 | // Prune Flat Boundary Triangles 13 | 14 | for(size_t ta = 0; ta < tr.NT; ta++) 15 | if(tr.boundary(ta) == 3) 16 | if(tr.prune(ta)) updated = true; 17 | 18 | // Attempt a Delaunay Flip on a Triangle's Largest Angle 19 | 20 | for(size_t ta = 0; ta < tr.NT; ta++){ 21 | 22 | int ha = 3*ta + 0; 23 | float maxangle = tr.angle( ha ); 24 | if(tr.angle( ha + 1 ) > maxangle) 25 | maxangle = tr.angle( ++ha ); 26 | if(tr.angle( ha + 1 ) > maxangle) 27 | maxangle = tr.angle( ++ha ); 28 | 29 | tr.flip(ha, tri::PI); 30 | 31 | } 32 | 33 | // Collapse Small Edges 34 | 35 | for(size_t ta = 0; ta < tr.triangles.size(); ta++){ 36 | 37 | int ha = 3*ta + 0; 38 | float minlength = tr.hlength( ha ); 39 | if(tr.hlength( ha + 1 ) < minlength) 40 | minlength = tr.hlength( ++ha ); 41 | if(tr.hlength( ha + 1 ) < minlength) 42 | minlength = tr.hlength( ++ha ); 43 | if(tr.collapse(ha)) 44 | updated = true; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_delaunay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/tests/opt_min_energy_edgeflip/strat/flip_delaunay.png -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_delaunay_dp_2.txt: -------------------------------------------------------------------------------- 1 | 4 1577764992 2 | 6 929794688 3 | 8 916832128 4 | 10 525473984 5 | 12 523090976 6 | 14 409508128 7 | 16 372214400 8 | 18 357839424 9 | 20 358140992 10 | 22 338096160 11 | 24 337305184 12 | 26 347111744 13 | 28 311663872 14 | 30 299091776 15 | 32 267859648 16 | 31 205104096 17 | 30 201826080 18 | 29 198271632 19 | 31 170776800 20 | 32 149569888 21 | 34 140761648 22 | 36 126592448 23 | 38 121187984 24 | 40 118578792 25 | 39 106613840 26 | 41 111737104 27 | 43 109504568 28 | 45 105118456 29 | 47 106097024 30 | 49 101560952 31 | 51 98116968 32 | 53 129685664 33 | 55 93353416 34 | 57 94682520 35 | 59 90619752 36 | 61 89052568 37 | 63 87378592 38 | 65 84284896 39 | 67 83261968 40 | 69 81843728 41 | 71 81090312 42 | 73 77928792 43 | 75 77473896 44 | 77 75671456 45 | 79 74682952 46 | 81 75459984 47 | 83 75882024 48 | 85 75072752 49 | 87 72226328 50 | 89 72045160 51 | 91 71801464 52 | 93 72441368 53 | 95 72232464 54 | 97 70906264 55 | 99 68803568 56 | 101 68633184 57 | 103 68014352 58 | 105 68646560 59 | 107 67781256 60 | 109 68323328 61 | 111 67564704 62 | 113 66802812 63 | 115 66746208 64 | 117 65345656 65 | 119 64481064 66 | 121 63472948 67 | 123 62235012 68 | 125 64376404 69 | 127 66162892 70 | 129 64093020 71 | 131 61197472 72 | 133 60448592 73 | 135 60221676 74 | 137 60976736 75 | 139 60881624 76 | 141 60418884 77 | 143 60300188 78 | 145 59435104 79 | 147 58466424 80 | 149 58367660 81 | 151 58117480 82 | 153 57782480 83 | 155 57066256 84 | 157 57738624 85 | 159 58573100 86 | 161 57223232 87 | 163 56275840 88 | 165 55420640 89 | 167 54745060 90 | 169 54389768 91 | 171 55126052 92 | 173 54779784 93 | 175 54036408 94 | 177 53927288 95 | 179 53822452 96 | 181 53836680 97 | 183 53397532 98 | 185 52954240 99 | 187 52763704 100 | 189 52003624 101 | 191 51930336 102 | 193 51763912 103 | 195 51722044 104 | 197 51117772 105 | 199 50697316 106 | 201 50971000 107 | 203 50759912 108 | 205 51781648 109 | 207 50936528 110 | 209 50532416 111 | 211 50563232 112 | 213 50303384 113 | 215 50178896 114 | 217 50115944 115 | 219 49417728 116 | 221 48559812 117 | 223 48320040 118 | 225 48231596 119 | 227 47688356 120 | 229 48121188 121 | 231 47594108 122 | 233 46925576 123 | 235 46996888 124 | 237 46690884 125 | 239 46994308 126 | 241 47173788 127 | 243 46185176 128 | 245 45686360 129 | 244 45695476 130 | 246 46572008 131 | 248 45880148 132 | 247 44761272 133 | 249 45714312 134 | 251 47032764 135 | 253 47188704 136 | 255 45608888 137 | 257 45007752 138 | 259 49763980 139 | 261 44399500 140 | 263 44282268 141 | 265 44118400 142 | 267 44366256 143 | 269 43629732 144 | 271 43429004 145 | 273 43242380 146 | 275 43325108 147 | 277 43350780 148 | 279 43524300 149 | 281 43347480 150 | 283 44225020 151 | 285 43785816 152 | 287 43485380 153 | 289 43277728 154 | 291 44026828 155 | 293 44079164 156 | 295 44030628 157 | 297 43762444 158 | 299 43648008 159 | 301 43537756 160 | 303 43693484 161 | 305 44116440 162 | 307 43709728 163 | 309 43992040 164 | 311 43034736 165 | 313 42959048 166 | 315 42685412 167 | 317 42879448 168 | 319 42640584 169 | 321 42531708 170 | 323 42601960 171 | 325 42841128 172 | 327 42852816 173 | 329 42472984 174 | 331 42180572 175 | 333 41860316 176 | 335 41593096 177 | 337 40911280 178 | 339 40845384 179 | 341 40679616 180 | 343 40649036 181 | 345 40578576 182 | 347 41115312 183 | 349 40713028 184 | 351 40483572 185 | 353 40288916 186 | 355 40164440 187 | 357 40237636 188 | 359 40390704 189 | 361 40259032 190 | 363 41213552 191 | 365 40323804 192 | 367 40130908 193 | 369 39925172 194 | 371 39755648 195 | 373 39801216 196 | 375 39754492 197 | 377 39747432 198 | 379 39765440 199 | 381 39832024 200 | 383 39803008 201 | 385 39753356 202 | 387 39809992 203 | 389 39790672 204 | 391 39489060 205 | 393 39327728 206 | 395 40145784 207 | 397 40190544 208 | 399 39632384 209 | 401 39224312 210 | 403 39190456 211 | 405 39182872 212 | 407 39172552 213 | 409 38907856 214 | 411 38801296 215 | 413 38851596 216 | 415 38691248 217 | 417 39011600 218 | 419 39516200 219 | 421 38578336 220 | 423 38782996 221 | 425 38705688 222 | 427 38610060 223 | 429 38496516 224 | 431 38466480 225 | 433 38477568 226 | 435 38310896 227 | 437 38251904 228 | 439 38090836 229 | 441 38815520 230 | 443 38230828 231 | 445 38633936 232 | 447 38182696 233 | 449 38056024 234 | 450 38003720 235 | 452 38665336 236 | 454 38286988 237 | 456 38051096 238 | 458 38296284 239 | 460 38173024 240 | 462 38077076 241 | 464 37893656 242 | 466 37635972 243 | 468 37549048 244 | 470 37177224 245 | 472 37219984 246 | 474 37021240 247 | 476 36923752 248 | 478 36754096 249 | 480 36627280 250 | 482 37083568 251 | 484 36626444 252 | 482 36083360 253 | 484 36372108 254 | 486 36332528 255 | 488 36200436 256 | 490 36374368 257 | 492 35826916 258 | 494 35787128 259 | 496 35934868 260 | 498 35752348 261 | 500 35778840 262 | 502 35274832 263 | 504 35112696 264 | 506 35057204 265 | 508 34976812 266 | 510 34819104 267 | 512 34781856 268 | 514 34765692 269 | 516 34866272 270 | 518 35266368 271 | 520 35137004 272 | 522 35239236 273 | 524 35037320 274 | 526 35038204 275 | 528 35181648 276 | 530 35152960 277 | 532 35195744 278 | 534 35089656 279 | 536 35041092 280 | 538 34939744 281 | 540 34883644 282 | 542 34808392 283 | 544 35662616 284 | 546 35215880 285 | 548 35115732 286 | 550 34696436 287 | 552 34901184 288 | 554 34932460 289 | 556 34915008 290 | 558 35027288 291 | 560 35477456 292 | 562 34773172 293 | 564 34644888 294 | 566 34564756 295 | 568 34482212 296 | 570 34475724 297 | 572 34448560 298 | 574 34323088 299 | 576 34299292 300 | 578 34185792 301 | 580 34046068 302 | 582 33683688 303 | 584 33797784 304 | 586 33660908 305 | 588 33674600 306 | 590 33637616 307 | 592 33539352 308 | 594 33534616 309 | 596 33453288 310 | 598 33442092 311 | 600 33384574 312 | 602 33374084 313 | 604 33642612 314 | 606 33669220 315 | 608 33596824 316 | 607 33257922 317 | 609 33497318 318 | 611 33429818 319 | 613 33357820 320 | 615 33266080 321 | 617 33135840 322 | 619 32922510 323 | 621 32905254 324 | 623 32776972 325 | 625 32654854 326 | 627 32555120 327 | 629 32575882 328 | 631 32464650 329 | 633 32569010 330 | 635 32397716 331 | 637 32430572 332 | 639 32231594 333 | 641 32205764 334 | 643 32182414 335 | 645 32158368 336 | 647 32367448 337 | 649 32133128 338 | 651 32066204 339 | 653 32107084 340 | 655 32022096 341 | 657 31855308 342 | 659 31815816 343 | 661 31632900 344 | 663 31857604 345 | 665 31838300 346 | 667 31636760 347 | 669 31417070 348 | 671 31360212 349 | 673 31346752 350 | 675 31132784 351 | 677 31081972 352 | 679 30993652 353 | 681 30918908 354 | 683 30807462 355 | 685 30667488 356 | 687 30853136 357 | 689 30799736 358 | 691 30671312 359 | 693 30610408 360 | 695 30517544 361 | 697 30515136 362 | 699 30802052 363 | 701 30541876 364 | 703 30545440 365 | 701 30350704 366 | 703 30545668 367 | 705 30512586 368 | 707 30565392 369 | 709 30480232 370 | 711 30406512 371 | 713 30296196 372 | 715 30457524 373 | 717 30455744 374 | 719 30333400 375 | 721 30245168 376 | 723 30191592 377 | 725 30010228 378 | 727 30076664 379 | 729 30176242 380 | 731 30012910 381 | 733 29975250 382 | 735 29992904 383 | 737 29983174 384 | 739 29815656 385 | 741 29745096 386 | 743 29859810 387 | 745 29643628 388 | 747 29667288 389 | 749 29547732 390 | 751 29525284 391 | 749 29255316 392 | 751 29605828 393 | 753 29600408 394 | 755 29513068 395 | 757 29518916 396 | 759 29488740 397 | 761 29375604 398 | 763 29258104 399 | 765 29244140 400 | 767 29267736 401 | 769 29275680 402 | 771 29220856 403 | 773 29212956 404 | 775 29070930 405 | 777 29120540 406 | 779 29097568 407 | 781 29389612 408 | 783 29147072 409 | 785 29116240 410 | 787 29088732 411 | 789 29010480 412 | 791 28947524 413 | 793 29011720 414 | 792 28776836 415 | 794 29052726 416 | 796 28948192 417 | 798 28953872 418 | 800 28929276 419 | 802 28780204 420 | 804 28876422 421 | 806 28775674 422 | 808 28941664 423 | 810 28784602 424 | 812 28632554 425 | 814 28517230 426 | 816 28936136 427 | 818 28563940 428 | 820 28526498 429 | 822 28562530 430 | 824 28411636 431 | 826 28665520 432 | 828 28413424 433 | 830 28335608 434 | 832 28363612 435 | 834 28579924 436 | 836 28366494 437 | 838 28265290 438 | 840 28204200 439 | 842 28123166 440 | 844 28080754 441 | 846 28036330 442 | 848 28093646 443 | 850 28059252 444 | 852 28130396 445 | 854 27910508 446 | 856 27907436 447 | 858 27885384 448 | 858 27949268 449 | 860 27993288 450 | 862 27855472 451 | 864 27832700 452 | 866 27872404 453 | 868 27826420 454 | 870 27811932 455 | 872 27772148 456 | 874 27799172 457 | 876 27830796 458 | 876 27751300 459 | 878 27780972 460 | 880 27779204 461 | 882 27882404 462 | 884 27838508 463 | 886 27856404 464 | 888 27739316 465 | 890 27651128 466 | 892 27620266 467 | 894 27697608 468 | 894 27558840 469 | 896 27547332 470 | 898 27590596 471 | 900 27468180 472 | 902 27490016 473 | 904 27487244 474 | 906 27536370 475 | 908 27515212 476 | 910 27663448 477 | 912 27610118 478 | 914 27795422 479 | 916 27775138 480 | 918 27803754 481 | 920 27798450 482 | 922 27679026 483 | 924 27644646 484 | 926 27780052 485 | 928 28003024 486 | 928 27774708 487 | 930 27670604 488 | 932 27620592 489 | 934 27634164 490 | 936 27702654 491 | 938 27609638 492 | 940 27648506 493 | 942 27481652 494 | 944 27419544 495 | 946 27345192 496 | 948 27240512 497 | 950 27189524 498 | 952 27120308 499 | 954 27070168 500 | 956 27097188 501 | 956 26883860 502 | 958 26873744 503 | 960 26914144 504 | 962 26881252 505 | 964 26816492 506 | 966 26878608 507 | 968 26877108 508 | 970 26862916 509 | 972 26887378 510 | 974 26888328 511 | 976 26869826 512 | 978 26891514 513 | 980 26854464 514 | 982 26802128 515 | 984 26787508 516 | 986 26747526 517 | 988 26712340 518 | 990 26740624 519 | 992 26682044 520 | 994 26700116 521 | 996 26655180 522 | 994 26572616 523 | 996 26606300 524 | 998 26519136 525 | 1000 26689032 526 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_delaunay_lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/tests/opt_min_energy_edgeflip/strat/flip_delaunay_lines.png -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_max.h: -------------------------------------------------------------------------------- 1 | // Only Single Energy Improving Flips! But also max angle! But no angle restricioon! 2 | 3 | /* 4 | 5 | Flip-Set: 6 | 7 | Order by energy, then slowly work off the set removing elements that are not in the set as I go. 8 | Meanwhile, remember which nodes were flipped so I can flip them back if the energy is unfavorable. 9 | 10 | Do this in its entirety. 11 | 12 | */ 13 | 14 | // I have the energy: 15 | 16 | //std::list triangles; 17 | //for(size_t i = 0; i < tr.triangles.size(); i++){ 18 | // triangles.push_front(i); 19 | //} 20 | 21 | // Take the triangles and sort them by their energy?? 22 | 23 | if( tri::geterr(&tr) < 1E-3 ){ 24 | 25 | int tta = tri::maxerrid(&tr); 26 | if(tta >= 0){ 27 | 28 | int ha = 3*tta + 0; 29 | 30 | float maxangle = tr.angle( ha ); 31 | if(tr.angle( ha + 1 ) > maxangle) 32 | maxangle = tr.angle( ++ha ); 33 | if(tr.angle( ha + 1 ) > maxangle) 34 | maxangle = tr.angle( ++ha ); 35 | 36 | if(tr.halfedges[ ha ] >= 0){ 37 | 38 | float energy = tri::terr[ tta ] + tri::terr[ (tr.halfedges[ ha ])/3 ]; 39 | 40 | // Try Flip Regardless of Angle 41 | 42 | if( tr.flip( ha, 0.0f ) ){ 43 | 44 | tri::upload(&tr, false); 45 | computecolors(); 46 | doenergy(); 47 | 48 | tri::tenergybuf->retrieve((13*tr.NT), tri::terr); 49 | 50 | // if Energy Fails, Flip it Back, Split it 51 | 52 | if( tri::terr[ tta ] + tri::terr[ (tr.halfedges[ ha ])/3 ] > energy ){ 53 | tr.flip( ha, 0.0f ); //Flip it Back 54 | if(tr.split( tta )) 55 | updated = true; 56 | } 57 | 58 | } 59 | 60 | else { 61 | if(tr.split( tta )) 62 | updated = true; 63 | } 64 | 65 | } 66 | 67 | else { 68 | if(tr.split( tta )) 69 | updated = true; 70 | } 71 | 72 | } 73 | 74 | } 75 | 76 | // Prune Flat Boundary Triangles 77 | 78 | for(size_t ta = 0; ta < tr.NT; ta++) 79 | if(tr.boundary(ta) == 3) 80 | if(tr.prune(ta)) updated = true; 81 | 82 | // Attempt a Delaunay Flip on a Triangle's Largest Angle 83 | 84 | for(size_t ta = 0; ta < tr.NT; ta++){ 85 | 86 | int ha = 3*ta + 0; 87 | float maxangle = tr.angle( ha ); 88 | if(tr.angle( ha + 1 ) > maxangle) 89 | maxangle = tr.angle( ++ha ); 90 | if(tr.angle( ha + 1 ) > maxangle) 91 | maxangle = tr.angle( ++ha ); 92 | 93 | if(maxangle >= 0.9*tri::PI) 94 | tr.flip(ha, 0.5*tri::PI); 95 | else tr.flip(ha, 1.5f*tri::PI); 96 | 97 | } 98 | 99 | // Collapse Small Edges 100 | 101 | for(size_t ta = 0; ta < tr.triangles.size(); ta++){ 102 | 103 | int ha = 3*ta + 0; 104 | float minlength = tr.hlength( ha ); 105 | if(tr.hlength( ha + 1 ) < minlength) 106 | minlength = tr.hlength( ++ha ); 107 | if(tr.hlength( ha + 1 ) < minlength) 108 | minlength = tr.hlength( ++ha ); 109 | if(tr.collapse(ha)) 110 | updated = true; 111 | 112 | } 113 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/tests/opt_min_energy_edgeflip/strat/flip_max.png -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_max_lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/tests/opt_min_energy_edgeflip/strat/flip_max_lines.png -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_set_maxangle.h: -------------------------------------------------------------------------------- 1 | // Only Single Energy Improving Flips! But also max angle! But no angle restricioon! 2 | 3 | /* 4 | 5 | Flip-Set: 6 | 7 | Order by energy, then slowly work off the set removing elements that are not in the set as I go. 8 | Meanwhile, remember which nodes were flipped so I can flip them back if the energy is unfavorable. 9 | 10 | Do this in its entirety. 11 | 12 | 13 | Set of all triangles with energies 14 | 15 | Sort set by energies 16 | 17 | Try flipping all triangles in order, removing triangles that are "not flippable" 18 | 19 | for flipped triangles, store the energies 20 | 21 | check the flipped set to see if its improved or not 22 | 23 | flip' em back 24 | 25 | */ 26 | 27 | // Sortable Container with Energies and Triangles 28 | 29 | 30 | 31 | 32 | // Take the triangles and sort them by their energy?? 33 | 34 | if( tpose::geterr(&tr) < 1E-3 ){ 35 | 36 | struct setsort { 37 | bool operator () (const std::pair& lhs, const std::pair& rhs) const { 38 | return lhs.second > rhs.second; 39 | } 40 | }; 41 | 42 | // Create the sorted set of max-angle half-edges 43 | 44 | std::set, setsort> hset; 45 | for(int t = 0; t < tr.triangles.size(); t++){ 46 | 47 | int ha = 3*t + 0; 48 | float maxangle = tr.angle( ha ); 49 | if(tr.angle( ha + 1 ) > maxangle) 50 | maxangle = tr.angle( ++ha ); 51 | if(tr.angle( ha + 1 ) > maxangle) 52 | maxangle = tr.angle( ++ha ); 53 | 54 | hset.emplace(ha, tpose::terr[t]); 55 | 56 | } 57 | 58 | std::set nflipset; // Halfedges NOT to flip! 59 | std::map hflipset; // Halfedges to Flip 60 | 61 | // Iterate over the sorted triangles 62 | 63 | for(auto& h: hset){ 64 | 65 | if(nflipset.contains(h.first)) // Non-Flip Halfedge 66 | continue; 67 | 68 | if( tr.halfedges[h.first] < 0 ) // No Opposing Halfedge 69 | continue; 70 | 71 | if(nflipset.contains(tr.halfedges[h.first])) // Opposing Half-Edge Not Flippable 72 | continue; 73 | 74 | // Compute Energy for this Half-Edge Pair 75 | 76 | hflipset[ h.first ] = tpose::terr[ h.first/3 ] + tpose::terr[ (tr.halfedges[ h.first ])/3 ]; 77 | 78 | // Add all Half-Edges of Both Triangles to the Non-Flip Set 79 | 80 | int ta = h.first/3; 81 | int tb = tr.halfedges[ h.first ]/3; 82 | 83 | nflipset.emplace( 3*ta + 0 ); 84 | nflipset.emplace( 3*ta + 1 ); 85 | nflipset.emplace( 3*ta + 2 ); 86 | nflipset.emplace( 3*tb + 0 ); 87 | nflipset.emplace( 3*tb + 1 ); 88 | nflipset.emplace( 3*tb + 2 ); 89 | 90 | } 91 | 92 | // Flip the flip set, then check the energy, and flip those that don't work back! 93 | 94 | for(auto& h: hflipset) 95 | tr.flip( h.first, 0.0f ); 96 | 97 | tpose::upload(&tr, false); 98 | computecolors(); 99 | doenergy(); 100 | 101 | tpose::tenergybuf->retrieve((13*tr.NT), tpose::terr); 102 | 103 | for(auto& h: hflipset){ 104 | 105 | if( tpose::terr[ h.first/3 ] + tpose::terr[ (tr.halfedges[ h.first ])/3 ] > h.second ) 106 | tr.flip( h.first, 0.0f ); //Flip it Back, Split 107 | 108 | } 109 | 110 | tpose::upload(&tr, false); 111 | computecolors(); 112 | doenergy(); 113 | tpose::tenergybuf->retrieve((13*tr.NT), tpose::terr); 114 | 115 | int tta = tpose::maxerrid(&tr); 116 | if(tta >= 0 && tr.split(tta)) 117 | updated = true; 118 | 119 | } 120 | 121 | // Prune Flat Boundary Triangles 122 | 123 | for(size_t ta = 0; ta < tr.NT; ta++) 124 | if(tr.boundary(ta) == 3) 125 | if(tr.prune(ta)) updated = true; 126 | 127 | // Attempt a Delaunay Flip on a Triangle's Largest Angle 128 | 129 | for(size_t ta = 0; ta < tr.NT; ta++){ 130 | 131 | int ha = 3*ta + 0; 132 | float maxangle = tr.angle( ha ); 133 | if(tr.angle( ha + 1 ) > maxangle) 134 | maxangle = tr.angle( ++ha ); 135 | if(tr.angle( ha + 1 ) > maxangle) 136 | maxangle = tr.angle( ++ha ); 137 | 138 | if(maxangle >= 0.9*tpose::PI) 139 | tr.flip(ha, 0.0); 140 | 141 | } 142 | 143 | // Collapse Small Edges 144 | 145 | for(size_t ta = 0; ta < tr.triangles.size(); ta++){ 146 | 147 | int ha = 3*ta + 0; 148 | float minlength = tr.hlength( ha ); 149 | if(tr.hlength( ha + 1 ) < minlength) 150 | minlength = tr.hlength( ++ha ); 151 | if(tr.hlength( ha + 1 ) < minlength) 152 | minlength = tr.hlength( ++ha ); 153 | if(tr.collapse(ha)) 154 | updated = true; 155 | 156 | } 157 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_set_maxenergy.h: -------------------------------------------------------------------------------- 1 | // Only Single Energy Improving Flips! But also max angle! But no angle restricioon! 2 | 3 | /* 4 | 5 | Flip-Set: 6 | 7 | Order by energy, then slowly work off the set removing elements that are not in the set as I go. 8 | Meanwhile, remember which nodes were flipped so I can flip them back if the energy is unfavorable. 9 | 10 | Do this in its entirety. 11 | 12 | 13 | Set of all triangles with energies 14 | 15 | Sort set by energies 16 | 17 | Try flipping all triangles in order, removing triangles that are "not flippable" 18 | 19 | for flipped triangles, store the energies 20 | 21 | check the flipped set to see if its improved or not 22 | 23 | flip' em back 24 | 25 | */ 26 | 27 | // Sortable Container with Energies and Triangles 28 | 29 | 30 | 31 | 32 | // Take the triangles and sort them by their energy?? 33 | 34 | if( tpose::geterr(&tr) < 1E-4 ){ 35 | 36 | struct setsort { 37 | bool operator () (const std::pair& lhs, const std::pair& rhs) const { 38 | return lhs.second > rhs.second; 39 | } 40 | }; 41 | 42 | // Create the sorted set of max-angle half-edges 43 | 44 | std::set, setsort> hset; 45 | for(int t = 0; t < tr.triangles.size(); t++){ 46 | 47 | if( tr.halfedges[ 3*t + 0 ] >= 0 ) 48 | hset.emplace( 3*t + 0, tpose::terr[t] + tpose::terr[tr.halfedges[ 3*t + 0 ]/3] ); 49 | if( tr.halfedges[ 3*t + 1 ] >= 0 ) 50 | hset.emplace( 3*t + 1, tpose::terr[t] + tpose::terr[tr.halfedges[ 3*t + 1 ]/3] ); 51 | if( tr.halfedges[ 3*t + 2 ] >= 0 ) 52 | hset.emplace( 3*t + 2, tpose::terr[t] + tpose::terr[tr.halfedges[ 3*t + 2 ]/3] ); 53 | 54 | } 55 | 56 | std::set nflipset; // Halfedges NOT to flip! 57 | std::map hflipset; // Halfedges to Flip 58 | 59 | // Iterate over the sorted triangles 60 | 61 | for(auto& h: hset){ 62 | 63 | if(nflipset.contains(h.first)) // Non-Flip Halfedge 64 | continue; 65 | 66 | if( tr.halfedges[h.first] < 0 ) // No Opposing Halfedge 67 | continue; 68 | 69 | if(nflipset.contains(tr.halfedges[h.first])) // Opposing Half-Edge Not Flippable 70 | continue; 71 | 72 | // Compute Energy for this Half-Edge Pair 73 | 74 | hflipset[ h.first ] = h.second; 75 | 76 | // Add all Half-Edges of Both Triangles to the Non-Flip Set 77 | 78 | int ta = h.first/3; 79 | int tb = tr.halfedges[ h.first ]/3; 80 | 81 | nflipset.emplace( 3*ta + 0 ); 82 | nflipset.emplace( 3*ta + 1 ); 83 | nflipset.emplace( 3*ta + 2 ); 84 | nflipset.emplace( 3*tb + 0 ); 85 | nflipset.emplace( 3*tb + 1 ); 86 | nflipset.emplace( 3*tb + 2 ); 87 | 88 | } 89 | 90 | // Flip the flip set, then check the energy, and flip those that don't work back! 91 | 92 | for(auto& h: hflipset) 93 | tr.flip( h.first, 0.0f ); 94 | 95 | tpose::upload(&tr, false); 96 | computecolors(); 97 | doenergy(); 98 | 99 | tpose::tenergybuf->retrieve((13*tr.NT), tpose::terr); 100 | 101 | for(auto& h: hflipset){ 102 | 103 | if( tpose::terr[ h.first/3 ] + tpose::terr[ (tr.halfedges[ h.first ])/3 ] > h.second ) 104 | tr.flip( h.first, 0.0f ); //Flip it Back, Split 105 | 106 | } 107 | 108 | tpose::upload(&tr, false); 109 | computecolors(); 110 | doenergy(); 111 | tpose::tenergybuf->retrieve((13*tr.NT), tpose::terr); 112 | 113 | int tta = tpose::maxerrid(&tr); 114 | if(tta >= 0 && tr.split(tta)) 115 | updated = true; 116 | 117 | } 118 | 119 | // Prune Flat Boundary Triangles 120 | 121 | for(size_t ta = 0; ta < tr.NT; ta++) 122 | if(tr.boundary(ta) == 3) 123 | if(tr.prune(ta)) updated = true; 124 | 125 | // Attempt a Delaunay Flip on a Triangle's Largest Angle 126 | 127 | for(size_t ta = 0; ta < tr.NT; ta++){ 128 | 129 | if(tr.angle( 3*ta + 0 ) > 0.8*tpose::PI) 130 | tr.flip( 3*ta + 0, 0.0 ); 131 | if(tr.angle( 3*ta + 1 ) > 0.8*tpose::PI) 132 | tr.flip( 3*ta + 1, 0.0 ); 133 | if(tr.angle( 3*ta + 2 ) > 0.8*tpose::PI) 134 | tr.flip( 3*ta + 2, 0.0 ); 135 | 136 | } 137 | 138 | // Collapse Small Edges 139 | 140 | for(size_t ta = 0; ta < tr.triangles.size(); ta++){ 141 | 142 | int ha = 3*ta + 0; 143 | float minlength = tr.hlength( ha ); 144 | if(tr.hlength( ha + 1 ) < minlength) 145 | minlength = tr.hlength( ++ha ); 146 | if(tr.hlength( ha + 1 ) < minlength) 147 | minlength = tr.hlength( ++ha ); 148 | if(tr.collapse(ha)) 149 | updated = true; 150 | 151 | } 152 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_set_maxenergy_dp_20.txt: -------------------------------------------------------------------------------- 1 | 4 1537764480 2 | 6 963693952 3 | 8 803256768 4 | 10 493107552 5 | 12 499130720 6 | 14 487574976 7 | 16 468622240 8 | 18 389837728 9 | 20 341664512 10 | 22 341494144 11 | 24 334676768 12 | 26 331640704 13 | 28 323613440 14 | 30 319196672 15 | 32 312901024 16 | 34 321704000 17 | 36 322258880 18 | 35 220769312 19 | 37 228864352 20 | 35 159894448 21 | 36 198249296 22 | 38 193620448 23 | 40 186802912 24 | 42 171355696 25 | 44 163025760 26 | 46 153098576 27 | 48 154213296 28 | 50 139968672 29 | 51 145677456 30 | 53 134783296 31 | 55 107037368 32 | 57 94605952 33 | 59 88905824 34 | 61 85949688 35 | 63 86522136 36 | 65 83300688 37 | 67 81489544 38 | 66 75298080 39 | 68 78794344 40 | 70 79158040 41 | 72 77721864 42 | 74 77198104 43 | 76 76567560 44 | 78 76250360 45 | 80 75804840 46 | 82 74684448 47 | 84 73587904 48 | 86 72938272 49 | 88 72207872 50 | 90 71830680 51 | 92 70764792 52 | 94 68922472 53 | 96 68855712 54 | 98 68465424 55 | 100 67616688 56 | 102 66526804 57 | 104 64752480 58 | 106 63975244 59 | 108 63719224 60 | 110 63302740 61 | 112 62992404 62 | 114 64074696 63 | 116 63154688 64 | 118 62585408 65 | 120 60905516 66 | 122 59886412 67 | 124 58710048 68 | 126 58478116 69 | 128 57832528 70 | 130 55862156 71 | 132 55151424 72 | 134 54776520 73 | 136 54234448 74 | 138 54011336 75 | 140 53610304 76 | 142 53328024 77 | 144 52500564 78 | 146 52252868 79 | 148 51888224 80 | 150 51438752 81 | 152 50703212 82 | 154 50728768 83 | 156 50422696 84 | 158 50428556 85 | 160 49723188 86 | 162 49891132 87 | 164 49233380 88 | 166 49372424 89 | 168 48883104 90 | 170 48777984 91 | 172 48309280 92 | 174 48001992 93 | 176 47478980 94 | 178 47464496 95 | 180 48479472 96 | 182 47389196 97 | 184 47308684 98 | 186 47374616 99 | 188 46675292 100 | 190 46903756 101 | 192 46668932 102 | 194 46248652 103 | 196 46060688 104 | 198 45322488 105 | 200 45049912 106 | 202 44890528 107 | 204 44687976 108 | 206 44608924 109 | 208 44374376 110 | 210 43936792 111 | 212 43759764 112 | 214 43803468 113 | 216 43536740 114 | 218 43773228 115 | 220 43255736 116 | 222 43112672 117 | 224 43218464 118 | 226 43293536 119 | 228 42858004 120 | 230 42742556 121 | 232 42473896 122 | 234 42327352 123 | 236 42696424 124 | 238 42141912 125 | 240 41840764 126 | 242 41671480 127 | 244 41118936 128 | 246 41052560 129 | 248 40861136 130 | 250 40605076 131 | 252 40524160 132 | 254 40414608 133 | 256 40861840 134 | 258 40494100 135 | 260 40294144 136 | 262 40072632 137 | 264 40012336 138 | 266 39646740 139 | 268 39638104 140 | 270 39574856 141 | 272 39448216 142 | 274 39158588 143 | 276 39073960 144 | 278 38966928 145 | 280 38758448 146 | 282 39033880 147 | 284 38804032 148 | 286 38805344 149 | 288 38656888 150 | 290 37825984 151 | 292 37506344 152 | 294 37381344 153 | 296 37259880 154 | 298 37069092 155 | 300 36872280 156 | 302 36840492 157 | 304 36714464 158 | 306 36599084 159 | 308 36538608 160 | 310 36496844 161 | 312 36237664 162 | 314 36026440 163 | 316 35880500 164 | 318 35697776 165 | 320 35472292 166 | 322 35380248 167 | 324 35286068 168 | 326 35342964 169 | 328 35296448 170 | 330 35150864 171 | 332 35049000 172 | 334 34900960 173 | 336 34826464 174 | 338 34713104 175 | 340 34510416 176 | 342 34457536 177 | 344 34367668 178 | 346 34357064 179 | 348 34190904 180 | 350 34149380 181 | 352 34084248 182 | 354 33931840 183 | 356 33701108 184 | 358 33581788 185 | 360 33290182 186 | 362 33191218 187 | 364 33363168 188 | 366 32791256 189 | 368 32730314 190 | 370 33175132 191 | 372 33003244 192 | 374 33092552 193 | 376 33031136 194 | 378 33085676 195 | 380 32983240 196 | 382 33073544 197 | 384 32798714 198 | 386 32707254 199 | 388 32979884 200 | 390 32467790 201 | 392 32239484 202 | 394 32129008 203 | 396 31937866 204 | 398 31820256 205 | 400 31480896 206 | 402 31307106 207 | 404 31225900 208 | 406 31283784 209 | 408 31206092 210 | 410 31399560 211 | 412 31286480 212 | 414 31199492 213 | 416 30991624 214 | 418 30924504 215 | 420 30864652 216 | 422 30763860 217 | 424 30588942 218 | 426 30591216 219 | 428 30518380 220 | 430 30357836 221 | 432 30435982 222 | 434 30345090 223 | 436 30145826 224 | 438 30119874 225 | 440 30039110 226 | 442 29761550 227 | 444 29752210 228 | 446 29722534 229 | 448 29560376 230 | 449 29254012 231 | 451 29319478 232 | 453 29371924 233 | 455 29324060 234 | 457 29347084 235 | 459 29124468 236 | 461 29154856 237 | 463 28985136 238 | 465 29041868 239 | 467 28932892 240 | 469 28882292 241 | 471 28712996 242 | 473 28838252 243 | 475 28830608 244 | 477 30021920 245 | 479 29331676 246 | 481 28669948 247 | 483 28551348 248 | 481 28361016 249 | 483 28552944 250 | 485 28482952 251 | 487 28403712 252 | 489 28311254 253 | 491 28463812 254 | 493 28438126 255 | 495 28389980 256 | 497 28271340 257 | 499 28210994 258 | 501 28182688 259 | 503 28074108 260 | 505 28020184 261 | 507 27933712 262 | 509 27619416 263 | 511 27555314 264 | 513 27433068 265 | 515 27370898 266 | 517 27256610 267 | 519 27266298 268 | 521 27134106 269 | 523 27039388 270 | 525 27021576 271 | 527 26934556 272 | 529 26827100 273 | 531 26571390 274 | 533 26548098 275 | 535 26512278 276 | 537 26461536 277 | 539 26407082 278 | 541 26307926 279 | 543 26204576 280 | 545 26202160 281 | 547 26121602 282 | 549 26079788 283 | 551 26012042 284 | 553 25948632 285 | 555 25872108 286 | 557 25844480 287 | 559 25922516 288 | 561 25893560 289 | 563 25781346 290 | 565 25759520 291 | 567 25717760 292 | 569 25398444 293 | 571 25337420 294 | 573 25322486 295 | 575 25296990 296 | 577 25279170 297 | 579 25428710 298 | 581 25319058 299 | 583 25243850 300 | 585 25137026 301 | 587 25001502 302 | 589 24994894 303 | 591 24897160 304 | 593 24817928 305 | 595 24704278 306 | 597 24655148 307 | 599 24650784 308 | 601 24606610 309 | 603 24544958 310 | 605 24518882 311 | 607 24503126 312 | 609 24466642 313 | 611 24446142 314 | 613 24377750 315 | 615 24358386 316 | 617 24316102 317 | 619 24276224 318 | 619 24051912 319 | 621 24155954 320 | 623 24036840 321 | 625 24049770 322 | 627 24038658 323 | 629 23968634 324 | 631 23837130 325 | 633 23933476 326 | 635 23836566 327 | 637 23908464 328 | 639 23741868 329 | 641 23812832 330 | 643 23633680 331 | 645 23664292 332 | 647 23575812 333 | 649 23546298 334 | 651 23331420 335 | 653 23426490 336 | 655 23295912 337 | 657 23341984 338 | 659 23297128 339 | 661 23055162 340 | 663 23015828 341 | 665 22977198 342 | 667 22969716 343 | 669 22962812 344 | 671 22957508 345 | 673 22911228 346 | 675 22847472 347 | 677 22821424 348 | 679 22778660 349 | 681 22712212 350 | 683 22679824 351 | 685 22649440 352 | 687 22639308 353 | 689 22598932 354 | 691 22627048 355 | 693 22552848 356 | 695 22513168 357 | 697 22472572 358 | 699 22469268 359 | 701 22402334 360 | 703 22333786 361 | 705 22375682 362 | 707 22342450 363 | 709 22325246 364 | 711 22306838 365 | 713 22244482 366 | 715 22201854 367 | 717 22107328 368 | 719 22099460 369 | 721 22066000 370 | 723 22040744 371 | 725 22050712 372 | 727 22036076 373 | 729 22043200 374 | 731 22026954 375 | 733 22036382 376 | 735 22131646 377 | 737 22070380 378 | 739 22052880 379 | 741 22028864 380 | 743 22019060 381 | 745 22034266 382 | 747 21959686 383 | 749 21954766 384 | 751 21932310 385 | 753 21852982 386 | 755 21726372 387 | 755 21573780 388 | 757 21650312 389 | 759 21634428 390 | 761 21525916 391 | 763 21553160 392 | 765 21413116 393 | 767 21357992 394 | 769 21187452 395 | 771 21187844 396 | 773 21169704 397 | 775 21101920 398 | 777 21071636 399 | 777 20943548 400 | 779 21077524 401 | 781 21004108 402 | 783 21040468 403 | 785 20963632 404 | 787 20991284 405 | 789 20970692 406 | 791 20966104 407 | 793 20912260 408 | 795 20951904 409 | 797 20866376 410 | 799 20854716 411 | 801 20797944 412 | 803 20759488 413 | 805 20714220 414 | 807 20710960 415 | 809 20661768 416 | 811 20650460 417 | 813 20610572 418 | 815 20566412 419 | 817 20568848 420 | 819 20582676 421 | 821 20542708 422 | 823 20536216 423 | 825 20502448 424 | 827 20462468 425 | 829 20423428 426 | 831 20328628 427 | 833 20314408 428 | 835 20269704 429 | 837 20193496 430 | 839 20146548 431 | 841 20147296 432 | 843 20107484 433 | 845 20116036 434 | 847 20127672 435 | 849 20160332 436 | 851 20112440 437 | 853 20117628 438 | 855 20096440 439 | 857 20054948 440 | 859 19994264 441 | 861 19999452 442 | 863 19948076 443 | 865 19930448 444 | 867 19914508 445 | 869 19894236 446 | 871 19851944 447 | 871 19723396 448 | 873 19819504 449 | 875 19723220 450 | 877 19689996 451 | 879 19654888 452 | 881 19668960 453 | 881 19572084 454 | 883 19660500 455 | 881 19665536 456 | 883 19641584 457 | 885 19639904 458 | 887 19594384 459 | 889 19589788 460 | 891 19546840 461 | 893 19523372 462 | 895 19499240 463 | 897 19478636 464 | 899 19460488 465 | 901 19450208 466 | 903 19472140 467 | 903 19372908 468 | 905 19499768 469 | 907 19437596 470 | 909 19386096 471 | 911 19331276 472 | 913 19317224 473 | 915 19308140 474 | 917 19297820 475 | 919 19267976 476 | 921 19262924 477 | 923 19231212 478 | 925 19219096 479 | 927 19193792 480 | 929 19164268 481 | 931 19162892 482 | 933 19152988 483 | 935 19129940 484 | 937 19098480 485 | 939 19058000 486 | 941 19034652 487 | 943 19039856 488 | 945 18939664 489 | 947 18898472 490 | 949 18865632 491 | 951 18820276 492 | 953 18788388 493 | 955 18772628 494 | 957 18877852 495 | 959 18813440 496 | 961 18781404 497 | 963 18814044 498 | 965 18763428 499 | 967 18744756 500 | 969 18735240 501 | 971 18701220 502 | 973 18693060 503 | 975 18710592 504 | 977 18696996 505 | 979 18718308 506 | 981 18718368 507 | 983 18692592 508 | 985 18678680 509 | 987 18647636 510 | 989 18634988 511 | 991 18636032 512 | 993 18632872 513 | 993 18536576 514 | 995 18640484 515 | 997 18601296 516 | 999 18611360 517 | 1001 18593892 518 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/flip_set_maxenergy_dp_50.txt: -------------------------------------------------------------------------------- 1 | 4 1538369792 2 | 6 964185280 3 | 8 803203392 4 | 10 497280544 5 | 12 498505056 6 | 14 431755264 7 | 16 397431392 8 | 18 350390016 9 | 20 345871232 10 | 22 343299392 11 | 24 340811264 12 | 26 337603104 13 | 28 334654848 14 | 30 327551776 15 | 32 327078464 16 | 34 317438112 17 | 36 306058176 18 | 38 284582112 19 | 37 241129440 20 | 36 240786864 21 | 38 270934528 22 | 40 274136448 23 | 42 270025568 24 | 44 230293952 25 | 46 196304976 26 | 48 195568608 27 | 50 182146912 28 | 52 162885136 29 | 54 164313152 30 | 53 150782800 31 | 55 161426960 32 | 57 159919616 33 | 59 150966240 34 | 61 123778296 35 | 63 121949152 36 | 65 113187400 37 | 67 112585184 38 | 69 109018696 39 | 71 107983944 40 | 73 102912712 41 | 75 99742640 42 | 77 97462408 43 | 79 95790640 44 | 81 92959216 45 | 83 91302608 46 | 85 90772896 47 | 87 88057816 48 | 89 87860544 49 | 91 85820344 50 | 93 83359376 51 | 95 81453120 52 | 97 81612808 53 | 99 80335136 54 | 101 80711296 55 | 103 78608384 56 | 105 78211344 57 | 107 77319720 58 | 109 77439248 59 | 111 75776496 60 | 113 75624416 61 | 115 73051296 62 | 117 74665168 63 | 119 72319568 64 | 121 72246672 65 | 123 71479576 66 | 125 71280688 67 | 127 69711152 68 | 129 68069976 69 | 131 66890416 70 | 133 66461144 71 | 135 64726968 72 | 137 64883600 73 | 139 63605168 74 | 141 63583996 75 | 143 62521336 76 | 145 62891136 77 | 147 60929520 78 | 149 60714972 79 | 151 59271188 80 | 153 59132260 81 | 155 58069100 82 | 157 58117240 83 | 159 56255100 84 | 161 56342492 85 | 163 55365580 86 | 165 55886128 87 | 167 55079528 88 | 169 55652696 89 | 171 54805004 90 | 173 55172784 91 | 174 54409568 92 | 176 54755584 93 | 178 53458332 94 | 180 52862732 95 | 182 52196364 96 | 184 52588792 97 | 186 51692372 98 | 188 51592736 99 | 190 50928680 100 | 192 50796432 101 | 194 49825688 102 | 196 50182528 103 | 198 49241816 104 | 200 48985904 105 | 202 48588288 106 | 204 48472096 107 | 206 48068248 108 | 208 48031096 109 | 210 47786532 110 | 212 47709184 111 | 214 47229648 112 | 216 47240808 113 | 218 47077464 114 | 220 46887804 115 | 222 46792540 116 | 224 46552160 117 | 226 46836736 118 | 228 46569668 119 | 230 46330800 120 | 232 45810796 121 | 234 45604112 122 | 236 45439136 123 | 238 45107568 124 | 240 44938108 125 | 242 44620776 126 | 244 44409156 127 | 246 43958584 128 | 248 44144180 129 | 250 43209312 130 | 252 42863860 131 | 254 42714052 132 | 256 42618320 133 | 258 41902056 134 | 260 41677064 135 | 262 41564844 136 | 264 41274796 137 | 266 41110952 138 | 268 40544168 139 | 270 39944960 140 | 272 39858536 141 | 274 40099060 142 | 276 39774820 143 | 278 39681448 144 | 280 39521416 145 | 282 39364600 146 | 284 39238648 147 | 286 39083152 148 | 288 39160468 149 | 290 39045572 150 | 292 39995060 151 | 294 39280724 152 | 296 39049336 153 | 298 38894608 154 | 300 38881608 155 | 302 38767728 156 | 304 38696304 157 | 306 38566868 158 | 308 38256804 159 | 310 38046656 160 | 312 37886048 161 | 314 37656208 162 | 316 37491832 163 | 318 37842264 164 | 320 37331592 165 | 322 37248720 166 | 324 37095376 167 | 326 37053628 168 | 328 36962176 169 | 330 36814208 170 | 332 36821628 171 | 334 36509296 172 | 336 36289584 173 | 338 36266844 174 | 340 36095920 175 | 342 35977140 176 | 344 35895036 177 | 346 35706144 178 | 348 35632948 179 | 350 35429976 180 | 352 35279944 181 | 354 35172584 182 | 356 34975232 183 | 358 34938544 184 | 360 34888160 185 | 362 34730352 186 | 364 34645672 187 | 366 34595624 188 | 368 34510184 189 | 370 34436856 190 | 372 34245704 191 | 374 34070400 192 | 376 33784348 193 | 378 33542002 194 | 380 33373282 195 | 382 33277508 196 | 384 33123068 197 | 386 33043326 198 | 388 32907340 199 | 390 32860264 200 | 392 32751852 201 | 394 32625812 202 | 396 32532814 203 | 398 32334908 204 | 400 32411832 205 | 402 32345752 206 | 404 32212228 207 | 406 31851328 208 | 408 31796238 209 | 410 31733200 210 | 412 31678700 211 | 414 31897158 212 | 416 31732560 213 | 418 31552452 214 | 420 31480172 215 | 422 31380128 216 | 424 31407684 217 | 426 31378806 218 | 428 31292452 219 | 430 31164192 220 | 432 31113212 221 | 434 30978042 222 | 436 30910200 223 | 438 30849478 224 | 440 30805972 225 | 442 30750952 226 | 444 30681184 227 | 446 30598614 228 | 448 30557952 229 | 450 30476688 230 | 452 30443916 231 | 454 30438486 232 | 456 30430318 233 | 458 30377066 234 | 460 30327074 235 | 462 30278354 236 | 464 30302564 237 | 466 30249272 238 | 468 30209988 239 | 470 30178116 240 | 472 30128744 241 | 474 30060952 242 | 476 29936752 243 | 478 29931952 244 | 480 29884596 245 | 482 29836420 246 | 484 29701904 247 | 486 29631788 248 | 488 29568640 249 | 490 29562064 250 | 492 29551148 251 | 494 29387864 252 | 496 29327020 253 | 498 29248892 254 | 500 29200004 255 | 502 29309914 256 | 504 29181986 257 | 506 29110192 258 | 508 28945372 259 | 510 28871656 260 | 512 28672284 261 | 514 28540396 262 | 516 28484280 263 | 518 28363638 264 | 520 28276558 265 | 522 28118846 266 | 524 28061538 267 | 526 27949150 268 | 528 27893952 269 | 530 27758932 270 | 532 27696380 271 | 534 27609118 272 | 536 27624532 273 | 538 27569176 274 | 540 27524164 275 | 542 27437802 276 | 544 27358716 277 | 546 27507942 278 | 548 27273048 279 | 550 27214628 280 | 552 27139388 281 | 552 27041464 282 | 554 27256490 283 | 556 27115220 284 | 556 26932980 285 | 558 26828732 286 | 560 26790584 287 | 562 26751734 288 | 564 26782656 289 | 566 26769160 290 | 568 26662260 291 | 570 26789818 292 | 572 26643708 293 | 574 27477574 294 | 576 27396280 295 | 578 27313104 296 | 580 27167760 297 | 582 27064860 298 | 584 26999728 299 | 586 26921488 300 | 588 26823956 301 | 590 26762964 302 | 592 26735736 303 | 594 26590728 304 | 596 26529228 305 | 598 26508716 306 | 600 26452892 307 | 602 26380656 308 | 604 26333732 309 | 606 26348462 310 | 608 26210864 311 | 610 26105646 312 | 612 26099112 313 | 614 26060182 314 | 616 26027660 315 | 618 25842414 316 | 620 25816568 317 | 622 25695020 318 | 624 25646160 319 | 626 25586880 320 | 628 25543920 321 | 630 25480548 322 | 632 25382714 323 | 634 25321580 324 | 636 25321372 325 | 638 25266890 326 | 640 25278936 327 | 642 25141274 328 | 644 25093984 329 | 646 25063196 330 | 648 25004598 331 | 650 25010638 332 | 652 25154512 333 | 654 25145362 334 | 656 25102016 335 | 658 25029248 336 | 660 24858550 337 | 662 24837190 338 | 664 24787228 339 | 666 24785838 340 | 668 24713516 341 | 670 24617892 342 | 672 24643124 343 | 674 24497892 344 | 676 24848000 345 | 678 24477792 346 | 678 24336668 347 | 680 24360244 348 | 682 24340352 349 | 684 24341960 350 | 686 24336534 351 | 688 24268392 352 | 690 24274656 353 | 692 24236958 354 | 694 24248256 355 | 696 24205548 356 | 698 24226736 357 | 700 24126952 358 | 702 24101096 359 | 704 24038408 360 | 706 24036896 361 | 706 23927152 362 | 708 24004288 363 | 710 23914840 364 | 712 23976768 365 | 714 23937036 366 | 714 23815252 367 | 716 23902062 368 | 716 23760272 369 | 718 23839824 370 | 720 23847536 371 | 722 23674548 372 | 724 23682388 373 | 726 23676436 374 | 728 23655156 375 | 730 23578952 376 | 732 23546212 377 | 734 23505120 378 | 736 23583178 379 | 738 23562256 380 | 740 23516008 381 | 742 23524770 382 | 744 23503294 383 | 746 23482864 384 | 748 23449120 385 | 750 23433908 386 | 752 23425140 387 | 752 23318998 388 | 754 23452196 389 | 754 23329652 390 | 756 23309918 391 | 758 23261462 392 | 760 23216978 393 | 762 23179846 394 | 764 23166760 395 | 766 23083716 396 | 768 23021872 397 | 770 23020900 398 | 772 23003940 399 | 774 22971632 400 | 776 22910770 401 | 778 22944108 402 | 780 22899908 403 | 782 22828704 404 | 784 22813396 405 | 786 22697144 406 | 788 22592368 407 | 790 22563368 408 | 792 22545224 409 | 794 22522352 410 | 796 22472716 411 | 798 22454620 412 | 800 22396034 413 | 802 22366172 414 | 804 22353490 415 | 806 22291640 416 | 808 22297888 417 | 810 22296590 418 | 812 22274828 419 | 814 22265196 420 | 816 22247404 421 | 818 22209680 422 | 820 22176240 423 | 822 22108918 424 | 824 22085932 425 | 826 22104476 426 | 828 22094380 427 | 830 22030324 428 | 832 22034428 429 | 834 22007160 430 | 836 21950652 431 | 838 21893576 432 | 840 21902592 433 | 842 21814024 434 | 844 21778168 435 | 846 21788000 436 | 848 21734500 437 | 850 21755764 438 | 852 21652824 439 | 854 21725238 440 | 856 21653472 441 | 858 21697158 442 | 860 21644800 443 | 862 21696330 444 | 864 21638954 445 | 866 21692026 446 | 868 21611434 447 | 870 21631448 448 | 872 21478328 449 | 874 21502280 450 | 876 21444656 451 | 878 21478080 452 | 880 21328116 453 | 882 21360852 454 | 884 21300832 455 | 886 21328664 456 | 888 21249896 457 | 890 21269156 458 | 892 21198308 459 | 894 21228260 460 | 896 21162880 461 | 898 21212872 462 | 900 21140460 463 | 902 21194026 464 | 904 21116140 465 | 906 21185460 466 | 908 21089664 467 | 910 21115452 468 | 912 21049784 469 | 914 21044986 470 | 916 20993596 471 | 918 21004152 472 | 920 20907812 473 | 922 20942320 474 | 924 20892480 475 | 926 20932004 476 | 928 20856184 477 | 930 20863804 478 | 932 20715876 479 | 934 20734044 480 | 936 20664860 481 | 938 20700660 482 | 940 20638992 483 | 942 20652738 484 | 944 20512320 485 | 946 20554614 486 | 948 20469340 487 | 950 20553356 488 | 952 20434488 489 | 954 20502704 490 | 956 20397696 491 | 958 20471188 492 | 960 20385174 493 | 962 20429160 494 | 964 20296850 495 | 966 20357894 496 | 968 20220946 497 | 970 20247110 498 | 972 20165264 499 | 972 20128794 500 | 972 20176338 501 | 974 20208992 502 | 976 20116774 503 | 978 20138764 504 | 980 20021468 505 | 982 20034468 506 | 982 19927842 507 | 982 20001628 508 | 984 20004728 509 | 986 20036700 510 | 988 19951684 511 | 988 19893572 512 | 990 19943892 513 | 990 19840664 514 | 992 19882676 515 | 994 19887552 516 | 996 19818904 517 | 998 19845824 518 | 1000 19782038 519 | -------------------------------------------------------------------------------- /tests/opt_min_energy_edgeflip/strat/plot.gp: -------------------------------------------------------------------------------- 1 | # gnuplot.sh 2 | # gnupload load "plot.gp" 3 | 4 | 5 | unset logscale; set logscale y; set logscale y; 6 | plot "flip_delaunay.txt" using 1:2 title 'delaunay' with lines,\ 7 | "flip_max.txt" using 1:2 title 'max' with lines, \ 8 | "flip_set_maxangle.txt" using 1:2 title 'set angle' with lines, \ 9 | "flip_set_maxenergy.txt" using 1:2 title 'set energy' with lines, \ 10 | "flip_set_maxenergy_dp_2.txt" using 1:2 title 'set energy, decrease dp linear 2' with lines, \ 11 | "flip_set_maxenergy_dp_3.txt" using 1:2 title 'set energy, decrease dp linear 3' with lines, \ 12 | "flip_set_maxenergy_dp_10.txt" using 1:2 title 'set energy, decrease dp linear 10' with lines, \ 13 | "flip_set_maxenergy_dp_20.txt" using 1:2 title 'set energy, decrease dp linear 20' with lines, \ 14 | "flip_set_maxenergy_dp_50.txt" using 1:2 title 'set energy, decrease dp linear 50' with lines, \ 15 | "flip_delaunay_dp_2.txt" using 1:2 title 'delaunay, decrease dp linear 2' with lines 16 | -------------------------------------------------------------------------------- /tests/opt_no_geom_shader/fruit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/tests/opt_no_geom_shader/fruit.png -------------------------------------------------------------------------------- /tests/opt_no_geom_shader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | using namespace glm; 11 | 12 | int main( int argc, char* args[] ) { 13 | 14 | Tiny::view.pointSize = 2.0f; 15 | Tiny::view.vsync = false; 16 | Tiny::view.antialias = 0; 17 | 18 | Tiny::window("Energy Based Image Triangulation, Nicholas Mcdonald 2022", 900, 600); 19 | tpose::RATIO = 9.0/6.0; 20 | 21 | glDisable(GL_CULL_FACE); 22 | 23 | // Shaders and Buffers 24 | 25 | Texture tex(image::load("fruit.png")); //Load Texture with Image 26 | Square2D flat; //Create Primitive Model 27 | 28 | tpose::init(); 29 | 30 | Shader triangleshader({"shader/triangle.vs", "shader/triangle.fs"}, {"in_Position"}, {"points", "index", "colacc", "colnum", "tenergy", "penergy", "gradient", "nring"}); 31 | triangleshader.bind("points", tpose::pointbuf); 32 | triangleshader.bind("index", tpose::trianglebuf); 33 | triangleshader.bind("colacc", tpose::tcolaccbuf); 34 | triangleshader.bind("colnum", tpose::tcolnumbuf); 35 | triangleshader.bind("tenergy", tpose::tenergybuf); 36 | triangleshader.bind("penergy", tpose::penergybuf); 37 | triangleshader.bind("gradient", tpose::pgradbuf); 38 | triangleshader.bind("nring", tpose::tnringbuf); 39 | 40 | Shader linestrip({"shader/linestrip.vs", "shader/linestrip.fs"}, {"in_Position"}, {"points", "index"}); 41 | linestrip.bind("points", tpose::pointbuf); 42 | linestrip.bind("index", tpose::trianglebuf); 43 | 44 | // SSBO Manipulation Compute Shaders (Reset / Average) 45 | 46 | Compute gradient({"shader/gradient.cs"}, {"index", "energy", "gradient"}); 47 | gradient.bind("index", tpose::trianglebuf); 48 | gradient.bind("energy", tpose::tenergybuf); 49 | gradient.bind("gradient", tpose::pgradbuf); 50 | 51 | Compute shift({"shader/shift.cs"}, {"points", "gradient"}); 52 | shift.bind("points", tpose::pointbuf); 53 | shift.bind("gradient", tpose::pgradbuf); 54 | 55 | // Triangulation and Models 56 | 57 | tpose::triangulation tr; 58 | tpose::upload(&tr, false); 59 | 60 | cout<<"Number of Triangles: "<("in_Position", tpose::pointbuf); 70 | 71 | // Main Functions 72 | 73 | bool paused = true; 74 | bool showlines = false; 75 | 76 | Tiny::view.interface = [](){}; 77 | Tiny::event.handler = [&](){ 78 | 79 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_p) 80 | paused = !paused; 81 | 82 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_n) 83 | showlines = !showlines; 84 | 85 | }; 86 | 87 | Tiny::view.pipeline = [&](){ 88 | 89 | Tiny::view.target(color::black); //Target Main Screen 90 | 91 | // Compute Colors 92 | 93 | triangleshader.use(); 94 | triangleshader.texture("imageTexture", tex); //Load Texture 95 | triangleshader.uniform("mode", 0); 96 | triangleshader.uniform("KTriangles", tr.NT); 97 | triangleshader.uniform("RATIO", tpose::RATIO); 98 | triangleinstance.render(GL_TRIANGLE_STRIP, (13*tr.NT)); 99 | 100 | // Draw 101 | 102 | triangleshader.use(); 103 | triangleshader.texture("imageTexture", tex); //Load Texture 104 | triangleshader.uniform("mode", 2); 105 | triangleshader.uniform("K", tr.NT); 106 | triangleshader.uniform("RATIO", tpose::RATIO); 107 | triangleinstance.render(GL_TRIANGLE_STRIP, tr.NT); 108 | 109 | if(showlines){ 110 | 111 | linestrip.use(); 112 | linestrip.uniform("RATIO", tpose::RATIO); 113 | linestripinstance.render(GL_LINE_STRIP, tr.NT); 114 | 115 | } 116 | 117 | }; 118 | 119 | Tiny::loop([&](){ 120 | 121 | if(paused) return; 122 | 123 | // Compute Cost and Gradients, Shift Points 124 | 125 | triangleshader.use(); 126 | triangleshader.texture("imageTexture", tex); 127 | triangleshader.uniform("mode", 1); 128 | triangleshader.uniform("KTriangles", tr.NT); 129 | triangleshader.uniform("RATIO", tpose::RATIO); 130 | triangleinstance.render(GL_TRIANGLE_STRIP, (13*tr.NT)); 131 | 132 | gradient.use(); 133 | gradient.uniform("KTriangles", tr.NT); 134 | gradient.uniform("RATIO", tpose::RATIO); 135 | gradient.dispatch(1 + tr.NT/1024); 136 | 137 | shift.use(); 138 | shift.uniform("NPoints", tr.NP); 139 | shift.uniform("RATIO", tpose::RATIO); 140 | shift.dispatch(1 + tr.NP/1024); 141 | 142 | // Retrieve Data from Compute Shader 143 | 144 | tpose::tenergybuf->retrieve((13*tr.NT), tpose::terr); 145 | tpose::penergybuf->retrieve((13*tr.NT), tpose::perr); 146 | tpose::tcolnumbuf->retrieve((13*tr.NT), tpose::cn); 147 | tpose::pointbuf->retrieve(tr.points); 148 | 149 | // TOPOLOGICAL OPTIMIZATIONS 150 | 151 | bool updated = false; 152 | 153 | if( tpose::geterr(&tr) < 1E-3 ){ 154 | 155 | int tta = tpose::maxerrid(&tr); 156 | if(tta >= 0) 157 | if(tr.split(tta)) 158 | updated = true; 159 | 160 | } 161 | 162 | if(tr.optimize()) 163 | updated = true; 164 | 165 | if(updated) 166 | tpose::upload(&tr, false); 167 | 168 | }); 169 | 170 | tpose::quit(); 171 | Tiny::quit(); 172 | 173 | return 0; 174 | } 175 | -------------------------------------------------------------------------------- /tests/opt_no_geom_shader/makefile: -------------------------------------------------------------------------------- 1 | # TinyEngine Makefile 2 | # Compiler Configuration 3 | 4 | CC = g++ -std=c++17 5 | CF = -Wfatal-errors -O 6 | LF = -I/usr/local/include -L/usr/local/lib 7 | 8 | # General Linking 9 | 10 | TINYLINK = -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem 11 | 12 | # OS Specific Linking 13 | 14 | UNAME := $(shell uname) 15 | ifeq ($(UNAME), Linux) #Detect GNU/Linux 16 | TINYOS = -lX11 -lGL 17 | endif 18 | ifeq ($(UNAME), Darwin) #Detext MacOS 19 | TINYOS = -framework OpenGL 20 | endif 21 | 22 | all: main.cpp 23 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 24 | 25 | # Build Embedded Form 26 | 27 | DAT = shader #data directory to embed 28 | .PHONY: embedded 29 | embedded: CEF = $(shell c-embed $(DAT)) c-embed.o -include /usr/local/include/c-embed.h -DCEMBED_TRANSLATE 30 | embedded: 31 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 32 | rm c-embed.o 33 | -------------------------------------------------------------------------------- /tests/opt_no_geom_shader/shader/gradient.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 1) buffer index { 6 | ivec4 ind[]; 7 | }; 8 | 9 | layout (std430, binding = 4) buffer tenergy { 10 | int en[]; 11 | }; 12 | 13 | layout (std430, binding = 6) buffer gradient { 14 | ivec2 gr[]; 15 | }; 16 | 17 | uniform int KTriangles; 18 | 19 | void main(){ 20 | 21 | const uint index = gl_GlobalInvocationID.x; 22 | if(index >= KTriangles) 23 | return; 24 | 25 | // Add the Non-Normalized Gradient to the Per-Vertex Gradients 26 | 27 | atomicAdd(gr[ind[index].x].x, en[ 1*KTriangles + index] - en[ 2*KTriangles + index]); 28 | atomicAdd(gr[ind[index].x].y, en[ 3*KTriangles + index] - en[ 4*KTriangles + index]); 29 | 30 | atomicAdd(gr[ind[index].y].x, en[ 5*KTriangles + index] - en[ 6*KTriangles + index]); 31 | atomicAdd(gr[ind[index].y].y, en[ 7*KTriangles + index] - en[ 8*KTriangles + index]); 32 | 33 | atomicAdd(gr[ind[index].z].x, en[ 9*KTriangles + index] - en[10*KTriangles + index]); 34 | atomicAdd(gr[ind[index].z].y, en[11*KTriangles + index] - en[12*KTriangles + index]); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /tests/opt_no_geom_shader/shader/linestrip.fs: -------------------------------------------------------------------------------- 1 | #version 430 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,1,1, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /tests/opt_no_geom_shader/shader/linestrip.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | layout (std430, binding = 1) buffer index { 11 | ivec4 ind[]; 12 | }; 13 | 14 | uniform float RATIO; 15 | 16 | void main() { 17 | 18 | vec2 tpos = vec2(0); 19 | if (in_Position.x > 0) tpos = p[ind[gl_InstanceID].x]; 20 | if (in_Position.y > 0) tpos = p[ind[gl_InstanceID].y]; 21 | if (in_Position.z > 0) tpos = p[ind[gl_InstanceID].z]; 22 | tpos.x /= RATIO; 23 | gl_Position = vec4(tpos, -1, 1.0f); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tests/opt_no_geom_shader/shader/shift.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 0) buffer points { 6 | vec2 p[]; 7 | }; 8 | 9 | layout (std430, binding = 6) buffer gradient { 10 | ivec2 gr[]; 11 | }; 12 | 13 | uniform int NPoints; 14 | uniform float RATIO; 15 | 16 | void main(){ 17 | 18 | const uint index = gl_GlobalInvocationID.x; 19 | 20 | if(index < 4 || index >= NPoints) 21 | return; 22 | 23 | vec2 tgr = gr[index]; 24 | 25 | if(p[index].x <= -RATIO){ 26 | p[index].x = -RATIO; 27 | tgr.x = 0; 28 | } 29 | 30 | else if(p[index].x >= RATIO){ 31 | p[index].x = RATIO; 32 | tgr.x = 0; 33 | } 34 | 35 | if(p[index].y <= -1){ 36 | p[index].y = -1; 37 | tgr.y = 0; 38 | } 39 | 40 | else if(p[index].y >= 1){ 41 | p[index].y = 1; 42 | tgr.y = 0; 43 | } 44 | 45 | tgr = 0.00005 * vec2(tgr) / 256 / 256; 46 | // if(abs(tgr.x) < 1E-4) tgr.x = 0; 47 | // if(abs(tgr.y) < 1E-4) tgr.y = 0; 48 | p[index] -= tgr; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /tests/opt_no_geom_shader/shader/triangle.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (std430, binding = 2) buffer colacc { 4 | ivec4 ca[]; 5 | }; 6 | 7 | layout (std430, binding = 3) buffer colnum { 8 | int cn[]; 9 | }; 10 | 11 | layout (std430, binding = 4) buffer tenergy { 12 | int ten[]; 13 | }; 14 | 15 | uniform sampler2D imageTexture; 16 | uniform int mode; 17 | 18 | in VS_OUT { 19 | vec2 position; 20 | flat int index; 21 | } vs_out; 22 | 23 | out vec4 fragColor; 24 | 25 | void main(){ 26 | 27 | if( mode == 0 ){ // Accumulate Color, Triangle Pixel Count 28 | 29 | fragColor = texture(imageTexture, vs_out.position); 30 | atomicAdd(cn[vs_out.index], 1); 31 | atomicAdd(ca[vs_out.index].r, int(255*fragColor.r)); 32 | atomicAdd(ca[vs_out.index].g, int(255*fragColor.g)); 33 | atomicAdd(ca[vs_out.index].b, int(255*fragColor.b)); 34 | 35 | } 36 | 37 | if( mode == 1 ){ // Accumulate Cost-Per-Pixel 38 | 39 | vec3 d = 255*texture(imageTexture, vs_out.position).rgb - vec3(ca[vs_out.index].rgb/cn[vs_out.index]); 40 | atomicAdd(ten[vs_out.index], int(0.5*dot(d, d))); 41 | 42 | } 43 | 44 | if( mode == 2 ){ // Draw Triangles 45 | 46 | // fragColor = mix(vec4(0,0,1,1), vec4(1,0,0,1), sqrt(float(en[vs_out.index]/cn[vs_out.index]))/255.0f); 47 | fragColor = vec4(vec3(ca[vs_out.index].rgb)/cn[vs_out.index]/255, 1); 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /tests/opt_no_geom_shader/shader/triangle.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | 5 | layout (std430, binding = 0) buffer points { 6 | vec2 p[]; 7 | }; 8 | 9 | layout (std430, binding = 1) buffer index { 10 | ivec4 ind[]; 11 | }; 12 | 13 | layout (std430, binding = 2) buffer colacc { 14 | ivec4 ca[]; 15 | }; 16 | 17 | layout (std430, binding = 3) buffer colnum { 18 | int cn[]; 19 | }; 20 | 21 | layout (std430, binding = 4) buffer tenergy { 22 | int ten[]; 23 | }; 24 | 25 | layout (std430, binding = 5) buffer penergy { 26 | int pen[]; 27 | }; 28 | 29 | layout (std430, binding = 6) buffer gradient { 30 | ivec2 gr[]; 31 | }; 32 | 33 | layout (std430, binding = 7) buffer nring { 34 | int nr[]; 35 | }; 36 | 37 | out VS_OUT { 38 | 39 | vec2 position; 40 | flat int index; 41 | 42 | } vs_out; 43 | 44 | uniform float RATIO; 45 | uniform int KTriangles; 46 | uniform int mode; 47 | 48 | void main() { 49 | 50 | const int TDIV = gl_InstanceID/KTriangles; 51 | const int TMOD = gl_InstanceID%KTriangles; 52 | vs_out.index = gl_InstanceID; 53 | 54 | int pind; // Vertex Index 55 | if (in_Position.x > 0) 56 | pind = ind[TMOD].x; 57 | if (in_Position.y > 0) 58 | pind = ind[TMOD].y; 59 | if (in_Position.z > 0) 60 | pind = ind[TMOD].z; 61 | 62 | vec2 tpos = p[pind]; // Vertex Image-Space (-RATIO, RATIO) x, (-1, 1) y 63 | const float dp = 0.05f; // Image-Space Pixel Shift 64 | 65 | if(TDIV == 1 && in_Position.x > 0) tpos += vec2(dp, 0); 66 | else if(TDIV == 2 && in_Position.x > 0) tpos -= vec2(dp, 0); 67 | else if(TDIV == 3 && in_Position.x > 0) tpos += vec2( 0,dp); 68 | else if(TDIV == 4 && in_Position.x > 0) tpos -= vec2( 0,dp); 69 | else if(TDIV == 5 && in_Position.y > 0) tpos += vec2(dp, 0); 70 | else if(TDIV == 6 && in_Position.y > 0) tpos -= vec2(dp, 0); 71 | else if(TDIV == 7 && in_Position.y > 0) tpos += vec2( 0,dp); 72 | else if(TDIV == 8 && in_Position.y > 0) tpos -= vec2( 0,dp); 73 | else if(TDIV == 9 && in_Position.z > 0) tpos += vec2(dp, 0); 74 | else if(TDIV == 10 && in_Position.z > 0) tpos -= vec2(dp, 0); 75 | else if(TDIV == 11 && in_Position.z > 0) tpos += vec2( 0,dp); 76 | else if(TDIV == 12 && in_Position.z > 0) tpos -= vec2( 0,dp); 77 | 78 | tpos.x /= RATIO; // Position in Screen-Space (-1, 1) for x,y 79 | 80 | gl_Position = vec4(tpos, -1, 1.0f); 81 | vs_out.position = vec2(0.5*(1.0+tpos.x), 0.5*(1.0-tpos.y)); 82 | 83 | 84 | if(mode == 0){ 85 | cn[vs_out.index] = 0; 86 | ca[vs_out.index] = ivec4(0); 87 | } 88 | 89 | if(mode == 1){ 90 | ten[vs_out.index] = 0; 91 | gr[ind[TMOD].x] = ivec2(0); 92 | gr[ind[TMOD].y] = ivec2(0); 93 | gr[ind[TMOD].z] = ivec2(0); 94 | } 95 | 96 | //Add One-Ring Energy 97 | 98 | if( TDIV == 0 && mode == 0 ) 99 | atomicAdd(nr[pind], 1 ); //count the n-ring! (divided by 3) 100 | 101 | if( TDIV == 0 && mode == 1 ) { 102 | 103 | const float lambda = 0*256*256; 104 | 105 | if (in_Position.x > 0){ 106 | 107 | vec2 wva = p[pind] - p[ind[TMOD].y]; //Distance from this Vertex to Prev 108 | vec2 wvb = p[pind] - p[ind[TMOD].z]; //Distance from this Vertex to Next 109 | //Add Direct Energy Gradient 110 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[pind]); 111 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[pind]); 112 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[pind]); 113 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[pind]); 114 | 115 | } 116 | 117 | if (in_Position.y > 0){ 118 | 119 | vec2 wva = p[pind] - p[ind[TMOD].z]; //Distance from this Vertex to Prev 120 | vec2 wvb = p[pind] - p[ind[TMOD].x]; //Distance from this Vertex to Next 121 | //Add Direct Energy Gradient 122 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[pind]); 123 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[pind]); 124 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[pind]); 125 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[pind]); 126 | 127 | } 128 | 129 | if (in_Position.z > 0){ 130 | 131 | vec2 wva = p[pind] - p[ind[TMOD].x]; //Distance from this Vertex to Prev 132 | vec2 wvb = p[pind] - p[ind[TMOD].y]; //Distance from this Vertex to Next 133 | //Add Direct Energy Gradient 134 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wva+vec2(dp, 0), wva+vec2(dp, 0)) - dot(wva-vec2(dp, 0), wva-vec2(dp, 0))))/nr[pind]); 135 | atomicAdd(gr[pind].x, int(lambda*0.5/3.0*(dot(wvb+vec2(dp, 0), wvb+vec2(dp, 0)) - dot(wvb-vec2(dp, 0), wvb-vec2(dp, 0))))/nr[pind]); 136 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wva+vec2( 0,dp), wva+vec2( 0,dp)) - dot(wva-vec2( 0,dp), wva-vec2( 0,dp))))/nr[pind]); 137 | atomicAdd(gr[pind].y, int(lambda*0.5/3.0*(dot(wvb+vec2( 0,dp), wvb+vec2( 0,dp)) - dot(wvb-vec2( 0,dp), wvb-vec2( 0,dp))))/nr[pind]); 138 | 139 | } 140 | 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /tests/opt_topology/fruit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/tests/opt_topology/fruit.png -------------------------------------------------------------------------------- /tests/opt_topology/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | using namespace glm; 11 | 12 | int main( int argc, char* args[] ) { 13 | 14 | Tiny::view.pointSize = 2.0f; 15 | Tiny::view.vsync = false; 16 | Tiny::view.antialias = 0; 17 | 18 | Tiny::window("Energy Based Image Triangulation, Nicholas Mcdonald 2022", 900, 600); 19 | 20 | tpose::RATIO= 9.0/6.0; 21 | 22 | bool paused = true; 23 | 24 | Tiny::event.handler = [&](){ 25 | 26 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_p) 27 | paused = !paused; 28 | 29 | }; 30 | Tiny::view.interface = [](){}; 31 | 32 | Texture tex(image::load("fruit.png")); //Load Texture with Image 33 | Square2D flat; //Create Primitive Model 34 | 35 | Shader image({"shader/image.vs", "shader/image.fs"}, {"in_Quad", "in_Tex"}); 36 | Shader point({"shader/point.vs", "shader/point.fs"}, {"in_Position"}); 37 | 38 | glDisable(GL_CULL_FACE); 39 | glDisable(GL_DEPTH_TEST); 40 | 41 | tpose::init(); 42 | tpose::triangulation tr; 43 | cout<<"Number of Triangles: "<("in_Index", tpose::trianglebuf); 49 | 50 | TLineStrip tlinestrip; 51 | Instance linestripinstance(&tlinestrip); 52 | linestripinstance.bind("in_Index", tpose::trianglebuf); 53 | 54 | Shader triangleshader({"shader/triangle.vs", "shader/triangle.gs", "shader/triangle.fs"}, {"in_Position", "in_Index"}, {"points", "colacc", "colnum", "energy"}); 55 | triangleshader.bind("points", tpose::pointbuf); 56 | triangleshader.bind("colacc", tpose::tcolaccbuf); 57 | triangleshader.bind("colnum", tpose::tcolnumbuf); 58 | triangleshader.bind("energy", tpose::tenergybuf); 59 | 60 | Shader linestrip({"shader/linestrip.vs", "shader/linestrip.fs"}, {"in_Position", "in_Index"}, {"points"}); 61 | linestrip.bind("points", tpose::pointbuf); 62 | 63 | // SSBO Manipulation Compute Shaders (Reset / Average) 64 | 65 | Compute reset({"shader/reset.cs"}, {"colacc", "colnum", "energy", "gradient"}); 66 | reset.bind("colacc", tpose::tcolaccbuf); 67 | reset.bind("colnum", tpose::tcolnumbuf); 68 | reset.bind("energy", tpose::tenergybuf); 69 | reset.bind("gradient", tpose::pgradbuf); 70 | 71 | Compute average({"shader/average.cs"}, {"colacc", "colnum", "energy"}); 72 | average.bind("colacc", tpose::tcolaccbuf); 73 | average.bind("colnum", tpose::tcolnumbuf); 74 | average.bind("energy", tpose::tenergybuf); 75 | 76 | Compute gradient({"shader/gradient.cs"}, {"energy", "gradient", "indices"}); 77 | gradient.bind("energy", tpose::tenergybuf); 78 | gradient.bind("gradient", tpose::pgradbuf); 79 | gradient.bind("indices", tpose::trianglebuf); 80 | 81 | Compute shift({"shader/shift.cs"}, {"points", "gradient"}); 82 | shift.bind("points", tpose::pointbuf); 83 | shift.bind("gradient", tpose::pgradbuf); 84 | 85 | Model pointmesh({"in_Position"}); 86 | pointmesh.bind("in_Position", tpose::pointbuf); 87 | pointmesh.SIZE = tr.NP; 88 | 89 | // Convenience Lambdas 90 | 91 | auto computecolors = [&]( bool other = true ){ 92 | 93 | reset.use(); 94 | reset.uniform("NTriangles", (13*tr.NT)); 95 | reset.uniform("NPoints", tr.NP); 96 | 97 | if((13*tr.NT) > tr.NP) reset.dispatch(1 + (13*tr.NT)/1024); 98 | else reset.dispatch(1 + tr.NP/1024); 99 | 100 | glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 101 | 102 | triangleshader.use(); 103 | triangleshader.texture("imageTexture", tex); //Load Texture 104 | triangleshader.uniform("mode", 0); 105 | triangleshader.uniform("KTriangles", tr.NT); 106 | triangleshader.uniform("drawother", other); 107 | triangleshader.uniform("RATIO", tpose::RATIO); 108 | triangleinstance.render(GL_TRIANGLE_STRIP, (13*tr.NT)); 109 | 110 | average.use(); 111 | average.uniform("NTriangles", (13*tr.NT)); 112 | average.dispatch(1 + (13*tr.NT)/1024); 113 | glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 114 | 115 | }; 116 | 117 | auto doenergy = [&](){ 118 | 119 | triangleshader.use(); 120 | triangleshader.texture("imageTexture", tex); 121 | triangleshader.uniform("mode", 1); 122 | triangleshader.uniform("KTriangles", tr.NT); 123 | triangleshader.uniform("drawother", true); 124 | triangleshader.uniform("RATIO", tpose::RATIO); 125 | triangleinstance.render(GL_TRIANGLE_STRIP, (13*tr.NT)); 126 | 127 | }; 128 | 129 | auto doshift = [&](){ 130 | 131 | gradient.use(); 132 | gradient.uniform("K", tr.NT); 133 | gradient.uniform("RATIO", tpose::RATIO); 134 | gradient.dispatch(1 + tr.NT/1024); 135 | glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 136 | 137 | shift.use(); 138 | shift.uniform("NPoints", tr.NP); 139 | shift.uniform("RATIO", tpose::RATIO); 140 | shift.dispatch(1 + tr.NP/1024); 141 | glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 142 | 143 | }; 144 | 145 | auto draw = [&](){ 146 | 147 | triangleshader.use(); 148 | triangleshader.texture("imageTexture", tex); //Load Texture 149 | triangleshader.uniform("mode", 2); 150 | triangleshader.uniform("drawother", false); 151 | triangleshader.uniform("K", tr.NT); 152 | triangleshader.uniform("RATIO", tpose::RATIO); 153 | triangleinstance.render(GL_TRIANGLE_STRIP, tr.NT); 154 | 155 | // point.use(); 156 | // point.uniform("RATIO", RATIO); 157 | // pointmesh.render(GL_POINTS); 158 | 159 | linestrip.use(); 160 | linestrip.uniform("RATIO", tpose::RATIO); 161 | linestripinstance.render(GL_LINE_STRIP, tr.NT); 162 | 163 | }; 164 | 165 | computecolors(); 166 | 167 | // Main Functions 168 | 169 | Tiny::view.pipeline = [&](){ 170 | 171 | Tiny::view.target(color::black); //Target Main Screen 172 | 173 | computecolors(); 174 | draw(); 175 | 176 | }; 177 | 178 | Tiny::loop([&](){ 179 | 180 | if(paused) return; 181 | 182 | // Compute Cost and Gradients, Shift Points 183 | 184 | doenergy(); 185 | doshift(); 186 | 187 | // Retrieve Data from Compute Shader 188 | 189 | tpose::tenergybuf->retrieve((13*tr.NT), tpose::terr); 190 | tpose::penergybuf->retrieve((13*tr.NT), tpose::perr); 191 | tpose::tcolnumbuf->retrieve((13*tr.NT), tpose::cn); 192 | tpose::pointbuf->retrieve(tr.points); 193 | 194 | // TOPOLOGICAL OPTIMIZATIONS 195 | 196 | bool updated = false; 197 | 198 | if( tpose::geterr(&tr) < 1E-3 ){ 199 | 200 | int tta = tpose::maxerrid(&tr); 201 | if(tta >= 0) 202 | if(tr.split(tta)) 203 | updated = true; 204 | 205 | } 206 | 207 | if(tr.optimize()) 208 | updated = true; 209 | 210 | if(updated) 211 | tpose::upload(&tr, false); 212 | 213 | }); 214 | 215 | tpose::quit(); 216 | Tiny::quit(); 217 | 218 | return 0; 219 | } 220 | -------------------------------------------------------------------------------- /tests/opt_topology/makefile: -------------------------------------------------------------------------------- 1 | # TinyEngine Makefile 2 | # Compiler Configuration 3 | 4 | CC = g++ -std=c++17 5 | CF = -Wfatal-errors -O 6 | LF = -I/usr/local/include -L/usr/local/lib 7 | 8 | # General Linking 9 | 10 | TINYLINK = -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem 11 | 12 | # OS Specific Linking 13 | 14 | UNAME := $(shell uname) 15 | ifeq ($(UNAME), Linux) #Detect GNU/Linux 16 | TINYOS = -lX11 -lGL 17 | endif 18 | ifeq ($(UNAME), Darwin) #Detext MacOS 19 | TINYOS = -framework OpenGL 20 | endif 21 | 22 | all: main.cpp 23 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 24 | 25 | # Build Embedded Form 26 | 27 | DAT = shader #data directory to embed 28 | .PHONY: embedded 29 | embedded: CEF = $(shell c-embed $(DAT)) c-embed.o -include /usr/local/include/c-embed.h -DCEMBED_TRANSLATE 30 | embedded: 31 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 32 | rm c-embed.o 33 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/average.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 1) buffer colacc { 6 | ivec4 ca[]; 7 | }; 8 | 9 | layout (std430, binding = 2) buffer colnum { 10 | int cn[]; 11 | }; 12 | 13 | layout (std430, binding = 3) buffer energy { 14 | int en[]; 15 | }; 16 | 17 | uniform int NTriangles; 18 | 19 | void main(){ 20 | 21 | const uint index = gl_GlobalInvocationID.x; 22 | 23 | if(index >= NTriangles) 24 | return; 25 | 26 | if(cn[index] > 0) 27 | ca[index] = ca[index]/cn[index]; 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/gradient.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 3) buffer energy { 6 | int en[]; 7 | }; 8 | 9 | layout (std430, binding = 4) buffer gradient { 10 | ivec2 gr[]; 11 | }; 12 | 13 | layout (std430, binding = 5) buffer indices { 14 | ivec4 ind[]; 15 | }; 16 | 17 | uniform int K; 18 | 19 | void main(){ 20 | 21 | const uint index = gl_GlobalInvocationID.x; 22 | if(index >= K) 23 | return; 24 | 25 | // Add the Non-Normalized Gradient to the Per-Vertex Gradients 26 | 27 | atomicAdd(gr[ind[index].x].x, en[ 1*K + index] - en[ 2*K + index]); 28 | atomicAdd(gr[ind[index].x].y, en[ 3*K + index] - en[ 4*K + index]); 29 | 30 | atomicAdd(gr[ind[index].y].x, en[ 5*K + index] - en[ 6*K + index]); 31 | atomicAdd(gr[ind[index].y].y, en[ 7*K + index] - en[ 8*K + index]); 32 | 33 | atomicAdd(gr[ind[index].z].x, en[ 9*K + index] - en[10*K + index]); 34 | atomicAdd(gr[ind[index].z].y, en[11*K + index] - en[12*K + index]); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/image.fs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 ex_Tex; 3 | out vec4 fragColor; 4 | 5 | uniform sampler2D imageTexture; 6 | uniform sampler2D blurTexture; 7 | 8 | //Effect Parameters 9 | uniform int index; 10 | uniform int res; 11 | uniform int bits; 12 | 13 | vec4 none(){ 14 | return texture(imageTexture, ex_Tex); 15 | } 16 | 17 | vec4 pixelate(){ 18 | return texture(imageTexture, floor(ex_Tex*vec2(res))/vec2(res)); 19 | } 20 | 21 | vec4 bitreduce(){ 22 | vec4 color = texture(imageTexture, ex_Tex); 23 | return vec4(round(color.xyz*vec3(bits))/vec3(bits), 1.0); 24 | } 25 | 26 | void main(){ 27 | //Get the fragment color from the effect choice 28 | if(index == 1) fragColor = pixelate(); 29 | else if(index == 2) fragColor = bitreduce(); 30 | else fragColor = none(); 31 | } 32 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/image.vs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 in_Quad; 3 | in vec2 in_Tex; 4 | out vec2 ex_Tex; 5 | 6 | //Position the Billboard in space! 7 | uniform mat4 model; 8 | 9 | void main(){ 10 | ex_Tex = in_Tex; 11 | gl_Position = model*vec4(in_Quad, -1.0, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/linestrip.fs: -------------------------------------------------------------------------------- 1 | #version 430 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,1,1, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/linestrip.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | uniform float RATIO; 11 | 12 | void main() { 13 | 14 | vec2 tpos = vec2(0); 15 | if (in_Position.x > 0) tpos = p[in_Index.x]; 16 | if (in_Position.y > 0) tpos = p[in_Index.y]; 17 | if (in_Position.z > 0) tpos = p[in_Index.z]; 18 | tpos.x /= RATIO; 19 | gl_Position = vec4(tpos, -1, 1.0f); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/point.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,1,1,1); 7 | } 8 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/point.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec2 in_Position; 4 | uniform float RATIO; 5 | 6 | void main(){ 7 | gl_Position = vec4(in_Position/vec2(RATIO, 1), -1.0f, 1.0f); 8 | } 9 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/reset.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 1) buffer colacc { 6 | ivec4 ca[]; 7 | }; 8 | 9 | layout (std430, binding = 2) buffer colnum { 10 | int cn[]; 11 | }; 12 | 13 | layout (std430, binding = 3) buffer energy { 14 | int en[]; 15 | }; 16 | 17 | layout (std430, binding = 4) buffer gradient { 18 | ivec2 gr[]; 19 | }; 20 | 21 | 22 | uniform int NTriangles; 23 | uniform int NPoints; 24 | 25 | void main(){ 26 | 27 | const uint index = gl_GlobalInvocationID.x; 28 | 29 | if(index < NTriangles){ 30 | 31 | ca[index] = ivec4(0); 32 | cn[index] = 0; 33 | en[index] = 0; 34 | 35 | } 36 | 37 | if(index < NPoints){ 38 | 39 | gr[index] = ivec2(0); 40 | 41 | } 42 | 43 | }; 44 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/shift.cs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout(local_size_x = 1024) in; 4 | 5 | layout (std430, binding = 0) buffer points { 6 | vec2 p[]; 7 | }; 8 | 9 | layout (std430, binding = 4) buffer gradient { 10 | ivec2 gr[]; 11 | }; 12 | 13 | uniform int NPoints; 14 | uniform float RATIO; 15 | 16 | void main(){ 17 | 18 | const uint index = gl_GlobalInvocationID.x; 19 | 20 | if(index < 4) 21 | return; 22 | 23 | if(index >= NPoints) 24 | return; 25 | 26 | vec2 tgr = gr[index]; 27 | 28 | if(p[index].x <= -RATIO){ 29 | p[index].x = -RATIO; 30 | tgr.x = 0; 31 | } 32 | 33 | if(p[index].x >= RATIO){ 34 | p[index].x = RATIO; 35 | tgr.x = 0; 36 | } 37 | 38 | if(p[index].y <= -1){ 39 | p[index].y = -1; 40 | tgr.y = 0; 41 | } 42 | 43 | if(p[index].y >= 1){ 44 | p[index].y = 1; 45 | tgr.y = 0; 46 | } 47 | 48 | tgr = 0.00005 * vec2(tgr) / 256 / 256; 49 | if(abs(tgr.x) < 1E-4) tgr.x = 0; 50 | if(abs(tgr.y) < 1E-4) tgr.y = 0; 51 | 52 | p[index] -= tgr; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/triangle.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (std430, binding = 1) buffer colacc { 4 | ivec4 ca[]; 5 | }; 6 | 7 | layout (std430, binding = 2) buffer colnum { 8 | int cn[]; 9 | }; 10 | 11 | layout (std430, binding = 3) buffer energy { 12 | int en[]; 13 | }; 14 | 15 | uniform sampler2D imageTexture; 16 | uniform int mode; 17 | 18 | in GS_OUT { 19 | vec2 position; 20 | flat int index; 21 | } gs_out; 22 | 23 | out vec4 fragColor; 24 | 25 | void main(){ 26 | 27 | // Accumulate Color 28 | 29 | if( mode == 0 ){ 30 | 31 | fragColor = texture(imageTexture, gs_out.position); 32 | atomicAdd(cn[gs_out.index], 1); 33 | atomicAdd(ca[gs_out.index].r, int(255*fragColor.r)); 34 | atomicAdd(ca[gs_out.index].g, int(255*fragColor.g)); 35 | atomicAdd(ca[gs_out.index].b, int(255*fragColor.b)); 36 | 37 | } 38 | 39 | // Accumulate Cost Function 40 | 41 | if( mode == 1 ){ 42 | 43 | vec3 d = 255*texture(imageTexture, gs_out.position).rgb - vec3(ca[gs_out.index].rgb); 44 | atomicAdd(en[gs_out.index], int(0.5*dot(d, d))); 45 | 46 | } 47 | 48 | // Display 49 | 50 | if( mode == 2 ){ 51 | 52 | // fragColor = mix(vec4(0,0,1,1), vec4(1,0,0,1), sqrt(float(en[gs_out.index]/cn[gs_out.index]))/255.0f); 53 | fragColor = vec4(vec3(ca[gs_out.index].rgb)/255, 1); 54 | // fragColor = vec4(0,0,0,1); 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/triangle.gs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (triangles) in; 4 | layout (triangle_strip, max_vertices = 128) out; 5 | 6 | uniform int KTriangles; 7 | const float dp = 0.05; 8 | 9 | in VS_OUT { 10 | vec2 position; 11 | flat int index; 12 | } gs_in []; 13 | 14 | out GS_OUT { 15 | vec2 position; 16 | flat int index; 17 | } gs_out; 18 | 19 | uniform bool drawother; 20 | 21 | void main() { 22 | 23 | vec2 tpos[3]; 24 | int index; 25 | 26 | // Original Triangle 27 | 28 | tpos[0] = gs_in[0].position; 29 | tpos[1] = gs_in[1].position; 30 | tpos[2] = gs_in[2].position; 31 | index = gs_in[0].index; 32 | 33 | gl_Position = vec4(tpos[0], -1, 1.0f); 34 | gs_out.position = vec2(0.5*(1.0+tpos[0].x), 0.5*(1.0-tpos[0].y)); 35 | gs_out.index = index; 36 | EmitVertex(); 37 | 38 | gl_Position = vec4(tpos[1], -1, 1.0f); 39 | gs_out.position = vec2(0.5*(1.0+tpos[1].x), 0.5*(1.0-tpos[1].y)); 40 | gs_out.index = index; 41 | EmitVertex(); 42 | 43 | gl_Position = vec4(tpos[2], -1, 1.0f); 44 | gs_out.position = vec2(0.5*(1.0+tpos[2].x), 0.5*(1.0-tpos[2].y)); 45 | gs_out.index = index; 46 | EmitVertex(); 47 | 48 | // Shifted Triangles 49 | 50 | if(drawother) 51 | for(int i = 0; i < 12; i++){ 52 | 53 | // Shift Triangle Vertices 54 | 55 | tpos[0] = gs_in[0].position; 56 | tpos[1] = gs_in[1].position; 57 | tpos[2] = gs_in[2].position; 58 | 59 | if(i == 0) tpos[0] += vec2(dp, 0); 60 | if(i == 1) tpos[0] -= vec2(dp, 0); 61 | if(i == 2) tpos[0] += vec2(0, dp); 62 | if(i == 3) tpos[0] -= vec2(0, dp); 63 | if(i == 4) tpos[1] += vec2(dp, 0); 64 | if(i == 5) tpos[1] -= vec2(dp, 0); 65 | if(i == 6) tpos[1] += vec2(0, dp); 66 | if(i == 7) tpos[1] -= vec2(0, dp); 67 | if(i == 8) tpos[2] += vec2(dp, 0); 68 | if(i == 9) tpos[2] -= vec2(dp, 0); 69 | if(i == 10) tpos[2] += vec2(0, dp); 70 | if(i == 11) tpos[2] -= vec2(0, dp); 71 | 72 | index = (1+i)*KTriangles + gs_in[0].index; 73 | 74 | // Degenerate Vertex 75 | 76 | EmitVertex(); 77 | 78 | gl_Position = vec4(tpos[0], -1, 1.0f); 79 | gs_out.position = vec2(0.5*(1.0+tpos[0].x), 0.5*(1.0-tpos[0].y)); 80 | gs_out.index = index; 81 | EmitVertex(); 82 | EmitVertex(); 83 | 84 | gl_Position = vec4(tpos[1], -1, 1.0f); 85 | gs_out.position = vec2(0.5*(1.0+tpos[1].x), 0.5*(1.0-tpos[1].y)); 86 | gs_out.index = index; 87 | EmitVertex(); 88 | 89 | gl_Position = vec4(tpos[2], -1, 1.0f); 90 | gs_out.position = vec2(0.5*(1.0+tpos[2].x), 0.5*(1.0-tpos[2].y)); 91 | gs_out.index = index; 92 | EmitVertex(); 93 | 94 | } 95 | 96 | EndPrimitive(); 97 | 98 | } 99 | -------------------------------------------------------------------------------- /tests/opt_topology/shader/triangle.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec4 in_Index; 5 | 6 | layout (std430, binding = 0) buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | out VS_OUT { 11 | 12 | vec2 position; 13 | flat int index; 14 | 15 | } vs_out; 16 | 17 | uniform float RATIO; 18 | 19 | void main() { 20 | 21 | vec2 tpos = vec2(0); 22 | if (in_Position.x > 0) tpos = p[in_Index.x]; 23 | if (in_Position.y > 0) tpos = p[in_Index.y]; 24 | if (in_Position.z > 0) tpos = p[in_Index.z]; 25 | tpos.x /= RATIO; 26 | 27 | vs_out.position = tpos; 28 | vs_out.index = gl_InstanceID; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /tests/sfm_match_test/README.md: -------------------------------------------------------------------------------- 1 | # reconstruct 2 | 3 | reconstruct 2D point matches to 3D points. 4 | 5 | Based off of the book by hartley and zisserman. 6 | 7 | ## usage 8 | 9 | space - toggle image 10 | m - toggle 3d view 11 | wasd / arrow keys: move and camera 12 | scroll to zoom (in 3D view) 13 | -------------------------------------------------------------------------------- /tests/sfm_match_test/data.txt: -------------------------------------------------------------------------------- 1 | 677 386 718 362 2 | 669 397 708 375 3 | 704 426 743 407 4 | 654 406 693 384 5 | 677 406 716 386 6 | 693 424 731 405 7 | 709 422 746 404 8 | 672 400 712 379 9 | 685 386 726 362 10 | 693 382 734 356 11 | 716 385 757 359 12 | 692 392 732 369 13 | 710 390 752 366 14 | 704 382 747 356 15 | 724 381 762 362 16 | 647 401 686 381 17 | 651 386 690 365 18 | 679 369 719 346 19 | 731 373 769 356 20 | 723 370 762 351 21 | 721 389 759 371 22 | 718 394 756 376 23 | 688 399 727 379 24 | 679 445 719 424 25 | 681 439 720 418 26 | 688 429 727 409 27 | 694 440 734 419 28 | 705 429 744 409 29 | 718 431 756 412 30 | 673 450 711 430 31 | 669 444 708 425 32 | 686 426 725 406 33 | 705 452 744 432 34 | 685 454 724 435 35 | 692 449 732 429 36 | 671 439 710 419 37 | 696 418 734 400 38 | 718 417 755 401 39 | 681 456 719 439 40 | 710 449 749 429 41 | 724 432 762 413 42 | 712 376 754 349 43 | 685 472 724 453 44 | 653 437 692 418 45 | 662 463 700 445 46 | 646 468 683 453 47 | 678 481 716 463 48 | 691 475 730 457 49 | 683 487 722 469 50 | 688 468 727 450 51 | 711 473 749 456 52 | 699 483 738 465 53 | 718 474 756 458 54 | 749 443 771 463 55 | 738 458 759 480 56 | 635 519 659 535 57 | 664 501 690 517 58 | 619 530 637 553 59 | 571 519 589 541 60 | 583 506 607 517 61 | 609 511 633 523 62 | 752 371 774 388 63 | 683 380 724 356 64 | 695 373 737 347 65 | 726 349 759 338 66 | 687 412 725 393 67 | 676 413 714 394 68 | 649 410 687 390 69 | 638 387 677 366 70 | 707 323 741 313 71 | 728 325 760 319 72 | 723 322 756 314 73 | 721 319 754 311 74 | 715 327 749 318 75 | 699 322 734 312 76 | 700 312 734 303 77 | 702 328 736 318 78 | 713 306 745 300 79 | 714 297 746 293 80 | 720 301 751 298 81 | 688 303 722 293 82 | 688 296 722 285 83 | 712 330 746 320 84 | 710 290 742 285 85 | 682 286 718 273 86 | 700 283 733 276 87 | 724 337 757 328 88 | 651 298 689 281 89 | 636 287 673 272 90 | 619 311 656 295 91 | 675 384 715 360 92 | 623 356 661 337 93 | 586 355 623 337 94 | 646 346 684 329 95 | 622 344 660 326 96 | 609 349 647 330 97 | 594 347 631 329 98 | 634 359 672 340 99 | 595 338 632 320 100 | 598 341 636 323 101 | 638 354 676 336 102 | 595 320 632 303 103 | 651 328 688 313 104 | 563 356 597 343 105 | 551 361 584 352 106 | 564 279 598 270 107 | 541 321 571 319 108 | 620 297 657 280 109 | 598 297 635 281 110 | 503 471 525 479 111 | 497 471 519 480 112 | 496 468 518 477 113 | 492 471 514 479 114 | 497 477 519 485 115 | 546 468 569 478 116 | 531 467 554 477 117 | 599 403 637 382 118 | 554 390 585 382 119 | 543 372 573 367 120 | 527 348 556 345 121 | 542 369 572 365 122 | 522 341 552 338 123 | 572 318 609 302 124 | 628 349 665 331 125 | 640 321 677 305 126 | 608 315 645 299 127 | 664 284 700 271 128 | 657 292 694 276 129 | 679 320 717 301 130 | 613 453 647 441 131 | 629 445 665 429 132 | 551 478 575 489 133 | 513 369 540 369 134 | 544 341 575 336 135 | 489 347 518 346 136 | 505 344 534 342 137 | 499 333 528 333 138 | 534 400 561 401 139 | 546 408 573 409 140 | 527 390 554 391 141 | 500 349 528 348 142 | 499 359 527 358 143 | 505 351 534 350 144 | 515 363 543 363 145 | 590 407 627 387 146 | 606 391 645 369 147 | 619 385 658 364 148 | 616 406 654 385 149 | 616 398 654 377 150 | 633 399 671 378 151 | 667 327 705 308 152 | 735 348 769 339 153 | 620 477 648 479 154 | 602 483 629 489 155 | 566 469 590 478 156 | 570 494 593 504 157 | 562 481 585 491 158 | 554 487 577 496 159 | 619 262 654 254 160 | 724 344 758 334 161 | 272 344 282 369 162 | 889 619 919 642 163 | 976 607 1007 629 164 | 1030 368 1043 398 165 | 16 420 7 441 166 | 33 419 24 441 167 | 354 318 367 345 168 | 74 119 113 110 169 | 98 131 135 125 170 | 779 132 787 182 171 | 709 295 741 290 172 | 711 313 744 305 173 | 722 326 755 318 174 | 705 315 738 306 175 | -------------------------------------------------------------------------------- /tests/sfm_match_test/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | using namespace glm; 12 | using namespace Eigen; 13 | 14 | int main( int argc, char* args[] ) { 15 | 16 | // Load Raw Pointmatches 17 | 18 | vector A, B; 19 | if(!tpose::io::readmatches("data.txt", A, B)) 20 | exit(0); 21 | 22 | cout << "Loaded " << A.size() << " point matches" << endl; 23 | 24 | // Normalize points to Image Width 25 | 26 | for(auto& a: A) 27 | a /= vec2(1200); 28 | 29 | for(auto& b: B) 30 | b /= vec2(1200); 31 | 32 | // Unproject the 2D Matches to 3D Points 33 | 34 | // Fundamental Matrix 35 | 36 | Matrix3f F = tpose::mview::F_LMEDS(A, B); 37 | cout<<"FUNDAMENTAL MATRIX: "< points3d = tpose::mview::triangulate(F, K, A, B); 44 | 45 | vector lA, lB; //Epipolar Lines 46 | 47 | for(size_t i = 0; i < A.size(); i++) 48 | lA.push_back(tpose::mview::eline(B[i], F)); 49 | 50 | for(size_t i = 0; i < B.size(); i++) 51 | lB.push_back(tpose::mview::eline(F, A[i])); 52 | 53 | Tiny::view.pointSize = 5.0f; 54 | Tiny::window("Point-Match Reconstruction, Nicholas Mcdonald 2022", 1200, 675); 55 | Tiny::view.interface = [&](){}; 56 | 57 | // Image Rendering 58 | 59 | Shader image({"shader/image.vs", "shader/image.fs"}, {"in_Quad", "in_Tex"}); 60 | 61 | Texture texA(image::load("../../resource/imageA.png")); //Load Texture with Image 62 | Texture texB(image::load("../../resource/imageB.png")); //Load Texture with Image 63 | Square2D flat; //Create Primitive Model 64 | 65 | // Feature Point / Line Rendering 66 | 67 | Shader point({"shader/point.vs", "shader/point.fs"}, {"in_Position"}); 68 | Shader point3d({"shader/point3d.vs", "shader/point3d.fs"}, {"in_Position"}); 69 | 70 | cam::far = 100.0f; //Projection Matrix Far-Clip 71 | cam::near = 0.001f; 72 | cam::moverate = 0.05f; 73 | cam::FOV = 0.5; 74 | cam::init(); 75 | cam::look = vec3(0,0,7); 76 | cam::update(); 77 | 78 | Buffer pbufA(A); 79 | Buffer pbufB(B); 80 | 81 | Model pmeshA({"in_Position"}); 82 | pmeshA.bind("in_Position", &pbufA); 83 | pmeshA.SIZE = A.size(); 84 | 85 | Model pmeshB({"in_Position"}); 86 | pmeshB.bind("in_Position", &pbufB); 87 | pmeshB.SIZE = B.size(); 88 | 89 | Buffer pbuf3D(points3d); 90 | Model pmesh3D({"in_Position"}); 91 | pmesh3D.bind("in_Position", &pbuf3D); 92 | pmesh3D.SIZE = points3d.size(); 93 | 94 | vector linevec; 95 | for(size_t n = 0; n < A.size(); n++){ 96 | linevec.push_back(A[n]); 97 | linevec.push_back(B[n]); 98 | } 99 | Buffer linebuf(linevec); 100 | 101 | Model linemesh({"in_Position"}); 102 | linemesh.bind("in_Position", &linebuf); 103 | linemesh.SIZE = linevec.size(); 104 | 105 | // Epipolar Line Rendering 106 | 107 | Shader epipolarline({"shader/epipolarline.vs", "shader/epipolarline.gs", "shader/epipolarline.fs"}, {"in_Position"}); 108 | 109 | Buffer lbufA(lA); 110 | Buffer lbufB(lB); 111 | 112 | Model lmeshA({"in_Position"}); 113 | lmeshA.bind("in_Position", &lbufA); 114 | lmeshA.SIZE = lA.size(); 115 | 116 | Model lmeshB({"in_Position"}); 117 | lmeshB.bind("in_Position", &lbufB); 118 | lmeshB.SIZE = lB.size(); 119 | 120 | // The triangulation needs to be 121 | 122 | bool flip = true; 123 | bool view3d = false; 124 | Tiny::event.handler = [&](){ 125 | 126 | cam::handler(); 127 | 128 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_SPACE) 129 | flip = !flip; 130 | if(!Tiny::event.press.empty() && Tiny::event.press.back() == SDLK_m) 131 | view3d = !view3d; 132 | 133 | }; 134 | 135 | Tiny::view.pipeline = [&](){ 136 | 137 | Tiny::view.target(color::black); //Target Main Screen 138 | 139 | if(!view3d){ 140 | 141 | image.use(); //Use Effect Shader 142 | image.texture("imageTextureA", texA); //Load Texture 143 | image.texture("imageTextureB", texB); //Load Texture 144 | image.uniform("flip", flip); 145 | image.uniform("model", flat.model); //Add Model Matrix 146 | flat.render(); 147 | 148 | 149 | if(flip) { 150 | 151 | point.use(); 152 | point.uniform("color", vec3(1,0,0)); 153 | pmeshA.render(GL_POINTS); 154 | 155 | epipolarline.use(); 156 | epipolarline.uniform("color", vec3(1,0,0)); 157 | lmeshA.render(GL_POINTS); 158 | 159 | } 160 | 161 | else { 162 | 163 | point.use(); 164 | point.uniform("color", vec3(1,0,1)); 165 | pmeshB.render(GL_POINTS); 166 | 167 | epipolarline.use(); 168 | epipolarline.uniform("color", vec3(1,0,1)); 169 | lmeshB.render(GL_POINTS); 170 | 171 | } 172 | 173 | point.use(); 174 | point.uniform("color", vec3(1,1,1)); 175 | linemesh.render(GL_LINES); 176 | 177 | } 178 | 179 | else{ 180 | 181 | point3d.use(); 182 | point3d.uniform("model", rotate(mat4(1.0f), 3.14159265f, vec3(0,0,1))); 183 | point3d.uniform("vp", cam::vp); 184 | pmesh3D.render(GL_POINTS); 185 | 186 | } 187 | 188 | }; 189 | 190 | Tiny::loop([&](){}); 191 | Tiny::quit(); 192 | 193 | return 0; 194 | } 195 | -------------------------------------------------------------------------------- /tests/sfm_match_test/makefile: -------------------------------------------------------------------------------- 1 | # TinyEngine Makefile 2 | # Compiler Configuration 3 | 4 | CC = g++ -std=c++17 5 | CF = -Wfatal-errors -O3 6 | LF = -I/usr/local/include -L/usr/local/lib -I/usr/include/opencv4 7 | 8 | # General Linking 9 | 10 | TINYLINK = -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem 11 | OPENCVLINK = -lopencv_core -lopencv_calib3d 12 | 13 | # OS Specific Linking 14 | 15 | UNAME := $(shell uname) 16 | ifeq ($(UNAME), Linux) #Detect GNU/Linux 17 | TINYOS = -lX11 -lGL 18 | endif 19 | ifeq ($(UNAME), Darwin) #Detext MacOS 20 | TINYOS = -framework OpenGL 21 | endif 22 | 23 | all: main.cpp 24 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(OPENCVLINK) $(TINYOS) $(TINYLINK) -o main 25 | 26 | # Build Embedded Form 27 | 28 | DAT = shader #data directory to embed 29 | .PHONY: embedded 30 | embedded: CEF = $(shell c-embed $(DAT)) c-embed.o -include /usr/local/include/c-embed.h -DCEMBED_TRANSLATE 31 | embedded: 32 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 33 | rm c-embed.o 34 | -------------------------------------------------------------------------------- /tests/sfm_match_test/shader/epipolarline.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | out vec4 fragColor; 4 | uniform vec3 color; 5 | 6 | void main(){ 7 | fragColor = vec4(color, 0.5); 8 | } 9 | -------------------------------------------------------------------------------- /tests/sfm_match_test/shader/epipolarline.gs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | layout (points) in; 4 | layout (line_strip, max_vertices = 2) out; 5 | 6 | in VS_OUT { 7 | vec3 P; 8 | } gs_in []; 9 | 10 | uniform int mode; 11 | 12 | void main() { 13 | 14 | vec3 P = gs_in[0].P; 15 | P.y *= (675.0/1200.0); 16 | float x = 0; 17 | vec2 p = vec2(x, P.z/P.y + x*P.x/P.y); 18 | 19 | 20 | p = 2*(vec2(p.x,1+p.y)-0.5); 21 | 22 | 23 | gl_Position = vec4(p.x, p.y, -1, 1.0f); 24 | EmitVertex(); 25 | 26 | P = gs_in[0].P; 27 | P.y *= (675.0/1200.0); 28 | 29 | x = 1; 30 | p = vec2(x, P.z/P.y + x*P.x/P.y); 31 | p = 2*vec2(p.x,1+p.y)-1; 32 | 33 | 34 | gl_Position = vec4(p.x, p.y, -1, 1.0f); 35 | EmitVertex(); 36 | 37 | EndPrimitive(); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /tests/sfm_match_test/shader/epipolarline.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | 5 | out VS_OUT { 6 | vec3 P; 7 | } vs_out; 8 | 9 | void main() { 10 | vs_out.P = in_Position; 11 | } 12 | -------------------------------------------------------------------------------- /tests/sfm_match_test/shader/image.fs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 ex_Tex; 3 | out vec4 fragColor; 4 | 5 | uniform sampler2D imageTextureA; 6 | uniform sampler2D imageTextureB; 7 | 8 | uniform bool flip; 9 | 10 | void main(){ 11 | if(flip) fragColor = texture(imageTextureA, ex_Tex); 12 | else fragColor = texture(imageTextureB, ex_Tex); 13 | } 14 | -------------------------------------------------------------------------------- /tests/sfm_match_test/shader/image.vs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 in_Quad; 3 | in vec2 in_Tex; 4 | out vec2 ex_Tex; 5 | 6 | //Position the Billboard in space! 7 | uniform mat4 model; 8 | 9 | void main(){ 10 | ex_Tex = in_Tex; 11 | gl_Position = model*vec4(in_Quad, -1.0, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/sfm_match_test/shader/point.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | out vec4 fragColor; 4 | uniform vec3 color; 5 | 6 | void main(){ 7 | fragColor = vec4(color,0.6); 8 | } 9 | -------------------------------------------------------------------------------- /tests/sfm_match_test/shader/point.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec2 in_Position; 4 | 5 | void main(){ 6 | vec2 p = in_Position; 7 | p = 2*(vec2(in_Position.x, 1.0f-in_Position.y/(675.0/1200.0))-0.5); 8 | gl_Position = vec4(p, -1.0f, 1.0f); 9 | } 10 | -------------------------------------------------------------------------------- /tests/sfm_match_test/shader/point3d.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,1,1,1); 7 | } 8 | -------------------------------------------------------------------------------- /tests/sfm_match_test/shader/point3d.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec4 in_Position; 4 | uniform mat4 vp; 5 | uniform mat4 model; 6 | 7 | void main(){ 8 | 9 | vec4 p = in_Position; 10 | p.xyz /= p.w; 11 | //p.y = -p.y; 12 | // p.x = -p.x; 13 | //p.y = -p.y; 14 | //p.x = -p.x; 15 | //gl_Position = vec4(p, -1.0f, 1.0f); 16 | 17 | //p = 2*(vec2(in_Position.x, 1.0f-in_Position.y/(675.0/1200.0))-0.5); 18 | 19 | 20 | gl_Position = vp*model*p; 21 | } 22 | -------------------------------------------------------------------------------- /tests/tri_render_direct/canyon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/tests/tri_render_direct/canyon.png -------------------------------------------------------------------------------- /tests/tri_render_direct/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../../source/include/delaunator-cpp/delaunator-header-only.hpp" 6 | #include "../../source/include/poisson.hpp" 7 | #include "triangulate.h" 8 | 9 | int main( int argc, char* args[] ) { 10 | 11 | Tiny::view.pointSize = 2.0f; 12 | 13 | Tiny::window("Energy Based Image Triangulation, Nicholas Mcdonald 2022", 1200, 800); 14 | Tiny::event.handler = [](){}; 15 | Tiny::view.interface = [](){}; 16 | 17 | Texture tex(image::load("canyon.png")); //Load Texture with Image 18 | Square2D flat; //Create Primitive Model 19 | Shader image({"shader/image.vs", "shader/image.fs"}, {"in_Quad", "in_Tex"}); 20 | Shader point({"shader/point.vs", "shader/point.fs"}, {"in_Position"}); 21 | 22 | // Triangulation 23 | 24 | Triangulation triangulation(2048); 25 | 26 | // The triangulation needs to be 27 | 28 | Tiny::view.pipeline = [&](){ 29 | 30 | Tiny::view.target(color::black); //Target Main Screen 31 | 32 | image.use(); //Use Effect Shader 33 | image.texture("imageTexture", tex); //Load Texture 34 | image.uniform("model", flat.model); //Add Model Matrix 35 | flat.render(); //Render Primitive 36 | 37 | point.use(); 38 | triangulation.render(GL_POINTS); 39 | triangulation.render(GL_LINES); 40 | 41 | }; 42 | 43 | Tiny::loop([&](){}); 44 | Tiny::quit(); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /tests/tri_render_direct/makefile: -------------------------------------------------------------------------------- 1 | # TinyEngine Makefile 2 | # Compiler Configuration 3 | 4 | CC = g++ -std=c++17 5 | CF = -Wfatal-errors -O 6 | LF = -I/usr/local/include -L/usr/local/lib 7 | 8 | # General Linking 9 | 10 | TINYLINK = -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem 11 | 12 | # OS Specific Linking 13 | 14 | UNAME := $(shell uname) 15 | ifeq ($(UNAME), Linux) #Detect GNU/Linux 16 | TINYOS = -lX11 -lGL 17 | endif 18 | ifeq ($(UNAME), Darwin) #Detext MacOS 19 | TINYOS = -framework OpenGL 20 | endif 21 | 22 | all: main.cpp 23 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 24 | 25 | # Build Embedded Form 26 | 27 | DAT = shader #data directory to embed 28 | .PHONY: embedded 29 | embedded: CEF = $(shell c-embed $(DAT)) c-embed.o -include /usr/local/include/c-embed.h -DCEMBED_TRANSLATE 30 | embedded: 31 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 32 | rm c-embed.o 33 | -------------------------------------------------------------------------------- /tests/tri_render_direct/shader/image.fs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 ex_Tex; 3 | out vec4 fragColor; 4 | 5 | uniform sampler2D imageTexture; 6 | uniform sampler2D blurTexture; 7 | 8 | //Effect Parameters 9 | uniform int index; 10 | uniform int res; 11 | uniform int bits; 12 | 13 | vec4 none(){ 14 | return texture(imageTexture, ex_Tex); 15 | } 16 | 17 | vec4 pixelate(){ 18 | return texture(imageTexture, floor(ex_Tex*vec2(res))/vec2(res)); 19 | } 20 | 21 | vec4 bitreduce(){ 22 | vec4 color = texture(imageTexture, ex_Tex); 23 | return vec4(round(color.xyz*vec3(bits))/vec3(bits), 1.0); 24 | } 25 | 26 | void main(){ 27 | //Get the fragment color from the effect choice 28 | if(index == 1) fragColor = pixelate(); 29 | else if(index == 2) fragColor = bitreduce(); 30 | else fragColor = none(); 31 | } 32 | -------------------------------------------------------------------------------- /tests/tri_render_direct/shader/image.vs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 in_Quad; 3 | in vec2 in_Tex; 4 | out vec2 ex_Tex; 5 | 6 | //Position the Billboard in space! 7 | uniform mat4 model; 8 | 9 | void main(){ 10 | ex_Tex = in_Tex; 11 | gl_Position = model*vec4(in_Quad, -1.0, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/tri_render_direct/shader/point.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,0,0,1); 7 | } 8 | -------------------------------------------------------------------------------- /tests/tri_render_direct/shader/point.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec2 in_Position; 4 | 5 | void main(){ 6 | gl_Position = vec4(in_Position/vec2(1.2/0.8, 1), -1.0f, 1.0f); 7 | } 8 | -------------------------------------------------------------------------------- /tests/tri_render_direct/triangulate.h: -------------------------------------------------------------------------------- 1 | // triangulate.h 2 | 3 | using namespace glm; 4 | using namespace std; 5 | 6 | struct Triangulation : Model { 7 | 8 | vector vertices; 9 | vector coords; 10 | vector indices; 11 | Buffer pos, ind; 12 | 13 | Triangulation(const size_t K) : Model({"in_Position"}){ 14 | 15 | std::vector points; //Coordinates for Delaunation 16 | 17 | points.emplace_back( -1.2/0.8f, -1 ); 18 | points.emplace_back( -1.2/0.8f, 1 ); 19 | points.emplace_back( 1.2/0.8f, -1 ); 20 | points.emplace_back( 1.2/0.8f, 1 ); 21 | 22 | while(points.size() < K/2) 23 | sample::disc(points, K, vec2(-12.0f/8.0f, -1.0f), vec2(12.0f/8.0f, 1.0f)); 24 | 25 | for(size_t i = 0; i < points.size(); i++){ 26 | vertices.push_back(points[i].x); 27 | vertices.push_back(points[i].y); 28 | coords.push_back(points[i].x); 29 | coords.push_back(points[i].y); 30 | } 31 | 32 | delaunator::Delaunator d(coords); //Compute Delaunay Triangulation 33 | 34 | for(size_t i = 0; i < d.triangles.size()/3; i++){ 35 | indices.push_back(d.triangles[3*i+0]); 36 | indices.push_back(d.triangles[3*i+1]); 37 | indices.push_back(d.triangles[3*i+1]); 38 | indices.push_back(d.triangles[3*i+2]); 39 | indices.push_back(d.triangles[3*i+2]); 40 | indices.push_back(d.triangles[3*i+0]); 41 | } 42 | 43 | pos.fill(vertices); 44 | ind.fill(indices); 45 | 46 | bind("in_Position", &pos); 47 | index(&ind); 48 | SIZE = indices.size(); 49 | 50 | } 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /tests/tri_render_indirect/canyon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigert/t-pose/f729996fad7cc14862c4e24760d31350c0375673/tests/tri_render_indirect/canyon.png -------------------------------------------------------------------------------- /tests/tri_render_indirect/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../../source/include/delaunator-cpp/delaunator-header-only.hpp" 6 | #include "../../source/include/poisson.hpp" 7 | #include "triangulate.h" 8 | 9 | int main( int argc, char* args[] ) { 10 | 11 | Tiny::view.pointSize = 2.0f; 12 | 13 | Tiny::window("Energy Based Image Triangulation, Nicholas Mcdonald 2022", 1200, 800); 14 | Tiny::event.handler = [](){}; 15 | Tiny::view.interface = [](){}; 16 | 17 | Texture tex(image::load("canyon.png")); //Load Texture with Image 18 | Square2D flat; //Create Primitive Model 19 | Shader image({"shader/image.vs", "shader/image.fs"}, {"in_Quad", "in_Tex"}); 20 | Shader point({"shader/point.vs", "shader/point.fs"}, {"in_Position"}); 21 | 22 | initialize(); 23 | 24 | Triangle triangle; 25 | Instance triangleinstance(&triangle); 26 | triangleinstance.bind("in_Index", trianglebuf); 27 | 28 | Shader triangleshader({"shader/triangle.vs", "shader/triangle.fs"}, {"in_Position", "in_Index"}, {"points"}); 29 | triangleshader.bind("points", pointbuf); 30 | 31 | Model pointmesh({"in_Position"}); 32 | pointmesh.bind("in_Position", pointbuf); 33 | pointmesh.SIZE = pointbuf->SIZE; 34 | 35 | Tiny::view.pipeline = [&](){ 36 | 37 | Tiny::view.target(color::black); //Target Main Screen 38 | 39 | image.use(); //Use Effect Shader 40 | image.texture("imageTexture", tex); //Load Texture 41 | image.uniform("model", flat.model); //Add Model Matrix 42 | flat.render(); //Render Primitive 43 | 44 | point.use(); 45 | pointmesh.render(GL_POINTS); 46 | 47 | triangleshader.use(); 48 | triangleinstance.render(GL_LINE_STRIP); 49 | //triangleinstance.render(GL_TRIANGLE_STRIP); 50 | 51 | }; 52 | 53 | Tiny::loop([&](){}); 54 | Tiny::quit(); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tests/tri_render_indirect/makefile: -------------------------------------------------------------------------------- 1 | # TinyEngine Makefile 2 | # Compiler Configuration 3 | 4 | CC = g++ -std=c++17 5 | CF = -Wfatal-errors -O 6 | LF = -I/usr/local/include -L/usr/local/lib 7 | 8 | # General Linking 9 | 10 | TINYLINK = -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem 11 | 12 | # OS Specific Linking 13 | 14 | UNAME := $(shell uname) 15 | ifeq ($(UNAME), Linux) #Detect GNU/Linux 16 | TINYOS = -lX11 -lGL 17 | endif 18 | ifeq ($(UNAME), Darwin) #Detext MacOS 19 | TINYOS = -framework OpenGL 20 | endif 21 | 22 | all: main.cpp 23 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 24 | 25 | # Build Embedded Form 26 | 27 | DAT = shader #data directory to embed 28 | .PHONY: embedded 29 | embedded: CEF = $(shell c-embed $(DAT)) c-embed.o -include /usr/local/include/c-embed.h -DCEMBED_TRANSLATE 30 | embedded: 31 | $(CC) main.cpp $(CF) $(LF) -lTinyEngine $(TINYOS) $(TINYLINK) -o main 32 | rm c-embed.o 33 | -------------------------------------------------------------------------------- /tests/tri_render_indirect/shader/image.fs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 ex_Tex; 3 | out vec4 fragColor; 4 | 5 | uniform sampler2D imageTexture; 6 | uniform sampler2D blurTexture; 7 | 8 | //Effect Parameters 9 | uniform int index; 10 | uniform int res; 11 | uniform int bits; 12 | 13 | vec4 none(){ 14 | return texture(imageTexture, ex_Tex); 15 | } 16 | 17 | vec4 pixelate(){ 18 | return texture(imageTexture, floor(ex_Tex*vec2(res))/vec2(res)); 19 | } 20 | 21 | vec4 bitreduce(){ 22 | vec4 color = texture(imageTexture, ex_Tex); 23 | return vec4(round(color.xyz*vec3(bits))/vec3(bits), 1.0); 24 | } 25 | 26 | void main(){ 27 | //Get the fragment color from the effect choice 28 | if(index == 1) fragColor = pixelate(); 29 | else if(index == 2) fragColor = bitreduce(); 30 | else fragColor = none(); 31 | } 32 | -------------------------------------------------------------------------------- /tests/tri_render_indirect/shader/image.vs: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 in_Quad; 3 | in vec2 in_Tex; 4 | out vec2 ex_Tex; 5 | 6 | //Position the Billboard in space! 7 | uniform mat4 model; 8 | 9 | void main(){ 10 | ex_Tex = in_Tex; 11 | gl_Position = model*vec4(in_Quad, -1.0, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/tri_render_indirect/shader/point.fs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,0,0,1); 7 | } 8 | -------------------------------------------------------------------------------- /tests/tri_render_indirect/shader/point.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec2 in_Position; 4 | 5 | void main(){ 6 | gl_Position = vec4(in_Position/vec2(1.2/0.8, 1), -1.0f, 1.0f); 7 | } 8 | -------------------------------------------------------------------------------- /tests/tri_render_indirect/shader/triangle.fs: -------------------------------------------------------------------------------- 1 | #version 430 core 2 | 3 | out vec4 fragColor; 4 | 5 | void main(){ 6 | fragColor = vec4(1,0,0,1); 7 | } 8 | -------------------------------------------------------------------------------- /tests/tri_render_indirect/shader/triangle.vs: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | 3 | in vec3 in_Position; 4 | in ivec3 in_Index; 5 | 6 | buffer points { 7 | vec2 p[]; 8 | }; 9 | 10 | void main() { 11 | 12 | vec2 tpos = vec2(0); 13 | if (in_Position.x > 0) tpos = p[in_Index.x]; 14 | if (in_Position.y > 0) tpos = p[in_Index.y]; 15 | if (in_Position.z > 0) tpos = p[in_Index.z]; 16 | tpos.x /= 1200.0f/800.0f; 17 | gl_Position = vec4(tpos, -1, 1.0f); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /tests/tri_render_indirect/triangulate.h: -------------------------------------------------------------------------------- 1 | // triangulate.h 2 | 3 | using namespace glm; 4 | using namespace std; 5 | 6 | struct Triangle : Model { 7 | Buffer vert; 8 | Triangle():Model({"vert"}), 9 | vert({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}){ 10 | bind("vert", &vert); 11 | SIZE = 3; 12 | } 13 | }; 14 | 15 | Buffer* trianglebuf; 16 | Buffer* pointbuf; 17 | 18 | void initialize( const int K = 2048 ){ 19 | 20 | // Create a Delaunator! 21 | 22 | vector points; //Coordinates for Delaunation 23 | while(points.size() < K/2) 24 | sample::disc(points, K, vec2(-12.0f/8.0f, -1.0f), vec2(12.0f/8.0f, 1.0f)); 25 | 26 | points.emplace_back(-1.2/0.8f,-1); 27 | points.emplace_back(-1.2/0.8f, 1); 28 | points.emplace_back( 1.2/0.8f,-1); 29 | points.emplace_back( 1.2/0.8f, 1); 30 | 31 | pointbuf = new Buffer(points); 32 | 33 | vector coords; //Coordinates for Delaunation 34 | for(size_t i = 0; i < points.size(); i++){ 35 | coords.push_back(points[i].x); 36 | coords.push_back(points[i].y); 37 | } 38 | 39 | delaunator::Delaunator d(coords); //Compute Delaunay Triangulation 40 | 41 | vector triangles; //Triangle Point Indexing 42 | for(size_t i = 0; i < d.triangles.size()/3; i++) 43 | triangles.emplace_back(d.triangles[3*i+2], d.triangles[3*i+1], d.triangles[3*i+0]); 44 | trianglebuf = new Buffer(triangles); 45 | 46 | } 47 | --------------------------------------------------------------------------------