diff --git a/Cargo.lock b/Cargo.lock index 10a594b..c76c494 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,6 +69,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" +[[package]] +name = "approx" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +dependencies = [ + "num-traits", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -181,6 +190,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cgmath" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" +dependencies = [ + "approx", + "num-traits", +] + [[package]] name = "cmake" version = "0.1.50" @@ -290,6 +309,8 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" name = "eruption" version = "0.1.0" dependencies = [ + "cgmath", + "tobj", "vulkano", "vulkano-shaders", "vulkano-win", @@ -571,6 +592,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "num_enum" version = "0.5.11" @@ -979,6 +1009,15 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tobj" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57381207291289bad19de63acd3fbf5948ff99b2868116c367b7224c37d55f90" +dependencies = [ + "ahash", +] + [[package]] name = "toml_datetime" version = "0.6.1" diff --git a/Cargo.toml b/Cargo.toml index a26d022..6609d77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,8 @@ authors = ["Sven Vogel"] vulkano = "0.33.0" vulkano-win = "0.33.0" vulkano-shaders = "0.33.0" -winit = "0.28.3" \ No newline at end of file +winit = "0.28.3" + +tobj = "3.2.5" + +cgmath = "0.18.0" \ No newline at end of file diff --git a/res/example-scene.mtl b/res/example-scene.mtl new file mode 100644 index 0000000..fdbbdd4 --- /dev/null +++ b/res/example-scene.mtl @@ -0,0 +1,52 @@ +# Blender 3.4.1 MTL File: 'example-scene.blend' +# www.blender.org + +newmtl glass +Ns 1000.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 + +newmtl green +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.006232 0.800000 0.014503 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 + +newmtl light +Ns 360.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl red +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.006232 0.009300 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 + +newmtl white +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/res/example-scene.obj b/res/example-scene.obj new file mode 100644 index 0000000..854e68a --- /dev/null +++ b/res/example-scene.obj @@ -0,0 +1,4788 @@ +# Blender 3.4.1 +# www.blender.org +mtllib example-scene.mtl +o Plane +v -4.000000 -4.000000 4.000000 +v 4.000000 -4.000000 4.000000 +v -4.000000 -4.000000 -4.000000 +v 4.000000 -4.000000 -4.000000 +v -4.000000 5.000000 -4.000000 +v 4.000000 5.000000 -4.000000 +v -4.000000 5.000000 4.000000 +v 4.000000 5.000000 4.000000 +s 0 +usemtl white +f 2 3 1 +f 4 5 3 +f 6 7 5 +f 7 2 1 +f 2 4 3 +f 4 6 5 +f 6 8 7 +f 7 8 2 +o Suzanne +v -1.161533 -2.876485 -0.975581 +v -1.954552 -2.876485 -0.605790 +v -1.114891 -2.978893 -1.023444 +v -2.021198 -2.978893 -0.600826 +v -1.100803 -3.073626 -1.104148 +v -2.092077 -3.073626 -0.641910 +v -1.245355 -3.115217 -0.951993 +v -1.882603 -3.115217 -0.654840 +v -1.223452 -3.012165 -0.905021 +v -1.860700 -3.012165 -0.607868 +v -1.226434 -2.893122 -0.911417 +v -1.863682 -2.893122 -0.614264 +v -1.299406 -2.858561 -0.883045 +v -1.795043 -2.858561 -0.651926 +v -1.365018 -2.947525 -0.857379 +v -1.733206 -2.947525 -0.685690 +v -1.430488 -3.033296 -0.886863 +v -1.713709 -3.033296 -0.754795 +v -1.544039 -2.875224 -0.945515 +v -1.685650 -2.875224 -0.879481 +v -1.457644 -2.825932 -0.908128 +v -1.712544 -2.825932 -0.789267 +v -1.346665 -2.794565 -0.910450 +v -1.785658 -2.794565 -0.705745 +v -1.339175 -2.724169 -0.968331 +v -1.834812 -2.724169 -0.737211 +v -1.436982 -2.704340 -1.011705 +v -1.805170 -2.704340 -0.840017 +v -1.523283 -2.719714 -1.085863 +v -1.806504 -2.719714 -0.953795 +v -1.376026 -2.673643 -1.232218 +v -2.013274 -2.673643 -0.935064 +v -1.325716 -2.666586 -1.124328 +v -1.962964 -2.666586 -0.827174 +v -1.281354 -2.707533 -1.029193 +v -1.918602 -2.707533 -0.732039 +v -1.201302 -2.742093 -1.060867 +v -1.994321 -2.742093 -0.691076 +v -1.186854 -2.735707 -1.177770 +v -2.093162 -2.735707 -0.755152 +v -1.193598 -2.760044 -1.303148 +v -2.184872 -2.760044 -0.840910 +v -1.080858 -2.928997 -1.246235 +v -2.213742 -2.928997 -0.717962 +v -1.099637 -2.866262 -1.138621 +v -2.119234 -2.866262 -0.663175 +v -1.154853 -2.816970 -1.035200 +v -2.004517 -2.816970 -0.638995 +v -1.142363 -2.808008 -1.026902 +v -2.006188 -2.808008 -0.624094 +v -1.190706 -2.726732 -1.056629 +v -1.997887 -2.726732 -0.680235 +v -1.277028 -2.681290 -1.019915 +v -1.914275 -2.681290 -0.722762 +v -1.340035 -2.704326 -0.951690 +v -1.821512 -2.704326 -0.727174 +v -1.352713 -2.781122 -0.886447 +v -1.763383 -2.781122 -0.694948 +v -1.296479 -2.851518 -0.858282 +v -1.777954 -2.851518 -0.633766 +v -1.236720 -2.776641 -0.933474 +v -1.873967 -2.776641 -0.636321 +v -1.214533 -2.892478 -0.885895 +v -1.851781 -2.892478 -0.588741 +v -1.147149 -2.873923 -0.963221 +v -1.954330 -2.873923 -0.586827 +v -1.630545 -2.672341 -0.946167 +v -1.584561 -2.691527 -0.847555 +v -1.364333 -3.585569 -0.375273 +v -1.435219 -3.264300 -0.527289 +v -1.462004 -3.146544 -0.584730 +v -1.347016 -3.671327 -0.338139 +v -1.673546 -2.772199 -1.038384 +v -1.724134 -2.655731 -1.146870 +v -2.190430 -3.027740 -2.146846 +v -2.214477 -3.477685 -2.198414 +v -2.087055 -3.867418 -1.925157 +v -1.812235 -3.965251 -1.335804 +v -1.359048 -3.280976 -0.844575 +v -1.727236 -3.280976 -0.672887 +v -1.196615 -3.481283 -0.755040 +v -1.763058 -3.481283 -0.490904 +v -1.098718 -3.692471 -0.637528 +v -1.735965 -3.692471 -0.340375 +v -1.050735 -3.874867 -0.571601 +v -1.716305 -3.874867 -0.261241 +v -1.075586 -3.924145 -0.532464 +v -1.670350 -3.924145 -0.255121 +v -1.193616 -3.925420 -0.434348 +v -1.519321 -3.925420 -0.282469 +v -1.344567 -3.924776 -0.332886 +v -1.168813 -3.260503 -0.991194 +v -1.961833 -3.260503 -0.621403 +v -1.013715 -3.172827 -1.120733 +v -2.160760 -3.172827 -0.585856 +v -0.914607 -3.073008 -1.370345 +v -2.415679 -3.073008 -0.670383 +v -0.903074 -2.757482 -1.419555 +v -2.460790 -2.757482 -0.693180 +v -1.040042 -2.694760 -1.362051 +v -2.328698 -2.694760 -0.761141 +v -1.245067 -2.562917 -1.284122 +v -2.137213 -2.562917 -0.868107 +v -1.422487 -2.408038 -1.257909 +v -2.003090 -2.408038 -0.987169 +v -1.553595 -2.426593 -1.150867 +v -1.836816 -2.426593 -1.018798 +v -1.586346 -2.616663 -0.999271 +v -1.699635 -2.616663 -0.946443 +v -1.467248 -2.667216 -0.984180 +v -1.764630 -2.667216 -0.845509 +v -1.478842 -2.761292 -0.916615 +v -1.705419 -2.761292 -0.810960 +v -1.365018 -2.947525 -0.857379 +v -1.733206 -2.947525 -0.685690 +v -1.203832 -3.033927 -0.918404 +v -1.883563 -3.033927 -0.601441 +v -1.119805 -3.013453 -1.015497 +v -2.011952 -3.013453 -0.599482 +v -1.037850 -2.924502 -1.154006 +v -2.170735 -2.924502 -0.625733 +v -1.050202 -2.834908 -1.217466 +v -2.211409 -2.834908 -0.675987 +v -1.099134 -2.761949 -1.229970 +v -2.189535 -2.761949 -0.721508 +v -1.251123 -2.679385 -1.149222 +v -2.029982 -2.679385 -0.786035 +v -1.408028 -2.631381 -1.060528 +v -1.861181 -2.631381 -0.849219 +v -1.343501 -3.655965 -0.330600 +v -1.255736 -3.617567 -0.401191 +v -1.453991 -3.617567 -0.308743 +v -1.228363 -3.727005 -0.360974 +v -1.440779 -3.727005 -0.261923 +v -1.271973 -3.774365 -0.325095 +v -1.385262 -3.774365 -0.272268 +v -1.329428 -3.785245 -0.300420 +v -1.476338 -3.179830 -0.615469 +v -1.492299 -3.139514 -0.649698 +v -1.398358 -3.145914 -0.688559 +v -1.582452 -3.145914 -0.602714 +v -1.355474 -3.205429 -0.652052 +v -1.582051 -3.205429 -0.546397 +v -1.378431 -3.261107 -0.608853 +v -1.534203 -3.261107 -0.536216 +v -1.178259 -3.103048 -0.919020 +v -1.900473 -3.103048 -0.582246 +v -1.020851 -3.046739 -1.099064 +v -2.139574 -3.046739 -0.577394 +v -0.965819 -2.938590 -1.239851 +v -2.282797 -2.938590 -0.625734 +v -0.974389 -2.766430 -1.295201 +v -2.319689 -2.766430 -0.667877 +v -1.009080 -2.694103 -1.240195 +v -2.255253 -2.694103 -0.659095 +v -1.243510 -2.544980 -1.151381 +v -2.036529 -2.544980 -0.781590 +v -1.366001 -2.445779 -1.118288 +v -1.932443 -2.445779 -0.854152 +v -1.454037 -2.456015 -1.048280 +v -1.822225 -2.456015 -0.876592 +v -1.503338 -2.614088 -0.913689 +v -1.687432 -2.614088 -0.827845 +v -1.364138 -3.067186 -0.670631 +v -1.590715 -3.067186 -0.564976 +v -1.238086 -3.407024 -0.603656 +v -1.620434 -3.407024 -0.425364 +v -1.148302 -3.631655 -0.503544 +v -1.601456 -3.631655 -0.292235 +v -1.113848 -3.741092 -0.466629 +v -1.595324 -3.741092 -0.242113 +v -1.130263 -3.835812 -0.427888 +v -1.555095 -3.835812 -0.229786 +v -1.190200 -3.848611 -0.390050 +v -1.487582 -3.848611 -0.251379 +v -1.332399 -3.856929 -0.306792 +v -1.543159 -2.994885 -0.758767 +v -1.569405 -2.838088 -0.815053 +v -1.344525 -2.633944 -1.109206 +v -1.939290 -2.633944 -0.831863 +v -1.409079 -2.904646 -0.859438 +v -1.706461 -2.904646 -0.720766 +v -1.451741 -2.842569 -0.876982 +v -1.692479 -2.842569 -0.764724 +v -1.256231 -3.591969 -0.420738 +v -1.468647 -3.591969 -0.321686 +v -1.344931 -3.384618 -0.518527 +v -1.486542 -3.384618 -0.452493 +v -1.415737 -3.384618 -0.485510 +v -1.446848 -3.293105 -0.552228 +v -1.361615 -3.225902 -0.591277 +v -1.531548 -3.225902 -0.512036 +v -1.332166 -3.178542 -0.620553 +v -1.572904 -3.178542 -0.508295 +v -1.381542 -3.110709 -0.670983 +v -1.579797 -3.110709 -0.578535 +v -1.447161 -3.104309 -0.645329 +v -1.517966 -3.104309 -0.612311 +v -1.447398 -3.141419 -0.553408 +v -1.423581 -3.105584 -0.613247 +v -1.508547 -3.105584 -0.573626 +v -1.379204 -3.111984 -0.628995 +v -1.549136 -3.111984 -0.549755 +v -1.342589 -3.160618 -0.587448 +v -1.540844 -3.160618 -0.495000 +v -1.373344 -3.193260 -0.579457 +v -1.514954 -3.193260 -0.513423 +v -1.434680 -3.225258 -0.526134 +v -1.281889 -3.387851 -0.808508 +v -1.749203 -3.387851 -0.590595 +v -1.329807 -3.240633 -0.689438 +v -1.627189 -3.240633 -0.550766 +v -1.298602 -3.298230 -0.659490 +v -1.624306 -3.298230 -0.507612 +v -1.318280 -3.336654 -0.831092 +v -1.743112 -3.336654 -0.632990 +v -1.333216 -3.772446 -0.308543 +v -1.292626 -3.766047 -0.332414 +v -1.377593 -3.766047 -0.292794 +v -1.253392 -3.714206 -0.359192 +v -1.423325 -3.714206 -0.279951 +v -1.266921 -3.641247 -0.388204 +v -1.436853 -3.641247 -0.308963 +v -1.366759 -3.713575 -0.380478 +v -1.286664 -3.683496 -0.430543 +v -1.456596 -3.683496 -0.351302 +v -1.279627 -3.748136 -0.415453 +v -1.449560 -3.748136 -0.336212 +v -1.315346 -3.784615 -0.381137 +v -1.400312 -3.784615 -0.341516 +v -1.355935 -3.791014 -0.357265 +v -1.410118 -2.822726 -0.880151 +v -1.721661 -2.822726 -0.734876 +v -1.383511 -2.878404 -0.860065 +v -1.723377 -2.878404 -0.701583 +v -1.320673 -2.663379 -1.076540 +v -1.929598 -2.663379 -0.792594 +v -1.370014 -2.660817 -1.034465 +v -1.865651 -2.660817 -0.803346 +v -1.229803 -2.680016 -1.085014 +v -1.994500 -2.680016 -0.728430 +v -1.118037 -2.763224 -1.178078 +v -2.137633 -2.763224 -0.702632 +v -1.084349 -2.818902 -1.161293 +v -2.146429 -2.818902 -0.666037 +v -1.071409 -2.900179 -1.115057 +v -2.119327 -2.900179 -0.626404 +v -1.127208 -2.954569 -0.994400 +v -1.991032 -2.954569 -0.591592 +v -1.201672 -2.973124 -0.913771 +v -1.881402 -2.973124 -0.596808 +v -1.334041 -2.912321 -0.846406 +v -1.744712 -2.912321 -0.654907 +v -1.421975 -2.758730 -0.924065 +v -1.747680 -2.758730 -0.772187 +v -1.412591 -2.694733 -0.977884 +v -1.794940 -2.694733 -0.799592 +v -1.395676 -2.720976 -0.997067 +v -1.820507 -2.720976 -0.798965 +v -1.415928 -2.772173 -0.948069 +v -1.769955 -2.772173 -0.782984 +v -1.331782 -2.912965 -0.878532 +v -1.770775 -2.912965 -0.673826 +v -1.212762 -2.962887 -0.937555 +v -1.892493 -2.962887 -0.620591 +v -1.150565 -2.950732 -1.007519 +v -1.986068 -2.950732 -0.617918 +v -1.106223 -2.891860 -1.115772 +v -2.097497 -2.891860 -0.653534 +v -1.116187 -2.834264 -1.155625 +v -2.121622 -2.834264 -0.686783 +v -1.147980 -2.784985 -1.168349 +v -2.110932 -2.784985 -0.719317 +v -1.243103 -2.699858 -1.095051 +v -1.993639 -2.699858 -0.745071 +v -1.359957 -2.684497 -1.031384 +v -1.869755 -2.684497 -0.793661 +v -1.317696 -2.687059 -1.070157 +v -1.926622 -2.687059 -0.786210 +v -1.381252 -2.879048 -0.892191 +v -1.749439 -2.879048 -0.720502 +v -1.401589 -2.834250 -0.917318 +v -1.755615 -2.834250 -0.752233 +v -1.584971 -2.722921 -1.107236 +v -1.783226 -2.722921 -1.014789 +v -1.553619 -2.552050 -1.243347 +v -1.907645 -2.552050 -1.078262 +v -1.439964 -2.546294 -1.332361 +v -2.048890 -2.546294 -1.048415 +v -1.286763 -2.677493 -1.355053 +v -2.164748 -2.677493 -0.945642 +v -1.106767 -2.796536 -1.431200 +v -2.338779 -2.796536 -0.856703 +v -1.000015 -2.852859 -1.479558 +v -2.444443 -2.852859 -0.806011 +v -0.992300 -3.100539 -1.407556 +v -2.394245 -3.100539 -0.753818 +v -1.094779 -3.212525 -1.220632 +v -2.185181 -3.212525 -0.712170 +v -1.201813 -3.257953 -1.061962 +v -1.994832 -3.257953 -0.692171 +v -1.901038 -2.548266 -1.526242 +v -2.048986 -2.688480 -1.843517 +v -1.968575 -3.995384 -1.671075 +v -1.606680 -3.720054 -0.894990 +v -1.387030 -3.985592 -0.423948 +v -1.469262 -3.912016 -0.600295 +v -1.534189 -3.733471 -0.739532 +v -1.568544 -3.685480 -0.813206 +v -1.049427 -3.226666 -1.714925 +v -2.592983 -3.226666 -0.995153 +v -1.098338 -3.214524 -1.838301 +v -2.656054 -3.214524 -1.111925 +v -1.298198 -3.483374 -2.063555 +v -2.700142 -3.483374 -1.409817 +v -1.715038 -3.494939 -2.218035 +v -2.550540 -3.494939 -1.828433 +v -1.082050 -3.448090 -1.507595 +v -2.413189 -3.448090 -0.886875 +v -1.271700 -3.646518 -1.581553 +v -2.347940 -3.646518 -1.079694 +v -1.349579 -3.702880 -1.859483 +v -2.510786 -3.702880 -1.318003 +v -1.722008 -3.786115 -1.937207 +v -2.330934 -3.786115 -1.653260 +v -1.345049 -3.504990 -0.888497 +v -1.769880 -3.504990 -0.690395 +v -1.430850 -3.641327 -0.943096 +v -1.756554 -3.641327 -0.791218 +v -1.216485 -3.812816 -0.742193 +v -1.740444 -3.812816 -0.497867 +v -1.300315 -3.635545 -0.829537 +v -1.753469 -3.635545 -0.618228 +v -1.126435 -3.970244 -0.641509 +v -1.721199 -3.970244 -0.364166 +v -1.345061 -3.860176 -0.666693 +v -1.599960 -3.860176 -0.547832 +v -1.414953 -3.685467 -0.779604 +v -1.641530 -3.685467 -0.673949 +v -1.254028 -3.973437 -0.526929 +v -1.551410 -3.973437 -0.388257 +v -1.368140 -3.433950 -0.901045 +v -1.764650 -3.433950 -0.716149 +v -1.374954 -3.366747 -0.897171 +v -1.757303 -3.366747 -0.718879 +v -1.384472 -3.304025 -0.899098 +v -1.752660 -3.304025 -0.727409 +v -1.440664 -3.675901 -1.038087 +v -1.823012 -3.675901 -0.859795 +v -1.530469 -3.858363 -1.434019 +v -2.068589 -3.858363 -1.183090 +v -1.622416 -3.880808 -1.742116 +v -2.245502 -3.880808 -1.451566 +v -1.715388 -2.959236 -2.200299 +v -2.536729 -2.959236 -1.817301 +v -1.622354 -2.728796 -2.000788 +v -2.443696 -2.728796 -1.617790 +v -1.497937 -2.618031 -1.733974 +v -2.319279 -2.618031 -1.350976 +v -1.343703 -2.774788 -1.421704 +v -2.179205 -2.774788 -1.032102 +v -1.107013 -2.924556 -1.542644 +v -2.423992 -2.924556 -0.928526 +v -1.222275 -2.917525 -1.567991 +v -2.369320 -2.917525 -1.033114 +v -1.354228 -2.842688 -1.869452 +v -2.515435 -2.842688 -1.327973 +v -1.154188 -2.917552 -1.810184 +v -2.598616 -2.917552 -1.136636 +v -1.251287 -3.011667 -2.018414 +v -2.695715 -3.011667 -1.344866 +v -1.452138 -2.947685 -2.079421 +v -2.613345 -2.947685 -1.537941 +v -1.521641 -3.148675 -2.228471 +v -2.682848 -3.148675 -1.686991 +v -1.316192 -3.214577 -2.157603 +v -2.760620 -3.214577 -1.484055 +v -1.506346 -3.517318 -2.140211 +v -2.625069 -3.517318 -1.618542 +v -1.539334 -3.744498 -1.896694 +v -2.417320 -3.744498 -1.487283 +v -1.189727 -3.297745 -1.941854 +v -2.676638 -3.297745 -1.248496 +v -1.322086 -3.505673 -1.245944 +v -2.058461 -3.505673 -0.902566 +v -1.419574 -3.731001 -1.510467 +v -2.198432 -3.731001 -1.147279 +v -1.155758 -3.251673 -2.035382 +v -2.770119 -3.251673 -1.282593 +v -1.091537 -3.636912 -1.620370 +v -2.493482 -3.636912 -0.966632 +v -0.930587 -3.721422 -1.903735 +v -2.814008 -3.721422 -1.025481 +v -0.784126 -3.651683 -2.162713 +v -3.106540 -3.651683 -1.079753 +v -0.782085 -3.429615 -2.324709 +v -3.231949 -3.429615 -1.182319 +v -0.933744 -3.276024 -2.372653 +v -3.171191 -3.276024 -1.329314 +v -1.079479 -3.238888 -2.186062 +v -2.934578 -3.238888 -1.321015 +v -1.063295 -3.276641 -2.132870 +v -2.904233 -3.276641 -1.274427 +v -0.948365 -3.315696 -2.293092 +v -3.100846 -3.315696 -1.289374 +v -0.846987 -3.446251 -2.260546 +v -3.141078 -3.446251 -1.190793 +v -0.845419 -3.619041 -2.127781 +v -3.040383 -3.619041 -1.104252 +v -0.944704 -3.656782 -1.915523 +v -2.813964 -3.656782 -1.043873 +v -1.061722 -3.583797 -1.685833 +v -2.562794 -3.583797 -0.985871 +v -1.110664 -3.281109 -2.012621 +v -2.781669 -3.281109 -1.233419 +v -1.100507 -3.366236 -2.046298 +v -2.813995 -3.366236 -1.247285 +v -1.050567 -3.590210 -1.791312 +v -2.650766 -3.590210 -1.045127 +v -0.968729 -3.660632 -1.985531 +v -2.852150 -3.660632 -1.107277 +v -0.883971 -3.628647 -2.154998 +v -3.036452 -3.628647 -1.151280 +v -0.879363 -3.500655 -2.256033 +v -3.116811 -3.500655 -1.212694 +v -0.959816 -3.406579 -2.280676 +v -3.083975 -3.406579 -1.290165 +v -1.063512 -3.374568 -2.151821 +v -2.918611 -3.374568 -1.286775 +v -1.161721 -3.334225 -1.937253 +v -2.691115 -3.334225 -1.224085 +v -1.162031 -3.466068 -1.919433 +v -2.677264 -3.466068 -1.212868 +v -1.213899 -3.530064 -1.845804 +v -2.587521 -3.530064 -1.205273 +v -1.155361 -3.536463 -1.868156 +v -2.642272 -3.536463 -1.174798 +v -1.117075 -3.594060 -1.841510 +v -2.646470 -3.594060 -1.128342 +v -1.137822 -3.619658 -1.812059 +v -2.610572 -3.619658 -1.125304 +v -1.149176 -3.490352 -1.633062 +v -2.466154 -3.490352 -1.018944 +v -1.185735 -3.567804 -1.692976 +v -2.488552 -3.567804 -1.085463 +v -1.206294 -3.525569 -1.737066 +v -2.509112 -3.525569 -1.129553 +v -1.183372 -3.404620 -1.872769 +v -2.627800 -3.404620 -1.199221 +v -1.126807 -3.403990 -1.973296 +v -2.741168 -3.403990 -1.220507 +v -1.143845 -3.441757 -2.009835 +v -2.758206 -3.441757 -1.257046 +v -1.154050 -3.646545 -1.846859 +v -2.626800 -3.646545 -1.160104 +v -1.126222 -3.620946 -1.879612 +v -2.669778 -3.620946 -1.159840 +v -1.162614 -3.569749 -1.902197 +v -2.663686 -3.569749 -1.202235 +v -1.223046 -3.556950 -1.883906 +v -2.610830 -3.556950 -1.236771 +v -1.171178 -3.492954 -1.957535 +v -2.700573 -3.492954 -1.244367 +v -1.064496 -3.418734 -2.190902 +v -2.947917 -3.418734 -1.312649 +v -0.958095 -3.446265 -2.313958 +v -3.110576 -3.446265 -1.310239 +v -0.872455 -3.533941 -2.296677 +v -3.152386 -3.533941 -1.233528 +v -0.874358 -3.657452 -2.189842 +v -3.069323 -3.657452 -1.166314 +v -0.980581 -3.691999 -2.029433 +v -2.878163 -3.691999 -1.144576 +v -1.071393 -3.615177 -1.835974 +v -2.671592 -3.615177 -1.089789 +v -1.108571 -3.410403 -2.082078 +v -2.836221 -3.410403 -1.276461 +v -1.116250 -3.548632 -1.950655 +v -2.730610 -3.548632 -1.197867 +v -1.065108 -3.591511 -1.951898 +v -2.764435 -3.591511 -1.159489 +v -1.034433 -3.558238 -2.034002 +v -2.847048 -3.558238 -1.188765 +v -1.075789 -3.510878 -2.030261 +v -2.817599 -3.510878 -1.218041 +v -1.049489 -3.473125 -2.103262 +v -2.890427 -3.473125 -1.244819 +v -1.005428 -3.516003 -2.101204 +v -2.917171 -3.516003 -1.209743 +v -0.964251 -3.501285 -2.142299 +v -2.975121 -3.501285 -1.204615 +v -1.000643 -3.450089 -2.164884 +v -2.969029 -3.450089 -1.247010 +v -1.129511 -3.369469 -2.293356 +v -2.984610 -3.369469 -1.428310 +v -0.953388 -3.379719 -2.451751 +v -3.219157 -3.379719 -1.395205 +v -0.789289 -3.493624 -2.377130 +v -3.267474 -3.493624 -1.221533 +v -0.790964 -3.709937 -2.251320 +v -3.170022 -3.709937 -1.141947 +v -0.991171 -3.802725 -2.033658 +v -2.874592 -3.802725 -1.155404 +v -1.151483 -3.740621 -1.785897 +v -2.581750 -3.740621 -1.118952 +v -1.229786 -3.356013 -2.120192 +v -2.787503 -3.356013 -1.393816 +s 0 +usemtl white +f 55 11 53 +f 12 56 54 +f 53 13 51 +f 14 54 52 +f 11 15 13 +f 16 12 14 +f 9 17 11 +f 18 10 12 +f 19 23 17 +f 24 20 18 +f 17 25 15 +f 26 18 16 +f 29 25 23 +f 30 26 28 +f 21 29 23 +f 30 22 24 +f 31 35 29 +f 36 32 30 +f 35 27 29 +f 36 28 38 +f 41 37 35 +f 42 38 40 +f 43 35 33 +f 44 36 42 +f 45 41 43 +f 46 42 48 +f 47 39 41 +f 48 40 50 +f 53 49 47 +f 54 50 52 +f 55 47 45 +f 56 48 54 +f 45 57 55 +f 46 58 60 +f 43 59 45 +f 44 60 62 +f 33 61 43 +f 34 62 64 +f 31 63 33 +f 32 64 66 +f 31 67 65 +f 68 32 66 +f 21 71 67 +f 72 22 68 +f 19 73 71 +f 74 20 72 +f 9 57 73 +f 58 10 74 +f 69 73 57 +f 58 74 70 +f 71 73 69 +f 70 74 72 +f 69 67 71 +f 72 68 70 +f 69 65 67 +f 68 66 70 +f 69 63 65 +f 66 64 70 +f 69 61 63 +f 64 62 70 +f 69 59 61 +f 62 60 70 +f 69 57 59 +f 60 58 70 +f 182 99 97 +f 183 99 184 +f 180 97 95 +f 181 98 183 +f 93 180 95 +f 181 94 96 +f 91 178 93 +f 179 92 94 +f 89 176 91 +f 177 90 92 +f 87 154 172 +f 155 88 173 +f 102 154 100 +f 103 155 157 +f 102 158 156 +f 159 103 157 +f 106 158 104 +f 107 159 161 +f 108 160 106 +f 109 161 163 +f 110 162 108 +f 111 163 165 +f 110 166 164 +f 167 111 165 +f 114 166 112 +f 115 167 169 +f 116 168 114 +f 117 169 171 +f 75 170 116 +f 75 171 76 +f 136 170 118 +f 137 171 169 +f 136 166 168 +f 167 137 169 +f 164 187 134 +f 165 188 167 +f 162 134 132 +f 163 135 165 +f 160 132 130 +f 161 133 163 +f 158 130 128 +f 159 131 161 +f 156 128 126 +f 157 129 159 +f 154 126 124 +f 155 127 157 +f 172 124 122 +f 173 125 155 +f 122 185 172 +f 185 123 173 +f 170 120 118 +f 171 121 76 +f 120 186 191 +f 186 121 192 +f 189 186 185 +f 190 186 192 +f 143 184 182 +f 184 144 183 +f 141 182 180 +f 183 142 181 +f 141 178 139 +f 142 179 181 +f 174 193 176 +f 194 175 177 +f 139 176 193 +f 177 140 194 +f 198 195 152 +f 198 196 197 +f 195 77 193 +f 196 77 197 +f 139 77 138 +f 140 77 194 +f 150 199 152 +f 200 151 153 +f 148 201 150 +f 202 149 151 +f 205 148 147 +f 206 149 204 +f 79 147 146 +f 79 147 206 +f 152 78 198 +f 153 78 200 +f 199 216 78 +f 200 216 215 +f 79 208 205 +f 209 79 206 +f 205 210 203 +f 211 206 204 +f 210 201 203 +f 211 202 213 +f 201 214 199 +f 215 202 200 +f 212 208 207 +f 213 209 211 +f 207 214 212 +f 215 207 213 +f 147 172 185 +f 173 147 185 +f 148 219 172 +f 220 149 173 +f 152 219 150 +f 153 220 222 +f 195 221 152 +f 196 222 175 +f 217 174 89 +f 218 175 222 +f 223 221 217 +f 224 222 220 +f 87 219 223 +f 220 88 224 +f 138 230 139 +f 138 231 80 +f 141 230 228 +f 231 142 229 +f 143 228 226 +f 229 144 227 +f 145 226 225 +f 227 145 225 +f 226 239 225 +f 227 239 238 +f 226 235 237 +f 236 227 238 +f 228 233 235 +f 234 229 236 +f 80 233 230 +f 80 234 232 +f 232 237 233 +f 238 232 234 +f 233 237 235 +f 236 238 234 +f 191 242 240 +f 243 192 241 +f 120 240 262 +f 241 121 263 +f 120 264 118 +f 121 265 263 +f 122 242 189 +f 123 243 261 +f 122 258 260 +f 259 123 261 +f 124 256 258 +f 257 125 259 +f 126 254 256 +f 255 127 257 +f 128 252 254 +f 253 129 255 +f 132 252 130 +f 133 253 251 +f 134 250 132 +f 135 251 249 +f 134 244 248 +f 245 135 249 +f 187 246 244 +f 247 188 245 +f 136 264 246 +f 265 137 247 +f 264 284 246 +f 265 285 267 +f 244 284 286 +f 285 245 287 +f 244 282 248 +f 245 283 287 +f 248 280 250 +f 249 281 283 +f 252 280 278 +f 281 253 279 +f 252 276 254 +f 253 277 279 +f 256 276 274 +f 277 257 275 +f 256 272 258 +f 257 273 275 +f 258 270 260 +f 259 271 273 +f 242 270 288 +f 271 243 289 +f 264 268 266 +f 269 265 267 +f 262 290 268 +f 291 263 269 +f 240 288 290 +f 289 241 291 +f 75 292 81 +f 293 75 81 +f 116 294 292 +f 295 117 293 +f 112 294 114 +f 113 295 297 +f 110 296 112 +f 111 297 299 +f 108 298 110 +f 109 299 301 +f 108 302 300 +f 303 109 301 +f 104 302 106 +f 105 303 305 +f 104 306 304 +f 307 105 305 +f 102 308 306 +f 309 103 307 +f 317 346 316 +f 317 347 337 +f 316 344 315 +f 316 345 347 +f 315 348 314 +f 315 349 345 +f 97 314 348 +f 314 98 349 +f 95 348 342 +f 349 96 343 +f 93 342 338 +f 343 94 339 +f 91 338 340 +f 339 92 341 +f 338 346 340 +f 347 339 341 +f 342 344 338 +f 343 345 349 +f 340 336 334 +f 341 337 347 +f 89 340 334 +f 341 90 335 +f 350 223 217 +f 351 224 353 +f 334 217 89 +f 335 218 351 +f 223 354 87 +f 224 355 353 +f 354 100 87 +f 355 101 309 +f 332 312 85 +f 333 312 361 +f 360 86 312 +f 361 86 359 +f 86 356 313 +f 357 86 313 +f 313 336 317 +f 337 313 317 +f 336 350 334 +f 337 351 357 +f 304 326 318 +f 327 305 319 +f 324 85 84 +f 325 85 333 +f 366 311 310 +f 367 311 365 +f 311 362 83 +f 363 311 83 +f 83 324 84 +f 325 83 84 +f 300 370 372 +f 371 301 373 +f 372 376 374 +f 377 373 375 +f 374 378 380 +f 379 375 381 +f 380 384 382 +f 385 381 383 +f 386 384 322 +f 387 385 383 +f 324 382 386 +f 383 325 387 +f 362 380 382 +f 381 363 383 +f 364 374 380 +f 375 365 381 +f 366 372 374 +f 373 367 375 +f 300 368 298 +f 301 369 373 +f 368 310 82 +f 369 310 367 +f 292 296 298 +f 297 293 299 +f 292 368 82 +f 369 293 82 +f 81 292 82 +f 82 293 81 +f 304 370 302 +f 305 371 319 +f 318 376 370 +f 377 319 371 +f 320 378 376 +f 379 321 377 +f 384 390 322 +f 385 391 379 +f 358 392 356 +f 359 393 395 +f 392 328 326 +f 393 329 395 +f 306 392 326 +f 393 307 327 +f 308 350 392 +f 351 309 393 +f 350 356 392 +f 393 357 351 +f 308 354 352 +f 353 355 309 +f 330 386 322 +f 331 387 389 +f 386 332 324 +f 387 333 389 +f 394 330 328 +f 395 331 389 +f 360 394 358 +f 361 395 389 +f 332 388 360 +f 361 389 333 +f 396 410 408 +f 397 411 423 +f 408 412 406 +f 413 409 407 +f 412 404 406 +f 413 405 415 +f 414 402 404 +f 415 403 417 +f 416 400 402 +f 417 401 419 +f 400 420 398 +f 421 401 399 +f 418 426 420 +f 427 419 421 +f 416 428 418 +f 429 417 419 +f 432 416 414 +f 433 417 431 +f 434 414 412 +f 435 415 433 +f 436 412 410 +f 437 413 435 +f 410 424 436 +f 425 411 437 +f 328 450 326 +f 329 451 453 +f 398 452 328 +f 399 453 421 +f 318 450 320 +f 451 319 321 +f 390 422 396 +f 423 391 397 +f 420 448 452 +f 449 421 453 +f 454 448 446 +f 455 449 453 +f 442 446 444 +f 447 443 445 +f 456 442 440 +f 457 443 455 +f 456 458 438 +f 457 459 441 +f 438 424 422 +f 439 425 459 +f 320 438 390 +f 439 321 391 +f 450 456 320 +f 451 457 455 +f 450 452 454 +f 455 453 451 +f 424 460 484 +f 461 425 485 +f 440 460 458 +f 441 461 471 +f 440 468 470 +f 469 441 471 +f 444 468 442 +f 445 469 467 +f 446 466 444 +f 447 467 465 +f 446 462 464 +f 463 447 465 +f 448 482 462 +f 483 449 463 +f 436 484 472 +f 485 437 473 +f 434 472 474 +f 473 435 475 +f 432 474 476 +f 475 433 477 +f 432 478 430 +f 433 479 477 +f 430 480 428 +f 431 481 479 +f 428 482 426 +f 429 483 481 +f 464 486 466 +f 465 487 489 +f 488 492 486 +f 489 493 491 +f 492 496 494 +f 497 493 495 +f 496 500 494 +f 497 501 499 +f 472 494 500 +f 495 473 501 +f 492 484 460 +f 493 485 495 +f 470 492 460 +f 471 493 487 +f 466 470 468 +f 471 467 469 +f 482 464 462 +f 483 465 489 +f 480 488 482 +f 489 481 483 +f 496 480 478 +f 497 481 491 +f 498 478 476 +f 499 479 497 +f 474 498 476 +f 499 475 477 +f 472 500 474 +f 475 501 473 +f 400 512 510 +f 513 401 511 +f 402 510 508 +f 511 403 509 +f 402 506 404 +f 403 507 509 +f 404 504 406 +f 405 505 507 +f 406 502 408 +f 407 503 505 +f 408 514 396 +f 409 515 503 +f 510 514 502 +f 511 515 513 +f 502 508 510 +f 509 503 511 +f 504 506 508 +f 509 507 505 +f 390 514 322 +f 391 515 397 +f 322 512 330 +f 513 323 331 +f 328 512 398 +f 513 329 399 +f 55 9 11 +f 12 10 56 +f 53 11 13 +f 14 12 54 +f 11 17 15 +f 16 18 12 +f 9 19 17 +f 18 20 10 +f 19 21 23 +f 24 22 20 +f 17 23 25 +f 26 24 18 +f 29 27 25 +f 30 24 26 +f 21 31 29 +f 30 32 22 +f 31 33 35 +f 36 34 32 +f 35 37 27 +f 36 30 28 +f 41 39 37 +f 42 36 38 +f 43 41 35 +f 44 34 36 +f 45 47 41 +f 46 44 42 +f 47 49 39 +f 48 42 40 +f 53 51 49 +f 54 48 50 +f 55 53 47 +f 56 46 48 +f 45 59 57 +f 46 56 58 +f 43 61 59 +f 44 46 60 +f 33 63 61 +f 34 44 62 +f 31 65 63 +f 32 34 64 +f 31 21 67 +f 68 22 32 +f 21 19 71 +f 72 20 22 +f 19 9 73 +f 74 10 20 +f 9 55 57 +f 58 56 10 +f 182 184 99 +f 183 98 99 +f 180 182 97 +f 181 96 98 +f 93 178 180 +f 181 179 94 +f 91 176 178 +f 179 177 92 +f 89 174 176 +f 177 175 90 +f 87 100 154 +f 155 101 88 +f 102 156 154 +f 103 101 155 +f 102 104 158 +f 159 105 103 +f 106 160 158 +f 107 105 159 +f 108 162 160 +f 109 107 161 +f 110 164 162 +f 111 109 163 +f 110 112 166 +f 167 113 111 +f 114 168 166 +f 115 113 167 +f 116 170 168 +f 117 115 169 +f 75 76 170 +f 75 117 171 +f 136 168 170 +f 137 119 171 +f 136 187 166 +f 167 188 137 +f 164 166 187 +f 165 135 188 +f 162 164 134 +f 163 133 135 +f 160 162 132 +f 161 131 133 +f 158 160 130 +f 159 129 131 +f 156 158 128 +f 157 127 129 +f 154 156 126 +f 155 125 127 +f 172 154 124 +f 173 123 125 +f 122 189 185 +f 185 190 123 +f 170 76 120 +f 171 119 121 +f 120 76 186 +f 186 76 121 +f 189 191 186 +f 190 185 186 +f 143 145 184 +f 184 145 144 +f 141 143 182 +f 183 144 142 +f 141 180 178 +f 142 140 179 +f 174 195 193 +f 194 196 175 +f 139 178 176 +f 177 179 140 +f 198 197 195 +f 198 153 196 +f 195 197 77 +f 196 194 77 +f 139 193 77 +f 140 138 77 +f 150 201 199 +f 200 202 151 +f 148 203 201 +f 202 204 149 +f 205 203 148 +f 206 147 149 +f 79 205 147 +f 152 199 78 +f 153 198 78 +f 199 214 216 +f 200 78 216 +f 79 207 208 +f 209 207 79 +f 205 208 210 +f 211 209 206 +f 210 212 201 +f 211 204 202 +f 201 212 214 +f 215 213 202 +f 212 210 208 +f 213 207 209 +f 207 216 214 +f 215 216 207 +f 147 148 172 +f 173 149 147 +f 148 150 219 +f 220 151 149 +f 152 221 219 +f 153 151 220 +f 195 174 221 +f 196 153 222 +f 217 221 174 +f 218 90 175 +f 223 219 221 +f 224 218 222 +f 87 172 219 +f 220 173 88 +f 138 80 230 +f 138 140 231 +f 141 139 230 +f 231 140 142 +f 143 141 228 +f 229 142 144 +f 145 143 226 +f 227 144 145 +f 226 237 239 +f 227 225 239 +f 226 228 235 +f 236 229 227 +f 228 230 233 +f 234 231 229 +f 80 232 233 +f 80 231 234 +f 232 239 237 +f 238 239 232 +f 191 189 242 +f 243 190 192 +f 120 191 240 +f 241 192 121 +f 120 262 264 +f 121 119 265 +f 122 260 242 +f 123 190 243 +f 122 124 258 +f 259 125 123 +f 124 126 256 +f 257 127 125 +f 126 128 254 +f 255 129 127 +f 128 130 252 +f 253 131 129 +f 132 250 252 +f 133 131 253 +f 134 248 250 +f 135 133 251 +f 134 187 244 +f 245 188 135 +f 187 136 246 +f 247 137 188 +f 136 118 264 +f 265 119 137 +f 264 266 284 +f 265 247 285 +f 244 246 284 +f 285 247 245 +f 244 286 282 +f 245 249 283 +f 248 282 280 +f 249 251 281 +f 252 250 280 +f 281 251 253 +f 252 278 276 +f 253 255 277 +f 256 254 276 +f 277 255 257 +f 256 274 272 +f 257 259 273 +f 258 272 270 +f 259 261 271 +f 242 260 270 +f 271 261 243 +f 264 262 268 +f 269 263 265 +f 262 240 290 +f 291 241 263 +f 240 242 288 +f 289 243 241 +f 75 116 292 +f 293 117 75 +f 116 114 294 +f 295 115 117 +f 112 296 294 +f 113 115 295 +f 110 298 296 +f 111 113 297 +f 108 300 298 +f 109 111 299 +f 108 106 302 +f 303 107 109 +f 104 304 302 +f 105 107 303 +f 104 102 306 +f 307 103 105 +f 102 100 308 +f 309 101 103 +f 317 336 346 +f 317 316 347 +f 316 346 344 +f 316 315 345 +f 315 344 348 +f 315 314 349 +f 97 99 314 +f 314 99 98 +f 95 97 348 +f 349 98 96 +f 93 95 342 +f 343 96 94 +f 91 93 338 +f 339 94 92 +f 338 344 346 +f 347 345 339 +f 342 348 344 +f 343 339 345 +f 340 346 336 +f 341 335 337 +f 89 91 340 +f 341 92 90 +f 350 352 223 +f 351 218 224 +f 334 350 217 +f 335 90 218 +f 223 352 354 +f 224 88 355 +f 354 308 100 +f 355 88 101 +f 332 360 312 +f 333 85 312 +f 360 358 86 +f 361 312 86 +f 86 358 356 +f 357 359 86 +f 313 356 336 +f 337 357 313 +f 336 356 350 +f 337 335 351 +f 304 306 326 +f 327 307 305 +f 324 332 85 +f 325 84 85 +f 366 364 311 +f 367 310 311 +f 311 364 362 +f 363 365 311 +f 83 362 324 +f 325 363 83 +f 300 302 370 +f 371 303 301 +f 372 370 376 +f 377 371 373 +f 374 376 378 +f 379 377 375 +f 380 378 384 +f 385 379 381 +f 386 382 384 +f 387 323 385 +f 324 362 382 +f 383 363 325 +f 362 364 380 +f 381 365 363 +f 364 366 374 +f 375 367 365 +f 366 368 372 +f 373 369 367 +f 300 372 368 +f 301 299 369 +f 368 366 310 +f 369 82 310 +f 292 294 296 +f 297 295 293 +f 292 298 368 +f 369 299 293 +f 304 318 370 +f 305 303 371 +f 318 320 376 +f 377 321 319 +f 320 390 378 +f 379 391 321 +f 384 378 390 +f 385 323 391 +f 358 394 392 +f 359 357 393 +f 392 394 328 +f 393 327 329 +f 306 308 392 +f 393 309 307 +f 308 352 350 +f 351 353 309 +f 330 388 386 +f 331 323 387 +f 386 388 332 +f 387 325 333 +f 394 388 330 +f 395 329 331 +f 360 388 394 +f 361 359 395 +f 396 422 410 +f 397 409 411 +f 408 410 412 +f 413 411 409 +f 412 414 404 +f 413 407 405 +f 414 416 402 +f 415 405 403 +f 416 418 400 +f 417 403 401 +f 400 418 420 +f 421 419 401 +f 418 428 426 +f 427 429 419 +f 416 430 428 +f 429 431 417 +f 432 430 416 +f 433 415 417 +f 434 432 414 +f 435 413 415 +f 436 434 412 +f 437 411 413 +f 410 422 424 +f 425 423 411 +f 328 452 450 +f 329 327 451 +f 398 420 452 +f 399 329 453 +f 318 326 450 +f 451 327 319 +f 390 438 422 +f 423 439 391 +f 420 426 448 +f 449 427 421 +f 454 452 448 +f 455 447 449 +f 442 454 446 +f 447 455 443 +f 456 454 442 +f 457 441 443 +f 456 440 458 +f 457 439 459 +f 438 458 424 +f 439 423 425 +f 320 456 438 +f 439 457 321 +f 450 454 456 +f 451 321 457 +f 424 458 460 +f 461 459 425 +f 440 470 460 +f 441 459 461 +f 440 442 468 +f 469 443 441 +f 444 466 468 +f 445 443 469 +f 446 464 466 +f 447 445 467 +f 446 448 462 +f 463 449 447 +f 448 426 482 +f 483 427 449 +f 436 424 484 +f 485 425 437 +f 434 436 472 +f 473 437 435 +f 432 434 474 +f 475 435 433 +f 432 476 478 +f 433 431 479 +f 430 478 480 +f 431 429 481 +f 428 480 482 +f 429 427 483 +f 464 488 486 +f 465 467 487 +f 488 490 492 +f 489 487 493 +f 492 490 496 +f 497 491 493 +f 496 498 500 +f 497 495 501 +f 472 484 494 +f 495 485 473 +f 492 494 484 +f 493 461 485 +f 470 486 492 +f 471 461 493 +f 466 486 470 +f 471 487 467 +f 482 488 464 +f 483 463 465 +f 480 490 488 +f 489 491 481 +f 496 490 480 +f 497 479 481 +f 498 496 478 +f 499 477 479 +f 474 500 498 +f 499 501 475 +f 400 398 512 +f 513 399 401 +f 402 400 510 +f 511 401 403 +f 402 508 506 +f 403 405 507 +f 404 506 504 +f 405 407 505 +f 406 504 502 +f 407 409 503 +f 408 502 514 +f 409 397 515 +f 510 512 514 +f 511 503 515 +f 502 504 508 +f 509 505 503 +f 390 396 514 +f 391 323 515 +f 322 514 512 +f 513 515 323 +f 328 330 512 +f 513 331 329 +o Torus +v 1.277532 -1.122470 -1.043757 +v 1.316018 -0.934970 -1.076051 +v 1.277532 -0.747470 -1.043757 +v 1.172385 -0.610210 -0.955528 +v 1.028751 -0.559970 -0.835006 +v 0.885118 -0.610210 -0.714483 +v 0.779971 -0.747470 -0.626254 +v 0.741485 -0.934970 -0.593960 +v 0.779971 -1.122470 -0.626254 +v 0.885118 -1.259729 -0.714483 +v 1.028751 -1.309970 -0.835006 +v 1.172385 -1.259729 -0.955529 +v 1.109576 -1.114450 -1.222307 +v 1.152563 -0.927164 -1.249817 +v 1.126372 -0.740252 -1.204452 +v 1.038020 -0.603794 -1.098368 +v 0.911183 -0.554356 -0.959991 +v 0.779845 -0.605183 -0.826397 +v 0.679198 -0.742658 -0.733384 +v 0.636211 -0.929943 -0.705874 +v 0.662402 -1.116856 -0.751239 +v 0.750754 -1.253313 -0.857323 +v 0.877592 -1.302752 -0.995701 +v 1.008930 -1.251924 -1.129294 +v 0.923211 -1.090525 -1.379942 +v 0.971192 -0.903881 -1.403228 +v 0.958643 -0.718720 -1.346324 +v 0.888928 -0.584655 -1.224477 +v 0.780727 -0.537609 -1.070335 +v 0.663032 -0.590188 -0.925202 +v 0.567379 -0.728303 -0.827965 +v 0.519399 -0.914947 -0.804680 +v 0.531947 -1.100109 -0.861584 +v 0.601662 -1.234174 -0.983431 +v 0.709863 -1.281220 -1.137572 +v 0.827558 -1.228641 -1.282706 +v 0.721625 -1.051107 -1.513967 +v 0.775007 -0.865519 -1.533662 +v 0.777216 -0.683243 -1.466946 +v 0.727660 -0.553120 -1.331696 +v 0.639617 -0.510016 -1.164153 +v 0.536679 -0.565480 -1.009208 +v 0.446427 -0.704652 -0.908380 +v 0.393045 -0.890240 -0.888685 +v 0.390837 -1.072516 -0.955401 +v 0.440393 -1.202639 -1.090651 +v 0.528435 -1.245743 -1.258194 +v 0.631374 -1.190279 -1.413139 +v 0.508267 -0.996869 -1.622087 +v 0.567366 -0.812734 -1.638885 +v 0.585193 -0.634429 -1.564254 +v 0.556973 -0.509729 -1.418192 +v 0.490266 -0.472049 -1.239837 +v 0.402947 -0.531484 -1.076977 +v 0.318412 -0.672109 -0.973252 +v 0.259314 -0.856244 -0.956454 +v 0.241486 -1.034549 -1.031085 +v 0.269706 -1.159248 -1.177147 +v 0.336413 -1.196929 -1.355502 +v 0.423732 -1.137494 -1.518362 +v 0.286788 -0.928739 -1.702452 +v 0.351822 -0.746430 -1.717097 +v 0.385863 -0.573112 -1.636583 +v 0.379790 -0.455225 -1.482485 +v 0.335231 -0.424358 -1.296092 +v 0.264125 -0.488781 -1.127350 +v 0.185525 -0.631231 -1.021471 +v 0.120492 -0.813540 -1.006827 +v 0.086451 -0.986858 -1.087341 +v 0.092523 -1.104744 -1.241439 +v 0.137082 -1.135612 -1.427832 +v 0.208188 -1.071189 -1.596574 +v 0.060977 -0.847882 -1.753689 +v 0.132061 -0.667740 -1.766960 +v 0.182633 -0.500341 -1.682696 +v 0.199141 -0.390540 -1.523474 +v 0.177163 -0.367759 -1.331958 +v 0.122588 -0.438100 -1.159465 +v 0.050039 -0.582717 -1.052213 +v -0.021045 -0.762860 -1.038942 +v -0.071617 -0.930259 -1.123206 +v -0.088125 -1.040059 -1.282428 +v -0.066148 -1.062841 -1.473944 +v -0.011572 -0.992499 -1.646437 +v -0.165301 -0.755684 -1.774919 +v -0.088154 -0.578012 -1.787621 +v -0.021018 -0.417362 -1.701803 +v 0.018119 -0.316781 -1.540458 +v 0.018769 -0.303220 -1.346819 +v -0.019242 -0.380311 -1.172771 +v -0.085728 -0.527398 -1.064951 +v -0.162875 -0.705070 -1.052249 +v -0.230012 -0.865720 -1.138067 +v -0.269148 -0.966300 -1.299412 +v -0.269798 -0.979862 -1.493051 +v -0.231787 -0.902771 -1.667099 +v -0.388176 -0.653720 -1.765780 +v -0.305057 -0.478780 -1.778727 +v -0.221605 -0.325595 -1.693577 +v -0.160181 -0.235210 -1.533147 +v -0.137244 -0.231845 -1.340421 +v -0.158939 -0.316400 -1.167043 +v -0.219453 -0.466220 -1.059468 +v -0.302572 -0.641160 -1.046520 +v -0.386024 -0.794345 -1.131670 +v -0.447448 -0.884729 -1.292101 +v -0.470386 -0.888095 -1.484826 +v -0.448690 -0.803539 -1.658204 +v -0.603833 -0.543736 -1.726428 +v -0.514936 -0.371743 -1.740430 +v -0.415697 -0.226609 -1.658161 +v -0.332707 -0.147223 -1.501665 +v -0.288204 -0.154856 -1.312875 +v -0.294112 -0.247463 -1.142377 +v -0.348848 -0.400229 -1.035857 +v -0.437745 -0.572222 -1.021855 +v -0.536984 -0.717356 -1.104124 +v -0.619974 -0.796742 -1.260619 +v -0.664477 -0.789109 -1.449409 +v -0.658569 -0.696502 -1.619907 +v -0.808584 -0.427613 -1.657536 +v -0.714200 -0.258731 -1.673383 +v -0.599972 -0.122098 -1.596158 +v -0.496508 -0.054325 -1.446551 +v -0.431529 -0.073570 -1.264651 +v -0.422448 -0.174677 -1.099196 +v -0.471698 -0.330556 -0.994521 +v -0.566082 -0.499437 -0.978674 +v -0.680310 -0.636070 -1.055899 +v -0.783774 -0.703844 -1.205506 +v -0.848753 -0.684598 -1.387406 +v -0.857833 -0.583491 -1.552861 +v -0.998924 -0.307338 -1.560283 +v -0.899440 -0.141679 -1.578736 +v -0.771278 -0.013851 -1.508630 +v -0.648780 0.041895 -1.368749 +v -0.564767 0.010622 -1.196573 +v -0.541753 -0.099290 -1.038239 +v -0.585902 -0.258391 -0.936170 +v -0.685386 -0.424049 -0.917716 +v -0.813548 -0.551877 -0.987822 +v -0.936046 -0.607624 -1.127703 +v -1.020059 -0.576351 -1.299879 +v -1.043074 -0.466439 -1.458214 +v -1.171596 -0.184970 -1.436333 +v -1.067486 -0.022590 -1.458108 +v -0.926683 0.096280 -1.397076 +v -0.786918 0.139790 -1.269589 +v -0.685638 0.096280 -1.109809 +v -0.649983 -0.022590 -0.960548 +v -0.689505 -0.184970 -0.861800 +v -0.793616 -0.347350 -0.840025 +v -0.934418 -0.466220 -0.901058 +v -1.074184 -0.509729 -1.028544 +v -1.175464 -0.466220 -1.188324 +v -1.211119 -0.347350 -1.337586 +v -1.323647 -0.062601 -1.287807 +v -1.215462 0.096500 -1.313562 +v -1.063529 0.206412 -1.263402 +v -0.908558 0.237684 -1.150769 +v -0.792074 0.181938 -1.005841 +v -0.745287 0.054110 -0.867453 +v -0.780736 -0.111549 -0.772684 +v -0.888921 -0.270650 -0.746930 +v -1.040854 -0.380562 -0.797089 +v -1.195825 -0.411835 -0.909723 +v -1.312310 -0.356088 -1.054651 +v -1.359096 -0.228260 -1.193039 +v -1.452474 0.057673 -1.117247 +v -1.340838 0.213551 -1.147572 +v -1.179474 0.314659 -1.109898 +v -1.011620 0.333904 -1.014320 +v -0.882253 0.266130 -0.886449 +v -0.826036 0.129497 -0.760546 +v -0.858032 -0.039384 -0.670348 +v -0.969669 -0.195262 -0.640024 +v -1.131033 -0.296370 -0.677697 +v -1.298887 -0.315615 -0.773275 +v -1.428254 -0.247841 -0.901147 +v -1.484471 -0.111208 -1.027049 +v -1.555874 0.173796 -0.927570 +v -1.441467 0.326563 -0.962977 +v -1.272534 0.419169 -0.939189 +v -1.094340 0.426802 -0.862579 +v -0.954633 0.347416 -0.753675 +v -0.890846 0.202282 -0.641658 +v -0.920072 0.030290 -0.556542 +v -1.034480 -0.122477 -0.521135 +v -1.203413 -0.215084 -0.544923 +v -1.381607 -0.222717 -0.621533 +v -1.521314 -0.143331 -0.730438 +v -1.585100 0.001803 -0.842455 +v -1.632077 0.283780 -0.722023 +v -1.515628 0.433600 -0.762938 +v -1.341116 0.518155 -0.754196 +v -1.155302 0.514790 -0.698141 +v -1.007975 0.424405 -0.609792 +v -0.938610 0.271220 -0.512822 +v -0.965794 0.096280 -0.433214 +v -1.082243 -0.053540 -0.392299 +v -1.256755 -0.138095 -0.401040 +v -1.442569 -0.134729 -0.457096 +v -1.589896 -0.044345 -0.545445 +v -1.659261 0.108840 -0.642415 +v -1.679779 0.385744 -0.504121 +v -1.562052 0.532831 -0.550874 +v -1.384048 0.609923 -0.558084 +v -1.193464 0.596361 -0.523819 +v -1.041366 0.495780 -0.457260 +v -0.968509 0.335130 -0.376242 +v -0.994415 0.157458 -0.302472 +v -1.112143 0.010371 -0.255719 +v -1.290146 -0.066720 -0.248509 +v -1.480731 -0.053158 -0.282774 +v -1.632828 0.047423 -0.349333 +v -1.705685 0.208072 -0.430351 +v -1.698164 0.477943 -0.277593 +v -1.579944 0.622560 -0.330416 +v -1.400595 0.692902 -0.354209 +v -1.208172 0.670120 -0.342597 +v -1.054236 0.560319 -0.298691 +v -0.980033 0.392920 -0.234255 +v -1.005446 0.212778 -0.166556 +v -1.123666 0.068161 -0.113732 +v -1.303016 -0.002181 -0.089939 +v -1.495439 0.020601 -0.101552 +v -1.649375 0.130402 -0.145458 +v -1.723578 0.297800 -0.209893 +v -1.686918 0.558799 -0.046316 +v -1.568999 0.701249 -0.105336 +v -1.390473 0.765672 -0.146060 +v -1.199175 0.734805 -0.157576 +v -1.046363 0.616918 -0.136797 +v -0.972984 0.443600 -0.089292 +v -0.998699 0.261291 -0.027790 +v -1.116617 0.118841 0.031231 +v -1.295144 0.054418 0.071954 +v -1.486442 0.085286 0.083470 +v -1.639253 0.203172 0.062691 +v -1.712633 0.376490 0.015186 +v -1.646233 0.626929 0.185753 +v -1.529404 0.767554 0.120514 +v -1.353856 0.826989 0.062802 +v -1.166627 0.789309 0.028080 +v -1.017884 0.664609 0.025651 +v -0.947483 0.486304 0.056168 +v -0.974287 0.302169 0.111452 +v -1.091116 0.161544 0.176690 +v -1.266664 0.102109 0.234403 +v -1.453894 0.139790 0.269125 +v -1.602637 0.264489 0.271554 +v -1.673038 0.442794 0.241037 +v -1.576805 0.681167 0.414645 +v -1.461836 0.820339 0.343273 +v -1.291371 0.875803 0.268805 +v -1.111084 0.832699 0.211193 +v -0.969284 0.702576 0.185876 +v -0.903965 0.520300 0.199636 +v -0.932630 0.334712 0.248787 +v -1.047599 0.195541 0.320159 +v -1.218064 0.140076 0.394627 +v -1.398351 0.183180 0.452239 +v -1.540151 0.313304 0.477556 +v -1.605470 0.495579 0.463796 +v -1.479821 0.720586 0.636442 +v -1.367452 0.858701 0.559127 +v -1.204086 0.911280 0.468422 +v -1.033497 0.864234 0.388631 +v -0.901395 0.730169 0.341134 +v -0.843176 0.545007 0.338657 +v -0.874440 0.358363 0.381865 +v -0.986810 0.220248 0.459180 +v -1.150176 0.167669 0.549885 +v -1.320764 0.214715 0.629676 +v -1.452866 0.348780 0.677173 +v -1.511085 0.533942 0.679650 +v -1.356942 0.744510 0.847348 +v -1.247865 0.881984 0.764382 +v -1.093495 0.932812 0.658238 +v -0.935194 0.883373 0.557356 +v -0.815380 0.746916 0.488768 +v -0.766157 0.560003 0.470852 +v -0.800713 0.372718 0.508409 +v -0.909790 0.235243 0.591375 +v -1.064161 0.184416 0.697520 +v -1.222461 0.233854 0.798401 +v -1.342275 0.370312 0.866989 +v -1.391499 0.557225 0.884905 +v -1.210271 0.752530 1.043757 +v -1.105124 0.889790 0.955528 +v -0.961490 0.940030 0.835006 +v -0.817857 0.889790 0.714483 +v -0.712710 0.752530 0.626254 +v -0.674224 0.565030 0.593960 +v -0.712710 0.377530 0.626254 +v -0.817857 0.240271 0.714483 +v -0.961490 0.190030 0.835006 +v -1.105124 0.240271 0.955528 +v -1.210271 0.377530 1.043757 +v -1.248757 0.565030 1.076051 +v -1.042315 0.744510 1.222307 +v -0.941668 0.881984 1.129294 +v -0.810330 0.932812 0.995700 +v -0.683492 0.883373 0.857323 +v -0.595141 0.746916 0.751239 +v -0.568950 0.560003 0.705874 +v -0.611937 0.372718 0.733384 +v -0.712583 0.235243 0.826397 +v -0.843921 0.184416 0.959991 +v -0.970759 0.233854 1.098368 +v -1.059110 0.370312 1.204452 +v -1.085302 0.557225 1.249817 +v -0.855950 0.720586 1.379942 +v -0.760297 0.858701 1.282706 +v -0.642602 0.911280 1.137572 +v -0.534401 0.864234 0.983431 +v -0.464686 0.730169 0.861584 +v -0.452137 0.545007 0.804679 +v -0.500118 0.358363 0.827965 +v -0.595771 0.220248 0.925202 +v -0.713466 0.167669 1.070335 +v -0.821667 0.214715 1.224477 +v -0.891382 0.348780 1.346324 +v -0.903931 0.533942 1.403228 +v -0.654364 0.681167 1.513967 +v -0.564113 0.820339 1.413139 +v -0.461175 0.875804 1.258194 +v -0.373132 0.832699 1.090650 +v -0.323576 0.702576 0.955401 +v -0.325784 0.520300 0.888685 +v -0.379166 0.334712 0.908380 +v -0.469418 0.195541 1.009208 +v -0.572356 0.140076 1.164152 +v -0.660399 0.183180 1.331696 +v -0.709955 0.313304 1.466946 +v -0.707746 0.495579 1.533661 +v -0.441006 0.626929 1.622087 +v -0.356472 0.767554 1.518362 +v -0.269152 0.826989 1.355502 +v -0.202445 0.789309 1.177147 +v -0.174225 0.664609 1.031085 +v -0.192053 0.486304 0.956454 +v -0.251151 0.302169 0.973252 +v -0.335686 0.161544 1.076977 +v -0.423005 0.102109 1.239836 +v -0.489712 0.139790 1.418192 +v -0.517933 0.264489 1.564254 +v -0.500105 0.442795 1.638884 +v -0.219527 0.558799 1.702452 +v -0.140927 0.701249 1.596574 +v -0.069821 0.765672 1.427832 +v -0.025262 0.734805 1.241439 +v -0.019189 0.616918 1.087341 +v -0.053230 0.443600 1.006827 +v -0.118264 0.261291 1.021472 +v -0.196864 0.118841 1.127350 +v -0.267970 0.054418 1.296093 +v -0.312529 0.085286 1.482485 +v -0.318601 0.203172 1.636583 +v -0.284560 0.376490 1.717097 +v 0.006283 0.477943 1.753689 +v 0.078833 0.622560 1.646437 +v 0.133408 0.692901 1.473944 +v 0.155386 0.670120 1.282428 +v 0.138878 0.560319 1.123206 +v 0.088306 0.392920 1.038942 +v 0.017222 0.212778 1.052213 +v -0.055327 0.068161 1.159464 +v -0.109902 -0.002181 1.331958 +v -0.131880 0.020601 1.523474 +v -0.115372 0.130402 1.682696 +v -0.064800 0.297800 1.766960 +v 0.232562 0.385744 1.774919 +v 0.299048 0.532832 1.667099 +v 0.337059 0.609923 1.493051 +v 0.336409 0.596361 1.299412 +v 0.297272 0.495780 1.138067 +v 0.230136 0.335131 1.052249 +v 0.152989 0.157459 1.064951 +v 0.086503 0.010371 1.172771 +v 0.048492 -0.066720 1.346819 +v 0.049142 -0.053158 1.540458 +v 0.088278 0.047423 1.701803 +v 0.155415 0.208072 1.787621 +v 0.455438 0.283780 1.765780 +v 0.515952 0.433600 1.658204 +v 0.537647 0.518155 1.484826 +v 0.514710 0.514789 1.292101 +v 0.453286 0.424405 1.131670 +v 0.369834 0.271220 1.046520 +v 0.286715 0.096280 1.059468 +v 0.226200 -0.053540 1.167043 +v 0.204505 -0.138095 1.340421 +v 0.227443 -0.134730 1.533146 +v 0.288867 -0.044345 1.693577 +v 0.372319 0.108840 1.778727 +v 0.671095 0.173796 1.726428 +v 0.725831 0.326562 1.619907 +v 0.731738 0.419169 1.449409 +v 0.687235 0.426802 1.260619 +v 0.604246 0.347416 1.104123 +v 0.505007 0.202282 1.021855 +v 0.416109 0.030290 1.035856 +v 0.361373 -0.122477 1.142377 +v 0.355465 -0.215084 1.312875 +v 0.399969 -0.222717 1.501665 +v 0.482958 -0.143331 1.658161 +v 0.582197 0.001803 1.740429 +v 0.875845 0.057673 1.657536 +v 0.925094 0.213551 1.552861 +v 0.916013 0.314659 1.387406 +v 0.851035 0.333904 1.205506 +v 0.747571 0.266130 1.055899 +v 0.633343 0.129497 0.978674 +v 0.538959 -0.039384 0.994521 +v 0.489709 -0.195262 1.099196 +v 0.498790 -0.296370 1.264651 +v 0.563769 -0.315615 1.446551 +v 0.667233 -0.247841 1.596158 +v 0.781461 -0.111208 1.673384 +v 1.066184 -0.062601 1.560283 +v 1.110334 0.096500 1.458214 +v 1.087319 0.206412 1.299879 +v 1.003307 0.237685 1.127704 +v 0.880808 0.181938 0.987823 +v 0.752647 0.054110 0.917716 +v 0.653163 -0.111549 0.936170 +v 0.609013 -0.270650 1.038239 +v 0.632028 -0.380562 1.196574 +v 0.716040 -0.411834 1.368749 +v 0.838539 -0.356088 1.508631 +v 0.966700 -0.228260 1.578737 +v 1.238858 -0.184970 1.436333 +v 1.278380 -0.022590 1.337585 +v 1.242725 0.096280 1.188324 +v 1.141446 0.139789 1.028544 +v 1.001680 0.096280 0.901057 +v 0.860878 -0.022590 0.840025 +v 0.756767 -0.184970 0.861800 +v 0.717244 -0.347350 0.960548 +v 0.752899 -0.466220 1.109809 +v 0.854179 -0.509730 1.269589 +v 0.993945 -0.466220 1.397076 +v 1.134747 -0.347350 1.458108 +v 1.390908 -0.307338 1.287808 +v 1.426357 -0.141679 1.193040 +v 1.379570 -0.013851 1.054651 +v 1.263086 0.041895 0.909724 +v 1.108115 0.010622 0.797090 +v 0.956182 -0.099290 0.746930 +v 0.847997 -0.258391 0.772685 +v 0.812549 -0.424049 0.867453 +v 0.859335 -0.551878 1.005841 +v 0.975819 -0.607624 1.150769 +v 1.130790 -0.576351 1.263403 +v 1.282723 -0.466439 1.313563 +v 1.519735 -0.427612 1.117248 +v 1.551732 -0.258731 1.027050 +v 1.495515 -0.122098 0.901147 +v 1.366148 -0.054324 0.773275 +v 1.198294 -0.073570 0.677698 +v 1.036930 -0.174677 0.640024 +v 0.925294 -0.330555 0.670349 +v 0.893297 -0.499437 0.760547 +v 0.949514 -0.636070 0.886449 +v 1.078881 -0.703843 1.014321 +v 1.246735 -0.684598 1.109899 +v 1.408099 -0.583491 1.147572 +v 1.623136 -0.543736 0.927570 +v 1.652362 -0.371743 0.842454 +v 1.588575 -0.226609 0.730437 +v 1.448868 -0.147223 0.621533 +v 1.270674 -0.154856 0.544923 +v 1.101741 -0.247463 0.521135 +v 0.987334 -0.400230 0.556542 +v 0.958108 -0.572222 0.641657 +v 1.021894 -0.717356 0.753675 +v 1.161601 -0.796742 0.862579 +v 1.339795 -0.789109 0.939189 +v 1.508728 -0.696503 0.962977 +v 1.699338 -0.653720 0.722023 +v 1.726522 -0.478780 0.642415 +v 1.657158 -0.325595 0.545445 +v 1.509830 -0.235210 0.457095 +v 1.324016 -0.231845 0.401040 +v 1.149504 -0.316400 0.392299 +v 1.033055 -0.466220 0.433214 +v 1.005871 -0.641160 0.512821 +v 1.075236 -0.794345 0.609791 +v 1.222563 -0.884729 0.698141 +v 1.408377 -0.888095 0.754196 +v 1.582889 -0.803540 0.762937 +v 1.747040 -0.755684 0.504121 +v 1.772946 -0.578012 0.430352 +v 1.700089 -0.417362 0.349333 +v 1.547992 -0.316781 0.282774 +v 1.357407 -0.303219 0.248509 +v 1.179404 -0.380311 0.255719 +v 1.061676 -0.527398 0.302473 +v 1.035770 -0.705070 0.376242 +v 1.108627 -0.865719 0.457260 +v 1.260725 -0.966300 0.523820 +v 1.451309 -0.979862 0.558085 +v 1.629313 -0.902771 0.550875 +v 1.765426 -0.847882 0.277594 +v 1.790839 -0.667740 0.209895 +v 1.716636 -0.500341 0.145459 +v 1.562700 -0.390540 0.101553 +v 1.370277 -0.367759 0.089940 +v 1.190928 -0.438100 0.113733 +v 1.072708 -0.582717 0.166556 +v 1.047294 -0.762860 0.234256 +v 1.121497 -0.930258 0.298692 +v 1.275433 -1.040059 0.342598 +v 1.467856 -1.062841 0.354210 +v 1.647206 -0.992499 0.330417 +v 1.754179 -0.928739 0.046316 +v 1.779894 -0.746430 -0.015187 +v 1.706515 -0.573112 -0.062692 +v 1.553703 -0.455225 -0.083470 +v 1.362405 -0.424358 -0.071955 +v 1.183878 -0.488781 -0.031231 +v 1.065960 -0.631231 0.027789 +v 1.040245 -0.813540 0.089292 +v 1.113625 -0.986858 0.136797 +v 1.266436 -1.104745 0.157575 +v 1.457734 -1.135612 0.146060 +v 1.636261 -1.071189 0.105336 +v 1.713494 -0.996869 -0.185753 +v 1.740299 -0.812734 -0.241038 +v 1.669898 -0.634429 -0.271554 +v 1.521155 -0.509729 -0.269125 +v 1.333925 -0.472049 -0.234403 +v 1.158377 -0.531484 -0.176691 +v 1.041549 -0.672109 -0.111452 +v 1.014744 -0.856244 -0.056168 +v 1.085145 -1.034549 -0.025652 +v 1.233888 -1.159248 -0.028080 +v 1.421118 -1.196929 -0.062802 +v 1.596666 -1.137494 -0.120515 +v 1.644066 -1.051107 -0.414644 +v 1.672731 -0.865519 -0.463795 +v 1.607413 -0.683243 -0.477556 +v 1.465612 -0.553120 -0.452238 +v 1.285326 -0.510016 -0.394627 +v 1.114860 -0.565480 -0.320158 +v 0.999892 -0.704652 -0.248787 +v 0.971227 -0.890240 -0.199636 +v 1.036545 -1.072516 -0.185875 +v 1.178346 -1.202639 -0.211193 +v 1.358632 -1.245743 -0.268804 +v 1.529098 -1.190279 -0.343273 +v 1.547082 -1.090525 -0.636442 +v 1.578346 -0.903881 -0.679650 +v 1.520127 -0.718720 -0.677174 +v 1.388025 -0.584655 -0.629676 +v 1.217437 -0.537609 -0.549885 +v 1.054071 -0.590188 -0.459180 +v 0.941702 -0.728303 -0.381865 +v 0.910438 -0.914947 -0.338657 +v 0.968657 -1.100109 -0.341134 +v 1.100758 -1.234174 -0.388631 +v 1.271347 -1.281220 -0.468422 +v 1.434713 -1.228641 -0.559127 +v 1.424204 -1.114450 -0.847349 +v 1.458760 -0.927164 -0.884905 +v 1.409536 -0.740252 -0.866990 +v 1.289722 -0.603794 -0.798402 +v 1.131422 -0.554356 -0.697520 +v 0.977051 -0.605183 -0.591375 +v 0.867974 -0.742658 -0.508409 +v 0.833418 -0.929943 -0.470853 +v 0.882642 -1.116856 -0.488768 +v 1.002456 -1.253313 -0.557356 +v 1.160756 -1.302752 -0.658238 +v 1.315127 -1.251924 -0.764383 +s 0 +usemtl white +f 528 517 516 +f 517 530 518 +f 530 519 518 +f 531 520 519 +f 532 521 520 +f 521 534 522 +f 534 523 522 +f 535 524 523 +f 536 525 524 +f 537 526 525 +f 538 527 526 +f 539 516 527 +f 540 529 528 +f 541 530 529 +f 542 531 530 +f 543 532 531 +f 532 545 533 +f 545 534 533 +f 546 535 534 +f 547 536 535 +f 536 549 537 +f 537 550 538 +f 538 551 539 +f 551 528 539 +f 540 553 541 +f 553 542 541 +f 554 543 542 +f 543 556 544 +f 544 557 545 +f 545 558 546 +f 558 547 546 +f 559 548 547 +f 548 561 549 +f 549 562 550 +f 550 563 551 +f 563 540 551 +f 552 565 553 +f 553 566 554 +f 554 567 555 +f 567 556 555 +f 556 569 557 +f 569 558 557 +f 570 559 558 +f 571 560 559 +f 560 573 561 +f 573 562 561 +f 574 563 562 +f 575 552 563 +f 576 565 564 +f 565 578 566 +f 578 567 566 +f 579 568 567 +f 568 581 569 +f 581 570 569 +f 582 571 570 +f 583 572 571 +f 584 573 572 +f 585 574 573 +f 586 575 574 +f 575 576 564 +f 588 577 576 +f 589 578 577 +f 590 579 578 +f 591 580 579 +f 592 581 580 +f 593 582 581 +f 582 595 583 +f 595 584 583 +f 596 585 584 +f 597 586 585 +f 586 599 587 +f 599 576 587 +f 600 589 588 +f 589 602 590 +f 602 591 590 +f 603 592 591 +f 592 605 593 +f 605 594 593 +f 606 595 594 +f 607 596 595 +f 596 609 597 +f 597 610 598 +f 610 599 598 +f 611 588 599 +f 612 601 600 +f 601 614 602 +f 602 615 603 +f 615 604 603 +f 604 617 605 +f 617 606 605 +f 618 607 606 +f 619 608 607 +f 620 609 608 +f 621 610 609 +f 622 611 610 +f 623 600 611 +f 612 625 613 +f 625 614 613 +f 626 615 614 +f 627 616 615 +f 628 617 616 +f 629 618 617 +f 630 619 618 +f 631 620 619 +f 620 633 621 +f 621 634 622 +f 634 623 622 +f 635 612 623 +f 636 625 624 +f 637 626 625 +f 638 627 626 +f 639 628 627 +f 628 641 629 +f 641 630 629 +f 642 631 630 +f 643 632 631 +f 644 633 632 +f 645 634 633 +f 646 635 634 +f 647 624 635 +f 648 637 636 +f 649 638 637 +f 638 651 639 +f 651 640 639 +f 652 641 640 +f 653 642 641 +f 642 655 643 +f 655 644 643 +f 644 657 645 +f 657 646 645 +f 658 647 646 +f 659 636 647 +f 660 649 648 +f 661 650 649 +f 662 651 650 +f 651 664 652 +f 652 665 653 +f 665 654 653 +f 666 655 654 +f 667 656 655 +f 668 657 656 +f 669 658 657 +f 670 659 658 +f 659 660 648 +f 672 661 660 +f 673 662 661 +f 674 663 662 +f 675 664 663 +f 676 665 664 +f 677 666 665 +f 666 679 667 +f 679 668 667 +f 668 681 669 +f 669 682 670 +f 670 683 671 +f 671 672 660 +f 684 673 672 +f 673 686 674 +f 674 687 675 +f 687 676 675 +f 688 677 676 +f 689 678 677 +f 690 679 678 +f 691 680 679 +f 692 681 680 +f 693 682 681 +f 694 683 682 +f 695 672 683 +f 696 685 684 +f 697 686 685 +f 698 687 686 +f 687 700 688 +f 700 689 688 +f 701 690 689 +f 702 691 690 +f 703 692 691 +f 692 705 693 +f 705 694 693 +f 694 707 695 +f 707 684 695 +f 708 697 696 +f 697 710 698 +f 710 699 698 +f 711 700 699 +f 712 701 700 +f 713 702 701 +f 714 703 702 +f 715 704 703 +f 716 705 704 +f 717 706 705 +f 718 707 706 +f 719 696 707 +f 720 709 708 +f 721 710 709 +f 722 711 710 +f 723 712 711 +f 724 713 712 +f 713 726 714 +f 726 715 714 +f 715 728 716 +f 716 729 717 +f 717 730 718 +f 718 731 719 +f 731 708 719 +f 732 721 720 +f 733 722 721 +f 722 735 723 +f 735 724 723 +f 736 725 724 +f 737 726 725 +f 738 727 726 +f 727 740 728 +f 740 729 728 +f 741 730 729 +f 742 731 730 +f 743 720 731 +f 744 733 732 +f 745 734 733 +f 746 735 734 +f 735 748 736 +f 748 737 736 +f 749 738 737 +f 750 739 738 +f 739 752 740 +f 752 741 740 +f 753 742 741 +f 742 755 743 +f 755 732 743 +f 744 757 745 +f 757 746 745 +f 746 759 747 +f 759 748 747 +f 760 749 748 +f 761 750 749 +f 762 751 750 +f 763 752 751 +f 752 765 753 +f 765 754 753 +f 766 755 754 +f 767 744 755 +f 768 757 756 +f 769 758 757 +f 770 759 758 +f 759 772 760 +f 772 761 760 +f 773 762 761 +f 762 775 763 +f 775 764 763 +f 776 765 764 +f 777 766 765 +f 766 779 767 +f 779 756 767 +f 768 781 769 +f 781 770 769 +f 782 771 770 +f 771 784 772 +f 784 773 772 +f 785 774 773 +f 786 775 774 +f 787 776 775 +f 788 777 776 +f 777 790 778 +f 790 779 778 +f 791 768 779 +f 792 781 780 +f 793 782 781 +f 794 783 782 +f 795 784 783 +f 796 785 784 +f 797 786 785 +f 798 787 786 +f 787 800 788 +f 788 801 789 +f 789 802 790 +f 790 803 791 +f 791 792 780 +f 792 805 793 +f 805 794 793 +f 806 795 794 +f 807 796 795 +f 808 797 796 +f 809 798 797 +f 810 799 798 +f 799 812 800 +f 812 801 800 +f 813 802 801 +f 814 803 802 +f 815 792 803 +f 816 805 804 +f 817 806 805 +f 818 807 806 +f 819 808 807 +f 820 809 808 +f 821 810 809 +f 810 823 811 +f 823 812 811 +f 812 825 813 +f 813 826 814 +f 814 827 815 +f 815 816 804 +f 816 829 817 +f 817 830 818 +f 818 831 819 +f 819 832 820 +f 820 833 821 +f 833 822 821 +f 834 823 822 +f 835 824 823 +f 836 825 824 +f 837 826 825 +f 838 827 826 +f 827 828 816 +f 840 829 828 +f 841 830 829 +f 830 843 831 +f 843 832 831 +f 844 833 832 +f 845 834 833 +f 846 835 834 +f 835 848 836 +f 848 837 836 +f 849 838 837 +f 838 851 839 +f 839 840 828 +f 852 841 840 +f 853 842 841 +f 854 843 842 +f 855 844 843 +f 856 845 844 +f 845 858 846 +f 858 847 846 +f 859 848 847 +f 860 849 848 +f 849 862 850 +f 850 863 851 +f 863 840 851 +f 864 853 852 +f 865 854 853 +f 866 855 854 +f 855 868 856 +f 868 857 856 +f 869 858 857 +f 870 859 858 +f 859 872 860 +f 872 861 860 +f 873 862 861 +f 862 875 863 +f 875 852 863 +f 876 865 864 +f 865 878 866 +f 878 867 866 +f 879 868 867 +f 880 869 868 +f 881 870 869 +f 882 871 870 +f 883 872 871 +f 872 885 873 +f 885 874 873 +f 886 875 874 +f 887 864 875 +f 876 889 877 +f 877 890 878 +f 890 879 878 +f 879 892 880 +f 892 881 880 +f 893 882 881 +f 894 883 882 +f 895 884 883 +f 896 885 884 +f 897 886 885 +f 898 887 886 +f 899 876 887 +f 888 901 889 +f 901 890 889 +f 902 891 890 +f 903 892 891 +f 892 905 893 +f 905 894 893 +f 906 895 894 +f 907 896 895 +f 908 897 896 +f 897 910 898 +f 898 911 899 +f 911 888 899 +f 912 901 900 +f 913 902 901 +f 914 903 902 +f 915 904 903 +f 916 905 904 +f 917 906 905 +f 918 907 906 +f 919 908 907 +f 908 921 909 +f 921 910 909 +f 910 923 911 +f 923 900 911 +f 924 913 912 +f 925 914 913 +f 926 915 914 +f 927 916 915 +f 916 929 917 +f 929 918 917 +f 930 919 918 +f 931 920 919 +f 932 921 920 +f 933 922 921 +f 922 935 923 +f 935 912 923 +f 936 925 924 +f 925 938 926 +f 938 927 926 +f 939 928 927 +f 928 941 929 +f 941 930 929 +f 942 931 930 +f 943 932 931 +f 932 945 933 +f 945 934 933 +f 946 935 934 +f 947 924 935 +f 948 937 936 +f 949 938 937 +f 938 951 939 +f 939 952 940 +f 952 941 940 +f 941 954 942 +f 954 943 942 +f 955 944 943 +f 956 945 944 +f 957 946 945 +f 958 947 946 +f 959 936 947 +f 948 961 949 +f 961 950 949 +f 962 951 950 +f 963 952 951 +f 964 953 952 +f 965 954 953 +f 966 955 954 +f 955 968 956 +f 956 969 957 +f 969 958 957 +f 970 959 958 +f 971 948 959 +f 972 961 960 +f 973 962 961 +f 974 963 962 +f 975 964 963 +f 976 965 964 +f 965 978 966 +f 978 967 966 +f 979 968 967 +f 968 981 969 +f 969 982 970 +f 982 971 970 +f 983 960 971 +f 984 973 972 +f 985 974 973 +f 986 975 974 +f 987 976 975 +f 988 977 976 +f 989 978 977 +f 990 979 978 +f 991 980 979 +f 992 981 980 +f 981 994 982 +f 982 995 983 +f 995 972 983 +f 996 985 984 +f 997 986 985 +f 986 999 987 +f 987 1000 988 +f 1000 989 988 +f 1001 990 989 +f 1002 991 990 +f 1003 992 991 +f 1004 993 992 +f 1005 994 993 +f 1006 995 994 +f 995 996 984 +f 996 1009 997 +f 1009 998 997 +f 1010 999 998 +f 1011 1000 999 +f 1012 1001 1000 +f 1013 1002 1001 +f 1014 1003 1002 +f 1015 1004 1003 +f 1016 1005 1004 +f 1017 1006 1005 +f 1006 1019 1007 +f 1019 996 1007 +f 1008 1021 1009 +f 1021 1010 1009 +f 1010 1023 1011 +f 1011 1024 1012 +f 1012 1025 1013 +f 1025 1014 1013 +f 1026 1015 1014 +f 1027 1016 1015 +f 1028 1017 1016 +f 1029 1018 1017 +f 1018 1031 1019 +f 1031 1008 1019 +f 1020 1033 1021 +f 1033 1022 1021 +f 1022 1035 1023 +f 1035 1024 1023 +f 1036 1025 1024 +f 1037 1026 1025 +f 1038 1027 1026 +f 1027 1040 1028 +f 1028 1041 1029 +f 1041 1030 1029 +f 1042 1031 1030 +f 1043 1020 1031 +f 1044 1033 1032 +f 1045 1034 1033 +f 1046 1035 1034 +f 1047 1036 1035 +f 1048 1037 1036 +f 1049 1038 1037 +f 1050 1039 1038 +f 1039 1052 1040 +f 1052 1041 1040 +f 1053 1042 1041 +f 1042 1055 1043 +f 1055 1032 1043 +f 1056 1045 1044 +f 1057 1046 1045 +f 1046 1059 1047 +f 1059 1048 1047 +f 1060 1049 1048 +f 1061 1050 1049 +f 1062 1051 1050 +f 1063 1052 1051 +f 1064 1053 1052 +f 1065 1054 1053 +f 1066 1055 1054 +f 1067 1044 1055 +f 1068 1057 1056 +f 1069 1058 1057 +f 1070 1059 1058 +f 1071 1060 1059 +f 1072 1061 1060 +f 1073 1062 1061 +f 1074 1063 1062 +f 1063 1076 1064 +f 1076 1065 1064 +f 1077 1066 1065 +f 1078 1067 1066 +f 1079 1056 1067 +f 1068 1081 1069 +f 1069 1082 1070 +f 1070 1083 1071 +f 1083 1072 1071 +f 1084 1073 1072 +f 1073 1086 1074 +f 1086 1075 1074 +f 1087 1076 1075 +f 1076 1089 1077 +f 1089 1078 1077 +f 1090 1079 1078 +f 1091 1068 1079 +f 516 1081 1080 +f 517 1082 1081 +f 518 1083 1082 +f 519 1084 1083 +f 520 1085 1084 +f 521 1086 1085 +f 1086 523 1087 +f 523 1088 1087 +f 524 1089 1088 +f 525 1090 1089 +f 1090 527 1091 +f 1091 516 1080 +f 528 529 517 +f 517 529 530 +f 530 531 519 +f 531 532 520 +f 532 533 521 +f 521 533 534 +f 534 535 523 +f 535 536 524 +f 536 537 525 +f 537 538 526 +f 538 539 527 +f 539 528 516 +f 540 541 529 +f 541 542 530 +f 542 543 531 +f 543 544 532 +f 532 544 545 +f 545 546 534 +f 546 547 535 +f 547 548 536 +f 536 548 549 +f 537 549 550 +f 538 550 551 +f 551 540 528 +f 540 552 553 +f 553 554 542 +f 554 555 543 +f 543 555 556 +f 544 556 557 +f 545 557 558 +f 558 559 547 +f 559 560 548 +f 548 560 561 +f 549 561 562 +f 550 562 563 +f 563 552 540 +f 552 564 565 +f 553 565 566 +f 554 566 567 +f 567 568 556 +f 556 568 569 +f 569 570 558 +f 570 571 559 +f 571 572 560 +f 560 572 573 +f 573 574 562 +f 574 575 563 +f 575 564 552 +f 576 577 565 +f 565 577 578 +f 578 579 567 +f 579 580 568 +f 568 580 581 +f 581 582 570 +f 582 583 571 +f 583 584 572 +f 584 585 573 +f 585 586 574 +f 586 587 575 +f 575 587 576 +f 588 589 577 +f 589 590 578 +f 590 591 579 +f 591 592 580 +f 592 593 581 +f 593 594 582 +f 582 594 595 +f 595 596 584 +f 596 597 585 +f 597 598 586 +f 586 598 599 +f 599 588 576 +f 600 601 589 +f 589 601 602 +f 602 603 591 +f 603 604 592 +f 592 604 605 +f 605 606 594 +f 606 607 595 +f 607 608 596 +f 596 608 609 +f 597 609 610 +f 610 611 599 +f 611 600 588 +f 612 613 601 +f 601 613 614 +f 602 614 615 +f 615 616 604 +f 604 616 617 +f 617 618 606 +f 618 619 607 +f 619 620 608 +f 620 621 609 +f 621 622 610 +f 622 623 611 +f 623 612 600 +f 612 624 625 +f 625 626 614 +f 626 627 615 +f 627 628 616 +f 628 629 617 +f 629 630 618 +f 630 631 619 +f 631 632 620 +f 620 632 633 +f 621 633 634 +f 634 635 623 +f 635 624 612 +f 636 637 625 +f 637 638 626 +f 638 639 627 +f 639 640 628 +f 628 640 641 +f 641 642 630 +f 642 643 631 +f 643 644 632 +f 644 645 633 +f 645 646 634 +f 646 647 635 +f 647 636 624 +f 648 649 637 +f 649 650 638 +f 638 650 651 +f 651 652 640 +f 652 653 641 +f 653 654 642 +f 642 654 655 +f 655 656 644 +f 644 656 657 +f 657 658 646 +f 658 659 647 +f 659 648 636 +f 660 661 649 +f 661 662 650 +f 662 663 651 +f 651 663 664 +f 652 664 665 +f 665 666 654 +f 666 667 655 +f 667 668 656 +f 668 669 657 +f 669 670 658 +f 670 671 659 +f 659 671 660 +f 672 673 661 +f 673 674 662 +f 674 675 663 +f 675 676 664 +f 676 677 665 +f 677 678 666 +f 666 678 679 +f 679 680 668 +f 668 680 681 +f 669 681 682 +f 670 682 683 +f 671 683 672 +f 684 685 673 +f 673 685 686 +f 674 686 687 +f 687 688 676 +f 688 689 677 +f 689 690 678 +f 690 691 679 +f 691 692 680 +f 692 693 681 +f 693 694 682 +f 694 695 683 +f 695 684 672 +f 696 697 685 +f 697 698 686 +f 698 699 687 +f 687 699 700 +f 700 701 689 +f 701 702 690 +f 702 703 691 +f 703 704 692 +f 692 704 705 +f 705 706 694 +f 694 706 707 +f 707 696 684 +f 708 709 697 +f 697 709 710 +f 710 711 699 +f 711 712 700 +f 712 713 701 +f 713 714 702 +f 714 715 703 +f 715 716 704 +f 716 717 705 +f 717 718 706 +f 718 719 707 +f 719 708 696 +f 720 721 709 +f 721 722 710 +f 722 723 711 +f 723 724 712 +f 724 725 713 +f 713 725 726 +f 726 727 715 +f 715 727 728 +f 716 728 729 +f 717 729 730 +f 718 730 731 +f 731 720 708 +f 732 733 721 +f 733 734 722 +f 722 734 735 +f 735 736 724 +f 736 737 725 +f 737 738 726 +f 738 739 727 +f 727 739 740 +f 740 741 729 +f 741 742 730 +f 742 743 731 +f 743 732 720 +f 744 745 733 +f 745 746 734 +f 746 747 735 +f 735 747 748 +f 748 749 737 +f 749 750 738 +f 750 751 739 +f 739 751 752 +f 752 753 741 +f 753 754 742 +f 742 754 755 +f 755 744 732 +f 744 756 757 +f 757 758 746 +f 746 758 759 +f 759 760 748 +f 760 761 749 +f 761 762 750 +f 762 763 751 +f 763 764 752 +f 752 764 765 +f 765 766 754 +f 766 767 755 +f 767 756 744 +f 768 769 757 +f 769 770 758 +f 770 771 759 +f 759 771 772 +f 772 773 761 +f 773 774 762 +f 762 774 775 +f 775 776 764 +f 776 777 765 +f 777 778 766 +f 766 778 779 +f 779 768 756 +f 768 780 781 +f 781 782 770 +f 782 783 771 +f 771 783 784 +f 784 785 773 +f 785 786 774 +f 786 787 775 +f 787 788 776 +f 788 789 777 +f 777 789 790 +f 790 791 779 +f 791 780 768 +f 792 793 781 +f 793 794 782 +f 794 795 783 +f 795 796 784 +f 796 797 785 +f 797 798 786 +f 798 799 787 +f 787 799 800 +f 788 800 801 +f 789 801 802 +f 790 802 803 +f 791 803 792 +f 792 804 805 +f 805 806 794 +f 806 807 795 +f 807 808 796 +f 808 809 797 +f 809 810 798 +f 810 811 799 +f 799 811 812 +f 812 813 801 +f 813 814 802 +f 814 815 803 +f 815 804 792 +f 816 817 805 +f 817 818 806 +f 818 819 807 +f 819 820 808 +f 820 821 809 +f 821 822 810 +f 810 822 823 +f 823 824 812 +f 812 824 825 +f 813 825 826 +f 814 826 827 +f 815 827 816 +f 816 828 829 +f 817 829 830 +f 818 830 831 +f 819 831 832 +f 820 832 833 +f 833 834 822 +f 834 835 823 +f 835 836 824 +f 836 837 825 +f 837 838 826 +f 838 839 827 +f 827 839 828 +f 840 841 829 +f 841 842 830 +f 830 842 843 +f 843 844 832 +f 844 845 833 +f 845 846 834 +f 846 847 835 +f 835 847 848 +f 848 849 837 +f 849 850 838 +f 838 850 851 +f 839 851 840 +f 852 853 841 +f 853 854 842 +f 854 855 843 +f 855 856 844 +f 856 857 845 +f 845 857 858 +f 858 859 847 +f 859 860 848 +f 860 861 849 +f 849 861 862 +f 850 862 863 +f 863 852 840 +f 864 865 853 +f 865 866 854 +f 866 867 855 +f 855 867 868 +f 868 869 857 +f 869 870 858 +f 870 871 859 +f 859 871 872 +f 872 873 861 +f 873 874 862 +f 862 874 875 +f 875 864 852 +f 876 877 865 +f 865 877 878 +f 878 879 867 +f 879 880 868 +f 880 881 869 +f 881 882 870 +f 882 883 871 +f 883 884 872 +f 872 884 885 +f 885 886 874 +f 886 887 875 +f 887 876 864 +f 876 888 889 +f 877 889 890 +f 890 891 879 +f 879 891 892 +f 892 893 881 +f 893 894 882 +f 894 895 883 +f 895 896 884 +f 896 897 885 +f 897 898 886 +f 898 899 887 +f 899 888 876 +f 888 900 901 +f 901 902 890 +f 902 903 891 +f 903 904 892 +f 892 904 905 +f 905 906 894 +f 906 907 895 +f 907 908 896 +f 908 909 897 +f 897 909 910 +f 898 910 911 +f 911 900 888 +f 912 913 901 +f 913 914 902 +f 914 915 903 +f 915 916 904 +f 916 917 905 +f 917 918 906 +f 918 919 907 +f 919 920 908 +f 908 920 921 +f 921 922 910 +f 910 922 923 +f 923 912 900 +f 924 925 913 +f 925 926 914 +f 926 927 915 +f 927 928 916 +f 916 928 929 +f 929 930 918 +f 930 931 919 +f 931 932 920 +f 932 933 921 +f 933 934 922 +f 922 934 935 +f 935 924 912 +f 936 937 925 +f 925 937 938 +f 938 939 927 +f 939 940 928 +f 928 940 941 +f 941 942 930 +f 942 943 931 +f 943 944 932 +f 932 944 945 +f 945 946 934 +f 946 947 935 +f 947 936 924 +f 948 949 937 +f 949 950 938 +f 938 950 951 +f 939 951 952 +f 952 953 941 +f 941 953 954 +f 954 955 943 +f 955 956 944 +f 956 957 945 +f 957 958 946 +f 958 959 947 +f 959 948 936 +f 948 960 961 +f 961 962 950 +f 962 963 951 +f 963 964 952 +f 964 965 953 +f 965 966 954 +f 966 967 955 +f 955 967 968 +f 956 968 969 +f 969 970 958 +f 970 971 959 +f 971 960 948 +f 972 973 961 +f 973 974 962 +f 974 975 963 +f 975 976 964 +f 976 977 965 +f 965 977 978 +f 978 979 967 +f 979 980 968 +f 968 980 981 +f 969 981 982 +f 982 983 971 +f 983 972 960 +f 984 985 973 +f 985 986 974 +f 986 987 975 +f 987 988 976 +f 988 989 977 +f 989 990 978 +f 990 991 979 +f 991 992 980 +f 992 993 981 +f 981 993 994 +f 982 994 995 +f 995 984 972 +f 996 997 985 +f 997 998 986 +f 986 998 999 +f 987 999 1000 +f 1000 1001 989 +f 1001 1002 990 +f 1002 1003 991 +f 1003 1004 992 +f 1004 1005 993 +f 1005 1006 994 +f 1006 1007 995 +f 995 1007 996 +f 996 1008 1009 +f 1009 1010 998 +f 1010 1011 999 +f 1011 1012 1000 +f 1012 1013 1001 +f 1013 1014 1002 +f 1014 1015 1003 +f 1015 1016 1004 +f 1016 1017 1005 +f 1017 1018 1006 +f 1006 1018 1019 +f 1019 1008 996 +f 1008 1020 1021 +f 1021 1022 1010 +f 1010 1022 1023 +f 1011 1023 1024 +f 1012 1024 1025 +f 1025 1026 1014 +f 1026 1027 1015 +f 1027 1028 1016 +f 1028 1029 1017 +f 1029 1030 1018 +f 1018 1030 1031 +f 1031 1020 1008 +f 1020 1032 1033 +f 1033 1034 1022 +f 1022 1034 1035 +f 1035 1036 1024 +f 1036 1037 1025 +f 1037 1038 1026 +f 1038 1039 1027 +f 1027 1039 1040 +f 1028 1040 1041 +f 1041 1042 1030 +f 1042 1043 1031 +f 1043 1032 1020 +f 1044 1045 1033 +f 1045 1046 1034 +f 1046 1047 1035 +f 1047 1048 1036 +f 1048 1049 1037 +f 1049 1050 1038 +f 1050 1051 1039 +f 1039 1051 1052 +f 1052 1053 1041 +f 1053 1054 1042 +f 1042 1054 1055 +f 1055 1044 1032 +f 1056 1057 1045 +f 1057 1058 1046 +f 1046 1058 1059 +f 1059 1060 1048 +f 1060 1061 1049 +f 1061 1062 1050 +f 1062 1063 1051 +f 1063 1064 1052 +f 1064 1065 1053 +f 1065 1066 1054 +f 1066 1067 1055 +f 1067 1056 1044 +f 1068 1069 1057 +f 1069 1070 1058 +f 1070 1071 1059 +f 1071 1072 1060 +f 1072 1073 1061 +f 1073 1074 1062 +f 1074 1075 1063 +f 1063 1075 1076 +f 1076 1077 1065 +f 1077 1078 1066 +f 1078 1079 1067 +f 1079 1068 1056 +f 1068 1080 1081 +f 1069 1081 1082 +f 1070 1082 1083 +f 1083 1084 1072 +f 1084 1085 1073 +f 1073 1085 1086 +f 1086 1087 1075 +f 1087 1088 1076 +f 1076 1088 1089 +f 1089 1090 1078 +f 1090 1091 1079 +f 1091 1080 1068 +f 516 517 1081 +f 517 518 1082 +f 518 519 1083 +f 519 520 1084 +f 520 521 1085 +f 521 522 1086 +f 1086 522 523 +f 523 524 1088 +f 524 525 1089 +f 525 526 1090 +f 1090 526 527 +f 1091 527 516 +o Cone +v 2.500000 -4.000000 -2.800000 +v 3.207107 -4.000000 -2.507107 +v 3.500000 -4.000000 -1.800000 +v 3.207107 -4.000000 -1.092893 +v 2.500000 -4.000000 -0.800000 +v 1.792893 -4.000000 -1.092893 +v 1.500000 -4.000000 -1.800000 +v 1.792893 -4.000000 -2.507107 +v 2.500000 -2.000000 -1.800000 +s 0 +usemtl white +f 1095 1094 1100 +f 1096 1095 1100 +f 1097 1096 1100 +f 1098 1097 1100 +f 1099 1098 1100 +f 1100 1092 1099 +f 1093 1092 1100 +f 1095 1097 1099 +f 1094 1093 1100 +f 1099 1092 1093 +f 1093 1094 1095 +f 1095 1096 1097 +f 1097 1098 1099 +f 1099 1093 1095 +o Icosphere +v 0.000000 4.200000 0.000000 +v 0.868329 4.642224 0.630870 +v -0.331666 4.642224 1.020779 +v -1.073312 4.642228 0.000000 +v -0.331666 4.642224 -1.020779 +v 0.868329 4.642224 -0.630870 +v -0.194947 4.319477 0.599994 +v 0.510387 4.319477 0.370814 +v 0.315443 4.579410 0.970814 +v 1.020777 4.579412 0.000000 +v 0.510387 4.319477 -0.370814 +v -0.630876 4.319479 0.000000 +v -0.825827 4.579411 0.599996 +v -0.194947 4.319477 -0.599994 +v -0.825827 4.579411 -0.599996 +v 0.315443 4.579410 -0.970814 +v 1.141269 5.000000 0.370815 +v 1.141269 5.000000 -0.370815 +v 0.000000 5.000000 1.200000 +v 0.705343 5.000000 0.970820 +v -1.141269 5.000000 0.370815 +v -0.705343 5.000000 0.970820 +v -0.705343 5.000000 -0.970820 +v -1.141269 5.000000 -0.370815 +v 0.705343 5.000000 -0.970820 +v 0.000000 5.000000 -1.200000 +s 0 +usemtl light +f 1101 1108 1107 +f 1102 1108 1110 +f 1101 1107 1112 +f 1101 1112 1114 +f 1101 1114 1111 +f 1102 1110 1117 +f 1103 1109 1119 +f 1104 1113 1121 +f 1105 1115 1123 +f 1106 1116 1125 +f 1102 1117 1120 +f 1103 1119 1122 +f 1104 1121 1124 +f 1105 1123 1126 +f 1106 1125 1118 +f 1125 1116 1126 +f 1116 1105 1126 +f 1123 1115 1124 +f 1115 1104 1124 +f 1121 1113 1122 +f 1113 1103 1122 +f 1119 1109 1120 +f 1109 1102 1120 +f 1117 1110 1118 +f 1110 1106 1118 +f 1111 1116 1106 +f 1111 1114 1116 +f 1114 1105 1116 +f 1114 1115 1105 +f 1114 1112 1115 +f 1112 1104 1115 +f 1112 1113 1104 +f 1112 1107 1113 +f 1107 1103 1113 +f 1110 1111 1106 +f 1110 1108 1111 +f 1108 1101 1111 +f 1107 1109 1103 +f 1107 1108 1109 +f 1108 1102 1109 +o Plane.001 +v 4.000000 -4.000000 4.000000 +v 4.000000 -4.000000 -4.000000 +v 4.000000 5.000000 -4.000000 +v 4.000000 5.000000 4.000000 +s 0 +usemtl green +f 1130 1128 1127 +f 1130 1129 1128 +o Plane.002 +v -4.000000 -4.000000 4.000000 +v -4.000000 -4.000000 -4.000000 +v -4.000000 5.000000 -4.000000 +v -4.000000 5.000000 4.000000 +s 0 +usemtl red +f 1133 1131 1132 +f 1133 1134 1131 +o Sphere +v -3.074677 3.239490 -0.476862 +v -3.074677 2.963591 -0.752761 +v -3.074677 2.603111 -0.902077 +v -3.074677 2.408020 -0.921291 +v -3.074677 2.212930 -0.902077 +v -3.074677 1.852450 -0.752761 +v -3.036617 3.388806 -0.112633 +v -3.000019 3.331900 -0.296622 +v -2.966291 3.239490 -0.466186 +v -2.936727 3.115127 -0.614811 +v -2.912465 2.963591 -0.736784 +v -2.894437 2.790704 -0.827419 +v -2.883335 2.603111 -0.883231 +v -2.879587 2.408020 -0.902077 +v -2.883335 2.212930 -0.883231 +v -2.894437 2.025337 -0.827419 +v -2.912465 1.852450 -0.736784 +v -2.936727 1.700914 -0.614811 +v -2.966291 1.576551 -0.466186 +v -3.000019 1.484141 -0.296622 +v -3.036617 1.427235 -0.112633 +v -3.000019 3.388806 -0.101531 +v -2.928230 3.331900 -0.274845 +v -2.862069 3.239490 -0.434571 +v -2.804079 3.115127 -0.574573 +v -2.756487 2.963591 -0.689469 +v -2.721124 2.790704 -0.774845 +v -2.699347 2.603111 -0.827419 +v -2.691993 2.408020 -0.845171 +v -2.699347 2.212930 -0.827419 +v -2.721124 2.025337 -0.774845 +v -2.756487 1.852450 -0.689469 +v -2.804079 1.700914 -0.574573 +v -2.862069 1.576551 -0.434571 +v -2.928230 1.484141 -0.274845 +v -3.000019 1.427235 -0.101531 +v -2.966291 3.388806 -0.083503 +v -2.862069 3.331900 -0.239481 +v -2.766019 3.239490 -0.383231 +v -2.681829 3.115127 -0.509229 +v -2.612737 2.963591 -0.612633 +v -2.561397 2.790704 -0.689469 +v -2.529782 2.603111 -0.736784 +v -2.519107 2.408020 -0.752761 +v -2.529782 2.212930 -0.736784 +v -2.561397 2.025337 -0.689469 +v -2.612737 1.852450 -0.612633 +v -2.681829 1.700914 -0.509229 +v -2.766019 1.576551 -0.383231 +v -2.862069 1.484141 -0.239481 +v -2.966291 1.427235 -0.083503 +v -2.936727 3.388806 -0.059241 +v -2.804079 3.331900 -0.191889 +v -2.681829 3.239490 -0.314139 +v -2.574677 3.115127 -0.421291 +v -2.486739 2.963591 -0.509229 +v -2.421396 2.790704 -0.574573 +v -2.381157 2.603111 -0.614811 +v -2.367570 2.408020 -0.628398 +v -2.381157 2.212930 -0.614811 +v -2.421396 2.025337 -0.574573 +v -2.486739 1.852450 -0.509229 +v -2.574677 1.700914 -0.421291 +v -2.681829 1.576551 -0.314139 +v -2.804079 1.484141 -0.191889 +v -2.936727 1.427235 -0.059241 +v -2.912465 3.388806 -0.029678 +v -2.756487 3.331900 -0.133899 +v -2.612737 3.239490 -0.229950 +v -2.486739 3.115127 -0.314139 +v -2.383335 2.963591 -0.383231 +v -2.306499 2.790704 -0.434571 +v -2.259184 2.603111 -0.466186 +v -2.243207 2.408020 -0.476861 +v -2.259184 2.212930 -0.466186 +v -2.306499 2.025337 -0.434571 +v -2.383335 1.852450 -0.383231 +v -2.486739 1.700914 -0.314139 +v -2.612737 1.576551 -0.229950 +v -2.756487 1.484141 -0.133899 +v -2.912465 1.427235 -0.029678 +v -3.074677 3.408020 0.078709 +v -2.894437 3.388806 0.004051 +v -2.721124 3.331900 -0.067738 +v -2.561397 3.239490 -0.133899 +v -2.421396 3.115127 -0.191889 +v -2.306499 2.963591 -0.239481 +v -2.221124 2.790704 -0.274845 +v -2.168550 2.603111 -0.296622 +v -2.150798 2.408020 -0.303975 +v -2.168550 2.212930 -0.296622 +v -2.221124 2.025337 -0.274845 +v -2.306499 1.852450 -0.239481 +v -2.421396 1.700914 -0.191889 +v -2.561397 1.576551 -0.133899 +v -2.721124 1.484141 -0.067738 +v -2.894437 1.427235 0.004051 +v -2.883335 3.388806 0.040648 +v -2.699347 3.331900 0.004051 +v -2.529782 3.239490 -0.029678 +v -2.381157 3.115127 -0.059241 +v -2.259184 2.963591 -0.083503 +v -2.168550 2.790704 -0.101531 +v -2.112737 2.603111 -0.112633 +v -2.093892 2.408020 -0.116381 +v -2.112737 2.212930 -0.112633 +v -2.168550 2.025337 -0.101531 +v -2.259184 1.852450 -0.083503 +v -2.381157 1.700914 -0.059241 +v -2.529782 1.576551 -0.029678 +v -2.699347 1.484141 0.004051 +v -2.883335 1.427235 0.040648 +v -2.879587 3.388806 0.078709 +v -2.691994 3.331900 0.078709 +v -2.519107 3.239490 0.078709 +v -2.367570 3.115127 0.078709 +v -2.243207 2.963591 0.078709 +v -2.150798 2.790704 0.078709 +v -2.093892 2.603111 0.078709 +v -2.074677 2.408020 0.078709 +v -2.093892 2.212930 0.078709 +v -2.150798 2.025337 0.078709 +v -2.243207 1.852450 0.078709 +v -2.367570 1.700914 0.078709 +v -2.519107 1.576551 0.078709 +v -2.691994 1.484141 0.078709 +v -2.879587 1.427235 0.078709 +v -2.883335 3.388806 0.116769 +v -2.699347 3.331900 0.153367 +v -2.529782 3.239490 0.187095 +v -2.381157 3.115127 0.216658 +v -2.259184 2.963591 0.240920 +v -2.168550 2.790704 0.258949 +v -2.112737 2.603111 0.270050 +v -2.093892 2.408020 0.273799 +v -2.112737 2.212930 0.270050 +v -2.168550 2.025337 0.258949 +v -2.259184 1.852450 0.240920 +v -2.381157 1.700914 0.216658 +v -2.529782 1.576551 0.187095 +v -2.699347 1.484141 0.153367 +v -2.883335 1.427235 0.116769 +v -2.894437 3.388806 0.153366 +v -2.721124 3.331900 0.225155 +v -2.561397 3.239490 0.291316 +v -2.421396 3.115127 0.349307 +v -2.306499 2.963591 0.396898 +v -2.221124 2.790704 0.432262 +v -2.168550 2.603111 0.454039 +v -2.150798 2.408020 0.461392 +v -2.168550 2.212930 0.454039 +v -2.221124 2.025337 0.432262 +v -2.306499 1.852450 0.396898 +v -2.421396 1.700914 0.349307 +v -2.561397 1.576551 0.291316 +v -2.721124 1.484141 0.225155 +v -2.894437 1.427235 0.153366 +v -2.912465 3.388806 0.187095 +v -2.756487 3.331900 0.291316 +v -2.612737 3.239490 0.387367 +v -2.486739 3.115127 0.471556 +v -2.383336 2.963591 0.540648 +v -2.306499 2.790704 0.591989 +v -2.259184 2.603111 0.623604 +v -2.243208 2.408020 0.634279 +v -2.259184 2.212930 0.623604 +v -2.306499 2.025337 0.591989 +v -2.383336 1.852450 0.540648 +v -2.486739 1.700914 0.471556 +v -2.612737 1.576551 0.387367 +v -2.756487 1.484141 0.291316 +v -2.912465 1.427235 0.187095 +v -2.936727 3.388806 0.216658 +v -2.804079 3.331900 0.349307 +v -2.681830 3.239490 0.471556 +v -2.574677 3.115127 0.578709 +v -2.486739 2.963591 0.666646 +v -2.421396 2.790704 0.731990 +v -2.381157 2.603111 0.772228 +v -2.367571 2.408020 0.785815 +v -2.381157 2.212930 0.772228 +v -2.421396 2.025337 0.731990 +v -2.486739 1.852450 0.666646 +v -2.574677 1.700914 0.578709 +v -2.681830 1.576551 0.471556 +v -2.804079 1.484141 0.349307 +v -2.936727 1.427235 0.216658 +v -2.966291 3.388806 0.240920 +v -2.862070 3.331900 0.396898 +v -2.766019 3.239490 0.540648 +v -2.681829 3.115127 0.666646 +v -2.612737 2.963591 0.770050 +v -2.561397 2.790704 0.846886 +v -2.529782 2.603111 0.894202 +v -2.519107 2.408020 0.910178 +v -2.529782 2.212930 0.894202 +v -2.561397 2.025337 0.846886 +v -2.612737 1.852450 0.770050 +v -2.681829 1.700914 0.666646 +v -2.766019 1.576551 0.540648 +v -2.862070 1.484141 0.396898 +v -2.966291 1.427235 0.240920 +v -3.000019 3.388806 0.258949 +v -2.928231 3.331900 0.432262 +v -2.862070 3.239490 0.591988 +v -2.804079 3.115127 0.731990 +v -2.756488 2.963591 0.846886 +v -2.721124 2.790704 0.932262 +v -2.699347 2.603111 0.984836 +v -2.691994 2.408020 1.002588 +v -2.699347 2.212930 0.984836 +v -2.721124 2.025337 0.932262 +v -2.756488 1.852450 0.846886 +v -2.804079 1.700914 0.731990 +v -2.862070 1.576551 0.591988 +v -2.928231 1.484141 0.432262 +v -3.000019 1.427235 0.258949 +v -3.036617 3.388806 0.270050 +v -3.000019 3.331900 0.454039 +v -2.966291 3.239490 0.623604 +v -2.936727 3.115127 0.772228 +v -2.912466 2.963591 0.894202 +v -2.894437 2.790704 0.984836 +v -2.883336 2.603111 1.040648 +v -2.879587 2.408020 1.059493 +v -2.883336 2.212930 1.040648 +v -2.894437 2.025337 0.984836 +v -2.912466 1.852450 0.894202 +v -2.936727 1.700914 0.772228 +v -2.966291 1.576551 0.623604 +v -3.000019 1.484141 0.454039 +v -3.036617 1.427235 0.270050 +v -3.074677 3.388806 0.273799 +v -3.074677 3.331900 0.461392 +v -3.074677 3.239490 0.634279 +v -3.074677 3.115127 0.785815 +v -3.074677 2.963591 0.910178 +v -3.074677 2.790704 1.002588 +v -3.074677 2.603111 1.059494 +v -3.074677 2.408020 1.078708 +v -3.074677 2.212930 1.059494 +v -3.074677 2.025337 1.002588 +v -3.074677 1.852450 0.910178 +v -3.074677 1.700914 0.785815 +v -3.074677 1.576551 0.634279 +v -3.074677 1.484141 0.461392 +v -3.074677 1.427235 0.273799 +v -3.112737 3.388806 0.270050 +v -3.149335 3.331900 0.454039 +v -3.183064 3.239490 0.623603 +v -3.212627 3.115127 0.772228 +v -3.236889 2.963591 0.894201 +v -3.254917 2.790704 0.984836 +v -3.266019 2.603111 1.040648 +v -3.269768 2.408020 1.059493 +v -3.266019 2.212930 1.040648 +v -3.254917 2.025337 0.984836 +v -3.236889 1.852450 0.894201 +v -3.212627 1.700914 0.772228 +v -3.183064 1.576551 0.623603 +v -3.149335 1.484141 0.454039 +v -3.112737 1.427235 0.270050 +v -3.149335 3.388806 0.258948 +v -3.221124 3.331900 0.432262 +v -3.287284 3.239490 0.591988 +v -3.345275 3.115127 0.731990 +v -3.392867 2.963591 0.846886 +v -3.428230 2.790704 0.932262 +v -3.450007 2.603111 0.984836 +v -3.457361 2.408020 1.002587 +v -3.450007 2.212930 0.984836 +v -3.428230 2.025337 0.932262 +v -3.392867 1.852450 0.846886 +v -3.345275 1.700914 0.731990 +v -3.287284 1.576551 0.591988 +v -3.221124 1.484141 0.432262 +v -3.149335 1.427235 0.258948 +v -3.183063 3.388806 0.240920 +v -3.287284 3.331900 0.396898 +v -3.383335 3.239490 0.540648 +v -3.467525 3.115127 0.666646 +v -3.536617 2.963591 0.770050 +v -3.587957 2.790704 0.846886 +v -3.619572 2.603111 0.894201 +v -3.630247 2.408020 0.910177 +v -3.619572 2.212930 0.894201 +v -3.587957 2.025337 0.846886 +v -3.536617 1.852450 0.770050 +v -3.467525 1.700914 0.666646 +v -3.383335 1.576551 0.540648 +v -3.287284 1.484141 0.396898 +v -3.183063 1.427235 0.240920 +v -3.212626 3.388806 0.216658 +v -3.345275 3.331900 0.349307 +v -3.467524 3.239490 0.471556 +v -3.574677 3.115127 0.578709 +v -3.662615 2.963591 0.666646 +v -3.727958 2.790704 0.731990 +v -3.768197 2.603111 0.772228 +v -3.781784 2.408020 0.785815 +v -3.768197 2.212930 0.772228 +v -3.727958 2.025337 0.731990 +v -3.662615 1.852450 0.666646 +v -3.574677 1.700914 0.578709 +v -3.467524 1.576551 0.471556 +v -3.345275 1.484141 0.349307 +v -3.212626 1.427235 0.216658 +v -3.074677 1.408020 0.078709 +v -3.236889 3.388806 0.187095 +v -3.392867 3.331900 0.291316 +v -3.536617 3.239490 0.387367 +v -3.662615 3.115127 0.471556 +v -3.766018 2.963591 0.540648 +v -3.842854 2.790704 0.591988 +v -3.890170 2.603111 0.623603 +v -3.906146 2.408020 0.634278 +v -3.890170 2.212930 0.623603 +v -3.842854 2.025337 0.591988 +v -3.766018 1.852450 0.540648 +v -3.662615 1.700914 0.471556 +v -3.536617 1.576551 0.387367 +v -3.392867 1.484141 0.291316 +v -3.236889 1.427235 0.187095 +v -3.254917 3.388806 0.153366 +v -3.428230 3.331900 0.225155 +v -3.587957 3.239490 0.291316 +v -3.727958 3.115127 0.349307 +v -3.842854 2.963591 0.396898 +v -3.928230 2.790704 0.432262 +v -3.980804 2.603111 0.454039 +v -3.998556 2.408020 0.461391 +v -3.980804 2.212930 0.454039 +v -3.928230 2.025337 0.432262 +v -3.842854 1.852450 0.396898 +v -3.727958 1.700914 0.349307 +v -3.587957 1.576551 0.291316 +v -3.428230 1.484141 0.225155 +v -3.254917 1.427235 0.153366 +v -3.266019 3.388806 0.116769 +v -3.450007 3.331900 0.153366 +v -3.619572 3.239490 0.187095 +v -3.768197 3.115127 0.216658 +v -3.890170 2.963591 0.240920 +v -3.980804 2.790704 0.258949 +v -4.036616 2.603111 0.270050 +v -4.055461 2.408020 0.273798 +v -4.036616 2.212930 0.270050 +v -3.980804 2.025337 0.258949 +v -3.890170 1.852450 0.240920 +v -3.768197 1.700914 0.216658 +v -3.619572 1.576551 0.187095 +v -3.450007 1.484141 0.153366 +v -3.266019 1.427235 0.116769 +v -3.269767 3.388806 0.078709 +v -3.457360 3.331900 0.078709 +v -3.630247 3.239490 0.078708 +v -3.781784 3.115127 0.078709 +v -3.906146 2.963591 0.078708 +v -3.998556 2.790704 0.078709 +v -4.055462 2.603111 0.078708 +v -4.074676 2.408020 0.078708 +v -4.055462 2.212930 0.078708 +v -3.998556 2.025337 0.078709 +v -3.906146 1.852450 0.078708 +v -3.781784 1.700914 0.078709 +v -3.630247 1.576551 0.078708 +v -3.457360 1.484141 0.078709 +v -3.269767 1.427235 0.078709 +v -3.266019 3.388806 0.040648 +v -3.450007 3.331900 0.004051 +v -3.619572 3.239490 -0.029678 +v -3.768197 3.115127 -0.059241 +v -3.890170 2.963591 -0.083503 +v -3.980804 2.790704 -0.101531 +v -4.036616 2.603111 -0.112633 +v -4.055461 2.408020 -0.116382 +v -4.036616 2.212930 -0.112633 +v -3.980804 2.025337 -0.101531 +v -3.890170 1.852450 -0.083503 +v -3.768197 1.700914 -0.059241 +v -3.619572 1.576551 -0.029678 +v -3.450007 1.484141 0.004051 +v -3.266019 1.427235 0.040648 +v -3.254917 3.388806 0.004051 +v -3.428230 3.331900 -0.067738 +v -3.587956 3.239490 -0.133899 +v -3.727958 3.115127 -0.191889 +v -3.842854 2.963591 -0.239481 +v -3.928230 2.790704 -0.274845 +v -3.980804 2.603111 -0.296622 +v -3.998555 2.408020 -0.303975 +v -3.980804 2.212930 -0.296622 +v -3.928230 2.025337 -0.274845 +v -3.842854 1.852450 -0.239481 +v -3.727958 1.700914 -0.191889 +v -3.587956 1.576551 -0.133899 +v -3.428230 1.484141 -0.067738 +v -3.254917 1.427235 0.004051 +v -3.236888 3.388806 -0.029678 +v -3.392866 3.331900 -0.133899 +v -3.536616 3.239490 -0.229950 +v -3.662615 3.115127 -0.314139 +v -3.766018 2.963591 -0.383231 +v -3.842854 2.790704 -0.434571 +v -3.890170 2.603111 -0.466186 +v -3.906146 2.408020 -0.476861 +v -3.890170 2.212930 -0.466186 +v -3.842854 2.025337 -0.434571 +v -3.766018 1.852450 -0.383231 +v -3.662615 1.700914 -0.314139 +v -3.536616 1.576551 -0.229950 +v -3.392866 1.484141 -0.133899 +v -3.236888 1.427235 -0.029678 +v -3.212626 3.388806 -0.059241 +v -3.345275 3.331900 -0.191889 +v -3.467524 3.239490 -0.314139 +v -3.574677 3.115127 -0.421291 +v -3.662614 2.963591 -0.509229 +v -3.727958 2.790704 -0.574573 +v -3.768196 2.603111 -0.614811 +v -3.781783 2.408020 -0.628398 +v -3.768196 2.212930 -0.614811 +v -3.727958 2.025337 -0.574573 +v -3.662614 1.852450 -0.509229 +v -3.574677 1.700914 -0.421291 +v -3.467524 1.576551 -0.314139 +v -3.345275 1.484141 -0.191889 +v -3.212626 1.427235 -0.059241 +v -3.183063 3.388806 -0.083503 +v -3.287284 3.331900 -0.239481 +v -3.383335 3.239490 -0.383231 +v -3.467524 3.115127 -0.509229 +v -3.536616 2.963591 -0.612633 +v -3.587957 2.790704 -0.689469 +v -3.619572 2.603111 -0.736784 +v -3.630246 2.408020 -0.752760 +v -3.619572 2.212930 -0.736784 +v -3.587957 2.025337 -0.689469 +v -3.536616 1.852450 -0.612633 +v -3.467524 1.700914 -0.509229 +v -3.383335 1.576551 -0.383231 +v -3.287284 1.484141 -0.239481 +v -3.183063 1.427235 -0.083503 +v -3.149335 3.388806 -0.101531 +v -3.221123 3.331900 -0.274845 +v -3.287284 3.239490 -0.434571 +v -3.345275 3.115127 -0.574573 +v -3.392866 2.963591 -0.689469 +v -3.428230 2.790704 -0.774844 +v -3.450007 2.603111 -0.827418 +v -3.457360 2.408020 -0.845170 +v -3.450007 2.212930 -0.827418 +v -3.428230 2.025337 -0.774844 +v -3.392866 1.852450 -0.689469 +v -3.345275 1.700914 -0.574573 +v -3.287284 1.576551 -0.434571 +v -3.221123 1.484141 -0.274845 +v -3.149335 1.427235 -0.101531 +v -3.112737 3.388806 -0.112633 +v -3.149335 3.331900 -0.296621 +v -3.183063 3.239490 -0.466186 +v -3.212626 3.115127 -0.614811 +v -3.236888 2.963591 -0.736784 +v -3.254917 2.790704 -0.827418 +v -3.266018 2.603111 -0.883231 +v -3.269767 2.408020 -0.902076 +v -3.266018 2.212930 -0.883231 +v -3.254917 2.025337 -0.827418 +v -3.236888 1.852450 -0.736784 +v -3.212626 1.700914 -0.614811 +v -3.183063 1.576551 -0.466186 +v -3.149335 1.484141 -0.296621 +v -3.112737 1.427235 -0.112633 +v -3.074677 3.388806 -0.116381 +v -3.074677 3.331900 -0.303975 +v -3.074677 3.115127 -0.628398 +v -3.074677 2.790704 -0.845170 +v -3.074677 2.025337 -0.845170 +v -3.074677 1.700914 -0.628398 +v -3.074677 1.576551 -0.476861 +v -3.074677 1.484141 -0.303975 +v -3.074677 1.427235 -0.116381 +s 1 +usemtl glass +f 1140 1152 1613 +f 1136 1144 1145 +f 1613 1153 1614 +f 1611 1145 1146 +f 1614 1154 1615 +f 1137 1146 1147 +f 1615 1155 1616 +f 1137 1148 1138 +f 1608 1216 1141 +f 1442 1616 1155 +f 1138 1149 1139 +f 1609 1141 1142 +f 1139 1150 1612 +f 1135 1142 1143 +f 1612 1151 1140 +f 1610 1143 1144 +f 1142 1158 1143 +f 1150 1166 1151 +f 1143 1159 1144 +f 1151 1167 1152 +f 1144 1160 1145 +f 1153 1167 1168 +f 1145 1161 1146 +f 1154 1168 1169 +f 1147 1161 1162 +f 1154 1170 1155 +f 1147 1163 1148 +f 1141 1216 1156 +f 1442 1155 1170 +f 1148 1164 1149 +f 1141 1157 1142 +f 1149 1165 1150 +f 1161 1177 1162 +f 1169 1185 1170 +f 1162 1178 1163 +f 1156 1216 1171 +f 1442 1170 1185 +f 1164 1178 1179 +f 1156 1172 1157 +f 1164 1180 1165 +f 1157 1173 1158 +f 1166 1180 1181 +f 1158 1174 1159 +f 1167 1181 1182 +f 1159 1175 1160 +f 1168 1182 1183 +f 1160 1176 1161 +f 1168 1184 1169 +f 1181 1195 1196 +f 1173 1189 1174 +f 1181 1197 1182 +f 1174 1190 1175 +f 1182 1198 1183 +f 1175 1191 1176 +f 1183 1199 1184 +f 1177 1191 1192 +f 1184 1200 1185 +f 1178 1192 1193 +f 1171 1216 1186 +f 1442 1185 1200 +f 1178 1194 1179 +f 1171 1187 1172 +f 1179 1195 1180 +f 1172 1188 1173 +f 1199 1215 1200 +f 1193 1207 1208 +f 1186 1216 1201 +f 1442 1200 1215 +f 1193 1209 1194 +f 1186 1202 1187 +f 1194 1210 1195 +f 1187 1203 1188 +f 1196 1210 1211 +f 1188 1204 1189 +f 1196 1212 1197 +f 1190 1204 1205 +f 1197 1213 1198 +f 1190 1206 1191 +f 1199 1213 1214 +f 1192 1206 1207 +f 1211 1228 1212 +f 1205 1220 1221 +f 1212 1229 1213 +f 1205 1222 1206 +f 1213 1230 1214 +f 1207 1222 1223 +f 1215 1230 1231 +f 1208 1223 1224 +f 1201 1216 1217 +f 1442 1215 1231 +f 1208 1225 1209 +f 1201 1218 1202 +f 1209 1226 1210 +f 1202 1219 1203 +f 1211 1226 1227 +f 1203 1220 1204 +f 1217 1216 1232 +f 1442 1231 1246 +f 1224 1240 1225 +f 1218 1232 1233 +f 1225 1241 1226 +f 1218 1234 1219 +f 1227 1241 1242 +f 1219 1235 1220 +f 1227 1243 1228 +f 1221 1235 1236 +f 1229 1243 1244 +f 1221 1237 1222 +f 1230 1244 1245 +f 1223 1237 1238 +f 1230 1246 1231 +f 1224 1238 1239 +f 1236 1250 1251 +f 1244 1258 1259 +f 1236 1252 1237 +f 1244 1260 1245 +f 1238 1252 1253 +f 1245 1261 1246 +f 1239 1253 1254 +f 1232 1216 1247 +f 1442 1246 1261 +f 1239 1255 1240 +f 1233 1247 1248 +f 1240 1256 1241 +f 1233 1249 1234 +f 1242 1256 1257 +f 1234 1250 1235 +f 1242 1258 1243 +f 1254 1270 1255 +f 1247 1263 1248 +f 1255 1271 1256 +f 1248 1264 1249 +f 1257 1271 1272 +f 1249 1265 1250 +f 1257 1273 1258 +f 1251 1265 1266 +f 1259 1273 1274 +f 1251 1267 1252 +f 1259 1275 1260 +f 1253 1267 1268 +f 1260 1276 1261 +f 1254 1268 1269 +f 1247 1216 1262 +f 1442 1261 1276 +f 1274 1288 1289 +f 1266 1282 1267 +f 1274 1290 1275 +f 1268 1282 1283 +f 1276 1290 1291 +f 1269 1283 1284 +f 1262 1216 1277 +f 1442 1276 1291 +f 1269 1285 1270 +f 1262 1278 1263 +f 1270 1286 1271 +f 1264 1278 1279 +f 1272 1286 1287 +f 1264 1280 1265 +f 1272 1288 1273 +f 1266 1280 1281 +f 1277 1293 1278 +f 1285 1301 1286 +f 1279 1293 1294 +f 1287 1301 1302 +f 1279 1295 1280 +f 1287 1303 1288 +f 1281 1295 1296 +f 1289 1303 1304 +f 1281 1297 1282 +f 1289 1305 1290 +f 1283 1297 1298 +f 1290 1306 1291 +f 1284 1298 1299 +f 1277 1216 1292 +f 1442 1291 1306 +f 1284 1300 1285 +f 1296 1312 1297 +f 1305 1319 1320 +f 1298 1312 1313 +f 1306 1320 1321 +f 1299 1313 1314 +f 1292 1216 1307 +f 1442 1306 1321 +f 1299 1315 1300 +f 1292 1308 1293 +f 1300 1316 1301 +f 1293 1309 1294 +f 1302 1316 1317 +f 1294 1310 1295 +f 1302 1318 1303 +f 1296 1310 1311 +f 1303 1319 1304 +f 1315 1331 1316 +f 1309 1323 1324 +f 1317 1331 1332 +f 1309 1325 1310 +f 1317 1333 1318 +f 1311 1325 1326 +f 1319 1333 1334 +f 1311 1327 1312 +f 1319 1335 1320 +f 1313 1327 1328 +f 1320 1336 1321 +f 1314 1328 1329 +f 1307 1216 1322 +f 1442 1321 1336 +f 1314 1330 1315 +f 1308 1322 1323 +f 1334 1350 1335 +f 1328 1342 1343 +f 1335 1351 1336 +f 1329 1343 1344 +f 1322 1216 1337 +f 1442 1336 1351 +f 1329 1345 1330 +f 1322 1338 1323 +f 1330 1346 1331 +f 1323 1339 1324 +f 1332 1346 1347 +f 1324 1340 1325 +f 1332 1348 1333 +f 1326 1340 1341 +f 1334 1348 1349 +f 1326 1342 1327 +f 1347 1361 1362 +f 1339 1355 1340 +f 1347 1363 1348 +f 1341 1355 1356 +f 1349 1363 1364 +f 1341 1357 1342 +f 1349 1365 1350 +f 1343 1357 1358 +f 1350 1366 1351 +f 1344 1358 1359 +f 1337 1216 1352 +f 1442 1351 1366 +f 1344 1360 1345 +f 1337 1353 1338 +f 1345 1361 1346 +f 1338 1354 1339 +f 1366 1380 1381 +f 1359 1373 1374 +f 1352 1216 1367 +f 1442 1366 1381 +f 1359 1375 1360 +f 1352 1368 1353 +f 1360 1376 1361 +f 1354 1368 1369 +f 1362 1376 1377 +f 1354 1370 1355 +f 1362 1378 1363 +f 1356 1370 1371 +f 1364 1378 1379 +f 1356 1372 1357 +f 1364 1380 1365 +f 1358 1372 1373 +f 1369 1385 1370 +f 1377 1393 1378 +f 1371 1385 1386 +f 1379 1393 1394 +f 1371 1387 1372 +f 1379 1395 1380 +f 1373 1387 1388 +f 1380 1396 1381 +f 1374 1388 1389 +f 1367 1216 1382 +f 1442 1381 1396 +f 1374 1390 1375 +f 1367 1383 1368 +f 1375 1391 1376 +f 1368 1384 1369 +f 1377 1391 1392 +f 1389 1403 1404 +f 1382 1216 1397 +f 1442 1396 1411 +f 1389 1405 1390 +f 1383 1397 1398 +f 1390 1406 1391 +f 1383 1399 1384 +f 1392 1406 1407 +f 1384 1400 1385 +f 1392 1408 1393 +f 1386 1400 1401 +f 1394 1408 1409 +f 1386 1402 1387 +f 1394 1410 1395 +f 1388 1402 1403 +f 1395 1411 1396 +f 1407 1423 1408 +f 1401 1415 1416 +f 1409 1423 1424 +f 1401 1417 1402 +f 1409 1425 1410 +f 1403 1417 1418 +f 1411 1425 1426 +f 1404 1418 1419 +f 1397 1216 1412 +f 1442 1411 1426 +f 1404 1420 1405 +f 1398 1412 1413 +f 1405 1421 1406 +f 1398 1414 1399 +f 1407 1421 1422 +f 1399 1415 1400 +f 1412 1216 1427 +f 1442 1426 1441 +f 1419 1435 1420 +f 1412 1428 1413 +f 1420 1436 1421 +f 1413 1429 1414 +f 1422 1436 1437 +f 1414 1430 1415 +f 1422 1438 1423 +f 1416 1430 1431 +f 1424 1438 1439 +f 1416 1432 1417 +f 1424 1440 1425 +f 1418 1432 1433 +f 1426 1440 1441 +f 1419 1433 1434 +f 1431 1446 1447 +f 1439 1454 1455 +f 1431 1448 1432 +f 1439 1456 1440 +f 1433 1448 1449 +f 1440 1457 1441 +f 1434 1449 1450 +f 1427 1216 1443 +f 1442 1441 1457 +f 1434 1451 1435 +f 1427 1444 1428 +f 1435 1452 1436 +f 1428 1445 1429 +f 1437 1452 1453 +f 1429 1446 1430 +f 1437 1454 1438 +f 1450 1466 1451 +f 1443 1459 1444 +f 1451 1467 1452 +f 1444 1460 1445 +f 1453 1467 1468 +f 1445 1461 1446 +f 1453 1469 1454 +f 1446 1462 1447 +f 1455 1469 1470 +f 1447 1463 1448 +f 1455 1471 1456 +f 1449 1463 1464 +f 1456 1472 1457 +f 1450 1464 1465 +f 1443 1216 1458 +f 1442 1457 1472 +f 1470 1484 1485 +f 1462 1478 1463 +f 1470 1486 1471 +f 1464 1478 1479 +f 1471 1487 1472 +f 1465 1479 1480 +f 1458 1216 1473 +f 1442 1472 1487 +f 1465 1481 1466 +f 1458 1474 1459 +f 1466 1482 1467 +f 1459 1475 1460 +f 1468 1482 1483 +f 1460 1476 1461 +f 1468 1484 1469 +f 1462 1476 1477 +f 1481 1497 1482 +f 1475 1489 1490 +f 1483 1497 1498 +f 1475 1491 1476 +f 1483 1499 1484 +f 1477 1491 1492 +f 1485 1499 1500 +f 1477 1493 1478 +f 1485 1501 1486 +f 1479 1493 1494 +f 1486 1502 1487 +f 1480 1494 1495 +f 1473 1216 1488 +f 1442 1487 1502 +f 1480 1496 1481 +f 1473 1489 1474 +f 1500 1516 1501 +f 1494 1508 1509 +f 1501 1517 1502 +f 1495 1509 1510 +f 1488 1216 1503 +f 1442 1502 1517 +f 1495 1511 1496 +f 1488 1504 1489 +f 1496 1512 1497 +f 1490 1504 1505 +f 1498 1512 1513 +f 1490 1506 1491 +f 1498 1514 1499 +f 1492 1506 1507 +f 1500 1514 1515 +f 1492 1508 1493 +f 1505 1519 1520 +f 1513 1527 1528 +f 1505 1521 1506 +f 1513 1529 1514 +f 1507 1521 1522 +f 1515 1529 1530 +f 1507 1523 1508 +f 1515 1531 1516 +f 1509 1523 1524 +f 1516 1532 1517 +f 1510 1524 1525 +f 1503 1216 1518 +f 1442 1517 1532 +f 1510 1526 1511 +f 1503 1519 1504 +f 1511 1527 1512 +f 1524 1538 1539 +f 1531 1547 1532 +f 1525 1539 1540 +f 1518 1216 1533 +f 1442 1532 1547 +f 1525 1541 1526 +f 1519 1533 1534 +f 1526 1542 1527 +f 1519 1535 1520 +f 1528 1542 1543 +f 1520 1536 1521 +f 1528 1544 1529 +f 1522 1536 1537 +f 1530 1544 1545 +f 1522 1538 1523 +f 1531 1545 1546 +f 1543 1557 1558 +f 1535 1551 1536 +f 1543 1559 1544 +f 1537 1551 1552 +f 1545 1559 1560 +f 1537 1553 1538 +f 1545 1561 1546 +f 1539 1553 1554 +f 1546 1562 1547 +f 1540 1554 1555 +f 1533 1216 1548 +f 1442 1547 1562 +f 1540 1556 1541 +f 1533 1549 1534 +f 1541 1557 1542 +f 1535 1549 1550 +f 1561 1577 1562 +f 1555 1569 1570 +f 1548 1216 1563 +f 1442 1562 1577 +f 1555 1571 1556 +f 1548 1564 1549 +f 1556 1572 1557 +f 1550 1564 1565 +f 1558 1572 1573 +f 1550 1566 1551 +f 1558 1574 1559 +f 1552 1566 1567 +f 1560 1574 1575 +f 1552 1568 1553 +f 1560 1576 1561 +f 1554 1568 1569 +f 1565 1581 1566 +f 1573 1589 1574 +f 1567 1581 1582 +f 1575 1589 1590 +f 1567 1583 1568 +f 1575 1591 1576 +f 1569 1583 1584 +f 1576 1592 1577 +f 1570 1584 1585 +f 1563 1216 1578 +f 1442 1577 1592 +f 1570 1586 1571 +f 1564 1578 1579 +f 1571 1587 1572 +f 1564 1580 1565 +f 1573 1587 1588 +f 1585 1599 1600 +f 1578 1216 1593 +f 1442 1592 1607 +f 1585 1601 1586 +f 1578 1594 1579 +f 1586 1602 1587 +f 1580 1594 1595 +f 1588 1602 1603 +f 1580 1596 1581 +f 1588 1604 1589 +f 1582 1596 1597 +f 1590 1604 1605 +f 1582 1598 1583 +f 1590 1606 1591 +f 1584 1598 1599 +f 1592 1606 1607 +f 1603 1613 1604 +f 1597 1610 1136 +f 1605 1613 1614 +f 1598 1136 1611 +f 1605 1615 1606 +f 1599 1611 1137 +f 1606 1616 1607 +f 1600 1137 1138 +f 1593 1216 1608 +f 1442 1607 1616 +f 1600 1139 1601 +f 1594 1608 1609 +f 1601 1612 1602 +f 1595 1609 1135 +f 1602 1140 1603 +f 1596 1135 1610 +f 1140 1151 1152 +f 1136 1610 1144 +f 1613 1152 1153 +f 1611 1136 1145 +f 1614 1153 1154 +f 1137 1611 1146 +f 1615 1154 1155 +f 1137 1147 1148 +f 1138 1148 1149 +f 1609 1608 1141 +f 1139 1149 1150 +f 1135 1609 1142 +f 1612 1150 1151 +f 1610 1135 1143 +f 1142 1157 1158 +f 1150 1165 1166 +f 1143 1158 1159 +f 1151 1166 1167 +f 1144 1159 1160 +f 1153 1152 1167 +f 1145 1160 1161 +f 1154 1153 1168 +f 1147 1146 1161 +f 1154 1169 1170 +f 1147 1162 1163 +f 1148 1163 1164 +f 1141 1156 1157 +f 1149 1164 1165 +f 1161 1176 1177 +f 1169 1184 1185 +f 1162 1177 1178 +f 1164 1163 1178 +f 1156 1171 1172 +f 1164 1179 1180 +f 1157 1172 1173 +f 1166 1165 1180 +f 1158 1173 1174 +f 1167 1166 1181 +f 1159 1174 1175 +f 1168 1167 1182 +f 1160 1175 1176 +f 1168 1183 1184 +f 1181 1180 1195 +f 1173 1188 1189 +f 1181 1196 1197 +f 1174 1189 1190 +f 1182 1197 1198 +f 1175 1190 1191 +f 1183 1198 1199 +f 1177 1176 1191 +f 1184 1199 1200 +f 1178 1177 1192 +f 1178 1193 1194 +f 1171 1186 1187 +f 1179 1194 1195 +f 1172 1187 1188 +f 1199 1214 1215 +f 1193 1192 1207 +f 1193 1208 1209 +f 1186 1201 1202 +f 1194 1209 1210 +f 1187 1202 1203 +f 1196 1195 1210 +f 1188 1203 1204 +f 1196 1211 1212 +f 1190 1189 1204 +f 1197 1212 1213 +f 1190 1205 1206 +f 1199 1198 1213 +f 1192 1191 1206 +f 1211 1227 1228 +f 1205 1204 1220 +f 1212 1228 1229 +f 1205 1221 1222 +f 1213 1229 1230 +f 1207 1206 1222 +f 1215 1214 1230 +f 1208 1207 1223 +f 1208 1224 1225 +f 1201 1217 1218 +f 1209 1225 1226 +f 1202 1218 1219 +f 1211 1210 1226 +f 1203 1219 1220 +f 1224 1239 1240 +f 1218 1217 1232 +f 1225 1240 1241 +f 1218 1233 1234 +f 1227 1226 1241 +f 1219 1234 1235 +f 1227 1242 1243 +f 1221 1220 1235 +f 1229 1228 1243 +f 1221 1236 1237 +f 1230 1229 1244 +f 1223 1222 1237 +f 1230 1245 1246 +f 1224 1223 1238 +f 1236 1235 1250 +f 1244 1243 1258 +f 1236 1251 1252 +f 1244 1259 1260 +f 1238 1237 1252 +f 1245 1260 1261 +f 1239 1238 1253 +f 1239 1254 1255 +f 1233 1232 1247 +f 1240 1255 1256 +f 1233 1248 1249 +f 1242 1241 1256 +f 1234 1249 1250 +f 1242 1257 1258 +f 1254 1269 1270 +f 1247 1262 1263 +f 1255 1270 1271 +f 1248 1263 1264 +f 1257 1256 1271 +f 1249 1264 1265 +f 1257 1272 1273 +f 1251 1250 1265 +f 1259 1258 1273 +f 1251 1266 1267 +f 1259 1274 1275 +f 1253 1252 1267 +f 1260 1275 1276 +f 1254 1253 1268 +f 1274 1273 1288 +f 1266 1281 1282 +f 1274 1289 1290 +f 1268 1267 1282 +f 1276 1275 1290 +f 1269 1268 1283 +f 1269 1284 1285 +f 1262 1277 1278 +f 1270 1285 1286 +f 1264 1263 1278 +f 1272 1271 1286 +f 1264 1279 1280 +f 1272 1287 1288 +f 1266 1265 1280 +f 1277 1292 1293 +f 1285 1300 1301 +f 1279 1278 1293 +f 1287 1286 1301 +f 1279 1294 1295 +f 1287 1302 1303 +f 1281 1280 1295 +f 1289 1288 1303 +f 1281 1296 1297 +f 1289 1304 1305 +f 1283 1282 1297 +f 1290 1305 1306 +f 1284 1283 1298 +f 1284 1299 1300 +f 1296 1311 1312 +f 1305 1304 1319 +f 1298 1297 1312 +f 1306 1305 1320 +f 1299 1298 1313 +f 1299 1314 1315 +f 1292 1307 1308 +f 1300 1315 1316 +f 1293 1308 1309 +f 1302 1301 1316 +f 1294 1309 1310 +f 1302 1317 1318 +f 1296 1295 1310 +f 1303 1318 1319 +f 1315 1330 1331 +f 1309 1308 1323 +f 1317 1316 1331 +f 1309 1324 1325 +f 1317 1332 1333 +f 1311 1310 1325 +f 1319 1318 1333 +f 1311 1326 1327 +f 1319 1334 1335 +f 1313 1312 1327 +f 1320 1335 1336 +f 1314 1313 1328 +f 1314 1329 1330 +f 1308 1307 1322 +f 1334 1349 1350 +f 1328 1327 1342 +f 1335 1350 1351 +f 1329 1328 1343 +f 1329 1344 1345 +f 1322 1337 1338 +f 1330 1345 1346 +f 1323 1338 1339 +f 1332 1331 1346 +f 1324 1339 1340 +f 1332 1347 1348 +f 1326 1325 1340 +f 1334 1333 1348 +f 1326 1341 1342 +f 1347 1346 1361 +f 1339 1354 1355 +f 1347 1362 1363 +f 1341 1340 1355 +f 1349 1348 1363 +f 1341 1356 1357 +f 1349 1364 1365 +f 1343 1342 1357 +f 1350 1365 1366 +f 1344 1343 1358 +f 1344 1359 1360 +f 1337 1352 1353 +f 1345 1360 1361 +f 1338 1353 1354 +f 1366 1365 1380 +f 1359 1358 1373 +f 1359 1374 1375 +f 1352 1367 1368 +f 1360 1375 1376 +f 1354 1353 1368 +f 1362 1361 1376 +f 1354 1369 1370 +f 1362 1377 1378 +f 1356 1355 1370 +f 1364 1363 1378 +f 1356 1371 1372 +f 1364 1379 1380 +f 1358 1357 1372 +f 1369 1384 1385 +f 1377 1392 1393 +f 1371 1370 1385 +f 1379 1378 1393 +f 1371 1386 1387 +f 1379 1394 1395 +f 1373 1372 1387 +f 1380 1395 1396 +f 1374 1373 1388 +f 1374 1389 1390 +f 1367 1382 1383 +f 1375 1390 1391 +f 1368 1383 1384 +f 1377 1376 1391 +f 1389 1388 1403 +f 1389 1404 1405 +f 1383 1382 1397 +f 1390 1405 1406 +f 1383 1398 1399 +f 1392 1391 1406 +f 1384 1399 1400 +f 1392 1407 1408 +f 1386 1385 1400 +f 1394 1393 1408 +f 1386 1401 1402 +f 1394 1409 1410 +f 1388 1387 1402 +f 1395 1410 1411 +f 1407 1422 1423 +f 1401 1400 1415 +f 1409 1408 1423 +f 1401 1416 1417 +f 1409 1424 1425 +f 1403 1402 1417 +f 1411 1410 1425 +f 1404 1403 1418 +f 1404 1419 1420 +f 1398 1397 1412 +f 1405 1420 1421 +f 1398 1413 1414 +f 1407 1406 1421 +f 1399 1414 1415 +f 1419 1434 1435 +f 1412 1427 1428 +f 1420 1435 1436 +f 1413 1428 1429 +f 1422 1421 1436 +f 1414 1429 1430 +f 1422 1437 1438 +f 1416 1415 1430 +f 1424 1423 1438 +f 1416 1431 1432 +f 1424 1439 1440 +f 1418 1417 1432 +f 1426 1425 1440 +f 1419 1418 1433 +f 1431 1430 1446 +f 1439 1438 1454 +f 1431 1447 1448 +f 1439 1455 1456 +f 1433 1432 1448 +f 1440 1456 1457 +f 1434 1433 1449 +f 1434 1450 1451 +f 1427 1443 1444 +f 1435 1451 1452 +f 1428 1444 1445 +f 1437 1436 1452 +f 1429 1445 1446 +f 1437 1453 1454 +f 1450 1465 1466 +f 1443 1458 1459 +f 1451 1466 1467 +f 1444 1459 1460 +f 1453 1452 1467 +f 1445 1460 1461 +f 1453 1468 1469 +f 1446 1461 1462 +f 1455 1454 1469 +f 1447 1462 1463 +f 1455 1470 1471 +f 1449 1448 1463 +f 1456 1471 1472 +f 1450 1449 1464 +f 1470 1469 1484 +f 1462 1477 1478 +f 1470 1485 1486 +f 1464 1463 1478 +f 1471 1486 1487 +f 1465 1464 1479 +f 1465 1480 1481 +f 1458 1473 1474 +f 1466 1481 1482 +f 1459 1474 1475 +f 1468 1467 1482 +f 1460 1475 1476 +f 1468 1483 1484 +f 1462 1461 1476 +f 1481 1496 1497 +f 1475 1474 1489 +f 1483 1482 1497 +f 1475 1490 1491 +f 1483 1498 1499 +f 1477 1476 1491 +f 1485 1484 1499 +f 1477 1492 1493 +f 1485 1500 1501 +f 1479 1478 1493 +f 1486 1501 1502 +f 1480 1479 1494 +f 1480 1495 1496 +f 1473 1488 1489 +f 1500 1515 1516 +f 1494 1493 1508 +f 1501 1516 1517 +f 1495 1494 1509 +f 1495 1510 1511 +f 1488 1503 1504 +f 1496 1511 1512 +f 1490 1489 1504 +f 1498 1497 1512 +f 1490 1505 1506 +f 1498 1513 1514 +f 1492 1491 1506 +f 1500 1499 1514 +f 1492 1507 1508 +f 1505 1504 1519 +f 1513 1512 1527 +f 1505 1520 1521 +f 1513 1528 1529 +f 1507 1506 1521 +f 1515 1514 1529 +f 1507 1522 1523 +f 1515 1530 1531 +f 1509 1508 1523 +f 1516 1531 1532 +f 1510 1509 1524 +f 1510 1525 1526 +f 1503 1518 1519 +f 1511 1526 1527 +f 1524 1523 1538 +f 1531 1546 1547 +f 1525 1524 1539 +f 1525 1540 1541 +f 1519 1518 1533 +f 1526 1541 1542 +f 1519 1534 1535 +f 1528 1527 1542 +f 1520 1535 1536 +f 1528 1543 1544 +f 1522 1521 1536 +f 1530 1529 1544 +f 1522 1537 1538 +f 1531 1530 1545 +f 1543 1542 1557 +f 1535 1550 1551 +f 1543 1558 1559 +f 1537 1536 1551 +f 1545 1544 1559 +f 1537 1552 1553 +f 1545 1560 1561 +f 1539 1538 1553 +f 1546 1561 1562 +f 1540 1539 1554 +f 1540 1555 1556 +f 1533 1548 1549 +f 1541 1556 1557 +f 1535 1534 1549 +f 1561 1576 1577 +f 1555 1554 1569 +f 1555 1570 1571 +f 1548 1563 1564 +f 1556 1571 1572 +f 1550 1549 1564 +f 1558 1557 1572 +f 1550 1565 1566 +f 1558 1573 1574 +f 1552 1551 1566 +f 1560 1559 1574 +f 1552 1567 1568 +f 1560 1575 1576 +f 1554 1553 1568 +f 1565 1580 1581 +f 1573 1588 1589 +f 1567 1566 1581 +f 1575 1574 1589 +f 1567 1582 1583 +f 1575 1590 1591 +f 1569 1568 1583 +f 1576 1591 1592 +f 1570 1569 1584 +f 1570 1585 1586 +f 1564 1563 1578 +f 1571 1586 1587 +f 1564 1579 1580 +f 1573 1572 1587 +f 1585 1584 1599 +f 1585 1600 1601 +f 1578 1593 1594 +f 1586 1601 1602 +f 1580 1579 1594 +f 1588 1587 1602 +f 1580 1595 1596 +f 1588 1603 1604 +f 1582 1581 1596 +f 1590 1589 1604 +f 1582 1597 1598 +f 1590 1605 1606 +f 1584 1583 1598 +f 1592 1591 1606 +f 1603 1140 1613 +f 1597 1596 1610 +f 1605 1604 1613 +f 1598 1597 1136 +f 1605 1614 1615 +f 1599 1598 1611 +f 1606 1615 1616 +f 1600 1599 1137 +f 1600 1138 1139 +f 1594 1593 1608 +f 1601 1139 1612 +f 1595 1594 1609 +f 1602 1612 1140 +f 1596 1595 1135 diff --git a/src/main.rs b/src/main.rs index 647fbfc..efc04b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,4 +3,4 @@ mod shader; fn main() { vulkan::init(); -} \ No newline at end of file +} diff --git a/src/shader/composite.rs b/src/shader/composite.rs deleted file mode 100644 index 46469d0..0000000 --- a/src/shader/composite.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub(crate) mod vs { - vulkano_shaders::shader! { - ty: "vertex", - path: "src/shader/src/composite.vert" - } -} - -pub(crate) mod fs { - vulkano_shaders::shader! { - ty: "fragment", - include: ["src/shader/src"], - path: "src/shader/src/composite.frag" - } -} \ No newline at end of file diff --git a/src/shader/src/composite.frag b/src/shader/composite/final.frag similarity index 54% rename from src/shader/src/composite.frag rename to src/shader/composite/final.frag index 826a409..2910610 100644 --- a/src/shader/src/composite.frag +++ b/src/shader/composite/final.frag @@ -1,16 +1,20 @@ #version 450 -#include - layout(location = 0) in vec2 texture_coordinate; +layout(set = 0, binding = 0) uniform sampler2D image; + layout(location = 0) out vec4 frag_color; void main() { vec2 uv = texture_coordinate; - vec3 color = trace_path(uv); + vec3 color = texture(image, uv).rgb; + + // TODO: tonemapping + // TODO: denoising + // TODO: bloom frag_color = vec4(color, 1.0); } \ No newline at end of file diff --git a/src/shader/src/composite.vert b/src/shader/composite/final.vert similarity index 100% rename from src/shader/src/composite.vert rename to src/shader/composite/final.vert diff --git a/src/shader/composite/mod.rs b/src/shader/composite/mod.rs new file mode 100644 index 0000000..9ae26a2 --- /dev/null +++ b/src/shader/composite/mod.rs @@ -0,0 +1,140 @@ +use vulkano::command_buffer::allocator::StandardCommandBufferAllocator; +use vulkano::device::Queue; +use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint}; +use vulkano::render_pass::{Framebuffer, RenderPass}; +use std::sync::Arc; +use vulkano::buffer::{Subbuffer}; +use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer, RenderPassBeginInfo, SubpassContents}; +use vulkano::descriptor_set::allocator::StandardDescriptorSetAllocator; +use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet}; +use vulkano::image::{ImageViewAbstract, StorageImage}; +use vulkano::image::view::ImageView; +use vulkano::pipeline::graphics::viewport::Viewport; +use vulkano::sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo, SamplerMipmapMode}; +use crate::shader::create_final_composite; +use crate::shader::pathtracing::PathtracerPipeline; +use crate::vulkan::Renderer; +use crate::vulkan::textured_quad::{create_quad_buffer, TexturedVertex}; + +pub(crate) mod vs { + vulkano_shaders::shader! { + ty: "vertex", + path: "src/shader/composite/final.vert" + } +} + +pub(crate) mod fs { + vulkano_shaders::shader! { + ty: "fragment", + include: ["src/shader/src"], + path: "src/shader/composite/final.frag" + } +} + +pub struct TextureDrawPipeline { + gfx_queue: Arc, + pub(crate) pipeline: Arc, + command_buffer_allocator: Arc, + descriptor_set_allocator: Arc, + vertices: Subbuffer<[TexturedVertex]>, + indices: Subbuffer<[u32]>, +} + +impl TextureDrawPipeline { + pub fn new(renderer: &Renderer, gfx_queue: &Arc, render_pass: &Arc) -> Self { + let (vertices, indices) = create_quad_buffer(&renderer.memory_allocator); + + let composite = create_final_composite(render_pass, &gfx_queue.device().clone()); + + Self { + gfx_queue: gfx_queue.clone(), + pipeline: composite.pipeline, + command_buffer_allocator: renderer.command_buffer_allocator.clone(), + descriptor_set_allocator: renderer.descriptor_set_allocator.clone(), + vertices, + indices + } + } + + pub fn draw(&self, frame_buffer: Arc, viewport: &Viewport, pathtracer: &PathtracerPipeline) -> PrimaryAutoCommandBuffer { + let set = self.create_image_sampler_nearest(pathtracer.image()); + + // In order to draw, we have to build a *command buffer*. The command buffer object + // holds the list of commands that are going to be executed. + // + // Building a command buffer is an expensive operation (usually a few hundred + // microseconds), but it is known to be a hot path in the driver and is expected to + // be optimized. + // + // Note that we have to pass a queue family when we create the command buffer. The + // command buffer will only be executable on that given queue family. + let mut builder = AutoCommandBufferBuilder::primary( + &self.command_buffer_allocator, + self.gfx_queue.queue_family_index(), + CommandBufferUsage::OneTimeSubmit, + ).unwrap(); + + builder + // Before we can draw, we have to *enter a render pass*. + .begin_render_pass( + RenderPassBeginInfo { + // A list of values to clear the attachments with. This list contains + // one item for each attachment in the render pass. In this case, there + // is only one attachment, and we clear it with black. + // + // Only attachments that have `LoadOp::Clear` are provided with clear + // values, any others should use `ClearValue::None` as the clear value. + clear_values: vec![Some([0.0, 0.0, 0.0, 1.0].into())], + + ..RenderPassBeginInfo::framebuffer(frame_buffer) + }, + // The contents of the first (and only) subpass. This can be either + // `Inline` or `SecondaryCommandBuffers`. The latter is a bit more advanced + // and is not covered here. + SubpassContents::Inline, + ) + .unwrap() + // We are now inside the first subpass of the render pass. + .set_viewport(0, [viewport.clone()]) + .bind_pipeline_graphics(self.pipeline.clone()) + .bind_vertex_buffers(0, self.vertices.clone()) + .bind_index_buffer(self.indices.clone()) + .bind_descriptor_sets(PipelineBindPoint::Graphics, self.pipeline.layout().clone(), 0, set) + // We add a draw command. + .draw_indexed(self.indices.len() as u32, 1, 0, 0, 0) + .unwrap() + // We leave the render pass. Note that if we had multiple subpasses we could + // have called `next_subpass` to jump to the next subpass. + .end_render_pass() + .unwrap(); + + builder.build().unwrap() + } + + fn create_image_sampler_nearest( + &self, + image: &Arc>, + ) -> Arc { + let layout = self.pipeline.layout().set_layouts().get(0).unwrap(); + let sampler = Sampler::new( + self.gfx_queue.device().clone(), + SamplerCreateInfo { + mag_filter: Filter::Linear, + min_filter: Filter::Linear, + address_mode: [SamplerAddressMode::Repeat; 3], + mipmap_mode: SamplerMipmapMode::Nearest, + ..Default::default() + }, + ).unwrap(); + + PersistentDescriptorSet::new( + &self.descriptor_set_allocator, + layout.clone(), + [WriteDescriptorSet::image_view_sampler( + 0, + image.clone(), + sampler, + )], + ).unwrap() + } +} diff --git a/src/shader/mod.rs b/src/shader/mod.rs index ca75ecc..72ccc73 100644 --- a/src/shader/mod.rs +++ b/src/shader/mod.rs @@ -1,4 +1,5 @@ -mod composite; +pub mod composite; +pub mod pathtracing; use std::sync::Arc; use vulkano::device::Device; @@ -7,21 +8,27 @@ use vulkano::pipeline::graphics::vertex_input::Vertex; use vulkano::pipeline::graphics::viewport::ViewportState; use vulkano::pipeline::GraphicsPipeline; use vulkano::render_pass::{RenderPass, Subpass}; -use crate::vulkan::Vertex2d; +use vulkano::shader::ShaderModule; -pub fn create_program(render_pass: &Arc, device: &Arc) -> Arc { +pub struct Program { + pub pipeline: Arc, + pub vertex: Arc, + pub fragement: Arc +} + +pub fn create_final_composite(render_pass: &Arc, device: &Arc) -> Program { let vs = composite::vs::load(device.clone()).unwrap(); let fs = composite::fs::load(device.clone()).unwrap(); // Before we draw we have to create what is called a pipeline. This is similar to an OpenGL // program, but much more specific. - GraphicsPipeline::start() + let pipeline = GraphicsPipeline::start() // We have to indicate which subpass of which render pass this pipeline is going to be used // in. The pipeline will only be usable from this particular subpass. .render_pass(Subpass::from(render_pass.clone(), 0).unwrap()) // We need to indicate the layout of the vertices. - .vertex_input_state(Vertex2d::per_vertex()) + .vertex_input_state(crate::vulkan::textured_quad::TexturedVertex::per_vertex()) // The content of the vertex buffer describes a list of triangles. .input_assembly_state(InputAssemblyState::new()) // A Vulkan shader can in theory contain multiple entry points, so we have to specify @@ -33,5 +40,11 @@ pub fn create_program(render_pass: &Arc, device: &Arc) -> Ar .fragment_shader(fs.entry_point("main").unwrap(), ()) // Now that our builder is filled, we call `build()` to obtain an actual pipeline. .build(device.clone()) - .unwrap() + .unwrap(); + + return Program { + pipeline, + vertex: vs, + fragement: fs, + } } \ No newline at end of file diff --git a/src/shader/pathtracing/camera.rs b/src/shader/pathtracing/camera.rs new file mode 100644 index 0000000..574eff5 --- /dev/null +++ b/src/shader/pathtracing/camera.rs @@ -0,0 +1,35 @@ + +use cgmath::prelude::*; +use cgmath::{Rad, Vector2, Vector3}; + +pub struct Camera { + front: Vector3, + left: Vector3, + up: Vector3, + pos: Vector3, + fov: f32, +} + +impl Camera { + + pub fn new() -> Self { + Self { + front: Vector3::new(0.0, 0.0, 1.0), + left: Vector3::new(1.0, 0.0, 0.0), + up: Vector3::new(0.0, 1.0, 0.0), + pos: Vector3::new(0.0, 0.0, -4.0), + fov: 90.0f32 + } + } + + fn rotate(&mut self, rot_y: f32, rot_x: f32) { + let rot_mat_y = cgmath::Matrix4::from_angle_y(Rad(rot_y)); + let rot_mat_x = cgmath::Matrix4::from_angle_x(Rad(rot_x)); + + let mat = rot_mat_x * rot_mat_y; + + self.front = mat.transform_vector(self.front); + self.left = mat.transform_vector(self.left); + self.up = mat.transform_vector(self.up); + } +} \ No newline at end of file diff --git a/src/shader/pathtracing/mod.rs b/src/shader/pathtracing/mod.rs new file mode 100644 index 0000000..1f15833 --- /dev/null +++ b/src/shader/pathtracing/mod.rs @@ -0,0 +1,247 @@ +mod camera; + +use std::sync::Arc; +use std::time::Instant; +use vulkano::buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer}; +use vulkano::buffer::allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo}; +use vulkano::command_buffer::allocator::StandardCommandBufferAllocator; +use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer, PrimaryCommandBufferAbstract}; +use vulkano::descriptor_set::allocator::StandardDescriptorSetAllocator; +use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet}; +use vulkano::device::{Queue}; +use vulkano::format::Format; +use vulkano::image::{ImageAccess, ImageUsage, StorageImage}; +use vulkano::image::view::ImageView; +use vulkano::memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}; +use vulkano::padded::Padded; +use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint}; +use vulkano::sync::GpuFuture; +use crate::vulkan::Renderer; + +pub(crate) mod cs { + vulkano_shaders::shader! { + ty: "compute", + include: ["src/shader/pathtracing/"], + path: "src/shader/pathtracing/pathtracer.comp" + } +} + +pub struct PathtracerPipeline { + compute_queue: Arc, + compute_pipeline: Arc, + command_buffer_allocator: Arc, + descriptor_set_allocator: Arc, + memory_allocator: Arc, + image: Arc>, + raw_image: Subbuffer<[[f32; 4]]>, + seconds: Instant, + uniform_buffer: Arc, + vertex_buffer: Subbuffer<[[f32; 3]]>, + index_buffer: Subbuffer<[u32]>, +} + +impl PathtracerPipeline { + pub fn new(renderer: &Renderer, compute_queue: &Arc, size: [u32; 2]) -> Self { + let compute_pipeline = { + let shader = cs::load(compute_queue.device().clone()).unwrap(); + + ComputePipeline::new( + compute_queue.device().clone(), + shader.entry_point("main").unwrap(), + &(), + None, + |_| {}, + ).unwrap() + }; + + let (raw_image_buffer, image) = create_image(&renderer.memory_allocator, compute_queue, size); + + let uniform_buffer = SubbufferAllocator::new( + renderer.memory_allocator.clone(), + SubbufferAllocatorCreateInfo { + buffer_usage: BufferUsage::UNIFORM_BUFFER, + ..Default::default() + }, + ); + + let (vertices, indices) = load_example_scene(); + + let (vertex_buffer, index_buffer) = create_gpu_buffer(&vertices, &indices, &renderer.memory_allocator); + + return PathtracerPipeline { + compute_queue: compute_queue.clone(), + compute_pipeline, + command_buffer_allocator: renderer.command_buffer_allocator.clone(), + descriptor_set_allocator: renderer.descriptor_set_allocator.clone(), + memory_allocator: renderer.memory_allocator.clone(), + image, + raw_image: raw_image_buffer, + uniform_buffer: Arc::new(uniform_buffer), + vertex_buffer, + index_buffer, + seconds: Instant::now() + }; + } + + pub fn compute(&mut self) -> Box { + let mut builder = AutoCommandBufferBuilder::primary( + &self.command_buffer_allocator, + self.compute_queue.queue_family_index(), + CommandBufferUsage::OneTimeSubmit, + ).unwrap(); + + // Dispatch will mutate the builder adding commands which won't be sent before we build the + // command buffer after dispatches. This will minimize the commands we send to the GPU. For + // example, we could be doing tens of dispatches here depending on our needs. Maybe we + // wanted to simulate 10 steps at a time... + + // First compute the next state. + self.dispatch(&mut builder); + + let command_buffer = builder.build().unwrap(); + let finished = command_buffer.execute(self.compute_queue.clone()).unwrap(); + let after_pipeline = finished.then_signal_fence_and_flush().unwrap().boxed(); + + after_pipeline + } + + pub fn resize_image(&mut self, size: [u32; 2]) { + let (raw_image_buffer, image) = create_image(&self.memory_allocator, &self.compute_queue, size); + + self.image = image; + self.raw_image = raw_image_buffer; + } + + /// Builds the command for a dispatch. + fn dispatch( + &self, + builder: &mut AutoCommandBufferBuilder> + ) { + let camera = cs::Camera { + front: Padded::from([0f32, 0f32, 1f32]), + left: Padded::from([1f32, 0f32, 0f32]), + up: Padded::from([0f32, 1f32, 0f32]), + + position: [0f32, 0f32, -12f32], + + fov: 90f32 + }; + + let subbuffer = self.uniform_buffer.allocate_sized().unwrap(); + *subbuffer.write().unwrap() = camera; + + let size = self.image.image().dimensions().width_height(); + let pipeline_layout = self.compute_pipeline.layout(); + let desc_layout = pipeline_layout.set_layouts().get(0).unwrap(); + let set = PersistentDescriptorSet::new( + &self.descriptor_set_allocator, + desc_layout.clone(), + [ + WriteDescriptorSet::buffer(0, self.raw_image.clone()), + WriteDescriptorSet::image_view(1, self.image.clone()), + WriteDescriptorSet::buffer(2, subbuffer), + WriteDescriptorSet::buffer(3, self.vertex_buffer.clone()), + WriteDescriptorSet::buffer(4, self.index_buffer.clone()) + ], + ).unwrap(); + + let push_constants = cs::PushConstants { + resolution: [size[0] as f32, size[1] as f32], + seconds: (Instant::now() - self.seconds).as_secs_f32() + }; + + builder + .bind_pipeline_compute(self.compute_pipeline.clone()) + .bind_descriptor_sets(PipelineBindPoint::Compute, pipeline_layout.clone(), 0, set) + .push_constants(pipeline_layout.clone(), 0, push_constants) + .dispatch([size[0] / 8, size[1] / 8, 1]) + .unwrap(); + } + + pub fn image(&self) -> &Arc> { + &self.image + } +} + +fn create_image(memory_allocator: &StandardMemoryAllocator, queue: &Arc, size: [u32; 2]) -> (Subbuffer<[[f32; 4]]>, Arc>) { + let raw_image = Buffer::from_iter( + memory_allocator, + BufferCreateInfo { + usage: BufferUsage::STORAGE_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + usage: MemoryUsage::Upload, + ..Default::default() + }, + vec![[0f32; 4]; (size[0] * size[1]) as usize], + ).unwrap(); + + let image = StorageImage::general_purpose_image_view( + memory_allocator, + queue.clone(), + size, + Format::R8G8B8A8_UNORM, + ImageUsage::SAMPLED | ImageUsage::STORAGE | ImageUsage::TRANSFER_DST, + ).unwrap(); + + (raw_image, image) +} + +fn load_example_scene() -> (Vec<[f32; 3]>, Vec) { + let (mut models, materials) = tobj::load_obj("res/example-scene.obj", &tobj::GPU_LOAD_OPTIONS).expect("unable to load scene from obj"); + + let mut vertices:Vec<[f32; 3]> = Vec::new(); + let mut indices:Vec = Vec::new(); + + for model in models.iter_mut() { + let num_triangles = model.mesh.positions.len() / 3; + + for triangle_index in 0..num_triangles { + let vertex_index = triangle_index * 3; + vertices.push([ + model.mesh.positions[vertex_index], + model.mesh.positions[vertex_index + 1], + model.mesh.positions[vertex_index + 2] + ]); + } + + for index in model.mesh.indices.iter() { + indices.push(*index); + } + + // model.mesh.indices.iter_mut().for_each(|i| indices.push(*i)); + } + + (vertices, indices) +} + +fn create_gpu_buffer(vertices: &Vec<[f32; 3]>, indices: &Vec, memory_allocator: &StandardMemoryAllocator) -> (Subbuffer<[[f32; 3]]>, Subbuffer<[u32]>) { + let vertex_buffer = Buffer::from_iter( + memory_allocator, + BufferCreateInfo { + usage: BufferUsage::STORAGE_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + usage: MemoryUsage::Upload, + ..Default::default() + }, + vertices.clone(), + ).unwrap(); + + let index_buffer = Buffer::from_iter( + memory_allocator, + BufferCreateInfo { + usage: BufferUsage::STORAGE_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + usage: MemoryUsage::Upload, + ..Default::default() + }, + indices.clone(), + ).unwrap(); + + (vertex_buffer, index_buffer) +} \ No newline at end of file diff --git a/src/shader/pathtracing/pathtracer.comp b/src/shader/pathtracing/pathtracer.comp new file mode 100644 index 0000000..617a4b6 --- /dev/null +++ b/src/shader/pathtracing/pathtracer.comp @@ -0,0 +1,51 @@ +#version 450 + +#include "rand/random.glsl" +#include "raytracing/raytracing.glsl" +#include "raytracing/camera.glsl" + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +layout(set = 0, binding = 0) buffer LinearImage { vec4 pixels[]; }; + +layout(set = 0, binding = 1, rgba8) uniform writeonly image2D image; + +layout(push_constant) uniform PushConstants { + vec2 resolution; + float seconds; +} program_metadata; + +vec2 get_viewport_coordinate() { + vec2 texture_uv = (vec2(gl_GlobalInvocationID.xy + vec2(random(), random())) - 0.5 * program_metadata.resolution) / program_metadata.resolution.y; + + return texture_uv; +} + +uint get_pixel_index() { + return gl_GlobalInvocationID.y * uint(program_metadata.resolution.x) + gl_GlobalInvocationID.x; +} + +void main() { + init_random_state(floatBitsToInt(program_metadata.seconds)); + + vec2 uv = get_viewport_coordinate(); + + Ray camera_ray = construct_camera_ray_pinhole(uv); + + vec3 color = vec3(0); + + vec4 result = intersect_scene(camera_ray); + + if (result.a == 1.0) { + color = vec3(result.y, result.z, 0); + } + + // index of the current pixel as array index + uint pixel_index = get_pixel_index(); + + vec4 buffer_data = pixels[pixel_index] + vec4(color, 1); + // contribute to the raw pixel buffer + pixels[pixel_index] = buffer_data; + + imageStore(image, ivec2(gl_GlobalInvocationID.xy), vec4(buffer_data.rgb / buffer_data.a, 1)); +} \ No newline at end of file diff --git a/src/shader/pathtracing/rand/random.glsl b/src/shader/pathtracing/rand/random.glsl new file mode 100644 index 0000000..5a8c8fa --- /dev/null +++ b/src/shader/pathtracing/rand/random.glsl @@ -0,0 +1,36 @@ + +uint state; + +void init_random_state(uint seed) { + state = (gl_GlobalInvocationID.x << 16) | gl_GlobalInvocationID.y; + state += seed; +} + +// A single iteration of Bob Jenkins' One-At-A-Time hashing algorithm. +uint hash(in uint x) { + x += ( x << 10u ); + x ^= ( x >> 6u ); + x += ( x << 3u ); + x ^= ( x >> 11u ); + x += ( x << 15u ); + return x; +} + +// Construct a float with half-open range [0:1] using low 23 bits. +// All zeroes yields 0.0, all ones yields the next smallest representable value below 1.0. +float floatConstruct( uint m ) { + const uint ieeeMantissa = 0x007FFFFFu; // binary32 mantissa bitmask + const uint ieeeOne = 0x3F800000u; // 1.0 in IEEE binary32 + + m &= ieeeMantissa; // Keep only mantissa bits (fractional part) + m |= ieeeOne; // Add fractional part to 1.0 + + float f = uintBitsToFloat(m); // Range [1:2] + return f - 1.0; // Range [0:1] +} + +float random() { + state = hash(state); + + return floatConstruct(state); +} \ No newline at end of file diff --git a/src/shader/pathtracing/raytracing/camera.glsl b/src/shader/pathtracing/raytracing/camera.glsl new file mode 100644 index 0000000..72a1fad --- /dev/null +++ b/src/shader/pathtracing/raytracing/camera.glsl @@ -0,0 +1,25 @@ + +layout(set = 0, binding = 2) uniform Camera { + vec3 front; + vec3 left; + vec3 up; + + vec3 position; + + // camera fov in degrees + float fov; +} camera; + +Ray construct_camera_ray_pinhole(in vec2 uv) { + Ray camera_ray; + + float fov_fac = tan(camera.fov / 180.0 * 3.1412535 * 0.5); + + camera_ray.origin = camera.position; + camera_ray.direction = normalize(camera.front / fov_fac + camera.left * uv.x + camera.up * uv.y); + + camera_ray.near = 1e-3; + camera_ray.far = 1e3; + + return camera_ray; +} \ No newline at end of file diff --git a/src/shader/pathtracing/raytracing/raytracing.glsl b/src/shader/pathtracing/raytracing/raytracing.glsl new file mode 100644 index 0000000..9b6fcb2 --- /dev/null +++ b/src/shader/pathtracing/raytracing/raytracing.glsl @@ -0,0 +1,50 @@ + +struct Ray { + vec3 direction; + vec3 origin; + + float near; + float far; +}; + +layout(set = 0, binding = 3) buffer VertexBuffer { + vec3 vertices[]; +}; + +layout(set = 0, binding = 4) buffer IndexBuffer { + uint indices[]; +}; + +vec3 intersect_triangle(in Ray ray, in vec3 v0, in vec3 v1, in vec3 v2) { + vec3 v1v0 = v1 - v0; + vec3 v2v0 = v2 - v0; + vec3 rov0 = ray.origin - v0; + vec3 n = cross(v1v0, v2v0); + vec3 q = cross(rov0, ray.direction); + float d = 1.0 / dot(ray.direction, n); + float u = d * dot( -q, v2v0); + float v = d * dot( q, v1v0); + float t = d * dot( -n, rov0); + + t = min(u, min(v, min(1.0 - (u + v), t))); + + return vec3( t, u, v ); +} + +vec4 intersect_scene(in Ray ray) { + vec4 hit = vec4(ray.far, -1, -1, 0); + + for (int i = 0; i < indices.length(); i += 3) { + vec3 v0 = vertices[indices[i]]; + vec3 v1 = vertices[indices[i + 1]]; + vec3 v2 = vertices[indices[i + 2]]; + + vec3 result = intersect_triangle(ray, v0, v1, v2); + + if (result.x > ray.near && result.x < hit.x) { + hit = vec4(result, 1); + } + } + + return hit; +} \ No newline at end of file diff --git a/src/shader/src/pathtracing/camera.glsl b/src/shader/src/pathtracing/camera.glsl deleted file mode 100644 index e8586e4..0000000 --- a/src/shader/src/pathtracing/camera.glsl +++ /dev/null @@ -1,22 +0,0 @@ - -layout(push_constant) uniform Camera { - vec3 position; - vec3 front; - vec3 up; - vec3 left; - float fov; -} camera; - -vec3 generate_view_ray_direction(in vec2 uv) { - // convert camera fov from degrees to relative factor for scaling normalized front vector - float fov = 1.0 / tan(DegreeToRadians(camera.fov) * 0.5); - - return normalize(camera.front * fov + camera.up * uv.x + camera.left * uv.y); -} - -Ray generate_view_ray(in vec2 uv) { - Ray view_ray; - view_ray.origin = camera.position; - view_ray.direction = generate_view_ray_direction(uv); - return view_ray; -} \ No newline at end of file diff --git a/src/shader/src/pathtracing/common.glsl b/src/shader/src/pathtracing/common.glsl deleted file mode 100644 index c43bd32..0000000 --- a/src/shader/src/pathtracing/common.glsl +++ /dev/null @@ -1,7 +0,0 @@ - -#define DegreeToRadians(x) (x * 0.01745329251994330) - -struct Ray { - vec3 origin; - vec3 direction; -}; \ No newline at end of file diff --git a/src/shader/src/pathtracing/pathtracer.glsl b/src/shader/src/pathtracing/pathtracer.glsl deleted file mode 100644 index 4233c82..0000000 --- a/src/shader/src/pathtracing/pathtracer.glsl +++ /dev/null @@ -1,9 +0,0 @@ - -#include -#include - -vec3 trace_path(in vec2 uv) { - Ray view_ray = generate_view_ray(uv); - - return view_ray.direction; -} \ No newline at end of file diff --git a/src/vulkan/device.rs b/src/vulkan/device.rs new file mode 100644 index 0000000..61d234f --- /dev/null +++ b/src/vulkan/device.rs @@ -0,0 +1,133 @@ +use std::sync::Arc; +use vulkano::device::{Device, DeviceCreateInfo, Queue, QueueCreateInfo, QueueFlags, Properties, DeviceExtensions}; +use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType}; +use vulkano::instance::Instance; +use vulkano::swapchain::Surface; + +/// Choose the device to render on. +/// This function will favor certain devices over others in the following descending order: +/// * discrete GPU +/// * integrated GPU +/// * virtual GPU +/// * CPU +/// * others... +pub(crate) fn get_device(instance: &Arc, surface: &Arc) -> (Arc, impl ExactSizeIterator> + Sized) { + // Choose device extensions that we're going to use. In order to present images to a surface, + // we need a `Swapchain`, which is provided by the `khr_swapchain` extension. + let device_extensions = DeviceExtensions { + khr_swapchain: true, + ..DeviceExtensions::empty() + }; + + let (physical_device, queue_family_index) = choose_physical_device(&instance, &surface, device_extensions); + + print_physical_device_info(physical_device.properties()); + + // Now initializing the device. This is probably the most important object of Vulkan. + // + // An iterator of created queues is returned by the function alongside the device. + Device::new( + // Which physical device to connect to. + physical_device, + DeviceCreateInfo { + // A list of optional features and extensions that our program needs to work correctly. + // Some parts of the Vulkan specs are optional and must be enabled manually at device + // creation. In this example the only thing we are going to need is the `khr_swapchain` + // extension that allows us to draw to a window. + enabled_extensions: device_extensions, + + // The list of queues that we are going to use. Here we only use one queue, from the + // previously chosen queue family. + queue_create_infos: vec![QueueCreateInfo { + queue_family_index, + ..Default::default() + }], + + ..Default::default() + }, + ).unwrap() +} + +/// Choose the actual physical device to render on. +/// This function will favor certain devices over others in the following descending order: +/// * discrete GPU +/// * integrated GPU +/// * virtual GPU +/// * CPU +/// * others... +fn choose_physical_device(instance: &Arc, surface: &Arc, device_extensions: DeviceExtensions) -> (Arc, u32) { + // We then choose which physical device to use. First, we enumerate all the available physical + // devices, then apply filters to narrow them down to those that can support our needs. + instance + .enumerate_physical_devices() + .unwrap() + .filter(|p| { + // Some devices may not support the extensions or features that your application, or + // report properties and limits that are not sufficient for your application. These + // should be filtered out here. + p.supported_extensions().contains(&device_extensions) + }) + .filter_map(|p| { + // For each physical device, we try to find a suitable queue family that will execute + // our draw commands. + // + // Devices can provide multiple queues to run commands in parallel (for example a draw + // queue and a compute queue), similar to CPU threads. This is something you have to + // have to manage manually in Vulkan. Queues of the same type belong to the same queue + // family. + // + // Here, we look for a single queue family that is suitable for our purposes. In a + // real-world application, you may want to use a separate dedicated transfer queue to + // handle data transfers in parallel with graphics operations. You may also need a + // separate queue for compute operations, if your application uses those. + p.queue_family_properties() + .iter() + .enumerate() + .position(|(i, q)| { + // We select a queue family that supports graphics operations. When drawing to + // a window surface, as we do in this example, we also need to check that + // queues in this queue family are capable of presenting images to the surface. + q.queue_flags.intersects(QueueFlags::GRAPHICS) + && p.surface_support(i as u32, &surface).unwrap_or(false) + }) + // The code here searches for the first queue family that is suitable. If none is + // found, `None` is returned to `filter_map`, which disqualifies this physical + // device. + .map(|i| (p, i as u32)) + }) + // All the physical devices that pass the filters above are suitable for the application. + // However, not every device is equal, some are preferred over others. Now, we assign each + // physical device a score, and pick the device with the lowest ("best") score. + // + // In this example, we simply select the best-scoring device to use in the application. + // In a real-world setting, you may want to use the best-scoring device only as a "default" + // or "recommended" device, and let the user choose the device themself. + .min_by_key(|(p, _)| { + // We assign a lower score to device types that are likely to be faster/better. + match p.properties().device_type { + PhysicalDeviceType::DiscreteGpu => 0, + PhysicalDeviceType::IntegratedGpu => 1, + PhysicalDeviceType::VirtualGpu => 2, + PhysicalDeviceType::Cpu => 3, + PhysicalDeviceType::Other => 4, + _ => 5, + } + }) + .expect("no suitable physical device found") +} + +fn print_physical_device_info(device_properties: &Properties) { + println!("name: {}", device_properties.device_name); + + print_device_driver_info(device_properties); +} + +fn print_device_driver_info(device_properties: &Properties) { + let default_name = String::from(""); + let name = device_properties.driver_name.as_ref().unwrap_or(&default_name); + + let default_info = String::from(""); + let info = device_properties.driver_info.as_ref().unwrap_or(&default_info); + + println!("driver:\n\tname: {}\n\tversion: {}\n\tinfo: {}\n", name, device_properties.driver_version, info); +} \ No newline at end of file diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 9a1c2d2..0058828 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -1,62 +1,30 @@ +mod device; +pub(crate) mod textured_quad; use std::sync::Arc; -use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, Properties, Queue, QueueCreateInfo, QueueFlags}; -use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType}; +use vulkano::device::{Device}; use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage}; use vulkano::instance::{Instance, InstanceCreateInfo}; -use vulkano::memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}; +use vulkano::memory::allocator::{StandardMemoryAllocator}; use vulkano::swapchain::{acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo, SwapchainCreationError, SwapchainPresentInfo}; use vulkano::{sync, VulkanLibrary}; use vulkano_win::VkSurfaceBuild; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::{Window, WindowBuilder}; -use vulkano::buffer::{Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer}; use vulkano::command_buffer::allocator::StandardCommandBufferAllocator; -use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents}; +use vulkano::descriptor_set::allocator::{StandardDescriptorSetAllocator}; use vulkano::image::view::ImageView; -use vulkano::pipeline::graphics::vertex_input::Vertex; use vulkano::pipeline::graphics::viewport::Viewport; use vulkano::render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass}; use vulkano::sync::{FlushError, GpuFuture}; use winit::event::{Event, WindowEvent}; +use crate::shader::composite::TextureDrawPipeline; +use crate::shader::pathtracing::PathtracerPipeline; -// We now create a buffer that will store the shape of our triangle. We use `#[repr(C)]` here -// to force rustc to use a defined layout for our data, as the default representation has *no -// guarantees*. -#[derive(BufferContents, Vertex)] -#[repr(C)] -pub(crate) struct Vertex2d { - #[format(R32G32_SFLOAT)] - position: [f32; 2], - #[format(R32G32_SFLOAT)] - texture: [f32; 2] -} - -fn textured_quad() -> (Vec, Vec) { - ( - vec![ - Vertex2d { - position: [-1.0, -1.0], - texture: [0.0, 0.0] - }, - Vertex2d { - position: [1.0, -1.0], - texture: [1.0, 0.0] - }, - Vertex2d { - position: [1.0, 1.0], - texture: [1.0, 1.0] - }, - Vertex2d { - position: [-1.0, 1.0], - texture: [0.0, 1.0] - } - ], - vec![ - 0, 1, 2, - 0, 2, 3 - ] - ) +pub struct Renderer { + pub(crate) memory_allocator: Arc, + pub(crate) command_buffer_allocator: Arc, + pub(crate) descriptor_set_allocator: Arc } pub fn init() { @@ -91,7 +59,7 @@ pub fn init() { .build_vk_surface(&event_loop, instance.clone()) .unwrap(); - let (device, mut queues) = get_device(&instance, &surface); + let (device, mut queues) = device::get_device(&instance, &surface); // Since we can request multiple queues, the `queues` variable is in fact an iterator. We only // use one queue in this example, so we just retrieve the first and only element of the @@ -100,9 +68,7 @@ pub fn init() { let (mut swapchain, images) = create_swapchain(&device, &surface); - let memory_allocator = StandardMemoryAllocator::new_default(device.clone()); - - let (vertex_buffer, index_buffer) = create_quad_buffer(&memory_allocator); + let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); // At this point, OpenGL initialization would be finished. However in Vulkan it is not. OpenGL // implicitly does a lot of computation whenever you draw. In Vulkan, you have to do all this @@ -129,7 +95,17 @@ pub fn init() { // them. Vulkano provides a command buffer allocator, which manages raw Vulkan command pools // underneath and provides a safe interface for them. let command_buffer_allocator = - StandardCommandBufferAllocator::new(device.clone(), Default::default()); + Arc::new(StandardCommandBufferAllocator::new(device.clone(), Default::default())); + + let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new( + device.clone(), + )); + + let renderer = Renderer { + memory_allocator, + command_buffer_allocator, + descriptor_set_allocator + }; // Initialization is finally finished! @@ -152,7 +128,10 @@ pub fn init() { // that, we store the submission of the previous frame here. let mut previous_frame_end = Some(sync::now(device.clone()).boxed()); - let pipeline = crate::shader::create_program(&render_pass, &device); + let texture_drawer = TextureDrawPipeline::new(&renderer, &queue, &render_pass); + let mut pathtracer = PathtracerPipeline::new(&renderer, &queue, [512, 512]); + + let mut now_keys = [false; 255]; event_loop.run(move |event, _, control_flow| { match event { @@ -167,7 +146,31 @@ pub fn init() { .. } => { recreate_swapchain = true; - } + }, + Event::WindowEvent { + // Note this deeply nested pattern match + event: WindowEvent::KeyboardInput { + input:winit::event::KeyboardInput { + // Which serves to filter out only events we actually want + virtual_keycode:Some(keycode), + state, + .. + }, + .. + }, + .. + } => { + // It also binds these handy variable names! + match state { + winit::event::ElementState::Pressed => { + // VirtualKeycode is an enum with a defined representation + now_keys[keycode as usize] = true; + }, + winit::event::ElementState::Released => { + now_keys[keycode as usize] = false; + } + } + }, Event::RedrawEventsCleared => { // Do not draw the frame when the screen dimensions are zero. On Windows, this can // occur when minimizing the application. @@ -240,59 +243,9 @@ pub fn init() { recreate_swapchain = true; } - // In order to draw, we have to build a *command buffer*. The command buffer object - // holds the list of commands that are going to be executed. - // - // Building a command buffer is an expensive operation (usually a few hundred - // microseconds), but it is known to be a hot path in the driver and is expected to - // be optimized. - // - // Note that we have to pass a queue family when we create the command buffer. The - // command buffer will only be executable on that given queue family. - let mut builder = AutoCommandBufferBuilder::primary( - &command_buffer_allocator, - queue.queue_family_index(), - CommandBufferUsage::OneTimeSubmit, - ) - .unwrap(); + pathtracer.compute(); - builder - // Before we can draw, we have to *enter a render pass*. - .begin_render_pass( - RenderPassBeginInfo { - // A list of values to clear the attachments with. This list contains - // one item for each attachment in the render pass. In this case, there - // is only one attachment, and we clear it with a blue color. - // - // Only attachments that have `LoadOp::Clear` are provided with clear - // values, any others should use `ClearValue::None` as the clear value. - clear_values: vec![Some([0.0, 0.0, 1.0, 1.0].into())], - - ..RenderPassBeginInfo::framebuffer( - framebuffers[image_index as usize].clone(), - ) - }, - // The contents of the first (and only) subpass. This can be either - // `Inline` or `SecondaryCommandBuffers`. The latter is a bit more advanced - // and is not covered here. - SubpassContents::Inline, - ) - .unwrap() - // We are now inside the first subpass of the render pass. - .set_viewport(0, [viewport.clone()]) - .bind_pipeline_graphics(pipeline.clone()) - .bind_vertex_buffers(0, vertex_buffer.clone()) - .bind_index_buffer(index_buffer.clone()) - // We add a draw command. - .draw_indexed(index_buffer.len() as u32, 1, 0, 0, 0) - .unwrap() - // We leave the render pass. Note that if we had multiple subpasses we could - // have called `next_subpass` to jump to the next subpass. - .end_render_pass() - .unwrap(); - - // Finish building the command buffer by calling `build`. - let command_buffer = builder.build().unwrap(); + let command_buffer = texture_drawer.draw(framebuffers[image_index as usize].clone(), &viewport, &pathtracer); let future = previous_frame_end .take() @@ -333,38 +286,6 @@ pub fn init() { }); } -fn create_quad_buffer(memory_allocator: &StandardMemoryAllocator) -> (Subbuffer<[Vertex2d]>, Subbuffer<[u32]>) { - let (vertices, indices) = textured_quad(); - - let vertex_buffer = Buffer::from_iter( - memory_allocator, - BufferCreateInfo { - usage: BufferUsage::VERTEX_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - usage: MemoryUsage::Upload, - ..Default::default() - }, - vertices, - ).unwrap(); - - let index_buffer = Buffer::from_iter( - memory_allocator, - BufferCreateInfo { - usage: BufferUsage::INDEX_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - usage: MemoryUsage::Upload, - ..Default::default() - }, - indices, - ).unwrap(); - - (vertex_buffer, index_buffer) -} - /// This function is called once during initialization, then again whenever the window is resized. fn window_size_dependent_setup( images: &[Arc], @@ -386,45 +307,7 @@ fn window_size_dependent_setup( }, ) .unwrap() - }) - .collect::>() -} - -fn get_device(instance: &Arc, surface: &Arc) -> (Arc, impl ExactSizeIterator> + Sized) { - // Choose device extensions that we're going to use. In order to present images to a surface, - // we need a `Swapchain`, which is provided by the `khr_swapchain` extension. - let device_extensions = DeviceExtensions { - khr_swapchain: true, - ..DeviceExtensions::empty() - }; - - let (physical_device, queue_family_index) = choose_physical_device(&instance, &surface, device_extensions); - - print_physical_device_info(physical_device.properties()); - - // Now initializing the device. This is probably the most important object of Vulkan. - // - // An iterator of created queues is returned by the function alongside the device. - Device::new( - // Which physical device to connect to. - physical_device, - DeviceCreateInfo { - // A list of optional features and extensions that our program needs to work correctly. - // Some parts of the Vulkan specs are optional and must be enabled manually at device - // creation. In this example the only thing we are going to need is the `khr_swapchain` - // extension that allows us to draw to a window. - enabled_extensions: device_extensions, - - // The list of queues that we are going to use. Here we only use one queue, from the - // previously chosen queue family. - queue_create_infos: vec![QueueCreateInfo { - queue_family_index, - ..Default::default() - }], - - ..Default::default() - }, - ).unwrap() + }).collect::>() } fn create_render_pass(device: &Arc, swapchain: &Arc) -> Arc { @@ -463,67 +346,6 @@ fn create_render_pass(device: &Arc, swapchain: &Arc) -> Arc, surface: &Arc, device_extensions: DeviceExtensions) -> (Arc, u32) { - // We then choose which physical device to use. First, we enumerate all the available physical - // devices, then apply filters to narrow them down to those that can support our needs. - instance - .enumerate_physical_devices() - .unwrap() - .filter(|p| { - // Some devices may not support the extensions or features that your application, or - // report properties and limits that are not sufficient for your application. These - // should be filtered out here. - p.supported_extensions().contains(&device_extensions) - }) - .filter_map(|p| { - // For each physical device, we try to find a suitable queue family that will execute - // our draw commands. - // - // Devices can provide multiple queues to run commands in parallel (for example a draw - // queue and a compute queue), similar to CPU threads. This is something you have to - // have to manage manually in Vulkan. Queues of the same type belong to the same queue - // family. - // - // Here, we look for a single queue family that is suitable for our purposes. In a - // real-world application, you may want to use a separate dedicated transfer queue to - // handle data transfers in parallel with graphics operations. You may also need a - // separate queue for compute operations, if your application uses those. - p.queue_family_properties() - .iter() - .enumerate() - .position(|(i, q)| { - // We select a queue family that supports graphics operations. When drawing to - // a window surface, as we do in this example, we also need to check that - // queues in this queue family are capable of presenting images to the surface. - q.queue_flags.intersects(QueueFlags::GRAPHICS) - && p.surface_support(i as u32, &surface).unwrap_or(false) - }) - // The code here searches for the first queue family that is suitable. If none is - // found, `None` is returned to `filter_map`, which disqualifies this physical - // device. - .map(|i| (p, i as u32)) - }) - // All the physical devices that pass the filters above are suitable for the application. - // However, not every device is equal, some are preferred over others. Now, we assign each - // physical device a score, and pick the device with the lowest ("best") score. - // - // In this example, we simply select the best-scoring device to use in the application. - // In a real-world setting, you may want to use the best-scoring device only as a "default" - // or "recommended" device, and let the user choose the device themself. - .min_by_key(|(p, _)| { - // We assign a lower score to device types that are likely to be faster/better. - match p.properties().device_type { - PhysicalDeviceType::DiscreteGpu => 0, - PhysicalDeviceType::IntegratedGpu => 1, - PhysicalDeviceType::VirtualGpu => 2, - PhysicalDeviceType::Cpu => 3, - PhysicalDeviceType::Other => 4, - _ => 5, - } - }) - .expect("no suitable physical device found") -} - fn create_swapchain(device: &Arc, surface: &Arc) -> (Arc, Vec>) { // Before we can draw on the surface, we have to create what is called a swapchain. Creating a // swapchain allocates the color buffers that will contain the image that will ultimately be @@ -583,19 +405,3 @@ fn create_swapchain(device: &Arc, surface: &Arc) -> (Arc"); - let name = device_properties.driver_name.as_ref().unwrap_or(&default_name); - - let default_info = String::from(""); - let info = device_properties.driver_info.as_ref().unwrap_or(&default_info); - - println!("driver:\n\tname: {}\n\tversion: {}\n\tinfo: {}\n", name, device_properties.driver_version, info); -} \ No newline at end of file diff --git a/src/vulkan/textured_quad.rs b/src/vulkan/textured_quad.rs new file mode 100644 index 0000000..4a4f1a7 --- /dev/null +++ b/src/vulkan/textured_quad.rs @@ -0,0 +1,82 @@ + +/// This crate will utilize a textured quad to draw a texture onto a surface + +use vulkano::buffer::{Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer}; +use vulkano::memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}; +use vulkano::pipeline::graphics::vertex_input::Vertex; + +// We now create a buffer that will store the shape of our triangle. We use `#[repr(C)]` here +// to force rustc to use a defined layout for our data, as the default representation has *no +// guarantees*. +#[derive(BufferContents, Vertex)] +#[repr(C)] +pub struct TexturedVertex { + // vertex coordinates in object space + // in this case also equals to view space + #[format(R32G32_SFLOAT)] + position: [f32; 2], + // uv coordinates per vertex + #[format(R32G32_SFLOAT)] + texture: [f32; 2] +} + +fn textured_quad() -> (Vec, Vec) { + ( + // vertex list + vec![ + TexturedVertex { + position: [-1.0, -1.0], + texture: [0.0, 0.0] + }, + TexturedVertex { + position: [1.0, -1.0], + texture: [1.0, 0.0] + }, + TexturedVertex { + position: [1.0, 1.0], + texture: [1.0, 1.0] + }, + TexturedVertex { + position: [-1.0, 1.0], + texture: [0.0, 1.0] + } + ], + // indices list + vec![ + 0, 1, 2, + 0, 2, 3 + ] + ) +} + +pub fn create_quad_buffer(memory_allocator: &StandardMemoryAllocator) -> (Subbuffer<[TexturedVertex]>, Subbuffer<[u32]>) { + let (vertices, indices) = textured_quad(); + + let vertex_buffer = Buffer::from_iter( + memory_allocator, + BufferCreateInfo { + usage: BufferUsage::VERTEX_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + usage: MemoryUsage::Upload, + ..Default::default() + }, + vertices, + ).unwrap(); + + let index_buffer = Buffer::from_iter( + memory_allocator, + BufferCreateInfo { + usage: BufferUsage::INDEX_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + usage: MemoryUsage::Upload, + ..Default::default() + }, + indices, + ).unwrap(); + + (vertex_buffer, index_buffer) +}