├── .gitignore ├── README.md ├── build.sh ├── client ├── css │ ├── BasicStyles.css │ ├── Button.css │ ├── CircleSlider.css │ ├── Cross.css │ ├── Dropdown.css │ ├── Search.css │ ├── Slider.css │ ├── font-awesome.min.css │ └── fontawesome │ │ ├── css │ │ ├── fa-brands.css │ │ ├── fa-brands.min.css │ │ ├── fa-regular.css │ │ ├── fa-regular.min.css │ │ ├── fa-solid.css │ │ ├── fa-solid.min.css │ │ ├── fontawesome-all.css │ │ ├── fontawesome-all.min.css │ │ ├── fontawesome.css │ │ └── fontawesome.min.css │ │ └── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ └── fa-solid-900.woff2 └── js │ ├── apps │ ├── Common │ │ ├── Common.js │ │ ├── ModelLoader.js │ │ └── WindowManager.js │ └── Viewer │ │ ├── MeshRenderer.js │ │ ├── SVoxRenderer.js │ │ ├── SceneRenderer.js │ │ ├── Viewer.js │ │ ├── VoxRenderer.js │ │ ├── WireframeRenderer.js │ │ └── view │ │ ├── BrowseUI.js │ │ ├── MeshOptionsUI.js │ │ ├── MetadataUI.js │ │ └── RootUI.js │ └── lib │ ├── controls │ └── OrbitControls.js │ ├── geometry │ ├── Beam.js │ └── Cube.js │ ├── loader │ ├── MTLLoader.js │ ├── OBJLoader.js │ └── PLYLoader.js │ ├── proto │ ├── data3_pb.js │ ├── data_info_pb.js │ ├── svox_pb.js │ └── vox_pb.js │ ├── shader │ ├── PVVGLSL.js │ ├── PhongGLSL.js │ ├── PolygonColorGLSL.js │ ├── PolygonGLSL.js │ ├── PolygonInstanceGLSL.js │ └── SceneGLSL.js │ ├── vao │ ├── CamSphereVAO.js │ ├── GLProgram.js │ ├── ImageVAO.js │ ├── KeypointVAO.js │ ├── OBJModel.js │ ├── PickVisibleVertex.js │ ├── RotationVAO.js │ ├── ScaleVAO.js │ ├── SceneModel.js │ ├── SimpleVAO.js │ ├── ThickWireframe.js │ ├── VoxelGrid.js │ └── Wireframe.js │ └── webgl │ └── GLProgram.js ├── env.sh ├── package-lock.json ├── package.json ├── pics ├── json.png ├── nocs.png ├── ply.png ├── vox2.png └── wrf.png ├── server ├── Config.js ├── DetachProcess.sh ├── index.js ├── package-lock.json ├── package.json ├── run.sh ├── static │ └── root └── views │ ├── SceneViewer.pug │ └── Viewer.pug └── watch.sh /.gitignore: -------------------------------------------------------------------------------- 1 | #generated 2 | pid.txt 3 | *.vox 4 | log.txt 5 | 6 | # hidden files 7 | .* 8 | *~ 9 | 10 | #build folders 11 | build 12 | 13 | # node modules 14 | node_modules 15 | npm-debug.log 16 | 17 | # exception 18 | !.gitignore 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ServerMeshViewer 2 | 3 | ## Description: 4 | 5 | This is a WebGL based renderer for following file formats: 6 | 7 | - ```vox, vox2, voxnoc``` (dense voxel grids) 8 | - ```ply, obj``` (meshes) 9 | - ```wrf``` (wireframe files) 10 | - ```.json``` (scene files, can be used in mitsuba) 11 | - ```jpg, png, gif``` (images) 12 | 13 | If you want more file formats to be visualized, then open an issue and I'll write a shader for it as soon as I find some time 14 | 15 | ## How-To Use 16 | 17 | Just pase the absolute path of your file in the browser and it will render that file automatically: 18 | 19 | ```localhost:8080/Viewer/[abspath-to-file]``` 20 | 21 | ## Why? 22 | 23 | + No copying from server to local machine needed 24 | + No meshlab needed 25 | + No remote desktop needed 26 | + View outputs from anywhere 27 | + All you need is a browser 28 | + It's super fast to view predictions in the browser 29 | 30 | I have seen people copy outputs to their local machine and visualize with meshlab lol. I believe this will save a lot of time. 31 | 32 | ### Example: 33 | Open firefox or chrome and goto: 34 | 35 | ```localhost:8080/Viewer/home/amo/neural-network/prediction.voxnoc``` 36 | 37 | | ```.voxnoc``` (voxelwise rgb color) | 38 | :-------------------------:| 39 | ![](pics/nocs.png) 40 | | ```.json``` (scene fileformat) | 41 | ![](pics/json.png) 42 | | ```.ply``` (this is a black bunny lol) | 43 | ![](pics/ply.png) 44 | | ```.wrf``` (wireframe format) | 45 | ![](pics/wrf.png) 46 | | ```.vox2``` (this is a heatmap) | 47 | ![](pics/vox2.png) 48 | 49 | 50 | ### Get started 51 | 52 | 1. Clone this repo 53 | 2. `cd repo-name` (enter downloaded repository folder) 54 | 3. Install `nodejs` (=`npm`) from [https://nodejs.org/en/](https://nodejs.org/en/) 55 | 4. Run `npm install` for client-side 56 | * This will install all dependencies specified in `package.json` 57 | 5. `cd ./server/ && npm install` for server side. 58 | 6. Run `./build.sh` to compile 59 | 7. Run `./server/run.sh` to start the server. 60 | * Note that this assumes that you use `bash` 61 | 8. Go to *localhost:8080/Viewer/[abspath-to-file]* 62 | 63 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | source ./env.sh 2 | echo "base-url:" $NODE_BASE_URL 3 | NODE_BASE_URL=$NODE_BASE_URL npm run build --harmony 4 | -------------------------------------------------------------------------------- /client/css/BasicStyles.css: -------------------------------------------------------------------------------- 1 | @keyframes example { 2 | 0% {background-color: white;} 3 | 25% {background-color: #0069d9;} 4 | 50% {background-color: white;} 5 | 75% {background-color: #0069d9;} 6 | 100% {background-color: white;} 7 | } 8 | 9 | input[type=text]:focus { 10 | animation-name: example; 11 | animation-duration: 0.7s; 12 | animation-iteration-count: 1; 13 | 14 | -webkit-animation-name: example; 15 | -webkit-animation-duration: 0.7s; 16 | -webkit-animation-iteration-count: 1; 17 | } 18 | 19 | /*box-shadow: 0 0 2px 1px rgba(0, 140, 186, 0.5);*/ 20 | 21 | .imghover:hover { 22 | border : 2px solid rgba(0, 140, 200, 0.5); 23 | } 24 | 25 | 26 | 27 | @keyframes blue_flash { 28 | 0% {background-color: white;} 29 | 25% {background-color: #007bff;} 30 | 50% {background-color: white;} 31 | 75% {background-color: #007bff;} 32 | 100% {background-color: white;} 33 | } 34 | 35 | .card-info.focusable { 36 | animation-name: blue_flash; 37 | animation-duration: 0.7s; 38 | animation-iteration-count: 1; 39 | } 40 | -------------------------------------------------------------------------------- /client/css/Button.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --button-width : 80px; 3 | --button-height : 40px; 4 | } 5 | 6 | @keyframes button_focus { 7 | 0% {background-color: #007bff;} 8 | 25% {background-color: white;} 9 | 50% {background-color: #007bff;} 10 | 75% {background-color: white;} 11 | 100% {background-color: #007bff;} 12 | } 13 | 14 | @keyframes button_gray_focus { 15 | 0% {background-color: #868e96;} 16 | 25% {background-color: white;} 17 | 50% {background-color: #868e96;} 18 | 75% {background-color: white;} 19 | 100% {background-color: #868e96;} 20 | } 21 | 22 | @keyframes button_green_focus { 23 | 0% {background-color: #28a745;} 24 | 25% {background-color: white;} 25 | 50% {background-color: #28a745;} 26 | 75% {background-color: white;} 27 | 100% {background-color: #28a745;} 28 | } 29 | 30 | .button_green { 31 | background-color: #28a745; 32 | border: none; 33 | border-radius: 2px; 34 | color: white; 35 | /*padding: 8px 20px;*/ 36 | /*width : var(--button-width);*/ 37 | /*height : var(--button-height);*/ 38 | text-align: center; 39 | text-decoration: none; 40 | display: inline-block; 41 | font-size: 12px; 42 | cursor: pointer; 43 | } 44 | 45 | .button_blue { 46 | background-color: #007bff; 47 | border: none; 48 | border-radius: 2px; 49 | color: white; 50 | /*padding: 8px 20px;*/ 51 | /*width : var(--button-width);*/ 52 | /*height : var(--button-height);*/ 53 | text-align: center; 54 | text-decoration: none; 55 | display: inline-block; 56 | font-size: 12px; 57 | cursor: pointer; 58 | } 59 | 60 | .button_blue:hover { 61 | background-color: #0069d9; 62 | } 63 | 64 | .button_blue.focusable:focus { 65 | animation-name: button_focus; 66 | animation-duration: 0.7s; 67 | animation-iteration-count: 1; 68 | } 69 | 70 | .button_green.focusable:focus { 71 | animation-name: button_green_focus; 72 | animation-duration: 0.7s; 73 | animation-iteration-count: 1; 74 | } 75 | 76 | 77 | 78 | .button_red { 79 | background-color: #dc3545; 80 | border: none; 81 | border-radius: 2px; 82 | color: white; 83 | /*padding: 8px 20px;*/ 84 | /*width : var(--button-width);*/ 85 | /*height : var(--button-height);*/ 86 | text-align: center; 87 | text-decoration: none; 88 | display: inline-block; 89 | font-size: 12px; 90 | cursor: pointer; 91 | } 92 | 93 | .button_orange { 94 | background-color: #f4b942; 95 | border: none; 96 | border-radius: 2px; 97 | color: white; 98 | /*padding: 8px 20px;*/ 99 | /*width : var(--button-width);*/ 100 | /*height : var(--button-height);*/ 101 | text-align: center; 102 | text-decoration: none; 103 | display: inline-block; 104 | font-size: 12px; 105 | cursor: pointer; 106 | } 107 | 108 | .button_gray { 109 | background-color: #868e96; 110 | border: none; 111 | border-radius: 2px; 112 | color: white; 113 | /*padding: 8px 20px;*/ 114 | /*width : var(--button-width);*/ 115 | /*height : var(--button-height);*/ 116 | text-align: center; 117 | text-decoration: none; 118 | display: inline-block; 119 | font-size: 12px; 120 | cursor: pointer; 121 | } 122 | 123 | .button_gray.focusable:focus { 124 | animation-name: button_gray_focus; 125 | animation-duration: 0.7s; 126 | animation-iteration-count: 1; 127 | } 128 | 129 | 130 | .button_click { 131 | display: inline-block; 132 | font-size: 12px; 133 | cursor: pointer; 134 | text-align: center; 135 | text-decoration: none; 136 | outline: none; 137 | color: #fff; 138 | background-color: #4CAF50; 139 | border: none; 140 | border-radius: 2px; 141 | box-shadow: 0 4px #999; 142 | } 143 | 144 | .button_click:hover {background-color: #3e8e41} 145 | 146 | .button_click.active { 147 | background-color: #3e8e41; 148 | box-shadow: 0 2px #666; 149 | transform: translateY(4px); 150 | } 151 | 152 | .btn-group .button { 153 | background-color: #28a745; /* Green */ 154 | border: none; 155 | border-right: 1px solid green; 156 | text-align: center; 157 | padding : 3px 6px; 158 | text-decoration: none; 159 | display: inline-block; 160 | font-size: 12px; 161 | cursor: pointer; 162 | float: left; 163 | border-radius: 5px 0px 0px 5px; 164 | } 165 | .btn-group .button:last-child { 166 | border: none; /* Prevent double borders */ 167 | border-radius: 0px 5px 5px 0px; 168 | } 169 | .btn-group .button:hover { 170 | background-color: #4CAF50; 171 | } 172 | -------------------------------------------------------------------------------- /client/css/CircleSlider.css: -------------------------------------------------------------------------------- 1 | 2 | .circle { 3 | position: absolute; 4 | top: 0; 5 | left: 0; 6 | width: 100%; 7 | height: 100%; 8 | 9 | -webkit-box-sizing: border-box; 10 | -moz-box-sizing: border-box; 11 | box-sizing: border-box; 12 | border : 8px solid; 13 | border-color: #ddd; 14 | border-radius: 50%; 15 | transform: translate3d(-50%, -50%, 0); 16 | } 17 | 18 | 19 | .circle .dot { 20 | position: absolute; 21 | background-color: #99ccff; 22 | box-shadow: 0 0 5px #000; 23 | left : 50%; 24 | top : 50%; 25 | width: 1vw; 26 | height:1vw; 27 | z-index:100; 28 | border-radius: 50%; 29 | transform: translate3d(-50%, -50%, 0); 30 | transform-origin: center; 31 | cursor: pointer; 32 | } 33 | -------------------------------------------------------------------------------- /client/css/Cross.css: -------------------------------------------------------------------------------- 1 | .cross { 2 | position: absolute; 3 | top: 0; 4 | left: 0; 5 | width: 100%; 6 | height: 100%; 7 | border: none; 8 | background-color: #868e96; 9 | transform: translate3d(-50%, -50%, 0); 10 | } 11 | 12 | .tile { 13 | text-align: center; 14 | position: absolute; 15 | font-size: 22px; 16 | background-color: #28a745; 17 | //width: calc(100% - 2px); 18 | //height: calc(100% - 2px); 19 | width: 100%; 20 | height:100%; 21 | cursor:pointer; 22 | } 23 | 24 | .tile:hover { 25 | background-color: #4CAF50; 26 | } 27 | 28 | .cross .tile.up { 29 | border: 1px solid green; 30 | left: 0%; 31 | top: -100%; 32 | border-radius: 5px 5px 0px 0px; 33 | } 34 | 35 | .cross .tile.down { 36 | border: 1px solid green; 37 | left: 0%; 38 | top: 100%; 39 | border-radius: 0px 0px 5px 5px; 40 | } 41 | 42 | .cross .tile.left { 43 | border: 1px solid green; 44 | left: -100%; 45 | top: 0%; 46 | border-radius: 5px 0px 0px 5px; 47 | } 48 | 49 | .cross .tile.right { 50 | border: 1px solid green; 51 | left: 100%; 52 | top: 0%; 53 | border-radius: 0px 5px 5px 0px; 54 | } -------------------------------------------------------------------------------- /client/css/Dropdown.css: -------------------------------------------------------------------------------- 1 | /*.dropbtn { 2 | background-color: #4CAF50; 3 | color: white; 4 | padding: 12px; 5 | font-size: 12px; 6 | border: none; 7 | cursor: pointer; 8 | } 9 | 10 | .dropdown { 11 | position: relative; 12 | display: inline-block; 13 | } 14 | 15 | .dropdown:hover .dropdown-content { 16 | display: block; 17 | } 18 | 19 | .dropdown:hover .dropbtn { 20 | background-color: #3e8e41; 21 | }*/ 22 | 23 | /*.dropdown-content { 24 | display: none; 25 | position: absolute; 26 | background-color: #f9f9f9; 27 | min-width: 170px; 28 | z-index: 1; 29 | } 30 | 31 | .dropdown-content a { 32 | color: black; 33 | font-size: 12px; 34 | padding: 10px 12px; 35 | text-decoration: none; 36 | display: block; 37 | } 38 | 39 | .dropdown-content a:hover {background-color: #f1f1f1}*/ 40 | -------------------------------------------------------------------------------- /client/css/Search.css: -------------------------------------------------------------------------------- 1 | form.exampleform input[type=text] { 2 | padding: 10px; 3 | font-size: 1.2rem; 4 | border: 1px solid grey; 5 | float: left; 6 | width: 80%; 7 | background: #f1f1f1; 8 | } 9 | 10 | /*form.exampleform button { 11 | float: left; 12 | width: 20%; 13 | padding: 10px; 14 | background: #2196F3; 15 | color: white; 16 | font-size: 17px; 17 | border: 1px solid grey; 18 | border-left: none; 19 | cursor: pointer; 20 | }*/ 21 | 22 | /*form.exampleform button:hover { 23 | background: #0b7dda; 24 | }*/ 25 | 26 | form.exampleform::after { 27 | content: ""; 28 | clear: both; 29 | display: table; 30 | } 31 | -------------------------------------------------------------------------------- /client/css/Slider.css: -------------------------------------------------------------------------------- 1 | 2 | .range { 3 | position: absolute; 4 | top: 0; 5 | left: 0; 6 | width: 100%; 7 | height: 8px; 8 | background-color: #ddd; 9 | transform: translate3d(-50%, -50%, 0); 10 | } 11 | 12 | 13 | .range .dot { 14 | position: absolute; 15 | background-color: #99ccff; 16 | box-shadow: 0 0 5px #000; 17 | left : 50%; 18 | top : 50%; 19 | height: 1vw; 20 | width: 1vw; 21 | z-index:100; 22 | border-radius: 50%; 23 | transform: translate3d(-50%, -50%, 0); 24 | transform-origin: center; 25 | cursor: pointer; 26 | } 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /client/css/fontawesome/css/fa-brands.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Brands'; 7 | font-style: normal; 8 | font-weight: normal; 9 | src: url("../webfonts/fa-brands-400.eot"); 10 | src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } 11 | 12 | .fab { 13 | font-family: 'Font Awesome 5 Brands'; } 14 | -------------------------------------------------------------------------------- /client/css/fontawesome/css/fa-brands.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:Font Awesome\ 5 Brands;font-style:normal;font-weight:400;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:Font Awesome\ 5 Brands} -------------------------------------------------------------------------------- /client/css/fontawesome/css/fa-regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 400; 9 | src: url("../webfonts/fa-regular-400.eot"); 10 | src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } 11 | 12 | .far { 13 | font-family: 'Font Awesome 5 Free'; 14 | font-weight: 400; } 15 | -------------------------------------------------------------------------------- /client/css/fontawesome/css/fa-regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:400;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-family:Font Awesome\ 5 Free;font-weight:400} -------------------------------------------------------------------------------- /client/css/fontawesome/css/fa-solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 900; 9 | src: url("../webfonts/fa-solid-900.eot"); 10 | src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } 11 | 12 | .fa, 13 | .fas { 14 | font-family: 'Font Awesome 5 Free'; 15 | font-weight: 900; } 16 | -------------------------------------------------------------------------------- /client/css/fontawesome/css/fa-solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:Font Awesome\ 5 Free;font-weight:900} -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /client/css/fontawesome/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/client/css/fontawesome/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /client/js/apps/Common/Common.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | window.xhr_json = function (type, url) { 4 | return new Promise((resolve, reject) => { 5 | let xhr0 = new XMLHttpRequest(); 6 | xhr0.onreadystatechange = function() { 7 | if (this.readyState === 4 && this.status === 200) { 8 | let res = JSON.parse(this.response); 9 | resolve(res); 10 | } 11 | }; 12 | xhr0.open(type, url, true); 13 | xhr0.send(); 14 | }); 15 | }; 16 | 17 | window.xhr = function (type, url) { 18 | return new Promise((resolve, reject) => { 19 | let xhr0 = new XMLHttpRequest(); 20 | xhr0.onreadystatechange = function() { 21 | if (this.readyState === 4 && this.status === 200) { 22 | resolve(this.response); 23 | } 24 | }; 25 | xhr0.open(type, url, true); 26 | xhr0.send(); 27 | }); 28 | }; 29 | 30 | window.xhr_arraybuffer = function (type, url) { 31 | return new Promise((resolve, reject) => { 32 | let xhr0 = new XMLHttpRequest(); 33 | xhr0.responseType = "arraybuffer"; 34 | xhr0.onreadystatechange = function() { 35 | if (this.readyState === 4 && this.status === 200) { 36 | resolve(this.response); 37 | } 38 | }; 39 | xhr0.open(type, url, true); 40 | xhr0.send(); 41 | }); 42 | }; 43 | 44 | window.xhr_push = function (type, url, data) { 45 | return new Promise((resolve, reject) => { 46 | let xhr = new XMLHttpRequest(); 47 | xhr.open(type, url); 48 | xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); 49 | xhr.onreadystatechange = function() { 50 | if (this.readyState === 4 && this.status === 200) { 51 | let res = JSON.parse(this.response); 52 | resolve(res); 53 | } 54 | }; 55 | xhr.send(JSON.stringify(data)); 56 | }); 57 | }; 58 | 59 | window.xhr_goto_url = function (type, url) { 60 | let xhr0 = new XMLHttpRequest(); 61 | xhr0.onload = function() { 62 | document.body.innerHTML = this.response; 63 | } 64 | xhr0.responseType = "document"; 65 | xhr0.open(type, url); 66 | xhr0.send(); 67 | }; 68 | -------------------------------------------------------------------------------- /client/js/apps/Common/ModelLoader.js: -------------------------------------------------------------------------------- 1 | 2 | import SceneModel from '../../lib/vao/SceneModel'; 3 | import OBJModel from '../../lib/vao/OBJModel.js'; 4 | 5 | class ModelLoader { 6 | 7 | 8 | load_alignment(data, window) { 9 | let id_scene = data[0]; 10 | this.load_aligned_scene(id_scene, window).then( scene => 11 | console.log(scene) 12 | //Promise.all(this.load_aligned_models(data.aligned_models, window, model_manager, pvv_model)).then( res => { 13 | // this.load_all_keypoints(data.aligned_models, window, model_manager); 14 | // this.create_all_wireframes(window, model_manager); 15 | // pvv_model.set_active(1); 16 | //}) 17 | ); 18 | } 19 | 20 | load_aligned_scene(id_scene, window, model_manager) { 21 | return new Promise((resolve, reject) => { 22 | let scene = new SceneModel(); 23 | scene.init(window.gl); 24 | 25 | scene.load_scene("scannet", id_scene).then( res => { 26 | resolve(scene); 27 | }); 28 | }); 29 | } 30 | 31 | load_aligned_models(aligned_models_info, window, model_manager) { 32 | let asyncs = []; 33 | 34 | for (let key in aligned_models_info) { 35 | let promise = new Promise((resolve, reject) => { 36 | 37 | let id_model_shapenet = aligned_models_info[key].id_shapenet; 38 | let id_category = aligned_models_info[key].id_category_shapenet; 39 | let id_model = aligned_models_info[key].id; 40 | this.spawn_model(id_category, id_model_shapenet, id_model, window, model_manager).then(res => { 41 | let obj = model_manager.get_selected_obj(); 42 | let id_model = model_manager.get_selected_id_model(); 43 | const trs = aligned_models_info[key].trs; 44 | 45 | const scale = new THREE.Vector3().fromArray(trs.scale.slice(0)); 46 | const rotation = new THREE.Quaternion().fromArray(trs.rotation.slice(0)); 47 | const translation = new THREE.Vector3().fromArray(trs.translation.slice(0)); 48 | 49 | obj.scale_matrix0.makeScale(scale.x, scale.y, scale.z); 50 | obj.rotation_matrix0.makeRotationFromQuaternion(rotation); 51 | obj.translation_matrix0.makeTranslation(translation.x, translation.y, translation.z); 52 | 53 | obj.scale_matrix.makeScale(scale.x, scale.y, scale.z); 54 | obj.rotation_matrix.makeRotationFromQuaternion(rotation); 55 | obj.translation_matrix.makeTranslation(translation.x, translation.y, translation.z); 56 | 57 | resolve(); 58 | }); 59 | }); 60 | asyncs.push(promise); 61 | } 62 | return asyncs; 63 | } 64 | 65 | 66 | 67 | 68 | async spawn_model(id_category_shapenet, id_shapenet, id_model, window, model_manager, pvv_model) { 69 | 70 | var obj = new OBJModel(); 71 | obj.init(window.gl); 72 | await obj.load(id_category_shapenet, id_shapenet); 73 | 74 | let label_int32 = model_manager.create_obj_label(); 75 | let label_buffer_int32 = new Int32Array(obj.position_buffer.length/3); 76 | label_buffer_int32.fill(label_int32); 77 | obj.init_vao_offscreen(pvv_model.gl, obj.position_buffer, label_buffer_int32); 78 | 79 | model_manager.add_model_with_idmodel(id_category_shapenet, id_shapenet, id_model, obj); 80 | } 81 | 82 | 83 | load_all_keypoints(aligned_models, window, model_manager) { 84 | for (let key in model_manager.id2obj) { 85 | let obj = model_manager.id2obj[key]; 86 | 87 | const aligned_model = aligned_models.find(elem => {return elem.id === key;}); 88 | const data_keypoint0 = aligned_model.keypoint0; 89 | const data_keypoint1 = aligned_model.keypoint1; 90 | 91 | const pos0 = data_keypoint0.position.slice(); 92 | const pos1 = data_keypoint1.position.slice(); 93 | let pos = []; 94 | for (let i = 0; i < data_keypoint0.n_keypoints*3; i++) { 95 | pos.push(1*(pos0[i])); 96 | } 97 | 98 | var keypoint = new KeypointVAO(); 99 | keypoint.init(window.gl); 100 | keypoint.set_position_from_array(pos, data_keypoint1.n_keypoints); 101 | 102 | keypoint.vao.base_scale = 0.05; 103 | keypoint.set_color_to_green(); 104 | model_manager.add_keypoint0(key, keypoint); 105 | 106 | keypoint.is_visible = 1; 107 | 108 | } 109 | } 110 | 111 | create_all_wireframes(window, model_manager) { 112 | for (let key in model_manager.id2obj) { 113 | let id_model = key 114 | let obj = model_manager.id2obj[key]; 115 | 116 | var wireframe = new Wireframe(); 117 | wireframe.init(window.gl); 118 | wireframe.is_visible = 1; 119 | wireframe.update_box(obj.bounding_box.x, obj.bounding_box.y, obj.bounding_box.z); 120 | model_manager.add_wireframe0(id_model, wireframe); 121 | } 122 | } 123 | 124 | 125 | 126 | } 127 | 128 | export default ModelLoader; 129 | -------------------------------------------------------------------------------- /client/js/apps/Common/WindowManager.js: -------------------------------------------------------------------------------- 1 | import GLProgram from "../../lib/webgl/GLProgram"; 2 | import OrbitControls from "../../lib/controls/OrbitControls"; 3 | 4 | class WindowManager { 5 | constructor(id_panel, id_canvas) { 6 | this.gl = null; 7 | this.initialized = 0; 8 | this.pos_mouse = new THREE.Vector2(); 9 | this.is_mouse_in = 0; 10 | 11 | this.id_panel = id_panel; 12 | this.id_canvas = id_canvas; 13 | 14 | this.container = document.getElementById(id_panel); 15 | this.canvas = document.getElementById(id_canvas); 16 | 17 | // this.canvas.addEventListener("webglcontextlost", (event) => {console.log("lost context");}, false); 18 | 19 | this.window_width = Math.floor(this.container.getBoundingClientRect().width); 20 | this.window_height = Math.floor(this.container.getBoundingClientRect().height); 21 | this.window_left = Math.floor(this.container.getBoundingClientRect().left); 22 | this.window_top = Math.floor(this.container.getBoundingClientRect().top); 23 | this.window_ar = this.window_height/this.window_width; 24 | 25 | this.mouseenter_ref = this.mouseenter.bind(this); 26 | this.mouseleave_ref = this.mouseleave.bind(this); 27 | this.container.addEventListener('mouseenter', this.mouseenter_ref, false); 28 | this.container.addEventListener('mouseleave', this.mouseleave_ref, false); 29 | 30 | this.canvas.left = Math.floor(this.window_left); 31 | this.canvas.top = Math.floor(this.window_top); 32 | this.canvas.width = Math.floor(this.window_width); 33 | this.canvas.height = Math.floor(this.window_height); 34 | 35 | this.z_near = 0.1; 36 | this.z_far = 200.0; 37 | 38 | this.is_firefox = window.navigator.userAgent.toLowerCase().indexOf('firefox') > -1; 39 | console.log("is_firefox", this.is_firefox); 40 | } 41 | 42 | 43 | reinit() { 44 | this.container = document.getElementById(this.id_panel); 45 | this.canvas = document.getElementById(this.id_canvas); 46 | 47 | this.window_width = Math.floor(this.container.getBoundingClientRect().width); 48 | this.window_height = Math.floor(this.container.getBoundingClientRect().height); 49 | this.window_left = Math.floor(this.container.getBoundingClientRect().left); 50 | this.window_top = Math.floor(this.container.getBoundingClientRect().top); 51 | this.window_ar = this.window_height/this.window_width; 52 | 53 | this.mouseenter_ref = this.mouseenter.bind(this); 54 | this.mouseleave_ref = this.mouseleave.bind(this); 55 | this.container.addEventListener('mouseenter', this.mouseenter_ref, false); 56 | this.container.addEventListener('mouseleave', this.mouseleave_ref, false); 57 | 58 | this.canvas.left = Math.floor(this.window_left); 59 | this.canvas.top = Math.floor(this.window_top); 60 | this.canvas.width = Math.floor(this.window_width); 61 | this.canvas.height = Math.floor(this.window_height); 62 | 63 | this.init(); 64 | } 65 | 66 | init() { 67 | this.gl = GLProgram.init_webgl(this.canvas); 68 | this.init_camera(); 69 | this.init_navigation(); 70 | } 71 | 72 | advance(i_iteration, mspf) { 73 | this.navigation.update(mspf*0.001); 74 | this.camera.updateMatrixWorld(true); 75 | } 76 | 77 | init_camera() { 78 | // -> view/projection 79 | this.projection_matrix = new THREE.Matrix4(); 80 | const factor = 0.1; 81 | this.projection_matrix.makePerspective(-factor*1.0, factor*1.0, factor*this.window_ar, -factor*this.window_ar, this.z_near, this.z_far); 82 | //this.projection_matrix.makeOrthographic(-1.0, 1.0, this.window_ar, -this.window_ar, this.z_near, this.z_far); 83 | 84 | this.camera = new THREE.PerspectiveCamera(); 85 | this.camera.position.set(2, 2, -1); 86 | this.camera.up = new THREE.Vector3(0, 1, 0); 87 | this.camera.lookAt(new THREE.Vector3(0, 0, 0)); 88 | this.camera.updateMatrixWorld(true); 89 | // <- 90 | } 91 | 92 | init_navigation() { 93 | // -> navigation 94 | // this.navigation_fly = new FPFlyControls(this.camera, this.window_width, this.window_height, this.window_left, this.window_top); 95 | this.navigation_orbit = new OrbitControls(this.camera, this.container); 96 | this.navigation = this.navigation_orbit; 97 | // <- 98 | } 99 | 100 | set_camera_pos_and_lookat(pos, lookat) { 101 | this.camera.position.set(pos.x, pos.y, pos.z); 102 | this.camera.up = new THREE.Vector3(0, 1, 0); 103 | this.navigation.target = lookat; 104 | this.camera.updateMatrixWorld(true); 105 | } 106 | 107 | set_camera_pos_and_lookat_to_default() { 108 | this.camera.position.set(5, 5, -5); 109 | this.camera.up = new THREE.Vector3(0, 1, 0); 110 | this.navigation.target = new THREE.Vector3(0, 0, 0); 111 | this.camera.updateMatrixWorld(true); 112 | } 113 | 114 | get_camera_pos() { 115 | return this.camera.position; 116 | } 117 | 118 | touchstart(event) { 119 | this.navigation.touchstart(event); 120 | } 121 | 122 | touchmove(event) { 123 | // if (this.is_mouse_in_model_panel()) { 124 | this.pos_mouse.x = event.clientX - this.window_left; 125 | this.pos_mouse.y = event.clientY - this.window_top; 126 | this.navigation.touchmove(event); 127 | // } 128 | } 129 | 130 | touchend(event) { 131 | this.navigation.touchend(event); 132 | } 133 | 134 | mousemove(event) { 135 | // if (this.is_mouse_in_model_panel()) { 136 | this.pos_mouse.x = event.clientX - this.window_left; 137 | this.pos_mouse.y = event.clientY - this.window_top; 138 | this.navigation.mousemove(event); 139 | // } 140 | } 141 | 142 | mousedown(event) { 143 | this.navigation.mousedown(event); 144 | } 145 | 146 | mouseup(event) { 147 | this.navigation.mouseup(event); 148 | } 149 | 150 | 151 | mousewheel(event) { 152 | // if (this.is_mouse_in_model_panel()) 153 | this.navigation.mousewheel(event); 154 | } 155 | 156 | contextmenu(event) { 157 | this.navigation.contextmenu(event); 158 | } 159 | 160 | get_pos_mouse() { 161 | return this.pos_mouse; 162 | } 163 | 164 | get_relative_pos(pos) { 165 | return new THREE.Vector2(pos.x - this.window_left, pos.y - this.window_top); 166 | } 167 | 168 | on_window_resize(event) { 169 | this.window_width = Math.floor(this.container.getBoundingClientRect().width); 170 | this.window_height = Math.floor(this.container.getBoundingClientRect().height); 171 | this.window_left = Math.floor(this.container.getBoundingClientRect().left); 172 | this.window_top = Math.floor(this.container.getBoundingClientRect().top); 173 | this.window_ar = this.window_height/this.window_width; 174 | 175 | this.canvas.left = Math.floor(this.window_left); 176 | this.canvas.top = Math.floor(this.window_top); 177 | this.canvas.width = Math.floor(this.window_width); 178 | this.canvas.height = Math.floor(this.window_height); 179 | 180 | this.camera.aspect = this.window_width/this.window_height; 181 | this.camera.updateProjectionMatrix(true); 182 | }; 183 | 184 | 185 | mouseenter(event) { 186 | this.is_mouse_in = 1; 187 | } 188 | 189 | mouseleave(event) { 190 | this.is_mouse_in = 0; 191 | } 192 | 193 | is_mouse_in_model_panel() { 194 | return this.is_mouse_in; 195 | } 196 | 197 | 198 | add_listener(event_tag, event_callback) { 199 | if (event_tag === "mousemove") { 200 | this.container.parentNode.addEventListener( event_tag, event_callback, false ); 201 | } else if (event_tag == "mousewheel") { 202 | this.container.addEventListener( "wheel", event_callback, false ); 203 | } else { 204 | this.container.addEventListener( event_tag, event_callback, false ); 205 | } 206 | } 207 | 208 | remove_listener(event_tag, event_callback) { 209 | if (event_tag === "mousemove") { 210 | this.container.parentNode.removeEventListener( event_tag, event_callback, false ); 211 | } else if (event_tag === "mousewheel") { 212 | if (this.is_firefox) 213 | this.container.removeEventListener( "DOMMouseScroll", event_callback, false ); 214 | else 215 | this.container.removeEventListener( "mousewheel", event_callback, false ); 216 | } else { 217 | this.container.removeEventListener( event_tag, event_callback, false ); 218 | } 219 | } 220 | 221 | clear(){ 222 | this.gl.clearColor(230/255.0, 240/255.0, 230/255.0, 1.0); // Clear to black, fully opaque 223 | this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); 224 | } 225 | 226 | } 227 | 228 | export default WindowManager; 229 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/MeshRenderer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import csvparse from 'csv-parse'; 5 | 6 | import RootUI from './view/RootUI'; 7 | import MeshOptionsUI from './view/MeshOptionsUI'; 8 | 9 | import * as THREE from 'three/build/three'; 10 | window.THREE = THREE; 11 | import * as d3 from 'd3/build/d3'; 12 | 13 | import * as PolygonInstanceGLSL from '../../lib/shader/PolygonInstanceGLSL' 14 | import PickVisibleVertex from "../../lib/vao/PickVisibleVertex"; 15 | import WindowManager from "../Common/WindowManager" 16 | import SceneModel from "../../lib/vao/SceneModel" 17 | import OBJModel from "../../lib/vao/OBJModel" 18 | import Wireframe from "../../lib/vao/Wireframe" 19 | 20 | 21 | class SceneRenderer { 22 | 23 | init(window0, filename) { 24 | //this.model_loader = new ModelLoader(); 25 | this.window0 = window0; 26 | this.models = []; 27 | 28 | 29 | this.pvv = new PickVisibleVertex(); 30 | this.pvv.init(this.window0.gl, this.window0.window_width, this.window0.window_height); 31 | this.pvv.set_active(); 32 | 33 | this.obj = null; 34 | 35 | return this.load_mesh(filename).then(obj => { 36 | 37 | //obj.scale_matrix.makeScale(trs.scale.x, trs.scale.y, trs.scale.z); 38 | //obj.rotation_matrix.makeRotationFromQuaternion(trs.rot); 39 | //obj.translation_matrix.makeTranslation(trs.trans.x, trs.trans.y, trs.trans.z); 40 | //obj.calc_model_matrix(); 41 | 42 | 43 | let c = obj.bbox_center; 44 | obj.translation_matrix.makeTranslation(-c.x, -c.y, -c.z); 45 | obj.calc_model_matrix(); 46 | 47 | 48 | this.obj = obj; 49 | this.window0.gl.disable(this.window0.gl.CULL_FACE); 50 | console.log(obj); 51 | 52 | //let wireframe = new Wireframe(); 53 | //wireframe.init(this.window0.gl); 54 | //wireframe.is_visible = 1; 55 | //wireframe.update_box(obj.bounding_box.x, obj.bounding_box.y, obj.bounding_box.z); 56 | //wireframe.model_matrix = obj.model_matrix; 57 | //this.models.push(wireframe); 58 | }); 59 | 60 | 61 | 62 | } 63 | 64 | parse_trs(trans0, rot0, scale0) { 65 | let scale = new THREE.Vector3().fromArray(scale0.slice(0)); 66 | rot0 = [rot0[1], rot0[2], rot0[3], rot0[0]]; 67 | let rot = new THREE.Quaternion().fromArray(rot0.slice(0)).normalize(); 68 | 69 | let trans = new THREE.Vector3().fromArray(trans0.slice(0)); 70 | return {"trans" : trans, "rot" : rot, "scale" : scale}; 71 | } 72 | 73 | load_mesh(filename, trs) { 74 | return new Promise((resolve, reject) => { 75 | let obj = null; 76 | if (filename.endsWith("obj")) { 77 | obj = new OBJModel(); 78 | } else if (filename.endsWith("ply")) { 79 | obj = new SceneModel(); 80 | 81 | } 82 | obj.init(this.window0.gl); 83 | 84 | obj.load(filename).then( res => { 85 | resolve(obj); 86 | }); 87 | }); 88 | } 89 | 90 | load_scene(id_scene) { 91 | return new Promise((resolve, reject) => { 92 | let scene = new SceneModel(); 93 | scene.init(this.window0.gl); 94 | 95 | scene.load_scene("scannet", id_scene).then( res => { 96 | resolve(scene); 97 | }); 98 | }); 99 | } 100 | 101 | static basename(str) { 102 | let base = new String(str).substring(str.lastIndexOf('/') + 1); 103 | if(base.lastIndexOf(".") != -1) 104 | base = base.substring(0, base.lastIndexOf(".")); 105 | return base; 106 | } 107 | 108 | 109 | draw() { 110 | this.window0.clear(); 111 | this.window0.advance(0, 16); 112 | this.obj.draw(this.window0.camera.matrixWorldInverse, this.window0.projection_matrix); 113 | 114 | } 115 | 116 | } 117 | 118 | export default SceneRenderer; 119 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/SVoxRenderer.js: -------------------------------------------------------------------------------- 1 | 2 | import * as THREE from 'three/build/three'; 3 | window.THREE = THREE; 4 | 5 | import * as PolygonInstanceGLSL from '../../lib/shader/PolygonInstanceGLSL' 6 | import WindowManager from "../Common/WindowManager" 7 | import VoxelGridVAO from "../../lib/vao/VoxelGrid" 8 | import * as Cube from "../../lib/geometry/Cube" 9 | import Wireframe from "../../lib/vao/Wireframe" 10 | import {Data3} from "../../lib/proto/data3_pb.js" 11 | 12 | class SVoxData { 13 | constructor() { 14 | this.n_elems = 0; 15 | this.res = 0; 16 | this.bbox = null; 17 | this.grid2world = null; 18 | this.coords = null; 19 | this.mask = null; 20 | this.rgb = null; 21 | 22 | } 23 | } 24 | 25 | class VAOData { 26 | constructor() { 27 | this.scale = 0; 28 | this.model_matrix = null; 29 | 30 | this.vertices = null; 31 | this.normals = null; 32 | this.positions = null; 33 | this.colors = null; 34 | this.n_vertices = 0; 35 | this.n_instances = 0; 36 | } 37 | } 38 | 39 | class VoxRenderer { 40 | 41 | init(window0, filename) { 42 | this.svox = new SVoxData(); 43 | this.vao0 = new VoxelGridVAO(); 44 | this.vao_data0 = new VAOData(); 45 | this.window0 = window0; 46 | this.wireframe = new Wireframe(); 47 | 48 | 49 | this.vao0.init(this.window0.gl); 50 | 51 | return this.load_svox(filename).then(res => { 52 | this.vox0 = res["svox"]; 53 | 54 | 55 | this.suffix = filename.split('.').pop(); 56 | let colormode = "none"; 57 | 58 | console.log(this.vox0); 59 | if (this.vox0.mask) 60 | colormode = "mask"; 61 | if (this.vox0.rgb) 62 | colormode = "direct"; 63 | 64 | 65 | this.vao_data0 = this.create_vao_data(this.vox0, colormode) 66 | this.vao0.upload_data(this.vao_data0.n_vertices, this.vao_data0.n_instances, this.vao_data0.vertices, this.vao_data0.normals, this.vao_data0.positions, this.vao_data0.colors); 67 | this.vao0.set_active(); 68 | 69 | this.wireframe.init(this.window0.gl); 70 | let bbox = this.vox0.bbox; 71 | let extent = [bbox[3] - bbox[0], bbox[4] - bbox[1], bbox[5] - bbox[2]]; 72 | let dimmax = Math.max(Math.max(extent[0], extent[1]), extent[2]); 73 | this.wireframe.update_box(0.5*extent[0]/dimmax, 0.5*extent[1]/dimmax, 0.5*extent[2]/dimmax); 74 | this.wireframe.is_visible = 1; 75 | }); 76 | } 77 | create_vao_data(svox, colormode="none", should_rotate=false, only_surface=false) { 78 | let vao_data = new VAOData(); 79 | 80 | let res = svox.res; 81 | let coords = svox.coords; 82 | let mask = svox.mask; 83 | 84 | 85 | let bbox = this.vox0.bbox; 86 | let extent = [bbox[3] - bbox[0], bbox[4] - bbox[1], bbox[5] - bbox[2]]; 87 | 88 | let dimmax = Math.max(extent[0], extent[1], extent[2]); 89 | 90 | let positions = [] 91 | let colors = [] 92 | let n_elems = svox.n_elems; 93 | console.log("n-elems:", n_elems); 94 | for (let i = 0; i < n_elems; i++) { 95 | let px = 1.0*coords[3*i + 0]; 96 | let py = 1.0*coords[3*i + 1]; 97 | let pz = 1.0*coords[3*i + 2]; 98 | positions.push(px/dimmax - 0.5*extent[0]/dimmax); 99 | positions.push(py/dimmax - 0.5*extent[1]/dimmax); 100 | positions.push(pz/dimmax - 0.5*extent[2]/dimmax); 101 | if (colormode == "mask") { 102 | let color1 = this.convert_value_to_rgb(mask[i]) 103 | colors.push(color1[0]); 104 | colors.push(color1[1]); 105 | colors.push(color1[2]); 106 | } else if (colormode == "direct") { 107 | colors.push(svox.rgb[3*i + 0]); 108 | colors.push(svox.rgb[3*i + 1]); 109 | colors.push(svox.rgb[3*i + 2]); 110 | } else if (colormode == "none") { 111 | colors.push(0.2); 112 | colors.push(0.2); 113 | colors.push(0.2); 114 | } 115 | } 116 | 117 | vao_data.scale = 0.45/dimmax; 118 | vao_data.model_matrix = new THREE.Matrix4(); 119 | let rot = new THREE.Matrix4(); 120 | if (should_rotate) { 121 | rot.makeRotationAxis(new THREE.Vector3(1, 0, 0), -Math.PI*0.5); 122 | vao_data.model_matrix.premultiply(rot); 123 | } 124 | 125 | let cube = Cube.create_cube(); 126 | vao_data.vertices = cube.vertices;`` 127 | vao_data.normals = cube.normals; 128 | vao_data.positions = new Float32Array(positions); 129 | vao_data.colors = new Float32Array(colors); 130 | vao_data.n_vertices = cube.n_vertices; 131 | vao_data.n_instances = n_elems; 132 | 133 | return vao_data; 134 | } 135 | 136 | convert_hsv_to_rgb(hsv) { 137 | let H = hsv[0]; 138 | let S = hsv[1]; 139 | let V = hsv[2]; 140 | 141 | let hd = H/60.0; 142 | let h = Math.floor(hd); 143 | let f = hd - h; 144 | 145 | let p = V*(1.0 - S); 146 | let q = V*(1.0 - S*f); 147 | let t = V*(1.0 - S*(1.0 - f)); 148 | 149 | if (h == 0 || h == 6) 150 | return [V, t, p]; 151 | else if (h == 1) 152 | return [q, V, p]; 153 | else if (h == 2) 154 | return [p, V, t]; 155 | else if (h == 3) 156 | return [p, q, V]; 157 | else if (h == 4) 158 | return [t, p, V]; 159 | else 160 | return [V, p, q]; 161 | } 162 | 163 | convert_value_to_rgb(val, vmin = -0.2, vmax = 1) { 164 | let val0to1 = (val - vmin) / (vmax - vmin); 165 | let x = 1.0 - val0to1; 166 | if (x < 0.0) x = 0.0; 167 | if (x > 1.0) x = 1.0; 168 | return this.convert_hsv_to_rgb([240.0*x, 1.0, 0.5]); 169 | } 170 | 171 | unpack_binary(filename, buffer0) { 172 | let suffix = filename.split('.').pop(); 173 | let vox_files = new Set(["svox", "svox2", "svoxrgb"]); 174 | 175 | if (vox_files.has(suffix) === false) { 176 | console.log("Filetype not known."); 177 | return 0; 178 | } 179 | 180 | let is_col_major = true; 181 | 182 | 183 | let svox = new SVoxData(); 184 | 185 | let offset = 0*4; 186 | 187 | let n_elems = new Int32Array(buffer0, offset, 1)[0]; 188 | svox.n_elems = n_elems; 189 | offset += 1*4; 190 | 191 | 192 | let res = new Float32Array(buffer0, offset, 1)[0]; 193 | svox.res = res; 194 | offset += 1*4; 195 | 196 | 197 | let bbox = new Int32Array(buffer0, offset, 6); 198 | svox.bbox = bbox; 199 | offset += 6*4; 200 | 201 | let grid2world = new Float32Array(buffer0, offset, 16); 202 | svox.grid2world = grid2world; 203 | 204 | console.log(grid2world); 205 | 206 | offset += 16*4; 207 | 208 | svox.coords = new Int32Array(buffer0, offset, n_elems*3); 209 | offset += n_elems*3*4; 210 | 211 | if (buffer0.byteLength > offset) { // <-- svox2 212 | svox.mask = new Float32Array(buffer0, offset, n_elems); 213 | offset += n_elems*4; 214 | } 215 | if (buffer0.byteLength > offset) { // <-- svoxrgb 216 | svox.rgb = new Float32Array(buffer0, offset, n_elems*3); 217 | offset += n_elems*3*4; 218 | } 219 | 220 | return svox; 221 | } 222 | 223 | unpack_proto(filename, res) { 224 | let message = Data3.deserializeBinary(res).getSvox(); 225 | 226 | let svox = new SVoxData(); 227 | 228 | 229 | svox.n_elems = message.getNElems(); 230 | svox.res = message.getRes(); 231 | 232 | svox.bbox = message.getBboxList(); 233 | svox.grid2world = message.getGrid2worldList(); 234 | 235 | 236 | svox.coords = new Int32Array(message.getCoordsList()); 237 | 238 | svox.mask = new Float32Array(message.getMaskList()); 239 | 240 | svox.rgb = new Float32Array(message.getRgbList()); 241 | 242 | return svox; 243 | 244 | } 245 | 246 | load_svox(filename) { 247 | return xhr_arraybuffer("GET", "/download/vox/" + filename).then(res => { 248 | let suffix = filename.split('.').pop(); 249 | let svox = null; 250 | if (suffix === "pb") 251 | svox = this.unpack_proto(filename, res); 252 | else 253 | svox = this.unpack_binary(filename, res); 254 | return {"filename" : filename, "svox" : svox}; 255 | }).catch(err => { 256 | console.log(err); 257 | return {"filename" : filename, "svox" : null}; 258 | }); 259 | } 260 | 261 | 262 | draw() { 263 | this.window0.clear(); 264 | this.window0.advance(0, 16); 265 | this.vao0.draw(this.vao_data0.scale, this.vao_data0.model_matrix, this.window0.camera.matrixWorldInverse, this.window0.projection_matrix); 266 | this.wireframe.draw(this.window0.camera.matrixWorldInverse, this.window0.projection_matrix); 267 | 268 | let pos_mouse = this.window0.get_pos_mouse(); 269 | } 270 | 271 | } 272 | 273 | export default VoxRenderer; 274 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/SceneRenderer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import csvparse from 'csv-parse'; 5 | 6 | import RootUI from './view/RootUI'; 7 | import MeshOptionsUI from './view/MeshOptionsUI'; 8 | 9 | import * as THREE from 'three/build/three'; 10 | window.THREE = THREE; 11 | import * as d3 from 'd3/build/d3'; 12 | 13 | import * as PolygonInstanceGLSL from '../../lib/shader/PolygonInstanceGLSL' 14 | import PickVisibleVertex from "../../lib/vao/PickVisibleVertex"; 15 | import WindowManager from "../Common/WindowManager" 16 | import SceneModel from "../../lib/vao/SceneModel" 17 | import OBJModel from "../../lib/vao/OBJModel" 18 | import Wireframe from "../../lib/vao/Wireframe" 19 | 20 | 21 | class SceneRenderer { 22 | 23 | init(window0, filename) { 24 | //this.model_loader = new ModelLoader(); 25 | this.window0 = window0; 26 | this.models = []; 27 | 28 | 29 | this.pvv = new PickVisibleVertex(); 30 | this.pvv.init(this.window0.gl, this.window0.window_width, this.window0.window_height); 31 | this.pvv.set_active(); 32 | this.M_global = new THREE.Matrix4(); 33 | 34 | this.geometric_centers = []; 35 | 36 | return xhr_json("GET", "/download/json/" + filename).then(res => { 37 | let trs_global = this.parse_trs(res["trs_global"]["trans"], res["trs_global"]["rot"], res["trs_global"]["scale"]); 38 | let t0 = new THREE.Matrix4(); 39 | let r0 = new THREE.Matrix4(); 40 | let s0 = new THREE.Matrix4(); 41 | 42 | t0.makeTranslation(trs_global.trans.x, trs_global.trans.y, trs_global.trans.z); 43 | r0.makeRotationFromQuaternion(trs_global.rot); 44 | s0.makeScale(trs_global.scale.x, trs_global.scale.y, trs_global.scale.z); 45 | 46 | let M_global = new THREE.Matrix4(); 47 | M_global.premultiply(s0); 48 | M_global.premultiply(r0); 49 | M_global.premultiply(t0); 50 | 51 | let asyncs = []; 52 | for (let [i,mesh] of Object.entries(res["meshes"])) { 53 | let filename = mesh["filename"]; 54 | 55 | let trs = this.parse_trs(mesh["trs"]["trans"], mesh["trs"]["rot"], mesh["trs"]["scale"]); 56 | let color = null; 57 | if ("color" in mesh) 58 | color = mesh["color"]; 59 | 60 | let a = this.load_mesh(filename).then(obj => { 61 | 62 | obj.scale_matrix.makeScale(trs.scale.x, trs.scale.y, trs.scale.z); 63 | obj.rotation_matrix.makeRotationFromQuaternion(trs.rot); 64 | obj.translation_matrix.makeTranslation(trs.trans.x, trs.trans.y, trs.trans.z); 65 | obj.calc_model_matrix(); 66 | 67 | if (color) { 68 | let factor = (color[0] % 1 === 0) ? 1.0/255.0 : 1.0; 69 | for (let j = 0; j < obj.color_buffer.length/3; j++) { 70 | obj.color_buffer[j*3 + 0] = color[0]*factor; 71 | obj.color_buffer[j*3 + 1] = color[1]*factor; 72 | obj.color_buffer[j*3 + 2] = color[2]*factor; 73 | } 74 | obj.upload_all_buffers(); 75 | } 76 | 77 | this.correct_mesh_trs(obj, M_global); 78 | 79 | let c = obj.bbox_center.applyMatrix4(obj.model_matrix); 80 | this.geometric_centers.push(c); 81 | 82 | let label_buffer = new Int32Array(obj.position_buffer.length/3); 83 | label_buffer.fill(i + 1) 84 | 85 | this.models.push(obj); 86 | 87 | //let wireframe = new Wireframe(); 88 | //wireframe.init(this.window0.gl); 89 | //wireframe.is_visible = 1; 90 | //wireframe.update_box(obj.bounding_box.x, obj.bounding_box.y, obj.bounding_box.z); 91 | //wireframe.model_matrix = obj.model_matrix; 92 | //this.models.push(wireframe); 93 | }); 94 | asyncs.push(a); 95 | } 96 | 97 | Promise.all(asyncs).then(reses => { 98 | let c = new THREE.Vector3(0,0,0); 99 | for (let i in this.geometric_centers) { 100 | c.add(this.geometric_centers[i]); 101 | } 102 | 103 | c.multiplyScalar(-1.0/this.geometric_centers.length); 104 | let C = new THREE.Matrix4(); 105 | C.makeTranslation(c.x, c.y, c.z); 106 | //C.premultiply(M_global); 107 | //M_global.multiply(C); 108 | this.M_global = C.clone(); 109 | 110 | for (let i in this.models) { 111 | this.correct_mesh_trs(this.models[i], C); 112 | } 113 | }); 114 | 115 | }); 116 | 117 | } 118 | correct_mesh_trs(model, M_global) { 119 | let model_matrix = model.model_matrix; 120 | model_matrix.premultiply(M_global); 121 | let t = new THREE.Vector3(); let q = new THREE.Quaternion(); let s = new THREE.Vector3(); 122 | model_matrix.decompose(t, q, s); 123 | 124 | let trans = (new THREE.Matrix4()).makeTranslation(t.x, t.y, t.z); 125 | let rot = (new THREE.Matrix4()).makeRotationFromQuaternion(q); 126 | let scale = (new THREE.Matrix4()).makeScale(s.x, s.y, s.z); 127 | 128 | model.translation_matrix = trans; 129 | model.rotation_matrix = rot; 130 | model.scale_matrix = scale; 131 | model.calc_model_matrix(); 132 | } 133 | 134 | parse_trs(trans0, rot0, scale0) { 135 | let scale = new THREE.Vector3().fromArray(scale0.slice(0)); 136 | rot0 = [rot0[1], rot0[2], rot0[3], rot0[0]]; 137 | let rot = new THREE.Quaternion().fromArray(rot0.slice(0)).normalize(); 138 | 139 | let trans = new THREE.Vector3().fromArray(trans0.slice(0)); 140 | return {"trans" : trans, "rot" : rot, "scale" : scale}; 141 | } 142 | 143 | load_mesh(filename, trs) { 144 | return new Promise((resolve, reject) => { 145 | if (filename.endsWith("obj")) { 146 | let obj = new OBJModel(); 147 | obj.init(this.window0.gl); 148 | 149 | obj.load(filename).then( res => { 150 | resolve(obj); 151 | }); 152 | } else if (filename.endsWith("ply")) { 153 | let ply = new SceneModel(); 154 | ply.init(this.window0.gl); 155 | 156 | ply.load(filename).then( res => { 157 | resolve(ply); 158 | }); 159 | 160 | } 161 | }); 162 | } 163 | 164 | load_scene(id_scene) { 165 | return new Promise((resolve, reject) => { 166 | let scene = new SceneModel(); 167 | scene.init(this.window0.gl); 168 | 169 | scene.load_scene("scannet", id_scene).then( res => { 170 | resolve(scene); 171 | }); 172 | }); 173 | } 174 | 175 | static basename(str) { 176 | let base = new String(str).substring(str.lastIndexOf('/') + 1); 177 | if(base.lastIndexOf(".") != -1) 178 | base = base.substring(0, base.lastIndexOf(".")); 179 | return base; 180 | } 181 | 182 | 183 | draw() { 184 | this.window0.clear(); 185 | this.window0.advance(0, 16); 186 | for (let i in this.models) { 187 | this.models[i].draw(this.window0.camera.matrixWorldInverse, this.window0.projection_matrix); 188 | } 189 | 190 | let tmp = this.M_global.clone(); 191 | let t = new THREE.Vector3(); let q = new THREE.Quaternion(); let s = new THREE.Vector3(); 192 | tmp.decompose(t, q, s); 193 | t.multiplyScalar(-1); 194 | let cam_pos = this.window0.camera.position.clone().add(t); 195 | //let cam_target = this.window0.navigation.target.clone().applyMatrix4(tmp); 196 | let cam_target = this.window0.navigation.target.clone().add(t); 197 | 198 | 199 | //console.log("cam-pos:",[cam_pos.x, cam_pos.y, cam_pos.z], "cam-target:",[cam_target.x, cam_target.y, cam_target.z]); 200 | 201 | //let pos_mouse = this.window0.get_pos_mouse(); 202 | } 203 | 204 | } 205 | 206 | export default SceneRenderer; 207 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/Viewer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import csvparse from 'csv-parse'; 5 | import plotly from 'plotly.js/lib/core'; 6 | plotly.register([ 7 | require('plotly.js/lib/histogram'), 8 | ]); 9 | 10 | import {RootUI, ImgUI} from './view/RootUI'; 11 | import BrowseUI from './view/BrowseUI'; 12 | import MeshOptionsUI from './view/MeshOptionsUI'; 13 | import MetadataUI from './view/MetadataUI'; 14 | 15 | import * as THREE from 'three/build/three'; 16 | window.THREE = THREE; 17 | import * as d3 from 'd3/build/d3'; 18 | 19 | import * as PolygonInstanceGLSL from '../../lib/shader/PolygonInstanceGLSL' 20 | import WindowManager from "../Common/WindowManager" 21 | import VoxelGridVAO from "../../lib/vao/VoxelGrid" 22 | import * as Cube from "../../lib/geometry/Cube" 23 | import SceneModel from "../../lib/vao/SceneModel" 24 | import OBJModel from "../../lib/vao/OBJModel" 25 | import Wireframe from "../../lib/vao/Wireframe" 26 | import SceneRenderer from "./SceneRenderer" 27 | import VoxRenderer from "./VoxRenderer" 28 | import SVoxRenderer from "./SVoxRenderer" 29 | import MeshRenderer from "./MeshRenderer" 30 | import WireframeRenderer from "./WireframeRenderer" 31 | 32 | import {Data3} from "../../lib/proto/data3_pb.js" 33 | 34 | 35 | 36 | class Viewer { 37 | 38 | init(filename) { 39 | this.suffix = filename.split('.').pop(); 40 | console.log("suffix", this.suffix); 41 | this.dtype = ""; 42 | 43 | let pb = new Set(["pb"]); // <-- protobuf 44 | let vox_files = new Set(["vox", "vox2", "df", "sdf", "voxnoc", "voxsis"]); 45 | let svox_files = new Set(["svox", "svox2", "svoxrgb"]); 46 | let mesh_files = new Set(["obj", "ply"]); 47 | let scene_files = new Set(["json"]); 48 | let wireframe_files = new Set(["wrf"]); 49 | let image_files = new Set(["jpg", "jpeg", "png", "gif"]); 50 | 51 | // -> check if packed up (.pb, .zip, .hd5, etc) 52 | let check_container = new Promise((resolve, reject) => { 53 | if (pb.has(this.suffix)) { 54 | let dtype = this.peek_type_from_protobuf(filename); 55 | resolve(dtype); 56 | } else { 57 | resolve(this.suffix); 58 | } 59 | }); 60 | // <- 61 | 62 | 63 | Promise.all([check_container]).then(reses => { 64 | this.dtype = reses[0]; 65 | console.log("all", this.dtype); 66 | if (vox_files.has(this.dtype)) 67 | this.load_and_render_vox(filename); 68 | else if (svox_files.has(this.dtype)) 69 | this.load_and_render_svox(filename); 70 | else if (wireframe_files.has(this.dtype)) 71 | this.load_and_render_wireframe(filename); 72 | else if (mesh_files.has(this.dtype)) 73 | this.load_and_render_mesh(filename); 74 | else if (image_files.has(this.dtype)) 75 | this.load_and_draw_image(filename); 76 | else if (scene_files.has(this.dtype)) 77 | this.load_and_render_scene(filename); 78 | else 79 | console.log("filetype not accepted"); 80 | }) 81 | } 82 | 83 | peek_type_from_protobuf(filename) { 84 | return new Promise((resolve, reject) => { 85 | xhr_arraybuffer("GET", "/download/vox/" + filename).then(res => { 86 | let message = Data3.deserializeBinary(res); 87 | 88 | if (message.hasSvox()) { 89 | resolve("svox"); 90 | } else if (message.hasVox()) { 91 | resolve("vox"); 92 | } 93 | }); 94 | }); 95 | } 96 | 97 | 98 | load_and_render_scene(filename) { 99 | 100 | this.draw_root(true); 101 | 102 | this.window0 = new WindowManager("id_div_panel", "id_div_canvas"); 103 | this.window0.init(); 104 | this.attach_listener(this.window0); 105 | this.advance_ref = this.advance.bind(this); 106 | 107 | this.renderer = new SceneRenderer(); 108 | this.renderer.init(this.window0, filename).then(res => { 109 | console.log("all loaded"); 110 | this.advance(); 111 | }); 112 | } 113 | 114 | load_and_render_mesh(filename) { 115 | this.draw_root(true); 116 | 117 | this.window0 = new WindowManager("id_div_panel", "id_div_canvas"); 118 | this.window0.init(); 119 | this.attach_listener(this.window0); 120 | this.advance_ref = this.advance.bind(this); 121 | 122 | this.renderer = new MeshRenderer(); 123 | this.renderer.init(this.window0, filename).then(res => { 124 | this.advance(); 125 | }); 126 | } 127 | 128 | load_and_render_wireframe(filename) { 129 | this.draw_root(true); 130 | 131 | this.window0 = new WindowManager("id_div_panel", "id_div_canvas"); 132 | this.window0.init(); 133 | this.attach_listener(this.window0); 134 | this.advance_ref = this.advance.bind(this); 135 | 136 | this.renderer = new WireframeRenderer(); 137 | this.renderer.init(this.window0, filename).then(res => { 138 | this.advance(); 139 | }); 140 | } 141 | 142 | load_and_render_svox(filename) { 143 | this.draw_root(true); 144 | 145 | this.window0 = new WindowManager("id_div_panel", "id_div_canvas"); 146 | this.window0.init(); 147 | this.attach_listener(this.window0); 148 | this.advance_ref = this.advance.bind(this); 149 | 150 | this.renderer = new SVoxRenderer(); 151 | this.renderer.init(this.window0, filename).then(res => { 152 | this.advance(); 153 | }); 154 | } 155 | 156 | load_and_render_vox(filename) { 157 | this.draw_root(true); 158 | 159 | this.window0 = new WindowManager("id_div_panel", "id_div_canvas"); 160 | this.window0.init(); 161 | this.attach_listener(this.window0); 162 | this.advance_ref = this.advance.bind(this); 163 | 164 | this.renderer = new VoxRenderer(); 165 | this.renderer.init(this.window0, filename).then(res => { 166 | this.advance(); 167 | }); 168 | } 169 | 170 | 171 | load_and_draw_image(filename) { 172 | this.draw_root(false); 173 | ReactDOM.render(, document.getElementById('id_div_pic')); 174 | } 175 | 176 | advance() { 177 | this.window0.clear(); 178 | this.window0.advance(0, 16); 179 | this.renderer.draw(); 180 | requestAnimationFrame(this.advance_ref); 181 | } 182 | 183 | draw_root(is_webgl) { 184 | ReactDOM.render(, document.getElementById('id_div_root')); 185 | } 186 | 187 | 188 | touchstart ( event ) { 189 | this.window0.touchstart(event); 190 | } 191 | 192 | touchmove ( event ) { 193 | this.window0.touchmove(event); 194 | } 195 | 196 | touchend( event ) { 197 | this.window0.touchend(event); 198 | } 199 | 200 | mousedown ( event ) { 201 | this.window0.mousedown(event); 202 | } 203 | 204 | mousemove ( event ) { 205 | this.window0.mousemove(event); 206 | } 207 | 208 | mouseup( event ) { 209 | this.window0.mouseup(event); 210 | } 211 | 212 | mousewheel ( event ) { 213 | this.window0.navigation.mousewheel(event); 214 | } 215 | 216 | contextmenu( event ) { 217 | this.window0.navigation.contextmenu(event); 218 | } 219 | 220 | attach_listener(window) { 221 | // -> event listeners 222 | this.contextmenu_ref = this.contextmenu.bind(this); 223 | this.mousedown_ref = this.mousedown.bind(this); 224 | this.mousemove_ref = this.mousemove.bind(this); 225 | this.mouseup_ref = this.mouseup.bind(this); 226 | this.touchstart_ref = this.touchstart.bind(this); 227 | this.touchmove_ref = this.touchmove.bind(this); 228 | this.touchend_ref = this.touchend.bind(this); 229 | this.mousewheel_ref = this.mousewheel.bind(this); 230 | 231 | window.add_listener('contextmenu', this.contextmenu_ref); 232 | window.add_listener('mousedown', this.mousedown_ref); 233 | window.add_listener('mousemove', this.mousemove_ref); 234 | window.add_listener('mouseup', this.mouseup_ref); 235 | window.add_listener('touchstart', this.touchstart_ref); 236 | window.add_listener('touchmove', this.touchmove_ref); 237 | window.add_listener('touchend', this.touchend_ref); 238 | window.add_listener('mousewheel', this.mousewheel_ref); 239 | // <- 240 | } 241 | 242 | dispose_listener(window) { 243 | window.remove_listener( "contextmenu", this.contextmenu_ref); 244 | window.remove_listener( "mousemove", this.mousemove_ref); 245 | window.remove_listener( "mousedown", this.mousedown_ref); 246 | window.remove_listener( "mouseup", this.mouseup_ref); 247 | window.remove_listener( "mousewheel", this.mousewheel_ref); 248 | } 249 | 250 | } 251 | 252 | window.Viewer = Viewer; 253 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/VoxRenderer.js: -------------------------------------------------------------------------------- 1 | 2 | import * as THREE from 'three/build/three'; 3 | window.THREE = THREE; 4 | 5 | import * as PolygonInstanceGLSL from '../../lib/shader/PolygonInstanceGLSL' 6 | import WindowManager from "../Common/WindowManager" 7 | import VoxelGridVAO from "../../lib/vao/VoxelGrid" 8 | import * as Cube from "../../lib/geometry/Cube" 9 | import Wireframe from "../../lib/vao/Wireframe" 10 | 11 | class VoxData { 12 | constructor() { 13 | this.dims = [0, 0, 0]; 14 | this.res = 0; 15 | this.grid2world = null; 16 | this.sdf = null; 17 | this.pdf = null; 18 | 19 | this.nocx = null; 20 | this.nocy = null; 21 | this.nocz = null; 22 | } 23 | } 24 | 25 | class VAOData { 26 | constructor() { 27 | this.scale = 0; 28 | this.model_matrix = null; 29 | 30 | this.vertices = null; 31 | this.normals = null; 32 | this.positions = null; 33 | this.colors = null; 34 | this.n_vertices = 0; 35 | this.n_instances = 0; 36 | } 37 | } 38 | 39 | class VoxRenderer { 40 | 41 | init(window0, filename) { 42 | this.vox = new VoxData(); 43 | this.vao0 = new VoxelGridVAO(); 44 | this.vao_data0 = new VAOData(); 45 | this.window0 = window0; 46 | this.wireframe = new Wireframe(); 47 | 48 | 49 | this.vao0.init(this.window0.gl); 50 | 51 | return this.load_vox(filename).then(res => { 52 | this.vox0 = res["vox"]; 53 | 54 | this.suffix = filename.split('.').pop(); 55 | let colormode = "none"; 56 | 57 | if (this.suffix == "vox2") 58 | colormode = "pdf"; 59 | else if (this.suffix == "voxnoc") 60 | colormode = "noc"; 61 | 62 | 63 | this.vao_data0 = this.create_vao_data(this.vox0, colormode) 64 | this.vao0.upload_data(this.vao_data0.n_vertices, this.vao_data0.n_instances, this.vao_data0.vertices, this.vao_data0.normals, this.vao_data0.positions, this.vao_data0.colors); 65 | this.vao0.set_active(); 66 | 67 | this.wireframe.init(this.window0.gl); 68 | let dims = this.vox0.dims; 69 | let dimmax = Math.max(Math.max(dims[0], dims[1]), dims[2]); 70 | this.wireframe.update_box(0.5*dims[0]/dimmax, 0.5*dims[1]/dimmax, 0.5*dims[2]/dimmax); 71 | this.wireframe.is_visible = 1; 72 | }); 73 | } 74 | create_vao_data(vox, colormode="none", should_rotate=false, only_surface=false) { 75 | let vao_data = new VAOData(); 76 | 77 | let dims = vox.dims; 78 | let res = vox.res; 79 | let sdf = vox.sdf; 80 | let pdf = vox.pdf; 81 | 82 | let dimmax = Math.max(Math.max(dims[0], dims[1]), dims[2]); 83 | 84 | let positions = [] 85 | let colors = [] 86 | let n_size = 0; 87 | for (let k = 0; k < dims[2]; k++) { 88 | for (let j = 0; j < dims[1]; j++) { 89 | for (let i = 0; i < dims[0]; i++) { 90 | let index1 = k*dims[1]*dims[0] + j*dims[0] + i; 91 | if (Math.abs(sdf[index1]) <= 2.0*res) { 92 | positions.push(i/dimmax - 0.5*dims[0]/dimmax); 93 | positions.push(j/dimmax - 0.5*dims[1]/dimmax); 94 | positions.push(k/dimmax - 0.5*dims[2]/dimmax); 95 | if (colormode == "pdf") { 96 | let color1 = this.convert_value_to_rgb(pdf[index1]) 97 | colors.push(color1[0]); 98 | colors.push(color1[1]); 99 | colors.push(color1[2]); 100 | } else if (colormode == "noc") { 101 | colors.push(vox.nocx[index1]); 102 | colors.push(vox.nocy[index1]); 103 | colors.push(vox.nocz[index1]); 104 | } else if (colormode == "bbox") { 105 | let color1 = this.convert_value_to_rgb(vox.bbox[index1]) 106 | colors.push(color1[0]); 107 | colors.push(color1[1]); 108 | colors.push(color1[2]); 109 | } else if (colormode == "none") { 110 | colors.push(0.2); 111 | colors.push(0.2); 112 | colors.push(0.2); 113 | } 114 | n_size++; 115 | } 116 | } 117 | } 118 | } 119 | 120 | vao_data.scale = 0.45/dimmax; 121 | vao_data.model_matrix = new THREE.Matrix4(); 122 | let rot = new THREE.Matrix4(); 123 | if (should_rotate) { 124 | rot.makeRotationAxis(new THREE.Vector3(1, 0, 0), -Math.PI*0.5); 125 | vao_data.model_matrix.premultiply(rot); 126 | } 127 | 128 | let cube = Cube.create_cube(); 129 | vao_data.vertices = cube.vertices;`` 130 | vao_data.normals = cube.normals; 131 | vao_data.positions = new Float32Array(positions); 132 | vao_data.colors = new Float32Array(colors); 133 | vao_data.n_vertices = cube.n_vertices; 134 | vao_data.n_instances = n_size; 135 | 136 | return vao_data; 137 | } 138 | 139 | convert_hsv_to_rgb(hsv) { 140 | let H = hsv[0]; 141 | let S = hsv[1]; 142 | let V = hsv[2]; 143 | 144 | let hd = H/60.0; 145 | let h = Math.floor(hd); 146 | let f = hd - h; 147 | 148 | let p = V*(1.0 - S); 149 | let q = V*(1.0 - S*f); 150 | let t = V*(1.0 - S*(1.0 - f)); 151 | 152 | if (h == 0 || h == 6) 153 | return [V, t, p]; 154 | else if (h == 1) 155 | return [q, V, p]; 156 | else if (h == 2) 157 | return [p, V, t]; 158 | else if (h == 3) 159 | return [p, q, V]; 160 | else if (h == 4) 161 | return [t, p, V]; 162 | else 163 | return [V, p, q]; 164 | } 165 | 166 | convert_value_to_rgb(val, vmin = -0.2, vmax = 1) { 167 | let val0to1 = (val - vmin) / (vmax - vmin); 168 | let x = 1.0 - val0to1; 169 | if (x < 0.0) x = 0.0; 170 | if (x > 1.0) x = 1.0; 171 | return this.convert_hsv_to_rgb([240.0*x, 1.0, 0.5]); 172 | } 173 | 174 | unpack_binary(filename, buffer0) { 175 | let suffix = filename.split('.').pop(); 176 | let vox_files = new Set(["vox", "vox2", "df", "sdf", "voxnoc", "voxsis"]); 177 | 178 | if (vox_files.has(this.suffix) === false) { 179 | console.log("Filetype not known."); 180 | return 0; 181 | } 182 | 183 | let is_col_major = true; 184 | 185 | if (suffix == "df") 186 | is_col_major = false; 187 | else if (suffix == "sdf") 188 | is_col_major = false; 189 | 190 | let vox = new VoxData(); 191 | 192 | let dims = new Int32Array(buffer0, 0*4, 3); 193 | vox.dims = [dims[0], dims[1], dims[2]] 194 | let res = new Float32Array(buffer0, 3*4, 1); 195 | vox.res = res; 196 | let grid2world = new Float32Array(buffer0, 4*4, 16); 197 | vox.grid2world 198 | 199 | let offset = (4 + 16)*4; 200 | 201 | const n_elems = dims[0]*dims[1]*dims[2]; 202 | console.log("dims", vox.dims, dims, n_elems); 203 | vox.sdf = new Float32Array(buffer0, offset, n_elems); 204 | offset += n_elems*4; 205 | 206 | if (buffer0.byteLength > offset) { // <-- vox2 207 | vox.pdf = new Float32Array(buffer0, offset, n_elems); 208 | offset += n_elems*4; 209 | } 210 | if (buffer0.byteLength > offset) { // <-- voxnoc 211 | vox.nocx = new Float32Array(buffer0, offset, n_elems); 212 | offset += n_elems*4; 213 | vox.nocy = new Float32Array(buffer0, offset, n_elems); 214 | offset += n_elems*4; 215 | vox.nocz = new Float32Array(buffer0, offset, n_elems); 216 | offset += n_elems*4; 217 | } 218 | if (buffer0.byteLength > offset) { // <-- voxnoc 219 | vox.bbox = new Float32Array(buffer0, offset, n_elems); 220 | offset += n_elems*4; 221 | } 222 | 223 | return vox; 224 | } 225 | 226 | 227 | load_vox(filename) { 228 | this.suffix = filename.split('.').pop(); 229 | 230 | return xhr_arraybuffer("GET", "/download/vox/" + filename).then(res => { 231 | let vox = this.unpack_binary(filename, res); 232 | return {"filename" : filename, "vox" : vox}; 233 | }).catch(err => { 234 | return {"filename" : filename, "vox" : null}; 235 | }); 236 | } 237 | 238 | 239 | draw() { 240 | this.window0.clear(); 241 | this.window0.advance(0, 16); 242 | this.vao0.draw(this.vao_data0.scale, this.vao_data0.model_matrix, this.window0.camera.matrixWorldInverse, this.window0.projection_matrix); 243 | this.wireframe.draw(this.window0.camera.matrixWorldInverse, this.window0.projection_matrix); 244 | 245 | let pos_mouse = this.window0.get_pos_mouse(); 246 | } 247 | 248 | } 249 | 250 | export default VoxRenderer; 251 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/WireframeRenderer.js: -------------------------------------------------------------------------------- 1 | 2 | import * as THREE from 'three/build/three'; 3 | window.THREE = THREE; 4 | 5 | import WindowManager from "../Common/WindowManager" 6 | import WireframeVAO from "../../lib/vao/ThickWireframe" 7 | 8 | class WireframeData { 9 | constructor() { 10 | this.n_verts = 0; 11 | this.n_edges = 0; 12 | this.verts = null; 13 | this.edges = null; 14 | } 15 | } 16 | 17 | 18 | class ThickWireframe { 19 | 20 | init(window0, filename) { 21 | this.vao = new WireframeVAO(); 22 | this.window0 = window0; 23 | 24 | this.vao.init(this.window0.gl); 25 | 26 | return this.load_wrf(filename).then(res => { 27 | console.log(res); 28 | let mesh_data = this.vao.edges2mesh(res["data"]); 29 | //let colors = []; 30 | //for (let i = 0; i < mesh_data.n_verts; i++) { 31 | // colors.push(Math.random()); 32 | // colors.push(Math.random()); 33 | // colors.push(Math.random()); 34 | //} 35 | //mesh_data["colors"] = new Float32Array(colors); 36 | 37 | let c = this.calculate_center(res["data"]["verts"]); 38 | this.vao.translation_matrix.makeTranslation(-c.x, -c.y, -c.z); 39 | this.vao.calc_model_matrix(); 40 | 41 | this.vao.upload_data(mesh_data); 42 | 43 | this.vao.is_visible = 1; 44 | }); 45 | } 46 | 47 | calculate_center(verts) { 48 | let min_x = Infinity; 49 | let min_y = Infinity; 50 | let min_z = Infinity; 51 | 52 | let max_x = -Infinity; 53 | let max_y = -Infinity; 54 | let max_z = -Infinity; 55 | 56 | let n = verts.length/3; 57 | for (let i = 0; i < n; i++) { 58 | min_x = Math.min(min_x, verts[i][0]); 59 | min_y = Math.min(min_y, verts[i][1]); 60 | min_z = Math.min(min_z, verts[i][2]); 61 | 62 | max_x = Math.max(max_x, verts[i][0]); 63 | max_y = Math.max(max_y, verts[i][1]); 64 | max_z = Math.max(max_z, verts[i][2]); 65 | } 66 | 67 | 68 | let center_x = (min_x + max_x)/2.0; 69 | let center_y = (min_y + max_y)/2.0; 70 | let center_z = (min_z + max_z)/2.0; 71 | 72 | return new THREE.Vector3(center_x, center_y, center_z); 73 | } 74 | 75 | 76 | parse_wrf(filename, buffer) { 77 | let suffix = filename.split('.').pop(); 78 | let accepted_files = new Set(["wrf"]); 79 | 80 | if (accepted_files.has(this.suffix) === false) { 81 | console.log("Filetype not known."); 82 | return 0; 83 | } 84 | 85 | 86 | let wrf = new WireframeData(); 87 | 88 | let lines = buffer.split("\n"); 89 | // -> parse 90 | let n_verts = parseInt(lines.shift()); 91 | wrf.verts = lines.slice(0, n_verts).reduce(function(prev, curr) { 92 | return prev.concat([curr.split(' ').map(parseFloat)]); 93 | }, []); 94 | 95 | let n_edges = parseInt(lines[n_verts]); 96 | wrf.edges = lines.slice(n_verts + 1, -1).reduce(function(prev, curr) { 97 | return prev.concat([curr.split(' ').map(Number)]); 98 | }, []); 99 | wrf.n_verts = n_verts; 100 | wrf.n_edges = n_edges; 101 | return wrf; 102 | // <- 103 | } 104 | 105 | 106 | load_wrf(filename) { 107 | this.suffix = filename.split('.').pop(); 108 | 109 | return xhr("GET", "/download/mesh/" + filename).then(res => { 110 | let data = this.parse_wrf(filename, res); 111 | return {"filename" : filename, "data" : data}; 112 | }).catch(err => { 113 | return {"filename" : filename, "data" : null}; 114 | }); 115 | } 116 | 117 | 118 | draw() { 119 | this.window0.clear(); 120 | this.window0.advance(0, 16); 121 | this.vao.draw(this.vao.model_matrix, this.window0.camera.matrixWorldInverse, this.window0.projection_matrix); 122 | 123 | } 124 | 125 | } 126 | 127 | export default ThickWireframe 128 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/view/BrowseUI.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | class BrowseUI extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | 8 | render() { 9 | return ( 10 |
11 | 12 | 13 |
14 | ); 15 | } 16 | } 17 | 18 | 19 | export default BrowseUI; 20 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/view/MeshOptionsUI.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | class MeshOptionsUI extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | this.state = {is_checked_thresh : false}; 7 | } 8 | 9 | render() { 10 | return ( 11 | 13 | ); 14 | } 15 | 16 | toggle_thresh(nextProps) { 17 | this.setState({is_checked_thresh : !this.state.is_checked_thresh}); 18 | } 19 | } 20 | 21 | 22 | export default MeshOptionsUI; 23 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/view/MetadataUI.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | class MetadataUI extends React.Component { 4 | render() { 5 | return ( 6 |
7 | { 8 | this.props.cargo.map(item => { 9 | return this.create_button(item[0] + ": " + item[1]) 10 | }) 11 | } 12 |
13 | ); 14 | } 15 | 16 | create_button(val) { 17 | return 18 | } 19 | } 20 | 21 | 22 | export default MetadataUI; 23 | -------------------------------------------------------------------------------- /client/js/apps/Viewer/view/RootUI.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | class ImgUI extends React.Component { 4 | 5 | render() { 6 | console.log(this.props.src) 7 | 8 | return ( 9 |
10 | 11 |
12 | ); 13 | } 14 | 15 | } 16 | 17 | class RootUI extends React.Component { 18 | 19 | render() { 20 | let content = null; 21 | if (this.props.is_webgl) { 22 | content = (); 23 | } else { 24 | content = (
); 25 | } 26 | 27 | return ( 28 |
29 |
30 | {content}; 31 |
32 |
33 | ); 34 | } 35 | 36 | } 37 | 38 | 39 | export {ImgUI, RootUI}; 40 | -------------------------------------------------------------------------------- /client/js/lib/geometry/Beam.js: -------------------------------------------------------------------------------- 1 | 2 | import * as THREE from 'three/build/three'; 3 | window.THREE = THREE; 4 | import * as math from 'mathjs'; 5 | 6 | function skew_matrix(x) { 7 | return math.matrix([[0, -x[2], x[1]], [x[2], 0, -x[0]], [-x[1], x[0], 0]]); 8 | } 9 | 10 | 11 | export function create_beam(radius, p0, p1, n_sides=6) { 12 | // -> calc rot matrix 13 | let height = math.norm(math.subtract(math.matrix(p0), math.matrix(p1))); 14 | 15 | let a = math.matrix([0,1,0]); 16 | a = math.multiply(1.0/math.norm(a), a); 17 | let b = math.subtract(math.matrix(p1), math.matrix(p0)); 18 | b = math.multiply(1.0/math.norm(b), b); 19 | let v = math.cross(a, b); 20 | let c = math.dot(a,b); 21 | 22 | let ab = math.reshape(math.add(a,b), [3,1]); 23 | let abt = math.reshape(ab.clone(), [1,3]); 24 | let s = math.multiply(abt, ab).valueOf()[0]; 25 | let rot = math.multiply(-1.0, math.identity(3)); 26 | if (s != 0) 27 | rot = math.subtract(math.multiply(2.0/s, math.multiply(ab, abt)), math.identity(3)); 28 | 29 | 30 | let center = p0; 31 | 32 | let trs = (x,y,z) => math.add(math.multiply(rot, math.matrix([x,y,z])), center).valueOf(); 33 | let fix_normal = (x,y,z) => math.multiply(rot, math.matrix([x,y,z])).valueOf(); 34 | 35 | var index = 0; 36 | 37 | 38 | var offsetY = 0; 39 | 40 | let vertices = []; 41 | let normals = []; 42 | let faces = []; 43 | 44 | let index_bottom = n_sides*2 + 0; 45 | let index_top = n_sides*2 + 1; 46 | let p = null; 47 | for(var j=0; j < 2; j++) { 48 | for(var i = 0; i < n_sides; i++) { 49 | var r = radius; 50 | var y = offsetY + height *j; 51 | var x = r * Math.cos(i/n_sides * Math.PI * 2); 52 | var z = r * Math.sin(i/n_sides * Math.PI * 2); 53 | 54 | vertices.push(trs(x,y,z)); 55 | normals.push(fix_normal(x, 0, z)); 56 | if (j == 0) { 57 | faces.push([ index, (index + 1) % n_sides, (index + 1)%n_sides + n_sides]) 58 | faces.push([ index, index + n_sides, (index + 1)%n_sides + n_sides]) 59 | } 60 | if (j == 0) { 61 | faces.push([ index, (index + 1)%n_sides, index_bottom]) 62 | faces.push([ index + n_sides, (index + 1)%n_sides + n_sides, index_top]) 63 | } 64 | 65 | index++; 66 | } 67 | } 68 | 69 | 70 | vertices.push(trs(0, 0, 0)); 71 | normals.push(fix_normal(0, -1, 0)); 72 | 73 | vertices.push(trs(0, height, 0)); 74 | normals.push(fix_normal(0, 1, 0)); 75 | 76 | 77 | return {vertices : vertices, normals : normals, faces : faces} 78 | } 79 | 80 | export function create_beam_polygon_on_3dplane(radius, p0, p1, n_sides=6) { 81 | // -> calc rot matrix 82 | let distance = math.norm(math.subtract(math.matrix(p1), math.matrix(p0))); 83 | let normal0 = math.multiply(1.0/distance, math.subtract(math.matrix(p0), math.matrix(p1))).valueOf(); 84 | let normal1 = math.multiply(1.0/distance, math.subtract(math.matrix(p1), math.matrix(p0))).valueOf(); 85 | 86 | //let argmax = normal.reduce((i_max, x, i, arr) => Math.abs(x) > Math.abs(arr[i_max]) ? i : i_max, 0); 87 | //let a = normal.slice(); 88 | //[a[argmax], a[(argmax + 1)%3]] = [a[(argmax + 1)%3], a[argmax]]; 89 | //a = math.matrix(a) 90 | //let b = math.cross(normal, a); 91 | 92 | //let d0 = -math.dot(normal0, p0); // <-- plane equation 93 | //let d1 = -math.dot(normal1, p1); // <-- plane equation 94 | 95 | let project_to_3dplane = (x, y, n, d=0) => { 96 | let k = -(n[0]*x + n[1]*y + d)/math.dot(n, n); 97 | return [x + n[0]*k, y + k*n[1], k*n[2]]; 98 | }; 99 | 100 | let vertices = []; 101 | let normals = []; 102 | let faces = []; 103 | 104 | let index = 0; 105 | let index_bottom = n_sides*2 + 0; 106 | let index_top = n_sides*2 + 1; 107 | for(let j = 0; j < 2; j++) { 108 | for(let i = 0; i < n_sides; i++) { 109 | let r = radius; 110 | let x = r * Math.cos(i/n_sides * Math.PI * 2); 111 | let y = r * Math.sin(i/n_sides * Math.PI * 2); 112 | 113 | let p = null; 114 | let n = null; 115 | if (j == 0) { 116 | p = p0; 117 | n = normal0; 118 | } else if (j == 1) { 119 | p = p1; 120 | n = normal1; 121 | } 122 | 123 | let v = math.add(project_to_3dplane(x, y, n), p).valueOf(); 124 | 125 | vertices.push(v); 126 | normals.push(n); 127 | 128 | if (j == 0) { 129 | faces.push([ index, (index + 1) % n_sides, (index + 1)%n_sides + n_sides]) 130 | faces.push([ index, index + n_sides, (index + 1)%n_sides + n_sides]) 131 | 132 | //faces.push([ index, (index + 1)%n_sides, index_bottom]) 133 | //faces.push([ index + n_sides, (index + 1)%n_sides + n_sides, index_top]) 134 | } 135 | 136 | index++; 137 | } 138 | } 139 | 140 | 141 | //vertices.push(trs(0, 0, 0)); 142 | //normals.push(fix_normal(0, -1, 0)); 143 | // 144 | //vertices.push(trs(0, height, 0)); 145 | //normals.push(fix_normal(0, 1, 0)); 146 | 147 | 148 | return {vertices : vertices, normals : normals, faces : faces} 149 | } 150 | -------------------------------------------------------------------------------- /client/js/lib/geometry/Cube.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | export function create_cube() { 4 | const vertices = new Float32Array([ 5 | -1.0,-1.0,-1.0, -1.0,-1.0, 1.0, -1.0, 1.0, 1.0, // Left Side 6 | -1.0,-1.0,-1.0, -1.0, 1.0, 1.0, -1.0, 1.0,-1.0, // Left Side 7 | 1.0, 1.0,-1.0, -1.0,-1.0,-1.0, -1.0, 1.0,-1.0, // Back Side 8 | 1.0, 1.0,-1.0, 1.0,-1.0,-1.0, -1.0,-1.0,-1.0, // Back Side 9 | 1.0,-1.0, 1.0, -1.0,-1.0,-1.0, 1.0,-1.0,-1.0, // Bottom Side 10 | 1.0,-1.0, 1.0, -1.0,-1.0, 1.0, -1.0,-1.0,-1.0, // Bottom Side 11 | -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, // Front Side 12 | 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0,-1.0, 1.0, // Front Side 13 | 1.0, 1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0, // Right Side 14 | 1.0,-1.0,-1.0, 1.0, 1.0, 1.0, 1.0,-1.0, 1.0, // Right Side 15 | 1.0, 1.0, 1.0, 1.0, 1.0,-1.0, -1.0, 1.0,-1.0, // Top Side 16 | 1.0, 1.0, 1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0, // Top Side 17 | ]); 18 | 19 | const normals = new Float32Array([ 20 | -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, // Left Side 21 | -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, // Left Side 22 | 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, // Back Side 23 | 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, // Back Side 24 | 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, // Bottom Side 25 | 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, // Bottom Side 26 | 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, // front Side 27 | 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, // front Side 28 | 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // right Side 29 | 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // right Side 30 | 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // top Side 31 | 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // top Side 32 | ]) 33 | 34 | return {normals : normals, vertices : vertices, n_vertices : 36}; 35 | } 36 | -------------------------------------------------------------------------------- /client/js/lib/loader/MTLLoader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Loads a Wavefront .mtl file specifying materials 3 | * 4 | * @author angelxuanchang 5 | */ 6 | 7 | import * as THREE from 'three/build/three'; 8 | 9 | THREE.MTLLoader = function ( manager ) { 10 | 11 | this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; 12 | 13 | }; 14 | 15 | THREE.MTLLoader.prototype = { 16 | 17 | constructor: THREE.MTLLoader, 18 | 19 | /** 20 | * Loads and parses a MTL asset from a URL. 21 | * 22 | * @param {String} url - URL to the MTL file. 23 | * @param {Function} [onLoad] - Callback invoked with the loaded object. 24 | * @param {Function} [onProgress] - Callback for download progress. 25 | * @param {Function} [onError] - Callback for download errors. 26 | * 27 | * @see setPath setTexturePath 28 | * 29 | * @note In order for relative texture references to resolve correctly 30 | * you must call setPath and/or setTexturePath explicitly prior to load. 31 | */ 32 | load: function ( url, onLoad, onProgress, onError ) { 33 | 34 | var scope = this; 35 | 36 | var loader = new THREE.FileLoader( this.manager ); 37 | loader.setPath( this.path ); 38 | loader.load( url, function ( text ) { 39 | 40 | onLoad( scope.parse( text ) ); 41 | 42 | }, onProgress, onError ); 43 | 44 | }, 45 | 46 | /** 47 | * Set base path for resolving references. 48 | * If set this path will be prepended to each loaded and found reference. 49 | * 50 | * @see setTexturePath 51 | * @param {String} path 52 | * 53 | * @example 54 | * mtlLoader.setPath( 'assets/obj/' ); 55 | * mtlLoader.load( 'my.mtl', ... ); 56 | */ 57 | setPath: function ( path ) { 58 | 59 | this.path = path; 60 | 61 | }, 62 | 63 | /** 64 | * Set base path for resolving texture references. 65 | * If set this path will be prepended found texture reference. 66 | * If not set and setPath is, it will be used as texture base path. 67 | * 68 | * @see setPath 69 | * @param {String} path 70 | * 71 | * @example 72 | * mtlLoader.setPath( 'assets/obj/' ); 73 | * mtlLoader.setTexturePath( 'assets/textures/' ); 74 | * mtlLoader.load( 'my.mtl', ... ); 75 | */ 76 | setTexturePath: function ( path ) { 77 | 78 | this.texturePath = path; 79 | 80 | }, 81 | 82 | setBaseUrl: function ( path ) { 83 | 84 | console.warn( 'THREE.MTLLoader: .setBaseUrl() is deprecated. Use .setTexturePath( path ) for texture path or .setPath( path ) for general base path instead.' ); 85 | 86 | this.setTexturePath( path ); 87 | 88 | }, 89 | 90 | setCrossOrigin: function ( value ) { 91 | 92 | this.crossOrigin = value; 93 | 94 | }, 95 | 96 | setMaterialOptions: function ( value ) { 97 | 98 | this.materialOptions = value; 99 | 100 | }, 101 | 102 | /** 103 | * Parses a MTL file. 104 | * 105 | * @param {String} text - Content of MTL file 106 | * @return {THREE.MTLLoader.MaterialCreator} 107 | * 108 | * @see setPath setTexturePath 109 | * 110 | * @note In order for relative texture references to resolve correctly 111 | * you must call setPath and/or setTexturePath explicitly prior to parse. 112 | */ 113 | parse: function ( text ) { 114 | 115 | var lines = text.split( '\n' ); 116 | var info = {}; 117 | var delimiter_pattern = /\s+/; 118 | var materialsInfo = {}; 119 | 120 | for ( var i = 0; i < lines.length; i ++ ) { 121 | 122 | var line = lines[ i ]; 123 | line = line.trim(); 124 | 125 | if ( line.length === 0 || line.charAt( 0 ) === '#' ) { 126 | 127 | // Blank line or comment ignore 128 | continue; 129 | 130 | } 131 | 132 | var pos = line.indexOf( ' ' ); 133 | 134 | var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line; 135 | key = key.toLowerCase(); 136 | 137 | var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : ''; 138 | value = value.trim(); 139 | 140 | if ( key === 'newmtl' ) { 141 | 142 | // New material 143 | 144 | info = { name: value }; 145 | materialsInfo[ value ] = info; 146 | 147 | } else if ( info ) { 148 | 149 | if ( key === 'ka' || key === 'kd' || key === 'ks' ) { 150 | 151 | var ss = value.split( delimiter_pattern, 3 ); 152 | info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ]; 153 | 154 | } else { 155 | 156 | info[ key ] = value; 157 | 158 | } 159 | 160 | } 161 | 162 | } 163 | 164 | var materialCreator = new THREE.MTLLoader.MaterialCreator( this.texturePath || this.path, this.materialOptions ); 165 | materialCreator.setCrossOrigin( this.crossOrigin ); 166 | materialCreator.setManager( this.manager ); 167 | materialCreator.setMaterials( materialsInfo ); 168 | return materialCreator; 169 | 170 | } 171 | 172 | }; 173 | 174 | /** 175 | * Create a new THREE-MTLLoader.MaterialCreator 176 | * @param baseUrl - Url relative to which textures are loaded 177 | * @param options - Set of options on how to construct the materials 178 | * side: Which side to apply the material 179 | * THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide 180 | * wrap: What type of wrapping to apply for textures 181 | * THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping 182 | * normalizeRGB: RGBs need to be normalized to 0-1 from 0-255 183 | * Default: false, assumed to be already normalized 184 | * ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's 185 | * Default: false 186 | * @constructor 187 | */ 188 | 189 | THREE.MTLLoader.MaterialCreator = function ( baseUrl, options ) { 190 | 191 | this.baseUrl = baseUrl || ''; 192 | this.options = options; 193 | this.materialsInfo = {}; 194 | this.materials = {}; 195 | this.materialsArray = []; 196 | this.nameLookup = {}; 197 | 198 | this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide; 199 | this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping; 200 | 201 | }; 202 | 203 | THREE.MTLLoader.MaterialCreator.prototype = { 204 | 205 | constructor: THREE.MTLLoader.MaterialCreator, 206 | 207 | crossOrigin: 'Anonymous', 208 | 209 | setCrossOrigin: function ( value ) { 210 | 211 | this.crossOrigin = value; 212 | 213 | }, 214 | 215 | setManager: function ( value ) { 216 | 217 | this.manager = value; 218 | 219 | }, 220 | 221 | setMaterials: function ( materialsInfo ) { 222 | 223 | this.materialsInfo = this.convert( materialsInfo ); 224 | this.materials = {}; 225 | this.materialsArray = []; 226 | this.nameLookup = {}; 227 | 228 | }, 229 | 230 | convert: function ( materialsInfo ) { 231 | 232 | if ( ! this.options ) return materialsInfo; 233 | 234 | var converted = {}; 235 | 236 | for ( var mn in materialsInfo ) { 237 | 238 | // Convert materials info into normalized form based on options 239 | 240 | var mat = materialsInfo[ mn ]; 241 | 242 | var covmat = {}; 243 | 244 | converted[ mn ] = covmat; 245 | 246 | for ( var prop in mat ) { 247 | 248 | var save = true; 249 | var value = mat[ prop ]; 250 | var lprop = prop.toLowerCase(); 251 | 252 | switch ( lprop ) { 253 | 254 | case 'kd': 255 | case 'ka': 256 | case 'ks': 257 | 258 | // Diffuse color (color under white light) using RGB values 259 | 260 | if ( this.options && this.options.normalizeRGB ) { 261 | 262 | value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ]; 263 | 264 | } 265 | 266 | if ( this.options && this.options.ignoreZeroRGBs ) { 267 | 268 | if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) { 269 | 270 | // ignore 271 | 272 | save = false; 273 | 274 | } 275 | 276 | } 277 | 278 | break; 279 | 280 | default: 281 | 282 | break; 283 | 284 | } 285 | 286 | if ( save ) { 287 | 288 | covmat[ lprop ] = value; 289 | 290 | } 291 | 292 | } 293 | 294 | } 295 | 296 | return converted; 297 | 298 | }, 299 | 300 | preload: function () { 301 | 302 | for ( var mn in this.materialsInfo ) { 303 | 304 | this.create( mn ); 305 | 306 | } 307 | 308 | }, 309 | 310 | getIndex: function ( materialName ) { 311 | 312 | return this.nameLookup[ materialName ]; 313 | 314 | }, 315 | 316 | getAsArray: function () { 317 | 318 | var index = 0; 319 | 320 | for ( var mn in this.materialsInfo ) { 321 | 322 | this.materialsArray[ index ] = this.create( mn ); 323 | this.nameLookup[ mn ] = index; 324 | index ++; 325 | 326 | } 327 | 328 | return this.materialsArray; 329 | 330 | }, 331 | 332 | create: function ( materialName ) { 333 | 334 | if ( this.materials[ materialName ] === undefined ) { 335 | 336 | this.createMaterial_( materialName ); 337 | 338 | } 339 | 340 | return this.materials[ materialName ]; 341 | 342 | }, 343 | 344 | createMaterial_: function ( materialName ) { 345 | 346 | // Create material 347 | 348 | var scope = this; 349 | var mat = this.materialsInfo[ materialName ]; 350 | var params = { 351 | 352 | name: materialName, 353 | side: this.side 354 | 355 | }; 356 | 357 | function resolveURL( baseUrl, url ) { 358 | 359 | if ( typeof url !== 'string' || url === '' ) 360 | return ''; 361 | 362 | // Absolute URL 363 | if ( /^https?:\/\//i.test( url ) ) return url; 364 | 365 | return baseUrl + url; 366 | 367 | } 368 | 369 | function setMapForType( mapType, value ) { 370 | 371 | if ( params[ mapType ] ) return; // Keep the first encountered texture 372 | 373 | var texParams = scope.getTextureParams( value, params ); 374 | var map = scope.loadTexture( resolveURL( scope.baseUrl, texParams.url ) ); 375 | 376 | map.repeat.copy( texParams.scale ); 377 | map.offset.copy( texParams.offset ); 378 | 379 | map.wrapS = scope.wrap; 380 | map.wrapT = scope.wrap; 381 | 382 | params[ mapType ] = map; 383 | 384 | } 385 | 386 | for ( var prop in mat ) { 387 | 388 | var value = mat[ prop ]; 389 | var n; 390 | 391 | if ( value === '' ) continue; 392 | 393 | switch ( prop.toLowerCase() ) { 394 | 395 | // Ns is material specular exponent 396 | 397 | case 'kd': 398 | 399 | // Diffuse color (color under white light) using RGB values 400 | 401 | params.color = new THREE.Color().fromArray( value ); 402 | 403 | break; 404 | 405 | case 'ks': 406 | 407 | // Specular color (color when light is reflected from shiny surface) using RGB values 408 | params.specular = new THREE.Color().fromArray( value ); 409 | 410 | break; 411 | 412 | case 'map_kd': 413 | 414 | // Diffuse texture map 415 | 416 | setMapForType( "map", value ); 417 | 418 | break; 419 | 420 | case 'map_ks': 421 | 422 | // Specular map 423 | 424 | setMapForType( "specularMap", value ); 425 | 426 | break; 427 | 428 | case 'norm': 429 | 430 | setMapForType( "normalMap", value ); 431 | 432 | break; 433 | 434 | case 'map_bump': 435 | case 'bump': 436 | 437 | // Bump texture map 438 | 439 | setMapForType( "bumpMap", value ); 440 | 441 | break; 442 | 443 | case 'ns': 444 | 445 | // The specular exponent (defines the focus of the specular highlight) 446 | // A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000. 447 | 448 | params.shininess = parseFloat( value ); 449 | 450 | break; 451 | 452 | case 'd': 453 | n = parseFloat( value ); 454 | 455 | if ( n < 1 ) { 456 | 457 | params.opacity = n; 458 | params.transparent = true; 459 | 460 | } 461 | 462 | break; 463 | 464 | case 'tr': 465 | n = parseFloat( value ); 466 | 467 | if ( this.options && this.options.invertTrProperty ) n = 1 - n; 468 | 469 | if ( n < 1 ) { 470 | 471 | params.opacity = n; 472 | params.transparent = true; 473 | 474 | } 475 | 476 | break; 477 | 478 | default: 479 | break; 480 | 481 | } 482 | 483 | } 484 | 485 | this.materials[ materialName ] = new THREE.MeshPhongMaterial( params ); 486 | return this.materials[ materialName ]; 487 | 488 | }, 489 | 490 | getTextureParams: function ( value, matParams ) { 491 | 492 | var texParams = { 493 | 494 | scale: new THREE.Vector2( 1, 1 ), 495 | offset: new THREE.Vector2( 0, 0 ) 496 | 497 | }; 498 | 499 | var items = value.split( /\s+/ ); 500 | var pos; 501 | 502 | pos = items.indexOf( '-bm' ); 503 | 504 | if ( pos >= 0 ) { 505 | 506 | matParams.bumpScale = parseFloat( items[ pos + 1 ] ); 507 | items.splice( pos, 2 ); 508 | 509 | } 510 | 511 | pos = items.indexOf( '-s' ); 512 | 513 | if ( pos >= 0 ) { 514 | 515 | texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) ); 516 | items.splice( pos, 4 ); // we expect 3 parameters here! 517 | 518 | } 519 | 520 | pos = items.indexOf( '-o' ); 521 | 522 | if ( pos >= 0 ) { 523 | 524 | texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) ); 525 | items.splice( pos, 4 ); // we expect 3 parameters here! 526 | 527 | } 528 | 529 | texParams.url = items.join( ' ' ).trim(); 530 | return texParams; 531 | 532 | }, 533 | 534 | loadTexture: function ( url, mapping, onLoad, onProgress, onError ) { 535 | 536 | var texture; 537 | var loader = THREE.Loader.Handlers.get( url ); 538 | var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager; 539 | 540 | if ( loader === null ) { 541 | 542 | loader = new THREE.TextureLoader( manager ); 543 | 544 | } 545 | 546 | if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin ); 547 | texture = loader.load( url, onLoad, onProgress, onError ); 548 | 549 | if ( mapping !== undefined ) texture.mapping = mapping; 550 | 551 | return texture; 552 | 553 | } 554 | 555 | }; 556 | -------------------------------------------------------------------------------- /client/js/lib/proto/data3_pb.js: -------------------------------------------------------------------------------- 1 | // source: data3.proto 2 | /** 3 | * @fileoverview 4 | * @enhanceable 5 | * @suppress {messageConventions} JS Compiler reports an error if a variable or 6 | * field starts with 'MSG_' and isn't a translatable message. 7 | * @public 8 | */ 9 | // GENERATED CODE -- DO NOT EDIT! 10 | 11 | var jspb = require('google-protobuf'); 12 | var goog = jspb; 13 | var global = Function('return this')(); 14 | 15 | var vox_pb = require('./vox_pb.js'); 16 | goog.object.extend(proto, vox_pb); 17 | var svox_pb = require('./svox_pb.js'); 18 | goog.object.extend(proto, svox_pb); 19 | goog.exportSymbol('proto.scan2cad.Data3', null, global); 20 | goog.exportSymbol('proto.scan2cad.Data3.RepCase', null, global); 21 | /** 22 | * Generated by JsPbCodeGenerator. 23 | * @param {Array=} opt_data Optional initial data array, typically from a 24 | * server response, or constructed directly in Javascript. The array is used 25 | * in place and becomes part of the constructed object. It is not cloned. 26 | * If no data is provided, the constructed object will be empty, but still 27 | * valid. 28 | * @extends {jspb.Message} 29 | * @constructor 30 | */ 31 | proto.scan2cad.Data3 = function(opt_data) { 32 | jspb.Message.initialize(this, opt_data, 0, -1, null, proto.scan2cad.Data3.oneofGroups_); 33 | }; 34 | goog.inherits(proto.scan2cad.Data3, jspb.Message); 35 | if (goog.DEBUG && !COMPILED) { 36 | /** 37 | * @public 38 | * @override 39 | */ 40 | proto.scan2cad.Data3.displayName = 'proto.scan2cad.Data3'; 41 | } 42 | 43 | /** 44 | * Oneof group definitions for this message. Each group defines the field 45 | * numbers belonging to that group. When of these fields' value is set, all 46 | * other fields in the group are cleared. During deserialization, if multiple 47 | * fields are encountered for a group, only the last value seen will be kept. 48 | * @private {!Array>} 49 | * @const 50 | */ 51 | proto.scan2cad.Data3.oneofGroups_ = [[1,2]]; 52 | 53 | /** 54 | * @enum {number} 55 | */ 56 | proto.scan2cad.Data3.RepCase = { 57 | REP_NOT_SET: 0, 58 | VOX: 1, 59 | SVOX: 2 60 | }; 61 | 62 | /** 63 | * @return {proto.scan2cad.Data3.RepCase} 64 | */ 65 | proto.scan2cad.Data3.prototype.getRepCase = function() { 66 | return /** @type {proto.scan2cad.Data3.RepCase} */(jspb.Message.computeOneofCase(this, proto.scan2cad.Data3.oneofGroups_[0])); 67 | }; 68 | 69 | 70 | 71 | if (jspb.Message.GENERATE_TO_OBJECT) { 72 | /** 73 | * Creates an object representation of this proto. 74 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 75 | * Optional fields that are not set will be set to undefined. 76 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 77 | * For the list of reserved names please see: 78 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 79 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 80 | * JSPB instance for transitional soy proto support: 81 | * http://goto/soy-param-migration 82 | * @return {!Object} 83 | */ 84 | proto.scan2cad.Data3.prototype.toObject = function(opt_includeInstance) { 85 | return proto.scan2cad.Data3.toObject(opt_includeInstance, this); 86 | }; 87 | 88 | 89 | /** 90 | * Static version of the {@see toObject} method. 91 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 92 | * the JSPB instance for transitional soy proto support: 93 | * http://goto/soy-param-migration 94 | * @param {!proto.scan2cad.Data3} msg The msg instance to transform. 95 | * @return {!Object} 96 | * @suppress {unusedLocalVariables} f is only used for nested messages 97 | */ 98 | proto.scan2cad.Data3.toObject = function(includeInstance, msg) { 99 | var f, obj = { 100 | vox: (f = msg.getVox()) && vox_pb.Vox.toObject(includeInstance, f), 101 | svox: (f = msg.getSvox()) && svox_pb.SVox.toObject(includeInstance, f) 102 | }; 103 | 104 | if (includeInstance) { 105 | obj.$jspbMessageInstance = msg; 106 | } 107 | return obj; 108 | }; 109 | } 110 | 111 | 112 | /** 113 | * Deserializes binary data (in protobuf wire format). 114 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 115 | * @return {!proto.scan2cad.Data3} 116 | */ 117 | proto.scan2cad.Data3.deserializeBinary = function(bytes) { 118 | var reader = new jspb.BinaryReader(bytes); 119 | var msg = new proto.scan2cad.Data3; 120 | return proto.scan2cad.Data3.deserializeBinaryFromReader(msg, reader); 121 | }; 122 | 123 | 124 | /** 125 | * Deserializes binary data (in protobuf wire format) from the 126 | * given reader into the given message object. 127 | * @param {!proto.scan2cad.Data3} msg The message object to deserialize into. 128 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 129 | * @return {!proto.scan2cad.Data3} 130 | */ 131 | proto.scan2cad.Data3.deserializeBinaryFromReader = function(msg, reader) { 132 | while (reader.nextField()) { 133 | if (reader.isEndGroup()) { 134 | break; 135 | } 136 | var field = reader.getFieldNumber(); 137 | switch (field) { 138 | case 1: 139 | var value = new vox_pb.Vox; 140 | reader.readMessage(value,vox_pb.Vox.deserializeBinaryFromReader); 141 | msg.setVox(value); 142 | break; 143 | case 2: 144 | var value = new svox_pb.SVox; 145 | reader.readMessage(value,svox_pb.SVox.deserializeBinaryFromReader); 146 | msg.setSvox(value); 147 | break; 148 | default: 149 | reader.skipField(); 150 | break; 151 | } 152 | } 153 | return msg; 154 | }; 155 | 156 | 157 | /** 158 | * Serializes the message to binary data (in protobuf wire format). 159 | * @return {!Uint8Array} 160 | */ 161 | proto.scan2cad.Data3.prototype.serializeBinary = function() { 162 | var writer = new jspb.BinaryWriter(); 163 | proto.scan2cad.Data3.serializeBinaryToWriter(this, writer); 164 | return writer.getResultBuffer(); 165 | }; 166 | 167 | 168 | /** 169 | * Serializes the given message to binary data (in protobuf wire 170 | * format), writing to the given BinaryWriter. 171 | * @param {!proto.scan2cad.Data3} message 172 | * @param {!jspb.BinaryWriter} writer 173 | * @suppress {unusedLocalVariables} f is only used for nested messages 174 | */ 175 | proto.scan2cad.Data3.serializeBinaryToWriter = function(message, writer) { 176 | var f = undefined; 177 | f = message.getVox(); 178 | if (f != null) { 179 | writer.writeMessage( 180 | 1, 181 | f, 182 | vox_pb.Vox.serializeBinaryToWriter 183 | ); 184 | } 185 | f = message.getSvox(); 186 | if (f != null) { 187 | writer.writeMessage( 188 | 2, 189 | f, 190 | svox_pb.SVox.serializeBinaryToWriter 191 | ); 192 | } 193 | }; 194 | 195 | 196 | /** 197 | * optional Vox vox = 1; 198 | * @return {?proto.scan2cad.Vox} 199 | */ 200 | proto.scan2cad.Data3.prototype.getVox = function() { 201 | return /** @type{?proto.scan2cad.Vox} */ ( 202 | jspb.Message.getWrapperField(this, vox_pb.Vox, 1)); 203 | }; 204 | 205 | 206 | /** 207 | * @param {?proto.scan2cad.Vox|undefined} value 208 | * @return {!proto.scan2cad.Data3} returns this 209 | */ 210 | proto.scan2cad.Data3.prototype.setVox = function(value) { 211 | return jspb.Message.setOneofWrapperField(this, 1, proto.scan2cad.Data3.oneofGroups_[0], value); 212 | }; 213 | 214 | 215 | /** 216 | * Clears the message field making it undefined. 217 | * @return {!proto.scan2cad.Data3} returns this 218 | */ 219 | proto.scan2cad.Data3.prototype.clearVox = function() { 220 | return this.setVox(undefined); 221 | }; 222 | 223 | 224 | /** 225 | * Returns whether this field is set. 226 | * @return {boolean} 227 | */ 228 | proto.scan2cad.Data3.prototype.hasVox = function() { 229 | return jspb.Message.getField(this, 1) != null; 230 | }; 231 | 232 | 233 | /** 234 | * optional SVox svox = 2; 235 | * @return {?proto.scan2cad.SVox} 236 | */ 237 | proto.scan2cad.Data3.prototype.getSvox = function() { 238 | return /** @type{?proto.scan2cad.SVox} */ ( 239 | jspb.Message.getWrapperField(this, svox_pb.SVox, 2)); 240 | }; 241 | 242 | 243 | /** 244 | * @param {?proto.scan2cad.SVox|undefined} value 245 | * @return {!proto.scan2cad.Data3} returns this 246 | */ 247 | proto.scan2cad.Data3.prototype.setSvox = function(value) { 248 | return jspb.Message.setOneofWrapperField(this, 2, proto.scan2cad.Data3.oneofGroups_[0], value); 249 | }; 250 | 251 | 252 | /** 253 | * Clears the message field making it undefined. 254 | * @return {!proto.scan2cad.Data3} returns this 255 | */ 256 | proto.scan2cad.Data3.prototype.clearSvox = function() { 257 | return this.setSvox(undefined); 258 | }; 259 | 260 | 261 | /** 262 | * Returns whether this field is set. 263 | * @return {boolean} 264 | */ 265 | proto.scan2cad.Data3.prototype.hasSvox = function() { 266 | return jspb.Message.getField(this, 2) != null; 267 | }; 268 | 269 | 270 | goog.object.extend(exports, proto.scan2cad); 271 | -------------------------------------------------------------------------------- /client/js/lib/proto/data_info_pb.js: -------------------------------------------------------------------------------- 1 | // source: data_info.proto 2 | /** 3 | * @fileoverview 4 | * @enhanceable 5 | * @suppress {messageConventions} JS Compiler reports an error if a variable or 6 | * field starts with 'MSG_' and isn't a translatable message. 7 | * @public 8 | */ 9 | // GENERATED CODE -- DO NOT EDIT! 10 | 11 | var jspb = require('google-protobuf'); 12 | var goog = jspb; 13 | var global = Function('return this')(); 14 | 15 | goog.exportSymbol('proto.scan2cad.DataInfo', null, global); 16 | /** 17 | * Generated by JsPbCodeGenerator. 18 | * @param {Array=} opt_data Optional initial data array, typically from a 19 | * server response, or constructed directly in Javascript. The array is used 20 | * in place and becomes part of the constructed object. It is not cloned. 21 | * If no data is provided, the constructed object will be empty, but still 22 | * valid. 23 | * @extends {jspb.Message} 24 | * @constructor 25 | */ 26 | proto.scan2cad.DataInfo = function(opt_data) { 27 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 28 | }; 29 | goog.inherits(proto.scan2cad.DataInfo, jspb.Message); 30 | if (goog.DEBUG && !COMPILED) { 31 | /** 32 | * @public 33 | * @override 34 | */ 35 | proto.scan2cad.DataInfo.displayName = 'proto.scan2cad.DataInfo'; 36 | } 37 | 38 | 39 | 40 | if (jspb.Message.GENERATE_TO_OBJECT) { 41 | /** 42 | * Creates an object representation of this proto. 43 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 44 | * Optional fields that are not set will be set to undefined. 45 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 46 | * For the list of reserved names please see: 47 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 48 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 49 | * JSPB instance for transitional soy proto support: 50 | * http://goto/soy-param-migration 51 | * @return {!Object} 52 | */ 53 | proto.scan2cad.DataInfo.prototype.toObject = function(opt_includeInstance) { 54 | return proto.scan2cad.DataInfo.toObject(opt_includeInstance, this); 55 | }; 56 | 57 | 58 | /** 59 | * Static version of the {@see toObject} method. 60 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 61 | * the JSPB instance for transitional soy proto support: 62 | * http://goto/soy-param-migration 63 | * @param {!proto.scan2cad.DataInfo} msg The msg instance to transform. 64 | * @return {!Object} 65 | * @suppress {unusedLocalVariables} f is only used for nested messages 66 | */ 67 | proto.scan2cad.DataInfo.toObject = function(includeInstance, msg) { 68 | var f, obj = { 69 | type: jspb.Message.getFieldWithDefault(msg, 1, ""), 70 | desc: jspb.Message.getFieldWithDefault(msg, 2, "") 71 | }; 72 | 73 | if (includeInstance) { 74 | obj.$jspbMessageInstance = msg; 75 | } 76 | return obj; 77 | }; 78 | } 79 | 80 | 81 | /** 82 | * Deserializes binary data (in protobuf wire format). 83 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 84 | * @return {!proto.scan2cad.DataInfo} 85 | */ 86 | proto.scan2cad.DataInfo.deserializeBinary = function(bytes) { 87 | var reader = new jspb.BinaryReader(bytes); 88 | var msg = new proto.scan2cad.DataInfo; 89 | return proto.scan2cad.DataInfo.deserializeBinaryFromReader(msg, reader); 90 | }; 91 | 92 | 93 | /** 94 | * Deserializes binary data (in protobuf wire format) from the 95 | * given reader into the given message object. 96 | * @param {!proto.scan2cad.DataInfo} msg The message object to deserialize into. 97 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 98 | * @return {!proto.scan2cad.DataInfo} 99 | */ 100 | proto.scan2cad.DataInfo.deserializeBinaryFromReader = function(msg, reader) { 101 | while (reader.nextField()) { 102 | if (reader.isEndGroup()) { 103 | break; 104 | } 105 | var field = reader.getFieldNumber(); 106 | switch (field) { 107 | case 1: 108 | var value = /** @type {string} */ (reader.readString()); 109 | msg.setType(value); 110 | break; 111 | case 2: 112 | var value = /** @type {string} */ (reader.readString()); 113 | msg.setDesc(value); 114 | break; 115 | default: 116 | reader.skipField(); 117 | break; 118 | } 119 | } 120 | return msg; 121 | }; 122 | 123 | 124 | /** 125 | * Serializes the message to binary data (in protobuf wire format). 126 | * @return {!Uint8Array} 127 | */ 128 | proto.scan2cad.DataInfo.prototype.serializeBinary = function() { 129 | var writer = new jspb.BinaryWriter(); 130 | proto.scan2cad.DataInfo.serializeBinaryToWriter(this, writer); 131 | return writer.getResultBuffer(); 132 | }; 133 | 134 | 135 | /** 136 | * Serializes the given message to binary data (in protobuf wire 137 | * format), writing to the given BinaryWriter. 138 | * @param {!proto.scan2cad.DataInfo} message 139 | * @param {!jspb.BinaryWriter} writer 140 | * @suppress {unusedLocalVariables} f is only used for nested messages 141 | */ 142 | proto.scan2cad.DataInfo.serializeBinaryToWriter = function(message, writer) { 143 | var f = undefined; 144 | f = message.getType(); 145 | if (f.length > 0) { 146 | writer.writeString( 147 | 1, 148 | f 149 | ); 150 | } 151 | f = message.getDesc(); 152 | if (f.length > 0) { 153 | writer.writeString( 154 | 2, 155 | f 156 | ); 157 | } 158 | }; 159 | 160 | 161 | /** 162 | * optional string type = 1; 163 | * @return {string} 164 | */ 165 | proto.scan2cad.DataInfo.prototype.getType = function() { 166 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); 167 | }; 168 | 169 | 170 | /** 171 | * @param {string} value 172 | * @return {!proto.scan2cad.DataInfo} returns this 173 | */ 174 | proto.scan2cad.DataInfo.prototype.setType = function(value) { 175 | return jspb.Message.setProto3StringField(this, 1, value); 176 | }; 177 | 178 | 179 | /** 180 | * optional string desc = 2; 181 | * @return {string} 182 | */ 183 | proto.scan2cad.DataInfo.prototype.getDesc = function() { 184 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); 185 | }; 186 | 187 | 188 | /** 189 | * @param {string} value 190 | * @return {!proto.scan2cad.DataInfo} returns this 191 | */ 192 | proto.scan2cad.DataInfo.prototype.setDesc = function(value) { 193 | return jspb.Message.setProto3StringField(this, 2, value); 194 | }; 195 | 196 | 197 | goog.object.extend(exports, proto.scan2cad); 198 | -------------------------------------------------------------------------------- /client/js/lib/shader/PVVGLSL.js: -------------------------------------------------------------------------------- 1 | export const PVVVS = `#version 300 es 2 | precision lowp float; 3 | layout(location = 0) in vec3 position; 4 | layout(location = 1) in int label; 5 | flat out int frag_color_vs; 6 | uniform mat4 model_matrix; 7 | uniform mat4 view_matrix; 8 | uniform mat4 projection_matrix; 9 | void main() { 10 | frag_color_vs = label; 11 | gl_Position = projection_matrix*view_matrix*model_matrix*vec4(position, 1.0); 12 | }`; 13 | 14 | export const PVVFS = `#version 300 es 15 | precision lowp float; 16 | flat in int frag_color_vs; 17 | layout(location = 0) out vec4 color; 18 | layout(location = 1) out vec4 depth; 19 | float near = 2.0; 20 | float far = 100.0; 21 | void main() { 22 | int r = (frag_color_vs & 0x000000FF) >> 0; 23 | int g = (frag_color_vs & 0x0000FF00) >> 8; 24 | int b = (frag_color_vs & 0x00FF0000) >> 16; 25 | int a = (frag_color_vs & 0xFF000000) >> 24; 26 | color = vec4(float(r)/255.0, float(g)/255.0, float(b)/255.0, 1.0); 27 | // float z_ndc = 2.0*gl_FragCoord.z - 1.0; 28 | // float z_linear = 2.0*near*far/(far + near - z_ndc*(far - near))/(far - near); 29 | int z_linear_int = int(gl_FragCoord.z *float(1 << 24)); 30 | int r1 = (z_linear_int & 0x000000FF) >> 0; 31 | int g1 = (z_linear_int & 0x0000FF00) >> 8; 32 | int b1 = (z_linear_int & 0x00FF0000) >> 16; 33 | depth = vec4(float(r1)/255.0, float(g1)/255.0, float(b1)/255.0, 1.0); 34 | }`; 35 | -------------------------------------------------------------------------------- /client/js/lib/shader/PhongGLSL.js: -------------------------------------------------------------------------------- 1 | export const PhongVS = `#version 300 es 2 | precision mediump float; 3 | 4 | layout (location = 0) in vec3 position; 5 | layout (location = 1) in vec2 uv; 6 | layout (location = 2) in vec3 normal; 7 | layout (location = 3) in float id_part; 8 | layout (location = 4) in float id_texture; 9 | 10 | out vec3 position_vs; 11 | out vec3 normal_vs; 12 | out vec2 uv_vs; 13 | flat out int id_texture_vs; 14 | flat out int id_part_vs; 15 | 16 | uniform mat4 model_matrix; 17 | uniform mat4 view_matrix; 18 | uniform mat4 projection_matrix; 19 | 20 | void main() { 21 | normal_vs = vec3(transpose(inverse(view_matrix*model_matrix))*vec4(normalize(normal), 1.0)); 22 | position_vs = vec3(view_matrix*model_matrix*vec4(position, 1.0)); 23 | uv_vs = uv; 24 | id_part_vs = int(id_part); 25 | id_texture_vs = int(id_texture); 26 | gl_Position = projection_matrix*view_matrix*model_matrix*vec4(position, 1.0); 27 | }`; 28 | 29 | export const PhongFS = `#version 300 es 30 | precision mediump float; 31 | #define N_MAX_TEXTURES 10 32 | 33 | in vec3 position_vs; 34 | in vec3 normal_vs; 35 | in vec2 uv_vs; 36 | flat in int id_texture_vs; 37 | flat in int id_part_vs; 38 | 39 | const vec3 pos_light = vec3(0, 0, 0); // Light position in eye coords. 40 | const vec3 la = vec3(0.3); // Ambient light intensity 41 | const vec3 ld = vec3(1.0); // Diffuse light intensity 42 | const vec3 ls = vec3(0.2); // Specular light intensity 43 | 44 | struct Material { 45 | vec3 ka; // Ambient reflectivity 46 | vec3 kd; // Diffuse reflectivity 47 | vec3 ks; // Specular reflectivity 48 | float shininess; // Specular shininess factor 49 | }; 50 | 51 | uniform Material material[50]; 52 | 53 | out vec4 frag_color; 54 | uniform sampler2D tex[N_MAX_TEXTURES]; 55 | 56 | void main() { 57 | vec4 color; 58 | if (id_texture_vs == 0) { 59 | color = texture(tex[0], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 60 | } else if (id_texture_vs == 1) { 61 | color = texture(tex[1], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 62 | } else if (id_texture_vs == 2) { 63 | color = texture(tex[2], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 64 | } else if (id_texture_vs == 3) { 65 | color = texture(tex[3], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 66 | } else if (id_texture_vs == 4) { 67 | color = texture(tex[4], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 68 | } else if (id_texture_vs == 5) { 69 | color = texture(tex[5], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 70 | } else if (id_texture_vs == 6) { 71 | color = texture(tex[6], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 72 | } else if (id_texture_vs == 7) { 73 | color = texture(tex[7], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 74 | } else if (id_texture_vs == 8) { 75 | color = texture(tex[8], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 76 | } else if (id_texture_vs == 9) { 77 | color = texture(tex[9], vec2(uv_vs.x*2.0, 1.0) - uv_vs); 78 | } else if (id_texture_vs == -1) { 79 | color = vec4(1.0); 80 | } 81 | 82 | 83 | vec3 normal1 = vec3(0); 84 | if (gl_FrontFacing) 85 | normal1 = normalize(normal_vs); 86 | else 87 | normal1 = normalize(-normal_vs); 88 | vec3 s = normalize(pos_light - position_vs); 89 | vec3 v = normalize(-position_vs); 90 | vec3 r = reflect(-s, normal1); 91 | 92 | float sDotN = max(dot(s, normal1), 0.0); 93 | vec3 ambient = la*material[id_part_vs].ka; 94 | vec3 diffuse = ld*material[id_part_vs].kd*sDotN; 95 | vec3 specular = vec3(0.0); 96 | if( sDotN > 0.0 ) 97 | specular = ls*material[id_part_vs].ks*pow(max(dot(r,v), 0.0), material[id_part_vs].shininess); 98 | 99 | frag_color = vec4( ambient + diffuse, 1 )*color + vec4( specular, 1 ); 100 | 101 | }`; 102 | -------------------------------------------------------------------------------- /client/js/lib/shader/PolygonColorGLSL.js: -------------------------------------------------------------------------------- 1 | export const VS = `#version 300 es 2 | precision mediump float; 3 | 4 | layout (location = 0) in vec3 vertex; 5 | layout (location = 1) in vec3 normal; 6 | layout (location = 2) in vec3 color; 7 | 8 | uniform mat4 model_matrix; 9 | uniform mat4 view_matrix; 10 | uniform mat4 projection_matrix; 11 | 12 | out vec3 position_vs; 13 | out vec3 normal_vs; 14 | out vec3 color_vs; 15 | 16 | void main() { 17 | mat4 mvp_matrix = projection_matrix*view_matrix*model_matrix; 18 | gl_Position = mvp_matrix*vec4(vertex, 1.0); 19 | 20 | mat4 normal_matrix = transpose(inverse(view_matrix*model_matrix)); 21 | 22 | vec4 pos1 = view_matrix*model_matrix*vec4(vertex, 1.0); 23 | position_vs = pos1.xyz; 24 | normal_vs = vec3(normal_matrix*vec4(normal, 0)); 25 | color_vs = color; 26 | } 27 | 28 | 29 | `; 30 | 31 | export const FS = `#version 300 es 32 | precision mediump float; 33 | 34 | in vec3 position_vs; 35 | in vec3 normal_vs; 36 | in vec3 color_vs; 37 | 38 | const vec3 la = vec3(0.3); 39 | const vec3 ld = vec3(1.0); 40 | const vec3 ls = vec3(0.3); 41 | 42 | 43 | const vec3 ka = vec3(1.0, 1.0, 1.0); 44 | const vec3 ks = vec3(0.5, 0.5, 0.5); 45 | const float shininess = 1.0; 46 | 47 | uniform mat4 model_matrix; 48 | uniform mat4 view_matrix; 49 | 50 | out vec4 frag_color; 51 | 52 | void main() { 53 | if (normal_vs == vec3(0,0,0)) { 54 | frag_color = vec4( color_vs, 1 ); 55 | } else { 56 | vec3 normal1 = normalize(normal_vs); 57 | 58 | vec3 pos_light = -view_matrix[3].xyz; 59 | vec3 s = normalize(pos_light - position_vs); 60 | vec3 v = normalize(-position_vs); 61 | vec3 r = reflect(-s, normal1); 62 | 63 | float sDotN = max(dot(s, normal1), 0.0); 64 | vec3 ambient = la*ka; 65 | vec3 diffuse = ld*color_vs*sDotN; 66 | vec3 specular = vec3(0.0); 67 | if( sDotN > 0.0 ) 68 | specular = ls*ks*pow(max(dot(r,v), 0.0), shininess); 69 | 70 | frag_color = vec4( diffuse + ambient + specular, 1 ); 71 | } 72 | } 73 | 74 | `; 75 | -------------------------------------------------------------------------------- /client/js/lib/shader/PolygonGLSL.js: -------------------------------------------------------------------------------- 1 | export const PolygonVS = `#version 300 es 2 | precision mediump float; 3 | 4 | layout (location = 0) in vec3 vertex; 5 | 6 | out vec4 frag_color_vs; 7 | 8 | uniform vec4 color; 9 | 10 | uniform mat4 model_matrix; 11 | uniform mat4 view_matrix; 12 | uniform mat4 projection_matrix; 13 | 14 | void main() { 15 | mat4 mvp_matrix = projection_matrix*view_matrix*model_matrix; 16 | gl_Position = mvp_matrix*vec4(vertex, 1.0); 17 | frag_color_vs = color; 18 | }`; 19 | 20 | export const PolygonFS = `#version 300 es 21 | precision mediump float; 22 | in vec4 frag_color_vs; 23 | out vec4 frag_color; 24 | 25 | void main() { 26 | frag_color = frag_color_vs; 27 | }`; 28 | -------------------------------------------------------------------------------- /client/js/lib/shader/PolygonInstanceGLSL.js: -------------------------------------------------------------------------------- 1 | export const VS = `#version 300 es 2 | precision mediump float; 3 | 4 | layout (location = 0) in vec3 vertex; 5 | layout (location = 1) in vec3 normal; 6 | layout (location = 2) in vec3 position; 7 | layout (location = 3) in vec3 color; 8 | 9 | uniform float scale; 10 | uniform mat4 model_matrix; 11 | uniform mat4 view_matrix; 12 | uniform mat4 projection_matrix; 13 | 14 | out vec3 position_vs; 15 | out vec3 normal_vs; 16 | out vec3 color_vs; 17 | 18 | void main() { 19 | mat4 mvp_matrix = projection_matrix*view_matrix*model_matrix; 20 | gl_Position = mvp_matrix*vec4(position + scale*vertex, 1.0); 21 | 22 | mat4 normal_matrix = transpose(inverse(view_matrix*model_matrix)); 23 | 24 | vec4 pos1 = view_matrix*model_matrix*vec4(position + scale*vertex, 1.0); 25 | position_vs = pos1.xyz/pos1.w; 26 | normal_vs = vec3(normal_matrix*vec4(normal, 0)); 27 | color_vs = color; 28 | } 29 | 30 | 31 | `; 32 | 33 | export const FS = `#version 300 es 34 | precision mediump float; 35 | 36 | in vec3 position_vs; 37 | in vec3 normal_vs; 38 | in vec3 color_vs; 39 | 40 | const vec3 la = vec3(0.0); 41 | const vec3 ld = vec3(1.0); 42 | const vec3 ls = vec3(0.1); 43 | 44 | 45 | const vec3 ka = vec3(1.0, 1.0, 1.0); 46 | const vec3 ks = vec3(0.5, 0.5, 0.5); 47 | const float shininess = 1.0; 48 | 49 | uniform mat4 model_matrix; 50 | uniform mat4 view_matrix; 51 | 52 | out vec4 frag_color; 53 | 54 | void main() { 55 | vec3 normal1 = normalize(normal_vs); 56 | 57 | vec3 pos_light = -view_matrix[3].xyz; 58 | vec3 s = normalize(pos_light - position_vs); 59 | vec3 v = normalize(-position_vs); 60 | vec3 r = reflect(-s, normal1); 61 | 62 | float sDotN = max(dot(s, normal1), 0.0); 63 | vec3 ambient = la*ka; 64 | vec3 diffuse = ld*color_vs*sDotN; 65 | vec3 specular = vec3(0.0); 66 | if( sDotN > 0.0 ) 67 | specular = ls*ks*pow(max(dot(r,v), 0.0), shininess); 68 | 69 | frag_color = vec4( diffuse + ambient + specular, 1 ); 70 | } 71 | 72 | `; 73 | -------------------------------------------------------------------------------- /client/js/lib/shader/SceneGLSL.js: -------------------------------------------------------------------------------- 1 | export const SceneVS = `#version 300 es 2 | precision mediump float; 3 | 4 | layout(location = 0) in vec3 position; 5 | layout(location = 1) in vec3 normal; 6 | layout(location = 2) in vec3 color; 7 | 8 | out vec3 position_vs; 9 | out vec3 normal_vs; 10 | out vec3 color_vs; 11 | 12 | uniform mat4 model_matrix; 13 | uniform mat4 view_matrix; 14 | uniform mat4 projection_matrix; 15 | 16 | void main() { 17 | position_vs = vec3(view_matrix*model_matrix*vec4(position, 1.0)); 18 | normal_vs = vec3(transpose(inverse(view_matrix*model_matrix))*vec4(normalize(normal), 1.0)); 19 | color_vs = color; 20 | gl_Position = projection_matrix*view_matrix*model_matrix*vec4(position, 1.0); 21 | }`; 22 | 23 | export const SceneFS = `#version 300 es 24 | precision mediump float; 25 | 26 | in vec3 position_vs; 27 | in vec3 normal_vs; 28 | in vec3 color_vs; 29 | 30 | out vec4 frag_color; 31 | 32 | const vec3 pos_light = vec3(0, 0, 0); 33 | const vec3 ld = vec3(1.0); 34 | const vec3 ls = vec3(0.1); 35 | 36 | void main() { 37 | vec3 X = dFdx(position_vs); 38 | vec3 Y = dFdy(position_vs); 39 | vec3 normal1 = normalize(cross(X,Y)); 40 | vec3 s = normalize(pos_light - position_vs); 41 | vec3 v = normalize(-position_vs); 42 | vec3 r = reflect(-s, normal1); 43 | 44 | float sDotN = max(dot(s, normal1), 0.0); 45 | vec3 diffuse = ld*color_vs*sDotN; 46 | vec3 specular = vec3(0.0); 47 | if(sDotN > 0.0) 48 | specular = ls*pow(max(dot(r,v), 0.0), 1.0); 49 | 50 | frag_color = vec4(diffuse + specular, 1); 51 | }`; 52 | -------------------------------------------------------------------------------- /client/js/lib/vao/CamSphereVAO.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three/build/three'; 2 | 3 | import GLProgram from './GLProgram.js'; 4 | import * as Shader from '../shader/PolygonGLSL.js'; 5 | import * as CamSphere from '../geometry/CamSphere'; 6 | 7 | 8 | class VAOMesh { 9 | constructor() { 10 | this.vbo_vertex = 0; 11 | this.ebo = 0; 12 | this.n_vertices = 0; 13 | this.n_elements = 0; 14 | this.n_instance = 0; 15 | 16 | this.color = null; 17 | } 18 | } 19 | 20 | class CamSphereVAO { 21 | init(gl) { 22 | this.gl = gl; 23 | this.program = GLProgram.compile_shaders_and_link_with_program(this.gl, Shader.PolygonVS, Shader.PolygonFS); 24 | this.gl.useProgram(this.program); 25 | 26 | this.is_active = 0; 27 | this.is_visible = 0; 28 | this.is_done = 0; 29 | 30 | // -> buffers 31 | this.vertex_buffer = new Float32Array(3*8); 32 | // <- 33 | 34 | // -> uniforms 35 | this.model_matrix = new THREE.Matrix4();; 36 | this.rotation_matrix = new THREE.Matrix4();; 37 | this.translation_matrix = new THREE.Matrix4();; 38 | this.scale_matrix = new THREE.Matrix4();; 39 | // <- 40 | 41 | this.box = null; 42 | 43 | this.vao = new VAOMesh(); 44 | this.init_vao(); 45 | } 46 | 47 | reinit(gl) { 48 | this.gl = gl; 49 | this.program = GLProgram.compile_shaders_and_link_with_program(this.gl, Shader.PolygonVS, Shader.PolygonFS); 50 | 51 | this.upload_all_buffers(); 52 | 53 | } 54 | 55 | set_active(value) { 56 | this.is_active = value; 57 | } 58 | 59 | set_color_to_blue() { 60 | this.vao.color.set(0.2, 0.2, 0.8, 1.0); 61 | } 62 | 63 | 64 | init_vao() { 65 | this.gl.useProgram(this.program); 66 | 67 | this.cam_sphere = CamSphere.make_cam_sphere(0.5); 68 | this.vao.n_elements = this.cam_sphere.n_elements; 69 | this.vao.n_vertices = this.cam_sphere.n_vertices; 70 | 71 | this.upload_all_buffers(); 72 | 73 | this.vao.color = new THREE.Vector4(0.0, 0.2, 0.8, 1.0); 74 | } 75 | 76 | upload_all_buffers() { 77 | this.gl.useProgram(this.program); 78 | 79 | // -> vbo vertex 80 | this.vao.vbo_vertex = this.gl.createBuffer(); 81 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_vertex); 82 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.cam_sphere.vertices, this.gl.STATIC_DRAW); 83 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 84 | this.gl.enableVertexAttribArray(0); 85 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 86 | // <- 87 | 88 | // -> ebo 89 | this.vao.ebo = this.gl.createBuffer(); 90 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.ebo); 91 | this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.cam_sphere.elements, this.gl.STATIC_DRAW); 92 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 93 | // <- 94 | } 95 | 96 | 97 | set_trs(translation_matrix, rotation_matrix, scale_matrix) { 98 | this.translation_matrix.copy(translation_matrix); 99 | this.rotation_matrix.copy(rotation_matrix); 100 | this.scale_matrix.copy(scale_matrix); 101 | } 102 | 103 | draw(view_matrix, projection_matrix) { 104 | if (this.is_visible) { 105 | this.gl.useProgram(this.program); 106 | 107 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_vertex); 108 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 109 | this.gl.enableVertexAttribArray(0); 110 | 111 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.ebo); 112 | this.gl.uniform4f(this.gl.getUniformLocation(this.program, "color"), this.vao.color.x, this.vao.color.y, this.vao.color.z, this.vao.color.w); 113 | 114 | this.model_matrix.identity(); 115 | this.model_matrix.premultiply(this.scale_matrix); 116 | this.model_matrix.premultiply(this.rotation_matrix); 117 | this.model_matrix.premultiply(this.translation_matrix); 118 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 119 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "view_matrix"), false, new Float32Array(view_matrix.elements)); 120 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "projection_matrix"), false, new Float32Array(projection_matrix.elements)); 121 | 122 | this.gl.drawElements(this.gl.LINES, this.vao.n_elements*2, this.gl.UNSIGNED_SHORT, 0); 123 | 124 | this.gl.useProgram(null); 125 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 126 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 127 | } 128 | } 129 | 130 | advance(i_iteration, mspf) { 131 | 132 | 133 | } 134 | 135 | } 136 | 137 | export default CamSphereVAO; 138 | -------------------------------------------------------------------------------- /client/js/lib/vao/GLProgram.js: -------------------------------------------------------------------------------- 1 | 2 | class GLProgram { 3 | 4 | static init_webgl(canvas) { 5 | var gl = null; 6 | 7 | // Try to grab the standard context. If it fails, fallback to experimental. 8 | gl = canvas.getContext('webgl2'); 9 | 10 | // If we don't have a GL context, give up now 11 | if (!gl) { 12 | alert('Unable to initialize WebGL. Your browser may not support it.'); 13 | } 14 | 15 | return gl; 16 | } 17 | 18 | static compile_shaders_and_link_with_program(gl, src_vs, src_fs) { 19 | var vertex_shader = GLProgram.compile_shader(gl, src_vs, gl.VERTEX_SHADER); 20 | var fragment_shader = GLProgram.compile_shader(gl, src_fs, gl.FRAGMENT_SHADER); 21 | 22 | // Create the shader program 23 | 24 | var program = gl.createProgram(); 25 | gl.attachShader(program, vertex_shader); 26 | gl.attachShader(program, fragment_shader); 27 | gl.linkProgram(program); 28 | 29 | // If creating the shader program failed, alert 30 | 31 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 32 | console.log('Unable to initialize the shader program: ' + gl.getProgramInfoLog(program)); 33 | } 34 | 35 | return program; 36 | } 37 | 38 | static compile_shader(gl, src, type) { 39 | const shader = gl.createShader(type); 40 | gl.shaderSource(shader, src); 41 | 42 | // Compile the shader program 43 | gl.compileShader(shader); 44 | 45 | // See if it compiled successfully 46 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 47 | console.log('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader)); 48 | gl.deleteShader(shader); 49 | return null; 50 | } 51 | 52 | return shader; 53 | } 54 | } 55 | 56 | export default GLProgram; -------------------------------------------------------------------------------- /client/js/lib/vao/ImageVAO.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three/build/three'; 2 | 3 | import GLProgram from './GLProgram'; 4 | import * as TextureGLSL from '../shader/TextureGLSL'; 5 | 6 | class VAOOffscreen { 7 | constructor(gl) { 8 | this.gl = gl; 9 | this.program = null; 10 | 11 | this.vbo_position = null; 12 | this.vbo_label = null; 13 | this.ebo = null; 14 | 15 | this.type_ebo = null; 16 | 17 | this.n_vertices = 0; 18 | this.n_elements = 0; 19 | } 20 | 21 | set_vbo_position(position_buffer) { 22 | // -> vbo position 23 | this.vbo_position = this.gl.createBuffer(); 24 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_position); 25 | this.gl.bufferData(this.gl.ARRAY_BUFFER, position_buffer, this.gl.STATIC_DRAW); 26 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 27 | this.gl.enableVertexAttribArray(0); 28 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 29 | // <- 30 | } 31 | 32 | set_vbo_label(label_buffer) { 33 | // -> vbo labels 34 | this.vbo_label = this.gl.createBuffer(); 35 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_label); 36 | this.gl.bufferData(this.gl.ARRAY_BUFFER, label_buffer, this.gl.STATIC_DRAW); 37 | this.gl.vertexAttribIPointer(1, 1, this.gl.INT, 0, 0); 38 | this.gl.enableVertexAttribArray(1); 39 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 40 | // <- 41 | } 42 | 43 | set_ebo(index_buffer) { 44 | // -> ebo 45 | this.ebo = this.gl.createBuffer(); 46 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.ebo); 47 | this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, index_buffer, this.gl.STATIC_DRAW); 48 | // <- 49 | 50 | if (index_buffer instanceof Uint16Array) 51 | this.type_ebo = this.gl.UNSIGNED_SHORT; 52 | else if (index_buffer instanceof Uint32Array) 53 | this.type_ebo = this.gl.UNSIGNED_INT; 54 | 55 | } 56 | } 57 | 58 | class VAOMesh { 59 | constructor() { 60 | this.vbo_position = 0; 61 | this.vbo_uv = 0; 62 | this.tex = 0; 63 | this.ebo = 0; 64 | this.n_vertices = 0; 65 | this.n_elements = 0; 66 | this.type_ebo = null; 67 | } 68 | } 69 | 70 | class ImageVAO { 71 | constructor() { 72 | this.id = null; 73 | this.gl = null; 74 | this.program = null; 75 | this.vao = null; 76 | this.vao_offscreen = null; 77 | 78 | this.model_matrix = null; 79 | this.is_active = 0; 80 | this.is_visible = 0; 81 | 82 | } 83 | 84 | init(gl) { 85 | this.gl = gl; 86 | this.vao = new VAOMesh(); 87 | 88 | this.program = GLProgram.compile_shaders_and_link_with_program(this.gl, TextureGLSL.TextureVS, TextureGLSL.TextureFS); 89 | 90 | this.model_matrix = new THREE.Matrix4(); 91 | 92 | this.setup_vao(); 93 | } 94 | 95 | create_plane() { 96 | return { position : new Float32Array([ -1, 1, -1, -1, 1, -1, 1, 1]), 97 | uv : new Float32Array([0, 1, 0, 0, 1, 0, 1, 1]), 98 | n_vertices : 4, 99 | n_elements: -1}; 100 | } 101 | 102 | setup_vao() { 103 | this.gl.useProgram(this.program); 104 | let vao = this.vao; 105 | 106 | this.plane = this.create_plane(); 107 | 108 | vao.n_vertices = this.plane.n_vertices; 109 | vao.n_elements = -1; 110 | 111 | // -> vbo vertex 112 | vao.vbo_position = this.gl.createBuffer(); 113 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vao.vbo_position); 114 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.plane.position, this.gl.STATIC_DRAW); 115 | this.gl.vertexAttribPointer(0, 2, this.gl.FLOAT, false, 0, 0); 116 | this.gl.enableVertexAttribArray(0); 117 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 118 | // <- 119 | 120 | // -> vbo uv 121 | vao.vbo_uv = this.gl.createBuffer(); 122 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vao.vbo_uv); 123 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.plane.uv, this.gl.STATIC_DRAW); 124 | this.gl.vertexAttribPointer(1, 2, this.gl.FLOAT, false, 0, 0); 125 | this.gl.enableVertexAttribArray(1); 126 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 127 | // <- 128 | 129 | // -> texture 130 | this.gl.activeTexture(this.gl.TEXTURE0); 131 | vao.tex = this.gl.createTexture(); 132 | this.gl.bindTexture(this.gl.TEXTURE_2D, vao.tex); 133 | this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR); 134 | this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR); 135 | // <- 136 | 137 | } 138 | 139 | update_image(image) { 140 | 141 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.vao.tex); 142 | this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGB, image.width, image.height, 0, this.gl.RGB, this.gl.UNSIGNED_BYTE, image); 143 | let ar = image.height/image.width; 144 | this.model_matrix.makeScale(1, ar, 1); 145 | } 146 | 147 | draw(view_matrix, projection_matrix) { 148 | if (this.is_visible) { 149 | this.gl.useProgram(this.program); 150 | // this.gl.enable(this.gl.BLEND); 151 | this.gl.disable(this.gl.CULL_FACE); 152 | 153 | this.gl.activeTexture(this.gl.TEXTURE0); 154 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.vao.tex); 155 | 156 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_position); 157 | this.gl.vertexAttribPointer(0, 2, this.gl.FLOAT, false, 0, 0); 158 | this.gl.enableVertexAttribArray(0); 159 | 160 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_uv); 161 | this.gl.vertexAttribPointer(1, 2, this.gl.FLOAT, false, 0, 0); 162 | this.gl.enableVertexAttribArray(1); 163 | 164 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 165 | 166 | 167 | this.gl.drawArrays(this.gl.TRIANGLE_FAN, 0, this.vao.n_vertices); 168 | 169 | this.gl.useProgram(null); 170 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 171 | } 172 | } 173 | 174 | init_vao_offscreen(gl, position_buffer, label_buffer, index_buffer) { 175 | this.vao_offscreen = new VAOOffscreen(gl); 176 | this.vao_offscreen.program = GLProgram.compile_shaders_and_link_with_program(gl, PVVGLSL.PVVVS, PVVGLSL.PVVFS); 177 | this.vao_offscreen.n_vertices = position_buffer.length/3; 178 | this.vao_offscreen.n_elements = index_buffer.length/3; 179 | 180 | this.vao_offscreen.set_vbo_position(position_buffer); 181 | this.vao_offscreen.set_vbo_label(label_buffer); 182 | this.vao_offscreen.set_ebo(index_buffer); 183 | 184 | } 185 | 186 | draw_offscreen(view_matrix, projection_matrix) { 187 | if (this.is_visible) { 188 | let vao = this.vao_offscreen; 189 | let gl = vao.gl; 190 | gl.useProgram(vao.program); 191 | 192 | gl.enable(gl.CULL_FACE); 193 | 194 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.vbo_position); 195 | gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); 196 | gl.enableVertexAttribArray(0); 197 | 198 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.vbo_label); 199 | gl.vertexAttribIPointer(1, 1, gl.INT, 0, 0); 200 | gl.enableVertexAttribArray(1); 201 | 202 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 203 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "view_matrix"), false, view_matrix); 204 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "projection_matrix"), false, projection_matrix); 205 | 206 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vao.ebo); 207 | 208 | gl.drawElements(gl.TRIANGLES, vao.n_elements*3, this.vao.type_ebo, 0); 209 | 210 | gl.useProgram(null); 211 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 212 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 213 | } 214 | } 215 | 216 | } 217 | 218 | export default ImageVAO; 219 | -------------------------------------------------------------------------------- /client/js/lib/vao/KeypointVAO.js: -------------------------------------------------------------------------------- 1 | 2 | import GLProgram from './GLProgram.js'; 3 | 4 | import * as Shader from '../shader/PolygonInstanceGLSL.js'; 5 | import * as Icosahedron from '../geometry/Icosahedron'; 6 | 7 | class VAOMesh { 8 | constructor() { 9 | this.vbo_vertex = 0; 10 | this.vbo_position = 0; 11 | this.vbo_normal = 0; 12 | this.vbo_color = 0; 13 | this.vbo_label = 0; 14 | this.ebo = 0; 15 | this.n_vertices = 0; 16 | this.n_elements = 0; 17 | this.n_instance = 0; 18 | 19 | this.color = new THREE.Vector3(0.8, 0.2, 0.2); 20 | this.base_scale = 0.05; 21 | } 22 | } 23 | 24 | class KeypointVAO { 25 | init(gl) { 26 | this.gl = gl; 27 | this.program = GLProgram.compile_shaders_and_link_with_program(this.gl, Shader.PolygonInstanceVS, Shader.PolygonInstanceFS); 28 | this.gl.useProgram(this.program); 29 | 30 | this.is_visible = 0; 31 | 32 | this.sphere = null; 33 | this.n_instance_max = 256; 34 | this.position_buffer = new Float32Array(this.n_instance_max*3); 35 | this.label_buffer = new Int32Array(this.n_instance_max); 36 | 37 | this.last_position = new THREE.Vector3(0, 0, 0); 38 | this.position0 = new THREE.Vector3(0, 0, 0); 39 | 40 | this.scale_matrix = new THREE.Matrix4(); 41 | this.rotation_matrix = new THREE.Matrix4(); 42 | this.translation_matrix = new THREE.Matrix4(); 43 | this.model_matrix = new THREE.Matrix4(); 44 | 45 | this.vao = new VAOMesh(); 46 | this.init_vao(); 47 | } 48 | 49 | reinit(gl) { 50 | this.gl = gl; 51 | this.program = GLProgram.compile_shaders_and_link_with_program(this.gl, Shader.PolygonInstanceVS, Shader.PolygonInstanceFS); 52 | this.gl.useProgram(this.program); 53 | 54 | this.upload_all_buffers(); 55 | } 56 | 57 | reinit_gl(gl) { 58 | this.gl = gl; 59 | this.program = GLProgram.compile_shaders_and_link_with_program(this.gl, Shader.PolygonInstanceVS, Shader.PolygonInstanceFS); 60 | this.gl.useProgram(this.program); 61 | 62 | this.init_vao(); 63 | } 64 | 65 | set_color_to_green() { 66 | this.vao.color.set(0.2, 0.8, 0.2); 67 | } 68 | 69 | set_color_to_red() { 70 | this.vao.color.set(0.8, 0.2, 0.2); 71 | } 72 | 73 | set_color_to_blue() { 74 | this.vao.color.set(0.2, 0.2, 0.8); 75 | } 76 | 77 | set_trs(translation_matrix, rotation_matrix, scale_matrix) { 78 | this.translation_matrix.copy(translation_matrix); 79 | this.rotation_matrix.copy(rotation_matrix); 80 | this.scale_matrix.copy(scale_matrix); 81 | } 82 | 83 | set_trs_to_default() { 84 | this.translation_matrix.identity(); 85 | this.rotation_matrix.identity(); 86 | this.scale_matrix.identity(); 87 | } 88 | 89 | package_data() { 90 | let positions = this.get_position_as_array(); 91 | positions = [].concat.apply([], positions); 92 | const data = { 93 | n_keypoints: this.vao.n_instance, 94 | position: positions, 95 | }; 96 | return data; 97 | } 98 | 99 | 100 | init_vao() { 101 | this.gl.useProgram(this.program); 102 | 103 | this.sphere = Icosahedron.make_icosahedron(); 104 | this.vao.n_elements = this.sphere.n_elements; 105 | this.vao.n_vertices = this.sphere.n_vertices; 106 | // this.vao.n_instance = 0; 107 | 108 | this.upload_all_buffers(); 109 | 110 | // -> vbo instance labels 111 | // vao.vbo_label = this.gl.createBuffer(); 112 | // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vao.vbo_label); 113 | // // this.gl.bufferData(this.gl.ARRAY_BUFFER, label_buffer, this.gl.STATIC_DRAW); 114 | // this.gl.vertexAttribIPointer(2, 1, this.gl.INT, 0, 0); 115 | // this.gl.enableVertexAttribArray(2); 116 | // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 117 | // <- 118 | 119 | } 120 | upload_all_buffers() { 121 | 122 | // -> vbo vertex 123 | this.vao.vbo_vertex = this.gl.createBuffer(); 124 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_vertex); 125 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.sphere.vertices, this.gl.STATIC_DRAW); 126 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 127 | this.gl.enableVertexAttribArray(0); 128 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 129 | // <- 130 | 131 | // -> ebo 132 | this.vao.ebo = this.gl.createBuffer(); 133 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.ebo); 134 | this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.sphere.elements, this.gl.STATIC_DRAW); 135 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 136 | // <- 137 | 138 | // -> vbo instance position 139 | this.vao.vbo_position = this.gl.createBuffer(); 140 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_position); 141 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.position_buffer, this.gl.STATIC_DRAW); 142 | this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0); 143 | this.gl.enableVertexAttribArray(1); 144 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 145 | } 146 | 147 | calc_centroid() { 148 | // this.calc_model_matrix(); 149 | let n = this.vao.n_instance; 150 | let c = new THREE.Vector3(0, 0, 0); 151 | for (let i = 0; i < n; i++) { 152 | let c0 = new THREE.Vector3(0, 0, 0); 153 | c0.x += this.position_buffer[i*3 + 0]; 154 | c0.y += this.position_buffer[i*3 + 1]; 155 | c0.z += this.position_buffer[i*3 + 2]; 156 | 157 | c0.applyMatrix4(this.model_matrix); 158 | c.add(c0); 159 | } 160 | c.multiplyScalar(1.0/n); 161 | 162 | return c; 163 | } 164 | 165 | calc_centroid_local() { 166 | // this.calc_model_matrix(); 167 | let n = this.vao.n_instance; 168 | let c = new THREE.Vector3(0, 0, 0); 169 | for (let i = 0; i < n; i++) { 170 | let c0 = new THREE.Vector3(0, 0, 0); 171 | c0.x += this.position_buffer[i*3 + 0]; 172 | c0.y += this.position_buffer[i*3 + 1]; 173 | c0.z += this.position_buffer[i*3 + 2]; 174 | 175 | c.add(c0); 176 | } 177 | c.multiplyScalar(1.0/n); 178 | 179 | return c; 180 | } 181 | 182 | recenter() { 183 | const c = this.calc_centroid_local(); 184 | 185 | let n = this.vao.n_instance; 186 | for (let i = 0; i < n; i++) { 187 | this.position_buffer[i*3 + 0] -= c.x; 188 | this.position_buffer[i*3 + 1] -= c.y; 189 | this.position_buffer[i*3 + 2] -= c.z; 190 | } 191 | 192 | let trans = new THREE.Matrix4(); 193 | this.position0.add(c); 194 | trans.makeTranslation(c.x, c.y, c.z); 195 | this.translation_matrix.premultiply(trans); 196 | this.calc_model_matrix(); 197 | 198 | // -> vbo instance position 199 | this.gl.useProgram(this.program); 200 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_position); 201 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.position_buffer, this.gl.STATIC_DRAW); 202 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 203 | // <- 204 | 205 | } 206 | 207 | get_position_and_trs() { 208 | let position = [] 209 | for (let i = 0; i < this.vao.n_instance; i++) { 210 | let p = new THREE.Vector3(); 211 | p.x = this.position_buffer[i*3 + 0]; 212 | p.y = this.position_buffer[i*3 + 1]; 213 | p.z = this.position_buffer[i*3 + 2]; 214 | position.push([p.x, p.y, p.z]); 215 | } 216 | 217 | let cargo = {position: position, trs : this.model_matrix}; 218 | return cargo; 219 | } 220 | 221 | get_position_as_array() { 222 | let positions = [] 223 | for (let i = 0; i < this.vao.n_instance; i++) { 224 | let p = new THREE.Vector3(); 225 | p.x = this.position_buffer[i*3 + 0]; 226 | p.y = this.position_buffer[i*3 + 1]; 227 | p.z = this.position_buffer[i*3 + 2]; 228 | 229 | p.applyMatrix4(this.model_matrix); 230 | 231 | positions.push([p.x, p.y, p.z]); 232 | } 233 | return positions; 234 | } 235 | 236 | push_back_mesh(position, label) { 237 | let position1 = position.clone(); 238 | position1.sub(this.position0); 239 | this.position_buffer.set([position1.x, position1.y, position1.z], this.vao.n_instance*3); 240 | this.label_buffer.set([label], this.vao.n_instance); 241 | this.vao.n_instance++; 242 | this.last_position.copy(position1); 243 | 244 | // -> vbo instance position 245 | this.gl.useProgram(this.program); 246 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_position); 247 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.position_buffer, this.gl.STATIC_DRAW); 248 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 249 | // <- 250 | } 251 | 252 | pop() { 253 | this.vao.n_instance--; 254 | this.last_position.x = this.position_buffer[(this.vao.n_instance - 1)*3 + 0]; 255 | this.last_position.y = this.position_buffer[(this.vao.n_instance - 1)*3 + 1]; 256 | this.last_position.z = this.position_buffer[(this.vao.n_instance - 1)*3 + 2]; 257 | } 258 | 259 | set_to_zero() { 260 | this.vao.n_instance = 0; 261 | } 262 | 263 | set_position_from_array(position_array, n_size) { 264 | this.vao.n_instance = n_size; 265 | 266 | this.position_buffer.set(position_array, 0); 267 | this.label_buffer.set(new Int32Array(n_size), this.vao.n_instance); 268 | 269 | // -> vbo instance position 270 | this.gl.useProgram(this.program); 271 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_position); 272 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.position_buffer, this.gl.STATIC_DRAW); 273 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 274 | } 275 | 276 | update_attribute() { 277 | this.gl.useProgram(this.program); 278 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_position); 279 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.position_buffer, this.gl.STATIC_DRAW); 280 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 281 | } 282 | 283 | set_origin_position(position) { 284 | this.translation_matrix.makeTranslation(position.x, position.y, position.z); 285 | this.position0.copy(position); 286 | } 287 | 288 | get_last_position() { 289 | let pos = new THREE.Vector3(); 290 | pos.copy(this.last_position); 291 | pos.applyMatrix4(this.model_matrix); 292 | return pos; 293 | } 294 | 295 | calc_model_matrix() { 296 | this.model_matrix.identity(); 297 | this.model_matrix.premultiply(this.scale_matrix); 298 | this.model_matrix.premultiply(this.rotation_matrix); 299 | this.model_matrix.premultiply(this.translation_matrix); 300 | } 301 | 302 | draw(view_matrix, projection_matrix) { 303 | if (this.is_visible) { 304 | this.gl.useProgram(this.program); 305 | this.gl.enable(this.gl.DEPTH_TEST); 306 | this.gl.disable(this.gl.CULL_FACE); 307 | this.gl.vertexAttribDivisor(1, 1); 308 | 309 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_vertex); 310 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 311 | this.gl.enableVertexAttribArray(0); 312 | 313 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_position); 314 | this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0); 315 | this.gl.enableVertexAttribArray(1); 316 | 317 | // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_normal); 318 | // this.gl.vertexAttribPointer(2, 3, this.gl.FLOAT, false, 0, 0); 319 | // this.gl.enableVertexAttribArray(2); 320 | 321 | // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_label); 322 | // this.gl.vertexAttribIPointer(2, 1, this.gl.INT, 0, 0); 323 | // this.gl.enableVertexAttribArray(2); 324 | 325 | this.calc_model_matrix(); 326 | 327 | this.model_matrix.identity(); 328 | this.model_matrix.premultiply(this.scale_matrix); 329 | this.model_matrix.premultiply(this.rotation_matrix); 330 | this.model_matrix.premultiply(this.translation_matrix); 331 | 332 | this.gl.uniform1f(this.gl.getUniformLocation(this.program, "base_scale"), this.vao.base_scale); 333 | this.gl.uniform3f(this.gl.getUniformLocation(this.program, "color"), this.vao.color.x, this.vao.color.y, this.vao.color.z); 334 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 335 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "view_matrix"), false, new Float32Array(view_matrix.elements)); 336 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "projection_matrix"), false, new Float32Array(projection_matrix.elements)); 337 | 338 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.ebo); 339 | this.gl.drawElementsInstanced(this.gl.TRIANGLES, this.vao.n_elements*3, this.gl.UNSIGNED_SHORT, 0, this.vao.n_instance); 340 | 341 | 342 | this.gl.useProgram(null); 343 | this.gl.vertexAttribDivisor(1, 0); 344 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 345 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 346 | this.gl.enable(this.gl.CULL_FACE); 347 | } 348 | } 349 | 350 | advance() { 351 | 352 | } 353 | 354 | } 355 | 356 | export default KeypointVAO; 357 | -------------------------------------------------------------------------------- /client/js/lib/vao/PickVisibleVertex.js: -------------------------------------------------------------------------------- 1 | import GLProgram from './GLProgram.js'; 2 | import * as Shader from '../shader/PVVGLSL.js'; 3 | 4 | class VAOOffscreen { 5 | constructor() { 6 | this.fbo = null; 7 | this.rbo = null; 8 | this.rbo_depth = null; 9 | this.rbo_depth_dummy = null; 10 | } 11 | } 12 | 13 | class VAOMesh { 14 | constructor(gl) { 15 | this.gl = gl; 16 | 17 | this.vbo_position = null; 18 | this.vbo_label = null; 19 | this.ebo = null; 20 | this.type = ""; 21 | 22 | this.is_culling = 0; 23 | 24 | this.n_vertices = 0; 25 | this.n_elements = 0; 26 | this.n_instances = 0; 27 | 28 | } 29 | 30 | set_vbo_position(position_buffer) { 31 | // -> vbo position 32 | this.vbo_position = this.gl.createBuffer(); 33 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_position); 34 | this.gl.bufferData(this.gl.ARRAY_BUFFER, position_buffer, this.gl.STATIC_DRAW); 35 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 36 | this.gl.enableVertexAttribArray(0); 37 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 38 | // <- 39 | } 40 | 41 | set_vbo_label(label_buffer) { 42 | // -> vbo labels 43 | this.vbo_label = this.gl.createBuffer(); 44 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_label); 45 | this.gl.bufferData(this.gl.ARRAY_BUFFER, label_buffer, this.gl.STATIC_DRAW); 46 | this.gl.vertexAttribIPointer(1, 1, this.gl.INT, 0, 0); 47 | this.gl.enableVertexAttribArray(1); 48 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 49 | // <- 50 | } 51 | 52 | set_ebo(indices_buffer) { 53 | // -> ebo 54 | this.ebo = this.gl.createBuffer(); 55 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.ebo); 56 | this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, indices_buffer, this.gl.STATIC_DRAW); 57 | // <- 58 | } 59 | } 60 | 61 | class PickVisibleVertex { 62 | 63 | constructor() { 64 | this.gl = null; 65 | this.initialized = 0; 66 | 67 | this.is_active = 0; 68 | this.is_lock = 0; 69 | 70 | this.vertex_info = {id_mesh: 0, id_segment : 0}; 71 | this.pixel_depth = 0; 72 | } 73 | 74 | 75 | init(gl, window_width, window_height) { 76 | this.gl = gl; 77 | 78 | this.offscreen = new VAOOffscreen(); 79 | 80 | this.setup_fbo_and_rbo(gl, window_width, window_height); 81 | 82 | this.offscreen_image = new Uint8Array(4); 83 | this.offscreen_depth = new Uint8Array(4); 84 | 85 | this.initialized = 0; 86 | // <- 87 | } 88 | 89 | reinit(gl, window_width, window_height) { 90 | this.gl = gl; 91 | this.offscreen = new VAOOffscreen(); 92 | 93 | this.setup_fbo_and_rbo(gl, window_width, window_height); 94 | } 95 | 96 | setup_fbo_and_rbo(gl, window_width, window_height) { 97 | // -> framebuffer camera (offscreen) 98 | this.offscreen.fbo = this.gl.createFramebuffer(); 99 | gl.bindFramebuffer(gl.FRAMEBUFFER, this.offscreen.fbo); 100 | // <- 101 | 102 | // -> renderbuffer camera (offscreen) 103 | this.offscreen.rbo = gl.createRenderbuffer(); 104 | gl.bindRenderbuffer(gl.RENDERBUFFER, this.offscreen.rbo); 105 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, window_width/4.0, window_height/4.0); 106 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this.offscreen.rbo); 107 | if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) { 108 | console.log("Error with framebuffer (color)."); 109 | } 110 | 111 | this.offscreen.rbo_depth = gl.createRenderbuffer(); 112 | gl.bindRenderbuffer(gl.RENDERBUFFER, this.offscreen.rbo_depth); 113 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, window_width/4.0, window_height/4.0); 114 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, this.offscreen.rbo_depth); 115 | if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) { 116 | console.log("Error with framebuffer (depth)."); 117 | } 118 | 119 | this.offscreen.rbo_depth_dummy = gl.createRenderbuffer(); 120 | gl.bindRenderbuffer(gl.RENDERBUFFER, this.offscreen.rbo_depth_dummy); 121 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT24, window_width/4.0, window_height/4.0); 122 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.offscreen.rbo_depth_dummy); 123 | if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) { 124 | console.log("Error with framebuffer (depth dummy)."); 125 | } 126 | // <- 127 | 128 | gl.bindFramebuffer(gl.FRAMEBUFFER, null); 129 | gl.bindRenderbuffer(gl.RENDERBUFFER, null); 130 | } 131 | 132 | set_active(value = 1) { 133 | this.is_active = value; 134 | } 135 | 136 | get_vertex_info() { 137 | return this.vertex_info; 138 | } 139 | 140 | pick(pos_x, pos_y, view_matrix, projection_matrix, window_width, window_height, vao_list) { 141 | 142 | if (this.is_active && Object.keys(vao_list).length > 0) { 143 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.offscreen.fbo); 144 | this.gl.viewport(0, 0, window_width/4.0, window_height/4.0); 145 | 146 | this.gl.clearColor(0, 0, 0, 1.0); 147 | this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); 148 | this.gl.enable(this.gl.DEPTH_TEST); 149 | 150 | this.gl.drawBuffers([this.gl.COLOR_ATTACHMENT0, this.gl.COLOR_ATTACHMENT1]); 151 | 152 | for (let key in vao_list) { 153 | let vao = vao_list[key]; 154 | if (typeof vao.draw_offscreen == "function") 155 | vao.draw_offscreen(view_matrix, projection_matrix); 156 | } 157 | 158 | 159 | this.gl.readBuffer(this.gl.COLOR_ATTACHMENT0); 160 | this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.offscreen.rbo); 161 | this.gl.readPixels(pos_x/4.0, (window_height - pos_y)/4.0, 1, 1, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.offscreen_image, 0); 162 | 163 | this.vertex_info.id_mesh = this.offscreen_image[0]; 164 | this.vertex_info.id_segment = 0; 165 | this.vertex_info.id_segment |= this.offscreen_image[1] << 0; 166 | this.vertex_info.id_segment |= this.offscreen_image[2] << 8; 167 | // vertex_info.id_segment |= this.offscreen_image[3] << 16; // <-- disabled because of alpha issues in gl.clearColor 168 | 169 | this.gl.readBuffer(this.gl.COLOR_ATTACHMENT1); 170 | this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.offscreen.rbo_depth); 171 | this.gl.readPixels(pos_x/4.0, (window_height - pos_y)/4.0, 1, 1, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.offscreen_depth, 0); 172 | let dummy = 0; 173 | dummy |= this.offscreen_depth[0] << 0; 174 | dummy |= this.offscreen_depth[1] << 8; 175 | dummy |= this.offscreen_depth[2] << 16; 176 | this.pixel_depth = dummy/16777215.0; 177 | 178 | this.gl.viewport(0, 0, window_width, window_height); 179 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null); 180 | this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null); 181 | } 182 | } 183 | 184 | term() { 185 | 186 | } 187 | 188 | } 189 | 190 | export default PickVisibleVertex; 191 | -------------------------------------------------------------------------------- /client/js/lib/vao/RotationVAO.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three/build/three'; 2 | 3 | import GLProgram from './GLProgram'; 4 | import * as CircularArrow from '../geometry/CircularArrow'; 5 | import * as Shader from '../shader/PolygonGLSL'; 6 | import * as PVVGLSL from '../shader/PVVGLSL'; 7 | 8 | class VAOOffscreen { 9 | constructor(gl) { 10 | this.gl = gl; 11 | this.program = null; 12 | 13 | this.vbo_position = null; 14 | this.vbo_label = null; 15 | this.ebo = null; 16 | 17 | this.n_vertices = 0; 18 | this.n_elements = 0; 19 | } 20 | 21 | set_vbo_position(position_buffer) { 22 | // -> vbo position 23 | this.vbo_position = this.gl.createBuffer(); 24 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_position); 25 | this.gl.bufferData(this.gl.ARRAY_BUFFER, position_buffer, this.gl.STATIC_DRAW); 26 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 27 | this.gl.enableVertexAttribArray(0); 28 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 29 | // <- 30 | } 31 | 32 | set_vbo_label(label_buffer) { 33 | // -> vbo labels 34 | this.vbo_label = this.gl.createBuffer(); 35 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_label); 36 | this.gl.bufferData(this.gl.ARRAY_BUFFER, label_buffer, this.gl.STATIC_DRAW); 37 | this.gl.vertexAttribIPointer(1, 1, this.gl.INT, 0, 0); 38 | this.gl.enableVertexAttribArray(1); 39 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 40 | // <- 41 | } 42 | 43 | set_ebo(indices_buffer) { 44 | // -> ebo 45 | this.ebo = this.gl.createBuffer(); 46 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.ebo); 47 | this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, indices_buffer, this.gl.STATIC_DRAW); 48 | // <- 49 | } 50 | } 51 | 52 | class VAOMesh { 53 | constructor() { 54 | this.vbo_vertex = 0; 55 | this.ebo = 0; 56 | this.n_vertices = 0; 57 | this.n_elements = 0; 58 | 59 | this.color = new THREE.Vector4(1, 0 , 0, 1.0); 60 | } 61 | } 62 | 63 | class RotationVAO { 64 | init(gl) { 65 | this.gl = gl; 66 | this.program = GLProgram.compile_shaders_and_link_with_program(this.gl, Shader.PolygonVS, Shader.PolygonFS); 67 | this.gl.useProgram(this.program); 68 | 69 | this.id_mesh = 3; 70 | 71 | this.is_active = 0; 72 | this.is_visible = 0; 73 | this.is_done = 0; 74 | 75 | // -> uniforms 76 | this.model_matrix = new THREE.Matrix4();; 77 | this.rotation_matrix = new THREE.Matrix4();; 78 | this.translation_matrix = new THREE.Matrix4();; 79 | this.scale_matrix = new THREE.Matrix4();; 80 | // <- 81 | 82 | this.mesh = null; 83 | 84 | this.vao = new VAOMesh(); 85 | } 86 | 87 | set_active(value) { 88 | this.is_active = value; 89 | } 90 | 91 | 92 | set_color_to_yellow() { 93 | this.vao.color.set(231/255.0, 244/255.0, 115/255.0, 1.0); 94 | } 95 | 96 | set_pos(a, b, c) { 97 | this.gl.useProgram(this.program); 98 | 99 | this.mesh = CircularArrow.make_circular_arrow(a, b, c, this.id_mesh); 100 | this.set_color_to_yellow(); 101 | 102 | this.vao.n_elements = this.mesh.n_elements; 103 | this.vao.n_vertices = this.mesh.n_vertices; 104 | 105 | // -> vbo vertex 106 | this.vao.vbo_vertex = this.gl.createBuffer(); 107 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_vertex); 108 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.mesh.vertices, this.gl.STATIC_DRAW); 109 | this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0); 110 | this.gl.enableVertexAttribArray(1); 111 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 112 | // <- 113 | 114 | // -> ebo 115 | this.vao.ebo = this.gl.createBuffer(); 116 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.ebo); 117 | this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.mesh.elements, this.gl.STATIC_DRAW); 118 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 119 | // <- 120 | 121 | } 122 | 123 | 124 | set_trs(translation_matrix, rotation_matrix, scale_matrix) { 125 | this.translation_matrix.copy(translation_matrix); 126 | this.rotation_matrix.copy(rotation_matrix); 127 | this.scale_matrix.copy(scale_matrix); 128 | } 129 | 130 | draw(view_matrix, projection_matrix) { 131 | if (this.is_visible) { 132 | this.gl.useProgram(this.program); 133 | this.gl.enable(this.gl.DEPTH_TEST); 134 | this.gl.disable(this.gl.CULL_FACE); 135 | this.gl.disable(this.gl.BLEND); 136 | 137 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_vertex); 138 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 139 | this.gl.enableVertexAttribArray(0); 140 | 141 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.ebo); 142 | this.gl.uniform4f(this.gl.getUniformLocation(this.program, "color"), this.vao.color.x, this.vao.color.y, this.vao.color.z, this.vao.color.w); 143 | 144 | this.model_matrix.identity(); 145 | this.model_matrix.premultiply(this.scale_matrix); 146 | this.model_matrix.premultiply(this.rotation_matrix); 147 | this.model_matrix.premultiply(this.translation_matrix); 148 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 149 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "view_matrix"), false, new Float32Array(view_matrix.elements)); 150 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "projection_matrix"), false, new Float32Array(projection_matrix.elements)); 151 | 152 | this.gl.drawElements(this.gl.TRIANGLES, this.vao.n_elements*3, this.gl.UNSIGNED_INT, 0); 153 | 154 | this.gl.useProgram(null); 155 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 156 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 157 | this.gl.enable(this.gl.CULL_FACE); 158 | this.gl.enable(this.gl.DEPTH_TEST); 159 | 160 | } 161 | } 162 | 163 | advance(i_iteration, mspf) { 164 | 165 | 166 | } 167 | 168 | init_vao_offscreen(gl, position_buffer, label_buffer, index_buffer) { 169 | this.vao_offscreen = new VAOOffscreen(gl); 170 | this.vao_offscreen.program = GLProgram.compile_shaders_and_link_with_program(gl, PVVGLSL.PVVVS, PVVGLSL.PVVFS); 171 | this.vao_offscreen.n_vertices = position_buffer.length/3; 172 | this.vao_offscreen.n_elements = index_buffer.length/3; 173 | 174 | this.vao_offscreen.set_vbo_position(position_buffer); 175 | this.vao_offscreen.set_vbo_label(label_buffer); 176 | this.vao_offscreen.set_ebo(index_buffer); 177 | 178 | } 179 | 180 | draw_offscreen(view_matrix, projection_matrix) { 181 | if (this.is_visible) { 182 | let vao = this.vao_offscreen; 183 | let gl = vao.gl; 184 | gl.useProgram(vao.program); 185 | gl.enable(gl.DEPTH_TEST); 186 | gl.disable(gl.CULL_FACE); 187 | 188 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.vbo_position); 189 | gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); 190 | gl.enableVertexAttribArray(0); 191 | 192 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.vbo_label); 193 | gl.vertexAttribIPointer(1, 1, gl.INT, 0, 0); 194 | gl.enableVertexAttribArray(1); 195 | 196 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 197 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "view_matrix"), false, view_matrix); 198 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "projection_matrix"), false, projection_matrix); 199 | 200 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vao.ebo); 201 | gl.drawElements(gl.TRIANGLES, vao.n_elements*3, gl.UNSIGNED_INT, 0); 202 | 203 | gl.useProgram(null); 204 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 205 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 206 | gl.disable(gl.CULL_FACE); 207 | gl.disable(gl.BLEND); 208 | gl.enable(gl.DEPTH_TEST); 209 | } 210 | } 211 | 212 | 213 | } 214 | 215 | export default RotationVAO; 216 | -------------------------------------------------------------------------------- /client/js/lib/vao/ScaleVAO.js: -------------------------------------------------------------------------------- 1 | import * as THREE from "three/build/three"; 2 | 3 | import GLProgram from "./GLProgram"; 4 | import * as CoordArrow from "../geometry/CoordArrow"; 5 | import * as Arrow from "../geometry/Arrow"; 6 | import * as Shader from "../shader/PolygonGLSL"; 7 | import * as PVVGLSL from "../shader/PVVGLSL"; 8 | 9 | class VAOOffscreen { 10 | constructor(gl) { 11 | this.gl = gl; 12 | this.program = null; 13 | 14 | this.vbo_position = null; 15 | this.vbo_label = null; 16 | this.ebo = null; 17 | 18 | this.n_vertices = 0; 19 | this.n_elements = 0; 20 | } 21 | 22 | set_vbo_position(position_buffer) { 23 | // -> vbo position 24 | this.vbo_position = this.gl.createBuffer(); 25 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_position); 26 | this.gl.bufferData(this.gl.ARRAY_BUFFER, position_buffer, this.gl.STATIC_DRAW); 27 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 28 | this.gl.enableVertexAttribArray(0); 29 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 30 | // <- 31 | } 32 | 33 | set_vbo_label(label_buffer) { 34 | // -> vbo labels 35 | this.vbo_label = this.gl.createBuffer(); 36 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_label); 37 | this.gl.bufferData(this.gl.ARRAY_BUFFER, label_buffer, this.gl.STATIC_DRAW); 38 | this.gl.vertexAttribIPointer(1, 1, this.gl.INT, 0, 0); 39 | this.gl.enableVertexAttribArray(1); 40 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 41 | // <- 42 | } 43 | 44 | set_ebo(indices_buffer) { 45 | // -> ebo 46 | this.ebo = this.gl.createBuffer(); 47 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.ebo); 48 | this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, indices_buffer, this.gl.STATIC_DRAW); 49 | // <- 50 | } 51 | } 52 | 53 | class VAOMesh { 54 | constructor() { 55 | this.vbo_vertex = 0; 56 | this.ebo = 0; 57 | this.n_vertices = 0; 58 | this.n_elements = 0; 59 | 60 | this.color = new THREE.Vector4(1, 0 , 0, 0.5); 61 | } 62 | } 63 | 64 | class ScaleVAO { 65 | init(gl) { 66 | this.gl = gl; 67 | this.program = GLProgram.compile_shaders_and_link_with_program(this.gl, Shader.PolygonVS, Shader.PolygonFS); 68 | this.gl.useProgram(this.program); 69 | 70 | this.id_mesh = 2; 71 | 72 | this.is_active = 0; 73 | this.is_visible = 0; 74 | this.is_done = 0; 75 | 76 | // -> uniforms 77 | this.model_matrix = new THREE.Matrix4();; 78 | this.rotation_matrix = new THREE.Matrix4();; 79 | this.translation_matrix = new THREE.Matrix4();; 80 | this.scale_matrix = new THREE.Matrix4();; 81 | // <- 82 | 83 | this.mesh = null; 84 | 85 | this.vao = new VAOMesh(); 86 | } 87 | 88 | set_active(value) { 89 | this.is_active = value; 90 | } 91 | 92 | 93 | set_color_to_red() { 94 | this.vao.color.set(254/255.0, 190/255.0, 175/255.0, 1.0); 95 | } 96 | 97 | set_pos(a, b, c) { 98 | this.gl.useProgram(this.program); 99 | 100 | this.mesh = Arrow.make_arrow(a*1.1, b*1.1, c*1.1, this.id_mesh); 101 | this.set_color_to_red(); 102 | 103 | this.vao.n_elements = this.mesh.n_elements; 104 | this.vao.n_vertices = this.mesh.n_vertices; 105 | 106 | // -> vbo vertex 107 | this.vao.vbo_vertex = this.gl.createBuffer(); 108 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_vertex); 109 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.mesh.vertices, this.gl.STATIC_DRAW); 110 | this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0); 111 | this.gl.enableVertexAttribArray(1); 112 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 113 | // <- 114 | 115 | // -> ebo 116 | this.vao.ebo = this.gl.createBuffer(); 117 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.ebo); 118 | this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.mesh.elements, this.gl.STATIC_DRAW); 119 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 120 | // <- 121 | 122 | } 123 | 124 | 125 | set_trs(translation_matrix, rotation_matrix, scale_matrix) { 126 | this.translation_matrix.copy(translation_matrix); 127 | this.rotation_matrix.copy(rotation_matrix); 128 | this.scale_matrix.copy(scale_matrix); 129 | } 130 | 131 | draw(view_matrix, projection_matrix) { 132 | if (this.is_visible) { 133 | this.gl.useProgram(this.program); 134 | this.gl.enable(this.gl.DEPTH_TEST); 135 | this.gl.disable(this.gl.CULL_FACE); 136 | 137 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.vbo_vertex); 138 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 139 | this.gl.enableVertexAttribArray(0); 140 | 141 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.ebo); 142 | this.gl.uniform4f(this.gl.getUniformLocation(this.program, "color"), this.vao.color.x, this.vao.color.y, this.vao.color.z, this.vao.color.w); 143 | 144 | this.model_matrix.identity(); 145 | this.model_matrix.premultiply(this.scale_matrix); 146 | this.model_matrix.premultiply(this.rotation_matrix); 147 | this.model_matrix.premultiply(this.translation_matrix); 148 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 149 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "view_matrix"), false, new Float32Array(view_matrix.elements)); 150 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "projection_matrix"), false, new Float32Array(projection_matrix.elements)); 151 | 152 | this.gl.drawElements(this.gl.TRIANGLES, this.vao.n_elements*3, this.gl.UNSIGNED_INT, 0); 153 | 154 | this.gl.useProgram(null); 155 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 156 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 157 | this.gl.enable(this.gl.CULL_FACE); 158 | } 159 | } 160 | 161 | advance(i_iteration, mspf) { 162 | 163 | 164 | } 165 | 166 | init_vao_offscreen(gl, position_buffer, label_buffer, index_buffer) { 167 | this.vao_offscreen = new VAOOffscreen(gl); 168 | this.vao_offscreen.program = GLProgram.compile_shaders_and_link_with_program(gl, PVVGLSL.PVVVS, PVVGLSL.PVVFS); 169 | this.vao_offscreen.n_vertices = position_buffer.length/3; 170 | this.vao_offscreen.n_elements = index_buffer.length/3; 171 | 172 | this.vao_offscreen.set_vbo_position(position_buffer); 173 | this.vao_offscreen.set_vbo_label(label_buffer); 174 | this.vao_offscreen.set_ebo(index_buffer); 175 | 176 | } 177 | 178 | draw_offscreen(view_matrix, projection_matrix) { 179 | if (this.is_visible) { 180 | let vao = this.vao_offscreen; 181 | let gl = vao.gl; 182 | gl.useProgram(vao.program); 183 | gl.enable(gl.DEPTH_TEST); 184 | gl.disable(gl.CULL_FACE); 185 | 186 | 187 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.vbo_position); 188 | gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); 189 | gl.enableVertexAttribArray(0); 190 | 191 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.vbo_label); 192 | gl.vertexAttribIPointer(1, 1, gl.INT, 0, 0); 193 | gl.enableVertexAttribArray(1); 194 | 195 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 196 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "view_matrix"), false, view_matrix); 197 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "projection_matrix"), false, projection_matrix); 198 | 199 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vao.ebo); 200 | gl.drawElements(gl.TRIANGLES, vao.n_elements*3, gl.UNSIGNED_INT, 0); 201 | 202 | gl.useProgram(null); 203 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 204 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 205 | gl.enable(gl.CULL_FACE); 206 | gl.enable(gl.DEPTH_TEST); 207 | 208 | } 209 | } 210 | 211 | 212 | } 213 | 214 | export default ScaleVAO; 215 | -------------------------------------------------------------------------------- /client/js/lib/vao/SimpleVAO.js: -------------------------------------------------------------------------------- 1 | 2 | import GLProgram from './GLProgram.js'; 3 | 4 | import * as THREE from 'three/build/three'; 5 | import * as PVVGLSL from '../shader/PVVGLSL'; 6 | 7 | 8 | class VAOOffscreen { 9 | constructor(gl) { 10 | this.gl = gl; 11 | this.program = null; 12 | 13 | this.vbo_position = null; 14 | this.vbo_label = null; 15 | 16 | this.n_vertices = 0; 17 | } 18 | 19 | set_vbo_position(position_buffer) { 20 | // -> vbo position 21 | this.vbo_position = this.gl.createBuffer(); 22 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_position); 23 | this.gl.bufferData(this.gl.ARRAY_BUFFER, position_buffer, this.gl.STATIC_DRAW); 24 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 25 | this.gl.enableVertexAttribArray(0); 26 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 27 | // <- 28 | } 29 | 30 | set_vbo_label(label_buffer) { 31 | // -> vbo labels 32 | this.vbo_label = this.gl.createBuffer(); 33 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vbo_label); 34 | this.gl.bufferData(this.gl.ARRAY_BUFFER, label_buffer, this.gl.STATIC_DRAW); 35 | this.gl.vertexAttribIPointer(1, 1, this.gl.INT, 0, 0); 36 | this.gl.enableVertexAttribArray(1); 37 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 38 | // <- 39 | } 40 | } 41 | class SimpleVAO { 42 | init() { 43 | this.vao_offscreen = null; 44 | 45 | this.model_matrix = new THREE.Matrix4(); 46 | this.scale_matrix = new THREE.Matrix4(); 47 | this.translation_matrix = new THREE.Matrix4(); 48 | this.rotation_matrix = new THREE.Matrix4(); 49 | } 50 | 51 | set_trs(translation_matrix, rotation_matrix, scale_matrix) { 52 | this.translation_matrix.copy(translation_matrix); 53 | this.rotation_matrix.copy(rotation_matrix); 54 | this.scale_matrix.copy(scale_matrix); 55 | 56 | this.model_matrix.identity(); 57 | this.model_matrix.premultiply(this.scale_matrix); 58 | this.model_matrix.premultiply(this.rotation_matrix); 59 | this.model_matrix.premultiply(this.translation_matrix); 60 | } 61 | 62 | init_vao_offscreen(gl, position_buffer, label_buffer) { 63 | this.vao_offscreen = new VAOOffscreen(gl); 64 | this.vao_offscreen.program = GLProgram.compile_shaders_and_link_with_program(gl, PVVGLSL.PVVVS, PVVGLSL.PVVFS); 65 | 66 | this.vao_offscreen.n_vertices = position_buffer.length/3; 67 | 68 | this.vao_offscreen.set_vbo_position(position_buffer); 69 | this.vao_offscreen.set_vbo_label(label_buffer); 70 | } 71 | 72 | draw_offscreen(view_matrix, projection_matrix) { 73 | let vao = this.vao_offscreen; 74 | let gl = this.vao_offscreen.gl; 75 | gl.useProgram(vao.program); 76 | gl.enable(gl.CULL_FACE); 77 | 78 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.vbo_position); 79 | gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); 80 | gl.enableVertexAttribArray(1); 81 | 82 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.vbo_label); 83 | gl.vertexAttribIPointer(1, 1, gl.INT, 0, 0); 84 | gl.enableVertexAttribArray(1); 85 | 86 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 87 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "projection_matrix"), false, projection_matrix); 88 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.program, "view_matrix"), false, view_matrix); 89 | 90 | gl.drawArrays(gl.TRIANGLES, 0, vao.n_vertices); 91 | 92 | gl.useProgram(null); 93 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 94 | } 95 | 96 | } 97 | 98 | export default SimpleVAO; 99 | -------------------------------------------------------------------------------- /client/js/lib/vao/ThickWireframe.js: -------------------------------------------------------------------------------- 1 | import GLProgram from "../webgl/GLProgram"; 2 | import * as PolygonColorGLSL from "../shader/PolygonColorGLSL"; 3 | import * as Beam from "../../lib/geometry/Beam" 4 | import * as math from 'mathjs'; 5 | 6 | class VAOType { 7 | constructor() { 8 | this.id_program = null; 9 | this.id_vbo_verts = null; 10 | this.id_vbo_normals = null; 11 | this.id_vbo_colors = null; 12 | 13 | this.id_ebo = null; 14 | 15 | this.n_vertices = 0; 16 | this.n_elements = 0; 17 | } 18 | } 19 | 20 | class ThickWireframe { 21 | 22 | init(gl) { 23 | this.gl = gl; 24 | this.vao = new VAOType(); 25 | 26 | this.vao.id_program = GLProgram.compile_shaders_and_link_with_program(this.gl, PolygonColorGLSL.VS, PolygonColorGLSL.FS); 27 | this.gl.useProgram(this.vao.id_program); 28 | 29 | this.scale_matrix = new THREE.Matrix4(); 30 | this.rotation_matrix = new THREE.Matrix4(); 31 | this.translation_matrix = new THREE.Matrix4(); 32 | this.model_matrix = new THREE.Matrix4(); 33 | 34 | this.is_visible = false; 35 | 36 | } 37 | 38 | edges2mesh(data) { 39 | 40 | let n_edges = data["n_edges"]; 41 | let verts = []; 42 | let normals = []; 43 | let colors = []; 44 | let faces = []; 45 | let n_verts = 0; 46 | let n_faces = 0; 47 | 48 | for (let i = 0; i < n_edges; i++) { 49 | let p0 = data["verts"][data["edges"][i][0]]; 50 | let p1 = data["verts"][data["edges"][i][1]]; 51 | let beam = Beam.create_beam(0.05, p0, p1); 52 | verts = verts.concat(beam.vertices); 53 | normals = normals.concat(beam.normals); 54 | let c = [Math.random(), Math.random(), Math.random()]; 55 | for (let j = 0; j < beam.vertices.length; j++) { 56 | colors.push(c); 57 | } 58 | beam.faces = math.add(n_verts, math.matrix(beam.faces)).valueOf(); 59 | faces = faces.concat(beam.faces); 60 | n_verts += beam.vertices.length; 61 | n_faces += beam.faces.length; 62 | } 63 | 64 | 65 | verts = new Float32Array(verts.reduce(function(prev, curr) { 66 | return prev.concat(curr); 67 | }, [])); 68 | normals = new Float32Array(normals.reduce(function(prev, curr) { 69 | return prev.concat(curr); 70 | }, [])); 71 | colors = new Float32Array(colors.reduce(function(prev, curr) { 72 | return prev.concat(curr); 73 | }, [])); 74 | faces = new Uint32Array(faces.reduce(function(prev, curr) { 75 | return prev.concat(curr); 76 | }, [])); 77 | 78 | return {"n_verts" : n_verts, "n_faces" : n_faces, "verts" : verts, "faces" : faces, "normals" : normals, "colors" : colors}; 79 | } 80 | 81 | upload_data(mesh_data) { 82 | this.gl.useProgram(this.vao.id_program); 83 | 84 | this.vao.n_vertices = mesh_data["n_verts"]; 85 | this.vao.n_elements = mesh_data["n_faces"] 86 | 87 | this.vao.id_vbo_verts = this.gl.createBuffer(); 88 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_verts); 89 | this.gl.bufferData(this.gl.ARRAY_BUFFER, mesh_data["verts"], this.gl.STATIC_DRAW); 90 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 91 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 92 | 93 | this.vao.id_vbo_normals = this.gl.createBuffer(); 94 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_normals); 95 | this.gl.bufferData(this.gl.ARRAY_BUFFER, mesh_data["normals"], this.gl.STATIC_DRAW); 96 | this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0); 97 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 98 | 99 | this.vao.id_vbo_colors = this.gl.createBuffer(); 100 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_colors); 101 | this.gl.bufferData(this.gl.ARRAY_BUFFER, mesh_data["colors"], this.gl.STATIC_DRAW); 102 | this.gl.vertexAttribPointer(2, 3, this.gl.FLOAT, false, 0, 0); 103 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 104 | 105 | 106 | // -> ebo 107 | this.vao.id_ebo = this.gl.createBuffer(); 108 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.id_ebo); 109 | this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, mesh_data["faces"], this.gl.STATIC_DRAW); 110 | this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 111 | // <- 112 | 113 | 114 | } 115 | 116 | calc_model_matrix() { 117 | this.model_matrix.identity(); 118 | this.model_matrix.premultiply(this.scale_matrix); 119 | this.model_matrix.premultiply(this.rotation_matrix); 120 | this.model_matrix.premultiply(this.translation_matrix); 121 | } 122 | 123 | 124 | draw(model_matrix, view_matrix, projection_matrix) { 125 | if (this.is_visible) { 126 | let vao = this.vao; 127 | let gl = this.gl; 128 | 129 | gl.useProgram(this.vao.id_program); 130 | gl.disable(gl.CULL_FACE); 131 | gl.enable(gl.DEPTH_TEST); 132 | 133 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.id_vbo_verts); 134 | gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); 135 | gl.enableVertexAttribArray(0); 136 | 137 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.id_vbo_normals); 138 | gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0); 139 | gl.enableVertexAttribArray(1); 140 | 141 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.id_vbo_colors); 142 | gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0); 143 | gl.enableVertexAttribArray(2); 144 | 145 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.id_program, "model_matrix"), false, new Float32Array(model_matrix.elements)); 146 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.id_program, "view_matrix"), false, new Float32Array(view_matrix.elements)); 147 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.id_program, "projection_matrix"), false, new Float32Array(projection_matrix.elements)); 148 | 149 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vao.id_ebo); 150 | gl.drawElements(gl.TRIANGLES, vao.n_elements*3, gl.UNSIGNED_INT, 0); 151 | 152 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 153 | gl.useProgram(null); 154 | gl.enable(gl.CULL_FACE); 155 | } 156 | } 157 | } 158 | 159 | export default ThickWireframe; 160 | -------------------------------------------------------------------------------- /client/js/lib/vao/VoxelGrid.js: -------------------------------------------------------------------------------- 1 | import GLProgram from "../webgl/GLProgram"; 2 | import * as PolygonInstanceGLSL from "../shader/PolygonInstanceGLSL"; 3 | 4 | class VAOType { 5 | constructor() { 6 | this.id_program = null; 7 | this.id_vbo_vertex = null; 8 | this.id_vbo_normal = null; 9 | this.id_vbo_positions = null; 10 | this.id_vbo_colors = null; 11 | 12 | this.n_vertices = 0; 13 | this.n_instances = 0; 14 | } 15 | } 16 | 17 | class VoxelGrid { 18 | constructor() { 19 | this.is_active = false; 20 | } 21 | 22 | init(gl) { 23 | this.gl = gl; 24 | this.vao = new VAOType(); 25 | 26 | this.vao.id_program = GLProgram.compile_shaders_and_link_with_program(this.gl, PolygonInstanceGLSL.VS, PolygonInstanceGLSL.FS); 27 | this.gl.useProgram(this.vao.id_program); 28 | 29 | this.vao.id_vbo_vertex = this.gl.createBuffer(); 30 | 31 | this.vao.id_vbo_normal = this.gl.createBuffer(); 32 | 33 | this.vao.id_vbo_positions = this.gl.createBuffer(); 34 | 35 | this.vao.id_vbo_colors = this.gl.createBuffer(); 36 | 37 | this.gl.enable(this.gl.DEPTH_TEST); 38 | this.gl.enable(this.gl.CULL_FACE); 39 | } 40 | 41 | upload_data(n_vertices, n_instances, vertices, normals, positions, colors) { 42 | this.gl.useProgram(this.vao.id_program); 43 | 44 | this.vao.n_vertices = n_vertices; 45 | this.vao.n_instances = n_instances; 46 | 47 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_vertex); 48 | this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW); 49 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 50 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 51 | 52 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_normal); 53 | this.gl.bufferData(this.gl.ARRAY_BUFFER, normals, this.gl.STATIC_DRAW); 54 | this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0); 55 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 56 | 57 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_positions); 58 | this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW); 59 | this.gl.vertexAttribPointer(2, 3, this.gl.FLOAT, false, 0, 0); 60 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 61 | 62 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_colors); 63 | this.gl.bufferData(this.gl.ARRAY_BUFFER, colors, this.gl.STATIC_DRAW); 64 | this.gl.vertexAttribPointer(3, 3, this.gl.FLOAT, false, 0, 0); 65 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 66 | 67 | } 68 | 69 | set_active() { 70 | this.is_active = true; 71 | } 72 | 73 | 74 | draw(scale, model_matrix, view_matrix, projection_matrix) { 75 | if (this.is_active) { 76 | let vao = this.vao; 77 | let gl = this.gl; 78 | 79 | gl.useProgram(this.vao.id_program); 80 | gl.vertexAttribDivisor(2, 1); 81 | gl.vertexAttribDivisor(3, 1); 82 | 83 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.id_vbo_vertex); 84 | gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); 85 | gl.enableVertexAttribArray(0); 86 | 87 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.id_vbo_normal); 88 | gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0); 89 | gl.enableVertexAttribArray(1); 90 | 91 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.id_vbo_positions); 92 | gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0); 93 | gl.enableVertexAttribArray(2); 94 | 95 | gl.bindBuffer(gl.ARRAY_BUFFER, vao.id_vbo_colors); 96 | gl.vertexAttribPointer(3, 3, gl.FLOAT, false, 0, 0); 97 | gl.enableVertexAttribArray(3); 98 | 99 | gl.uniform1f(gl.getUniformLocation(vao.id_program, "scale"), scale); 100 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.id_program, "model_matrix"), false, new Float32Array(model_matrix.elements)); 101 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.id_program, "view_matrix"), false, new Float32Array(view_matrix.elements)); 102 | gl.uniformMatrix4fv(gl.getUniformLocation(vao.id_program, "projection_matrix"), false, new Float32Array(projection_matrix.elements)); 103 | 104 | gl.drawArraysInstanced(gl.TRIANGLES, 0, vao.n_vertices, vao.n_instances); 105 | 106 | gl.useProgram(null); 107 | gl.vertexAttribDivisor(2, 0); 108 | gl.vertexAttribDivisor(3, 0); 109 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 110 | } 111 | } 112 | } 113 | 114 | export default VoxelGrid; 115 | -------------------------------------------------------------------------------- /client/js/lib/vao/Wireframe.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three/build/three'; 2 | 3 | import GLProgram from './GLProgram.js'; 4 | import * as Shader from '../shader/PolygonColorGLSL.js'; 5 | 6 | class VAOMesh { 7 | constructor() { 8 | this.id_vbo_vertex = 0; 9 | this.id_vbo_norm = 0; 10 | this.id_vbo_color = 0; 11 | this.ebo = 0; 12 | this.n_vertices = 0; 13 | this.n_elements = 0; 14 | this.n_instance = 0; 15 | 16 | this.color = null; 17 | } 18 | } 19 | 20 | class Wireframe { 21 | init(gl) { 22 | this.gl = gl; 23 | this.program = GLProgram.compile_shaders_and_link_with_program(this.gl, Shader.VS, Shader.FS); 24 | this.gl.useProgram(this.program); 25 | 26 | this.is_active = 0; 27 | this.is_visible = 0; 28 | this.is_done = 0; 29 | 30 | // -> uniforms 31 | this.model_matrix = new THREE.Matrix4();; 32 | this.rotation_matrix = new THREE.Matrix4();; 33 | this.translation_matrix = new THREE.Matrix4();; 34 | this.scale_matrix = new THREE.Matrix4();; 35 | // <- 36 | 37 | this.box = null; 38 | 39 | this.vao = new VAOMesh(); 40 | this.init_vao(); 41 | } 42 | 43 | set_active(value) { 44 | this.is_active = value; 45 | } 46 | 47 | make_box(a, b, c) { 48 | 49 | return { vertices : new Float32Array([ 50 | -a, -b, -c, a, -b, -c, // x 51 | -a, -b, c, a, -b, c, // x 52 | -a, b, -c, a, b, -c, // x 53 | -a, b, c, a, b, c, // x 54 | 55 | -a, -b, -c, -a, b, -c, // y 56 | a, -b, -c, a, b, -c, // y 57 | -a, -b, c, -a, b, c, // y 58 | a, -b, c, a, b, c, // y 59 | 60 | -a, -b, -c, -a, -b, c, // z 61 | a, -b, -c, a, -b, c, // z 62 | -a, b, -c, -a, b, c, // z 63 | a, b, -c, a, b, c]), 64 | 65 | colors : new Float32Array([ 66 | 0, 0, 0, 1, 0, 0, 67 | 1, 0, 0, 1, 0, 0, 68 | 1, 0, 0, 1, 0, 0, 69 | 1, 0, 0, 1, 1, 1, 70 | 71 | 0, 0, 0, 0, 1, 0, 72 | 0, 1, 0, 0, 1, 0, 73 | 0, 1, 0, 0, 1, 0, 74 | 0, 1, 0, 1, 1, 1, 75 | 76 | 0, 0, 0, 0, 0, 1, 77 | 0, 0, 1, 0, 0, 1, 78 | 0, 0, 1, 0, 0, 1, 79 | 0, 0, 1, 1, 1, 1]), 80 | elements: new Uint16Array([]), 81 | n_vertices : 24, 82 | n_elements: 0}; 83 | } 84 | 85 | init_vao() { 86 | this.gl.useProgram(this.program); 87 | 88 | this.box = this.make_box(0.5, 0.5, 0.5); 89 | this.vao.n_vertices = this.box.n_vertices; 90 | this.vao.n_elements = this.box.n_elements; 91 | 92 | // -> vbo vertex 93 | this.vao.id_vbo_vertex = this.gl.createBuffer(); 94 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_vertex); 95 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.box.vertices, this.gl.STATIC_DRAW); 96 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 97 | this.gl.enableVertexAttribArray(0); 98 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 99 | // <- 100 | 101 | // -> vbo normal 102 | let dummy_normals = new Float32Array(this.box.n_vertices*3); 103 | dummy_normals.fill(0); 104 | this.vao.id_vbo_normal = this.gl.createBuffer(); 105 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_normal); 106 | this.gl.bufferData(this.gl.ARRAY_BUFFER, dummy_normals, this.gl.STATIC_DRAW); // <-- dummy fill 107 | this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0); 108 | this.gl.enableVertexAttribArray(1); 109 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 110 | // <- 111 | 112 | // -> vbo color 113 | this.vao.id_vbo_color = this.gl.createBuffer(); 114 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_color); 115 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.box.colors, this.gl.STATIC_DRAW); 116 | this.gl.vertexAttribPointer(2, 3, this.gl.FLOAT, false, 0, 0); 117 | this.gl.enableVertexAttribArray(2); 118 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 119 | // <- 120 | 121 | // -> ebo 122 | //this.vao.ebo = this.gl.createBuffer(); 123 | //this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vao.ebo); 124 | //this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.box.elements, this.gl.STATIC_DRAW); 125 | //this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null); 126 | // <- 127 | } 128 | 129 | update_box(a, b, c) { 130 | this.box = this.make_box(a, b, c); 131 | 132 | // -> vbo vertex 133 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_vertex); 134 | this.gl.bufferData(this.gl.ARRAY_BUFFER, this.box.vertices, this.gl.STATIC_DRAW); 135 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 136 | this.gl.enableVertexAttribArray(1); 137 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 138 | // <- 139 | } 140 | 141 | set_trsc(translation_matrix, rotation_matrix, scale_matrix) { 142 | this.translation_matrix.copy(translation_matrix); 143 | this.rotation_matrix.copy(rotation_matrix); 144 | this.scale_matrix.copy(scale_matrix); 145 | this.vao.color = new THREE.Vector4(1, 0, 0, 1.0); 146 | } 147 | 148 | draw(view_matrix, projection_matrix) { 149 | if (this.is_visible) { 150 | this.gl.useProgram(this.program); 151 | 152 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_vertex); 153 | this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0); 154 | this.gl.enableVertexAttribArray(0); 155 | 156 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_normal); 157 | this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0); 158 | this.gl.enableVertexAttribArray(1); 159 | 160 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vao.id_vbo_color); 161 | this.gl.vertexAttribPointer(2, 3, this.gl.FLOAT, false, 0, 0); 162 | this.gl.enableVertexAttribArray(2); 163 | 164 | 165 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "model_matrix"), false, new Float32Array(this.model_matrix.elements)); 166 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "view_matrix"), false, new Float32Array(view_matrix.elements)); 167 | this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.program, "projection_matrix"), false, new Float32Array(projection_matrix.elements)); 168 | 169 | this.gl.drawArrays(this.gl.LINES, 0, 24) 170 | 171 | this.gl.useProgram(null); 172 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null); 173 | } 174 | } 175 | 176 | advance(i_iteration, mspf) { 177 | 178 | 179 | } 180 | 181 | } 182 | 183 | export default Wireframe; 184 | -------------------------------------------------------------------------------- /client/js/lib/webgl/GLProgram.js: -------------------------------------------------------------------------------- 1 | 2 | class GLProgram { 3 | 4 | static init_webgl(canvas) { 5 | var gl = null; 6 | 7 | // Try to grab the standard context. If it fails, fallback to experimental. 8 | gl = canvas.getContext('webgl2'); 9 | 10 | // If we don't have a GL context, give up now 11 | if (!gl) { 12 | alert('Unable to initialize WebGL. Your browser may not support it.'); 13 | } 14 | 15 | return gl; 16 | } 17 | 18 | static compile_shaders_and_link_with_program(gl, src_vs, src_fs) { 19 | var vertex_shader = GLProgram.compile_shader(gl, src_vs, gl.VERTEX_SHADER); 20 | var fragment_shader = GLProgram.compile_shader(gl, src_fs, gl.FRAGMENT_SHADER); 21 | 22 | // Create the shader program 23 | 24 | var program = gl.createProgram(); 25 | gl.attachShader(program, vertex_shader); 26 | gl.attachShader(program, fragment_shader); 27 | gl.linkProgram(program); 28 | 29 | // If creating the shader program failed, alert 30 | 31 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 32 | console.log('Unable to initialize the shader program: ' + gl.getProgramInfoLog(program)); 33 | } 34 | 35 | return program; 36 | } 37 | 38 | static compile_shader(gl, src, type) { 39 | const shader = gl.createShader(type); 40 | gl.shaderSource(shader, src); 41 | 42 | // Compile the shader program 43 | gl.compileShader(shader); 44 | 45 | // See if it compiled successfully 46 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 47 | console.log('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader)); 48 | gl.deleteShader(shader); 49 | return null; 50 | } 51 | 52 | return shader; 53 | } 54 | } 55 | 56 | export default GLProgram; -------------------------------------------------------------------------------- /env.sh: -------------------------------------------------------------------------------- 1 | NODE_BASE_URL="/Viewer" 2 | HTTP_SERVER_PORT=8070 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FileViewer", 3 | "version": "1.0.0", 4 | "description": "Viewing custom files", 5 | "main": "client/build/Bundle.js", 6 | "devDependencies": { 7 | "babel-core": "^6.26.3", 8 | "babel-preset-env": "^1.7.0", 9 | "babel-preset-react": "^6.24.1", 10 | "babelify": "^7.3.0", 11 | "browserify": "^16.5.1", 12 | "browserify-css": "^0.15.0", 13 | "react-bootstrap": "^0.31.3", 14 | "watchify": "^3.11.1" 15 | }, 16 | "dependencies": { 17 | "csv-parse": "^4.9.0", 18 | "d3": "^4.13.0", 19 | "google-protobuf": "^3.12.2", 20 | "mathjs": "^6.6.5", 21 | "plotly.js": "^1.54.1", 22 | "react": "^15.6.2", 23 | "react-dom": "^15.6.2", 24 | "three": "^0.86.0" 25 | }, 26 | "scripts": { 27 | "build": "mkdir -p ./client/build && browserify ./client/js/apps/Common/Common.js ./client/js/apps/Viewer/Viewer.js --standalone FileViewer -o ./client/build/Bundle.js -t [ babelify --presets [ env react ] ]", 28 | "watch": "mkdir -p ./client/build && watchify ./client/js/apps/Common/Common.js ./client/js/apps/Viewer/Viewer.js --standalone FileViewer -o ./client/build/Bundle.js -t [ babelify --presets [ env react ] ] --debug --verbose" 29 | }, 30 | "repository": { 31 | "type": "", 32 | "url": "" 33 | }, 34 | "author": "Armen Avetisyan", 35 | "license": "ISC" 36 | } 37 | -------------------------------------------------------------------------------- /pics/json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/pics/json.png -------------------------------------------------------------------------------- /pics/nocs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/pics/nocs.png -------------------------------------------------------------------------------- /pics/ply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/pics/ply.png -------------------------------------------------------------------------------- /pics/vox2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/pics/vox2.png -------------------------------------------------------------------------------- /pics/wrf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skanti/browser-renderer-neural-network/ab2f50edf7163bdca695af1881686af7b10aea81/pics/wrf.png -------------------------------------------------------------------------------- /server/Config.js: -------------------------------------------------------------------------------- 1 | var Config = {}; 2 | 3 | Config.base_url = process.env.NODE_BASE_URL || ""; 4 | Config.http_port = process.env.HTTP_SERVER_PORT || 8070; 5 | 6 | module.exports = Config; 7 | -------------------------------------------------------------------------------- /server/DetachProcess.sh: -------------------------------------------------------------------------------- 1 | ./run.sh log.txt & 2 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | var http = require("http"); 2 | var fs = require("fs"); 3 | var path = require("path"); 4 | var bodyParser = require("body-parser"); 5 | // const MongoClient = require("mongodb").MongoClient 6 | // var ObjectId = require("mongodb").ObjectID; 7 | var request = require("request"); 8 | const querystring = require('querystring'); 9 | const express = require("express"); 10 | const app = express(); 11 | const router = express.Router(); 12 | 13 | const Config = require("./Config"); 14 | 15 | app.use(bodyParser.urlencoded({ extended: true })); 16 | app.use(bodyParser.json()); 17 | 18 | app.use(express.static(path.join(__dirname, "/static"))); 19 | app.use(express.static(path.join(__dirname, "/../client"))); 20 | app.use(express.static(path.join(__dirname, "/../node_modules"))); 21 | app.use(express.static(path.join(__dirname, "/../resources"))); 22 | 23 | function get_folderlist(folder) { 24 | const is_dir = source => fs.lstatSync(source).isDirectory(); 25 | const getDirectories = source => fs.readdirSync(source).map(name => path.join(source, name)).filter(is_dir); 26 | let list = getDirectories(path.join(__dirname, "/static/data/", folder)); 27 | return list.map(x => path.basename(x)); 28 | } 29 | 30 | // ------------------------------------------------------------- 31 | app.set("view engine", "pug"); 32 | app.set("views", path.join(__dirname, "views")); 33 | 34 | function search_and_find_file(file0) { 35 | let file1 = path.join(__dirname, "/static/homearmen/", file0); 36 | let file2 = path.join(__dirname, "/static/root/", file0); 37 | let files = [file1, file2] 38 | for (let f in files) { 39 | if (fs.existsSync(files[f])) 40 | return files[f]; 41 | } 42 | return null; 43 | } 44 | 45 | app.get("/download/json/*", function (req, res) { 46 | let file = search_and_find_file(req.params["0"]); 47 | res.sendFile(file); 48 | }); 49 | 50 | app.get("/download/vox/*", function (req, res) { 51 | let file = search_and_find_file(req.params["0"]); 52 | res.sendFile(file); 53 | }); 54 | 55 | app.get("/download/mesh/*", function (req, res) { 56 | let file = search_and_find_file(req.params["0"]); 57 | res.sendFile(file); 58 | }); 59 | 60 | app.get("/download/image/*", function (req, res) { 61 | let file = search_and_find_file(req.params["0"]); 62 | res.sendFile(file); 63 | }); 64 | 65 | 66 | router.get("/", function (req, res) { 67 | res.redirect(path.join(Config.base_url, "/0")); 68 | }); 69 | 70 | 71 | router.get("/*", function (req, res) { 72 | res.render("Viewer", { 73 | id_file : req.params["0"] 74 | }); 75 | }); 76 | 77 | app.use(Config.base_url, router); 78 | module.exports = router; 79 | // ------------------------------------------------------------- 80 | 81 | let async0 = new Promise((resolve, reject) => { 82 | resolve(); 83 | }); 84 | 85 | 86 | Promise.all([async0]).then( res => { 87 | const server = http.createServer(app).listen(Config.http_port, function() { 88 | const host = server.address().address; 89 | const port = server.address().port; 90 | console.log("Server listening at address http://%s in port: %s", host, port) 91 | }); 92 | }); 93 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MonitorNet", 3 | "version": "1.0.0", 4 | "description": "Monitoring 3D output of neural networks", 5 | "main": "index.js", 6 | "dependencies": { 7 | "body-parser": "^1.19.0", 8 | "express": "^4.17.1", 9 | "jquery": "^3.4.0", 10 | "pug": "^2.0.4", 11 | "request": "^2.81.0", 12 | "three": "^0.85.2" 13 | }, 14 | "scripts": { 15 | "start": "node --harmony ./index.js" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "" 20 | }, 21 | "author": "Armen Avetisyan", 22 | "license": "ISC", 23 | "devDependencies": { 24 | "browserify-css": "^0.15.0", 25 | "mongoose": "^5.7.5" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /server/run.sh: -------------------------------------------------------------------------------- 1 | source ../env.sh 2 | echo "base-url:" $NODE_BASE_URL 3 | NODE_BASE_URL=$NODE_BASE_URL HTTP_SERVER_PORT=$HTTP_SERVER_PORT npm start --harmony 4 | 5 | -------------------------------------------------------------------------------- /server/static/root: -------------------------------------------------------------------------------- 1 | / -------------------------------------------------------------------------------- /server/views/SceneViewer.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang="en") 3 | head 4 | link(rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous") 5 | script(src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous") 6 | script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous") 7 | script(src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous") 8 | 9 | 10 | title= "Scene Viewer" 11 | meta(charset= "UTF-8") 12 | body 13 | script(src="/build/Bundle.js") 14 | 15 | div(id="id_div_root") 16 | 17 | 18 | script. 19 | 20 | $(window).on('load', function () { 21 | var viewer = null; 22 | viewer = new SceneViewer(); 23 | viewer.init("#{id_file}"); 24 | }); 25 | 26 | -------------------------------------------------------------------------------- /server/views/Viewer.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang="en") 3 | head 4 | link(rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous") 5 | script(src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous") 6 | script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous") 7 | script(src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous") 8 | 9 | 10 | title= "File Viewer" 11 | meta(charset= "UTF-8") 12 | body 13 | script(src="/build/Bundle.js") 14 | 15 | div(id="id_div_root") 16 | 17 | 18 | script. 19 | 20 | $(window).on('load', function () { 21 | var viewer = null; 22 | viewer = new Viewer(); 23 | viewer.init("#{id_file}"); 24 | }); 25 | 26 | -------------------------------------------------------------------------------- /watch.sh: -------------------------------------------------------------------------------- 1 | source ./env.sh 2 | echo "base-url:" $NODE_BASE_URL 3 | NODE_BASE_URL=$NODE_BASE_URL npm run watch --harmony 4 | --------------------------------------------------------------------------------