snappy 3.1.1__cp39-cp39-macosx_11_0_arm64.whl → 3.2__cp39-cp39-macosx_11_0_arm64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (464) hide show
  1. snappy/CyOpenGL.cpython-39-darwin.so +0 -0
  2. snappy/SnapPy.cpython-39-darwin.so +0 -0
  3. snappy/SnapPyHP.cpython-39-darwin.so +0 -0
  4. snappy/__init__.py +299 -402
  5. snappy/app.py +70 -20
  6. snappy/browser.py +18 -17
  7. snappy/canonical.py +249 -0
  8. snappy/{verify/cusp_shapes.py → cusps/__init__.py} +8 -18
  9. snappy/cusps/cusp_area_matrix.py +101 -0
  10. snappy/{verify/cusp_areas.py → cusps/cusp_areas_from_matrix.py} +23 -39
  11. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  12. snappy/cusps/test.py +21 -0
  13. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  14. snappy/database.py +10 -9
  15. snappy/decorated_isosig.py +337 -114
  16. snappy/dev/extended_ptolemy/complexVolumesClosed.py +40 -7
  17. snappy/dev/extended_ptolemy/extended.py +3 -3
  18. snappy/dev/extended_ptolemy/phc_wrapper.py +10 -10
  19. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +1 -1
  20. snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
  21. snappy/doc/_images/m125_paper_plane.jpg +0 -0
  22. snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
  23. snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
  24. snappy/doc/_sources/development.rst.txt +66 -46
  25. snappy/doc/_sources/index.rst.txt +72 -5
  26. snappy/doc/_sources/installing.rst.txt +145 -162
  27. snappy/doc/_sources/news.rst.txt +73 -1
  28. snappy/doc/_sources/ptolemy_examples1.rst.txt +8 -7
  29. snappy/doc/_sources/ptolemy_examples3.rst.txt +2 -2
  30. snappy/doc/_sources/triangulation.rst.txt +2 -2
  31. snappy/doc/_sources/verify.rst.txt +89 -29
  32. snappy/doc/_sources/verify_internals.rst.txt +5 -16
  33. snappy/doc/_static/basic.css +23 -1
  34. snappy/doc/_static/css/badge_only.css +1 -1
  35. snappy/doc/_static/css/theme.css +1 -1
  36. snappy/doc/_static/doctools.js +1 -1
  37. snappy/doc/_static/documentation_options.js +2 -3
  38. snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
  39. snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
  40. snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
  41. snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
  42. snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  43. snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  44. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  45. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  46. snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
  47. snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
  48. snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
  49. snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
  50. snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
  51. snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
  52. snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
  53. snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
  54. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  55. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  56. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  57. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  58. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  59. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  60. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  61. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  62. snappy/doc/_static/js/versions.js +228 -0
  63. snappy/doc/_static/language_data.js +2 -2
  64. snappy/doc/_static/pygments.css +1 -0
  65. snappy/doc/_static/searchtools.js +125 -71
  66. snappy/doc/_static/sphinx_highlight.js +13 -3
  67. snappy/doc/additional_classes.html +291 -122
  68. snappy/doc/bugs.html +17 -20
  69. snappy/doc/censuses.html +34 -53
  70. snappy/doc/credits.html +18 -21
  71. snappy/doc/development.html +88 -68
  72. snappy/doc/genindex.html +66 -145
  73. snappy/doc/index.html +86 -31
  74. snappy/doc/installing.html +164 -182
  75. snappy/doc/manifold.html +1168 -556
  76. snappy/doc/manifoldhp.html +18 -21
  77. snappy/doc/news.html +91 -33
  78. snappy/doc/objects.inv +0 -0
  79. snappy/doc/other.html +20 -22
  80. snappy/doc/platonic_census.html +31 -34
  81. snappy/doc/plink.html +19 -22
  82. snappy/doc/ptolemy.html +20 -22
  83. snappy/doc/ptolemy_classes.html +102 -105
  84. snappy/doc/ptolemy_examples1.html +34 -36
  85. snappy/doc/ptolemy_examples2.html +28 -31
  86. snappy/doc/ptolemy_examples3.html +26 -29
  87. snappy/doc/ptolemy_examples4.html +20 -23
  88. snappy/doc/ptolemy_prelim.html +25 -28
  89. snappy/doc/py-modindex.html +16 -19
  90. snappy/doc/screenshots.html +22 -24
  91. snappy/doc/search.html +15 -18
  92. snappy/doc/searchindex.js +1 -1
  93. snappy/doc/snap.html +18 -21
  94. snappy/doc/snappy.html +18 -20
  95. snappy/doc/spherogram.html +84 -87
  96. snappy/doc/todo.html +17 -20
  97. snappy/doc/triangulation.html +324 -215
  98. snappy/doc/tutorial.html +17 -20
  99. snappy/doc/verify.html +100 -46
  100. snappy/doc/verify_internals.html +106 -563
  101. snappy/drilling/__init__.py +153 -235
  102. snappy/drilling/barycentric.py +103 -0
  103. snappy/drilling/constants.py +0 -2
  104. snappy/drilling/crush.py +56 -130
  105. snappy/drilling/cusps.py +12 -6
  106. snappy/drilling/debug.py +2 -1
  107. snappy/drilling/exceptions.py +7 -40
  108. snappy/drilling/moves.py +302 -243
  109. snappy/drilling/perturb.py +63 -37
  110. snappy/drilling/shorten.py +36 -0
  111. snappy/drilling/subdivide.py +0 -5
  112. snappy/drilling/test.py +23 -0
  113. snappy/drilling/test_cases.py +126 -0
  114. snappy/drilling/tracing.py +9 -37
  115. snappy/exceptions.py +18 -5
  116. snappy/exterior_to_link/barycentric_geometry.py +2 -4
  117. snappy/exterior_to_link/main.py +8 -7
  118. snappy/exterior_to_link/mcomplex_with_link.py +2 -2
  119. snappy/exterior_to_link/rational_linear_algebra.py +1 -1
  120. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +1 -1
  121. snappy/exterior_to_link/test.py +21 -33
  122. snappy/geometric_structure/__init__.py +212 -0
  123. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  124. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +697 -0
  125. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +484 -0
  126. snappy/geometric_structure/cusp_neighborhood/exceptions.py +42 -0
  127. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +298 -0
  128. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +159 -0
  129. snappy/geometric_structure/cusp_neighborhood/vertices.py +32 -0
  130. snappy/geometric_structure/geodesic/__init__.py +0 -0
  131. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  132. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  133. snappy/geometric_structure/geodesic/canonical_keys.py +52 -0
  134. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  135. snappy/geometric_structure/geodesic/constants.py +6 -0
  136. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  137. snappy/{drilling → geometric_structure/geodesic}/fixed_points.py +34 -9
  138. snappy/{drilling/geodesic_info.py → geometric_structure/geodesic/geodesic_start_point_info.py} +139 -180
  139. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  140. snappy/geometric_structure/geodesic/line.py +30 -0
  141. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  142. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +101 -0
  143. snappy/geometric_structure/test.py +22 -0
  144. snappy/gui.py +23 -13
  145. snappy/horoviewer.py +7 -7
  146. snappy/hyperboloid/__init__.py +96 -31
  147. snappy/hyperboloid/distances.py +245 -0
  148. snappy/hyperboloid/horoball.py +19 -0
  149. snappy/hyperboloid/line.py +35 -0
  150. snappy/hyperboloid/point.py +9 -0
  151. snappy/hyperboloid/triangle.py +29 -0
  152. snappy/isometry_signature.py +382 -0
  153. snappy/len_spec/__init__.py +596 -0
  154. snappy/len_spec/geodesic_info.py +110 -0
  155. snappy/len_spec/geodesic_key_info_dict.py +117 -0
  156. snappy/len_spec/geodesic_piece.py +143 -0
  157. snappy/len_spec/geometric_structure.py +182 -0
  158. snappy/len_spec/geometry.py +80 -0
  159. snappy/len_spec/length_spectrum_geodesic_info.py +170 -0
  160. snappy/len_spec/spine.py +206 -0
  161. snappy/len_spec/test.py +24 -0
  162. snappy/len_spec/test_cases.py +69 -0
  163. snappy/len_spec/tile.py +275 -0
  164. snappy/len_spec/word.py +86 -0
  165. snappy/math_basics.py +39 -13
  166. snappy/matrix.py +52 -9
  167. snappy/number.py +12 -6
  168. snappy/numeric_output_checker.py +2 -3
  169. snappy/pari.py +8 -4
  170. snappy/phone_home.py +2 -1
  171. snappy/polyviewer.py +8 -8
  172. snappy/ptolemy/__init__.py +1 -1
  173. snappy/ptolemy/component.py +2 -2
  174. snappy/ptolemy/coordinates.py +25 -25
  175. snappy/ptolemy/findLoops.py +9 -9
  176. snappy/ptolemy/manifoldMethods.py +27 -29
  177. snappy/ptolemy/polynomial.py +50 -57
  178. snappy/ptolemy/processFileBase.py +60 -0
  179. snappy/ptolemy/ptolemyVariety.py +109 -41
  180. snappy/ptolemy/reginaWrapper.py +4 -4
  181. snappy/ptolemy/rur.py +1 -1
  182. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +9 -9
  183. snappy/ptolemy/test.py +99 -54
  184. snappy/ptolemy/utilities.py +1 -1
  185. snappy/raytracing/__init__.py +64 -0
  186. snappy/raytracing/additional_horospheres.py +64 -0
  187. snappy/raytracing/additional_len_spec_choices.py +63 -0
  188. snappy/raytracing/cohomology_fractal.py +0 -3
  189. snappy/raytracing/eyeball.py +123 -0
  190. snappy/raytracing/finite_raytracing_data.py +17 -17
  191. snappy/raytracing/finite_viewer.py +15 -15
  192. snappy/raytracing/geodesic_tube_info.py +93 -63
  193. snappy/raytracing/geodesics.py +94 -64
  194. snappy/raytracing/geodesics_window.py +56 -34
  195. snappy/raytracing/gui_utilities.py +21 -6
  196. snappy/raytracing/hyperboloid_navigation.py +29 -4
  197. snappy/raytracing/hyperboloid_utilities.py +73 -73
  198. snappy/raytracing/ideal_raytracing_data.py +121 -91
  199. snappy/raytracing/inside_viewer.py +199 -66
  200. snappy/raytracing/pack.py +22 -0
  201. snappy/raytracing/raytracing_data.py +37 -25
  202. snappy/raytracing/raytracing_view.py +70 -65
  203. snappy/raytracing/shaders/Eye.png +0 -0
  204. snappy/raytracing/shaders/NonGeometric.png +0 -0
  205. snappy/raytracing/shaders/__init__.py +39 -3
  206. snappy/raytracing/shaders/fragment.glsl +451 -133
  207. snappy/raytracing/test.py +29 -0
  208. snappy/raytracing/tooltip.py +146 -0
  209. snappy/raytracing/upper_halfspace_utilities.py +42 -9
  210. snappy/sage_helper.py +67 -134
  211. snappy/settings.py +90 -77
  212. snappy/shell.py +2 -0
  213. snappy/snap/character_varieties.py +2 -2
  214. snappy/snap/find_field.py +4 -3
  215. snappy/snap/fundamental_polyhedron.py +2 -2
  216. snappy/snap/kernel_structures.py +5 -1
  217. snappy/snap/nsagetools.py +9 -8
  218. snappy/snap/peripheral/dual_cellulation.py +4 -3
  219. snappy/snap/peripheral/peripheral.py +2 -2
  220. snappy/snap/peripheral/surface.py +5 -5
  221. snappy/snap/peripheral/test.py +1 -1
  222. snappy/snap/polished_reps.py +8 -8
  223. snappy/snap/slice_obs_HKL.py +16 -14
  224. snappy/snap/t3mlite/arrow.py +3 -3
  225. snappy/snap/t3mlite/edge.py +3 -3
  226. snappy/snap/t3mlite/homology.py +2 -2
  227. snappy/snap/t3mlite/mcomplex.py +3 -3
  228. snappy/snap/t3mlite/simplex.py +12 -0
  229. snappy/snap/t3mlite/spun.py +18 -17
  230. snappy/snap/t3mlite/test_vs_regina.py +4 -4
  231. snappy/snap/test.py +37 -53
  232. snappy/snap/utilities.py +4 -5
  233. snappy/test.py +121 -138
  234. snappy/test_cases.py +263 -0
  235. snappy/testing.py +131 -0
  236. snappy/tiling/__init__.py +2 -0
  237. snappy/tiling/canonical_key_dict.py +59 -0
  238. snappy/tiling/dict_based_set.py +79 -0
  239. snappy/tiling/floor.py +49 -0
  240. snappy/tiling/hyperboloid_dict.py +54 -0
  241. snappy/tiling/iter_utils.py +78 -0
  242. snappy/tiling/lifted_tetrahedron.py +22 -0
  243. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  244. snappy/tiling/real_hash_dict.py +164 -0
  245. snappy/tiling/test.py +23 -0
  246. snappy/tiling/tile.py +215 -0
  247. snappy/tiling/triangle.py +33 -0
  248. snappy/tkterminal.py +113 -84
  249. snappy/twister/main.py +1 -7
  250. snappy/twister/twister_core.cpython-39-darwin.so +0 -0
  251. snappy/upper_halfspace/__init__.py +78 -17
  252. snappy/verify/__init__.py +3 -7
  253. snappy/verify/{verifyCanonical.py → canonical.py} +78 -70
  254. snappy/verify/complex_volume/adjust_torsion.py +1 -2
  255. snappy/verify/complex_volume/closed.py +13 -13
  256. snappy/verify/complex_volume/cusped.py +6 -6
  257. snappy/verify/complex_volume/extended_bloch.py +5 -8
  258. snappy/verify/{cuspTranslations.py → cusp_translations.py} +1 -1
  259. snappy/verify/edge_equations.py +80 -0
  260. snappy/verify/exceptions.py +0 -55
  261. snappy/verify/{verifyHyperbolicity.py → hyperbolicity.py} +3 -3
  262. snappy/verify/interval_newton_shapes_engine.py +7 -5
  263. snappy/verify/interval_tree.py +5 -5
  264. snappy/verify/krawczyk_shapes_engine.py +17 -18
  265. snappy/verify/maximal_cusp_area_matrix/__init__.py +7 -74
  266. snappy/verify/maximal_cusp_area_matrix/cusp_tiling_engine.py +3 -4
  267. snappy/verify/maximal_cusp_area_matrix/cusp_translate_engine.py +1 -1
  268. snappy/verify/{realAlgebra.py → real_algebra.py} +1 -1
  269. snappy/verify/shapes.py +5 -3
  270. snappy/verify/short_slopes.py +39 -41
  271. snappy/verify/{squareExtensions.py → square_extensions.py} +14 -11
  272. snappy/verify/test.py +57 -60
  273. snappy/verify/upper_halfspace/extended_matrix.py +1 -1
  274. snappy/verify/upper_halfspace/finite_point.py +3 -4
  275. snappy/verify/upper_halfspace/ideal_point.py +9 -9
  276. snappy/verify/volume.py +2 -2
  277. snappy/version.py +2 -2
  278. {snappy-3.1.1.dist-info → snappy-3.2.dist-info}/METADATA +26 -11
  279. snappy-3.2.dist-info/RECORD +503 -0
  280. {snappy-3.1.1.dist-info → snappy-3.2.dist-info}/WHEEL +1 -1
  281. {snappy-3.1.1.dist-info → snappy-3.2.dist-info}/top_level.txt +6 -1
  282. snappy/__pycache__/__init__.cpython-39.pyc +0 -0
  283. snappy/__pycache__/browser.cpython-39.pyc +0 -0
  284. snappy/__pycache__/cache.cpython-39.pyc +0 -0
  285. snappy/__pycache__/database.cpython-39.pyc +0 -0
  286. snappy/__pycache__/db_utilities.cpython-39.pyc +0 -0
  287. snappy/__pycache__/decorated_isosig.cpython-39.pyc +0 -0
  288. snappy/__pycache__/exceptions.cpython-39.pyc +0 -0
  289. snappy/__pycache__/export_stl.cpython-39.pyc +0 -0
  290. snappy/__pycache__/filedialog.cpython-39.pyc +0 -0
  291. snappy/__pycache__/gui.cpython-39.pyc +0 -0
  292. snappy/__pycache__/horoviewer.cpython-39.pyc +0 -0
  293. snappy/__pycache__/infowindow.cpython-39.pyc +0 -0
  294. snappy/__pycache__/math_basics.cpython-39.pyc +0 -0
  295. snappy/__pycache__/matrix.cpython-39.pyc +0 -0
  296. snappy/__pycache__/number.cpython-39.pyc +0 -0
  297. snappy/__pycache__/numeric_output_checker.cpython-39.pyc +0 -0
  298. snappy/__pycache__/pari.cpython-39.pyc +0 -0
  299. snappy/__pycache__/polyviewer.cpython-39.pyc +0 -0
  300. snappy/__pycache__/sage_helper.cpython-39.pyc +0 -0
  301. snappy/__pycache__/version.cpython-39.pyc +0 -0
  302. snappy/doc/_sources/verify_canon.rst.txt +0 -90
  303. snappy/doc/_static/js/html5shiv-printshiv.min.js +0 -4
  304. snappy/doc/_static/js/html5shiv.min.js +0 -4
  305. snappy/doc/verify_canon.html +0 -304
  306. snappy/drilling/__pycache__/__init__.cpython-39.pyc +0 -0
  307. snappy/drilling/__pycache__/constants.cpython-39.pyc +0 -0
  308. snappy/drilling/__pycache__/crush.cpython-39.pyc +0 -0
  309. snappy/drilling/__pycache__/cusps.cpython-39.pyc +0 -0
  310. snappy/drilling/__pycache__/debug.cpython-39.pyc +0 -0
  311. snappy/drilling/__pycache__/epsilons.cpython-39.pyc +0 -0
  312. snappy/drilling/__pycache__/exceptions.cpython-39.pyc +0 -0
  313. snappy/drilling/__pycache__/fixed_points.cpython-39.pyc +0 -0
  314. snappy/drilling/__pycache__/geodesic_info.cpython-39.pyc +0 -0
  315. snappy/drilling/__pycache__/geodesic_tube.cpython-39.pyc +0 -0
  316. snappy/drilling/__pycache__/geometric_structure.cpython-39.pyc +0 -0
  317. snappy/drilling/__pycache__/line.cpython-39.pyc +0 -0
  318. snappy/drilling/__pycache__/moves.cpython-39.pyc +0 -0
  319. snappy/drilling/__pycache__/peripheral_curves.cpython-39.pyc +0 -0
  320. snappy/drilling/__pycache__/perturb.cpython-39.pyc +0 -0
  321. snappy/drilling/__pycache__/quotient_space.cpython-39.pyc +0 -0
  322. snappy/drilling/__pycache__/spatial_dict.cpython-39.pyc +0 -0
  323. snappy/drilling/__pycache__/subdivide.cpython-39.pyc +0 -0
  324. snappy/drilling/__pycache__/tracing.cpython-39.pyc +0 -0
  325. snappy/drilling/geodesic_tube.py +0 -441
  326. snappy/drilling/geometric_structure.py +0 -366
  327. snappy/drilling/line.py +0 -122
  328. snappy/drilling/quotient_space.py +0 -94
  329. snappy/drilling/spatial_dict.py +0 -128
  330. snappy/exterior_to_link/__pycache__/__init__.cpython-39.pyc +0 -0
  331. snappy/exterior_to_link/__pycache__/barycentric_geometry.cpython-39.pyc +0 -0
  332. snappy/exterior_to_link/__pycache__/exceptions.cpython-39.pyc +0 -0
  333. snappy/exterior_to_link/__pycache__/hyp_utils.cpython-39.pyc +0 -0
  334. snappy/exterior_to_link/__pycache__/link_projection.cpython-39.pyc +0 -0
  335. snappy/exterior_to_link/__pycache__/main.cpython-39.pyc +0 -0
  336. snappy/exterior_to_link/__pycache__/mcomplex_with_expansion.cpython-39.pyc +0 -0
  337. snappy/exterior_to_link/__pycache__/mcomplex_with_link.cpython-39.pyc +0 -0
  338. snappy/exterior_to_link/__pycache__/mcomplex_with_memory.cpython-39.pyc +0 -0
  339. snappy/exterior_to_link/__pycache__/pl_utils.cpython-39.pyc +0 -0
  340. snappy/exterior_to_link/__pycache__/put_in_S3.cpython-39.pyc +0 -0
  341. snappy/exterior_to_link/__pycache__/rational_linear_algebra.cpython-39.pyc +0 -0
  342. snappy/exterior_to_link/__pycache__/simplify_to_base_tri.cpython-39.pyc +0 -0
  343. snappy/exterior_to_link/__pycache__/stored_moves.cpython-39.pyc +0 -0
  344. snappy/hyperboloid/__pycache__/__init__.cpython-39.pyc +0 -0
  345. snappy/manifolds/__pycache__/__init__.cpython-39.pyc +0 -0
  346. snappy/ptolemy/__pycache__/__init__.cpython-39.pyc +0 -0
  347. snappy/ptolemy/__pycache__/component.cpython-39.pyc +0 -0
  348. snappy/ptolemy/__pycache__/coordinates.cpython-39.pyc +0 -0
  349. snappy/ptolemy/__pycache__/fieldExtensions.cpython-39.pyc +0 -0
  350. snappy/ptolemy/__pycache__/findLoops.cpython-39.pyc +0 -0
  351. snappy/ptolemy/__pycache__/homology.cpython-39.pyc +0 -0
  352. snappy/ptolemy/__pycache__/manifoldMethods.cpython-39.pyc +0 -0
  353. snappy/ptolemy/__pycache__/matrix.cpython-39.pyc +0 -0
  354. snappy/ptolemy/__pycache__/numericalSolutionsToGroebnerBasis.cpython-39.pyc +0 -0
  355. snappy/ptolemy/__pycache__/polynomial.cpython-39.pyc +0 -0
  356. snappy/ptolemy/__pycache__/processComponents.cpython-39.pyc +0 -0
  357. snappy/ptolemy/__pycache__/processFileBase.cpython-39.pyc +0 -0
  358. snappy/ptolemy/__pycache__/processFileDispatch.cpython-39.pyc +0 -0
  359. snappy/ptolemy/__pycache__/processMagmaFile.cpython-39.pyc +0 -0
  360. snappy/ptolemy/__pycache__/processRurFile.cpython-39.pyc +0 -0
  361. snappy/ptolemy/__pycache__/ptolemyGeneralizedObstructionClass.cpython-39.pyc +0 -0
  362. snappy/ptolemy/__pycache__/ptolemyObstructionClass.cpython-39.pyc +0 -0
  363. snappy/ptolemy/__pycache__/ptolemyVariety.cpython-39.pyc +0 -0
  364. snappy/ptolemy/__pycache__/ptolemyVarietyPrimeIdealGroebnerBasis.cpython-39.pyc +0 -0
  365. snappy/ptolemy/__pycache__/rur.cpython-39.pyc +0 -0
  366. snappy/ptolemy/__pycache__/solutionsToPrimeIdealGroebnerBasis.cpython-39.pyc +0 -0
  367. snappy/ptolemy/__pycache__/utilities.cpython-39.pyc +0 -0
  368. snappy/raytracing/__pycache__/__init__.cpython-39.pyc +0 -0
  369. snappy/raytracing/__pycache__/finite_raytracing_data.cpython-39.pyc +0 -0
  370. snappy/raytracing/__pycache__/gui_utilities.cpython-39.pyc +0 -0
  371. snappy/raytracing/__pycache__/hyperboloid_navigation.cpython-39.pyc +0 -0
  372. snappy/raytracing/__pycache__/hyperboloid_utilities.cpython-39.pyc +0 -0
  373. snappy/raytracing/__pycache__/ideal_raytracing_data.cpython-39.pyc +0 -0
  374. snappy/raytracing/__pycache__/inside_viewer.cpython-39.pyc +0 -0
  375. snappy/raytracing/__pycache__/raytracing_data.cpython-39.pyc +0 -0
  376. snappy/raytracing/__pycache__/raytracing_view.cpython-39.pyc +0 -0
  377. snappy/raytracing/__pycache__/upper_halfspace_utilities.cpython-39.pyc +0 -0
  378. snappy/raytracing/__pycache__/view_scale_controller.cpython-39.pyc +0 -0
  379. snappy/raytracing/zoom_slider/__pycache__/__init__.cpython-39.pyc +0 -0
  380. snappy/snap/__pycache__/__init__.cpython-39.pyc +0 -0
  381. snappy/snap/__pycache__/character_varieties.cpython-39.pyc +0 -0
  382. snappy/snap/__pycache__/fundamental_polyhedron.cpython-39.pyc +0 -0
  383. snappy/snap/__pycache__/interval_reps.cpython-39.pyc +0 -0
  384. snappy/snap/__pycache__/kernel_structures.cpython-39.pyc +0 -0
  385. snappy/snap/__pycache__/mcomplex_base.cpython-39.pyc +0 -0
  386. snappy/snap/__pycache__/nsagetools.cpython-39.pyc +0 -0
  387. snappy/snap/__pycache__/polished_reps.cpython-39.pyc +0 -0
  388. snappy/snap/__pycache__/shapes.cpython-39.pyc +0 -0
  389. snappy/snap/__pycache__/slice_obs_HKL.cpython-39.pyc +0 -0
  390. snappy/snap/__pycache__/utilities.cpython-39.pyc +0 -0
  391. snappy/snap/peripheral/__pycache__/__init__.cpython-39.pyc +0 -0
  392. snappy/snap/peripheral/__pycache__/dual_cellulation.cpython-39.pyc +0 -0
  393. snappy/snap/peripheral/__pycache__/link.cpython-39.pyc +0 -0
  394. snappy/snap/peripheral/__pycache__/peripheral.cpython-39.pyc +0 -0
  395. snappy/snap/peripheral/__pycache__/surface.cpython-39.pyc +0 -0
  396. snappy/snap/t3mlite/__pycache__/__init__.cpython-39.pyc +0 -0
  397. snappy/snap/t3mlite/__pycache__/arrow.cpython-39.pyc +0 -0
  398. snappy/snap/t3mlite/__pycache__/corner.cpython-39.pyc +0 -0
  399. snappy/snap/t3mlite/__pycache__/edge.cpython-39.pyc +0 -0
  400. snappy/snap/t3mlite/__pycache__/face.cpython-39.pyc +0 -0
  401. snappy/snap/t3mlite/__pycache__/files.cpython-39.pyc +0 -0
  402. snappy/snap/t3mlite/__pycache__/homology.cpython-39.pyc +0 -0
  403. snappy/snap/t3mlite/__pycache__/linalg.cpython-39.pyc +0 -0
  404. snappy/snap/t3mlite/__pycache__/mcomplex.cpython-39.pyc +0 -0
  405. snappy/snap/t3mlite/__pycache__/perm4.cpython-39.pyc +0 -0
  406. snappy/snap/t3mlite/__pycache__/simplex.cpython-39.pyc +0 -0
  407. snappy/snap/t3mlite/__pycache__/spun.cpython-39.pyc +0 -0
  408. snappy/snap/t3mlite/__pycache__/surface.cpython-39.pyc +0 -0
  409. snappy/snap/t3mlite/__pycache__/tetrahedron.cpython-39.pyc +0 -0
  410. snappy/snap/t3mlite/__pycache__/vertex.cpython-39.pyc +0 -0
  411. snappy/togl/__init__.py +0 -3
  412. snappy/togl/darwin-tk8.6/Togl2.1/LICENSE +0 -28
  413. snappy/togl/darwin-tk8.6/Togl2.1/libTogl2.1.dylib +0 -0
  414. snappy/togl/darwin-tk8.6/Togl2.1/pkgIndex.tcl +0 -5
  415. snappy/togl/darwin-tk8.7/Togl2.1/LICENSE +0 -28
  416. snappy/togl/darwin-tk8.7/Togl2.1/libTogl2.1.dylib +0 -0
  417. snappy/togl/darwin-tk8.7/Togl2.1/pkgIndex.tcl +0 -5
  418. snappy/togl/linux2-x86_64-tk8.6/Togl2.1/LICENSE +0 -28
  419. snappy/togl/linux2-x86_64-tk8.6/Togl2.1/libTogl2.1.so +0 -0
  420. snappy/togl/linux2-x86_64-tk8.6/Togl2.1/pkgIndex.tcl +0 -5
  421. snappy/togl/win32VC-tk8.6/Togl2.1/LICENSE +0 -28
  422. snappy/togl/win32VC-tk8.6/Togl2.1/Togl21.dll +0 -0
  423. snappy/togl/win32VC-tk8.6/Togl2.1/Togl21.lib +0 -0
  424. snappy/togl/win32VC-tk8.6/Togl2.1/pkgIndex.tcl +0 -6
  425. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/LICENSE +0 -28
  426. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/Togl21.dll +0 -0
  427. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/Togl21.lib +0 -0
  428. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/pkgIndex.tcl +0 -6
  429. snappy/twister/__pycache__/__init__.cpython-39.pyc +0 -0
  430. snappy/twister/__pycache__/main.cpython-39.pyc +0 -0
  431. snappy/upper_halfspace/__pycache__/__init__.cpython-39.pyc +0 -0
  432. snappy/upper_halfspace/__pycache__/ideal_point.cpython-39.pyc +0 -0
  433. snappy/verify/__pycache__/__init__.cpython-39.pyc +0 -0
  434. snappy/verify/__pycache__/cuspCrossSection.cpython-39.pyc +0 -0
  435. snappy/verify/__pycache__/cuspTranslations.cpython-39.pyc +0 -0
  436. snappy/verify/__pycache__/cusp_areas.cpython-39.pyc +0 -0
  437. snappy/verify/__pycache__/cusp_shapes.cpython-39.pyc +0 -0
  438. snappy/verify/__pycache__/exceptions.cpython-39.pyc +0 -0
  439. snappy/verify/__pycache__/interval_newton_shapes_engine.cpython-39.pyc +0 -0
  440. snappy/verify/__pycache__/interval_tree.cpython-39.pyc +0 -0
  441. snappy/verify/__pycache__/krawczyk_shapes_engine.cpython-39.pyc +0 -0
  442. snappy/verify/__pycache__/realAlgebra.cpython-39.pyc +0 -0
  443. snappy/verify/__pycache__/shapes.cpython-39.pyc +0 -0
  444. snappy/verify/__pycache__/short_slopes.cpython-39.pyc +0 -0
  445. snappy/verify/__pycache__/squareExtensions.cpython-39.pyc +0 -0
  446. snappy/verify/__pycache__/verifyCanonical.cpython-39.pyc +0 -0
  447. snappy/verify/__pycache__/verifyHyperbolicity.cpython-39.pyc +0 -0
  448. snappy/verify/__pycache__/volume.cpython-39.pyc +0 -0
  449. snappy/verify/complex_volume/__pycache__/__init__.cpython-39.pyc +0 -0
  450. snappy/verify/complex_volume/__pycache__/adjust_torsion.cpython-39.pyc +0 -0
  451. snappy/verify/complex_volume/__pycache__/closed.cpython-39.pyc +0 -0
  452. snappy/verify/complex_volume/__pycache__/compute_ptolemys.cpython-39.pyc +0 -0
  453. snappy/verify/complex_volume/__pycache__/cusped.cpython-39.pyc +0 -0
  454. snappy/verify/complex_volume/__pycache__/extended_bloch.cpython-39.pyc +0 -0
  455. snappy/verify/cuspCrossSection.py +0 -1422
  456. snappy/verify/maximal_cusp_area_matrix/__pycache__/__init__.cpython-39.pyc +0 -0
  457. snappy/verify/maximal_cusp_area_matrix/__pycache__/cusp_tiling_engine.cpython-39.pyc +0 -0
  458. snappy/verify/maximal_cusp_area_matrix/__pycache__/cusp_translate_engine.cpython-39.pyc +0 -0
  459. snappy/verify/upper_halfspace/__pycache__/__init__.cpython-39.pyc +0 -0
  460. snappy/verify/upper_halfspace/__pycache__/extended_matrix.cpython-39.pyc +0 -0
  461. snappy/verify/upper_halfspace/__pycache__/finite_point.cpython-39.pyc +0 -0
  462. snappy/verify/upper_halfspace/__pycache__/ideal_point.cpython-39.pyc +0 -0
  463. snappy-3.1.1.dist-info/RECORD +0 -585
  464. {snappy-3.1.1.dist-info → snappy-3.2.dist-info}/entry_points.txt +0 -0
@@ -26,6 +26,7 @@ out vec4 out_FragColor;
26
26
 
27
27
  uniform vec2 screenResolution;
28
28
  uniform float viewScale;
29
+ uniform bool crosshairs;
29
30
 
30
31
  uniform int currentTetIndex;
31
32
  uniform mat4 currentBoost;
@@ -34,7 +35,7 @@ uniform float currentWeight;
34
35
  uniform int maxSteps;
35
36
  uniform float maxDist;
36
37
  uniform int subpixelCount;
37
- uniform float edgeThickness;
38
+ uniform float edgeThicknessParam;
38
39
  uniform float contrast;
39
40
 
40
41
  const int perspectiveTypeMaterial = 0;
@@ -55,7 +56,7 @@ uniform bool showElevation = false;
55
56
 
56
57
  layout (std140) uniform TetrahedraCombinatorics
57
58
  {
58
- int otherTetNums[4 * ##num_tets##];
59
+ int otherTetNums[4 * ##num_tets##];
59
60
  int otherFaceNums[4 * ##num_tets##];
60
61
  };
61
62
 
@@ -89,6 +90,7 @@ const vec4 lightSourcePosition = vec4(1.0, 0.0, 0.7, 0.0);
89
90
 
90
91
  uniform bool isNonGeometric;
91
92
  uniform sampler2D nonGeometricTexture;
93
+ uniform sampler2D eyeTexture;
92
94
 
93
95
  const int num_tets = ##num_tets##;
94
96
  const int num_edges = ##num_edges##;
@@ -115,7 +117,7 @@ uniform float vertexSphereRadiusParam;
115
117
  // For an incomplete cusp, the Margulis tube is a cylinder about
116
118
  // the geodesic the triangulation spins about. In other words,
117
119
  // it is the cylinder fixed by the peripheral group of that cusp.
118
- // We encode it by its two end points and cosh(radius/2)^2/2.
120
+ // We encode it by its two end points and cosh(radius)^2/2.
119
121
  layout (std140) uniform MargulisTubes
120
122
  {
121
123
  vec4 margulisTubeTails[4 * ##num_tets##];
@@ -123,20 +125,72 @@ layout (std140) uniform MargulisTubes
123
125
  };
124
126
  uniform float margulisTubeRadiusParams[4 * ##num_tets##];
125
127
 
126
- #if ##num_geodesic_segments## > 0
128
+ #if defined(num_geodesic_segments) && num_geodesic_segments > 0
127
129
  layout (std140) uniform geodesics
128
130
  {
129
- vec4 geodesicTails[##num_geodesic_segments##];
130
- vec4 geodesicHeads[##num_geodesic_segments##];
131
- int geodesicIndex[##num_geodesic_segments##];
132
- float geodesicTubeRadiusParam[##num_geodesic_segments##];
131
+ vec4 geodesicTails[num_geodesic_segments];
132
+ vec4 geodesicHeads[num_geodesic_segments];
133
+ int geodesicIndex[num_geodesic_segments];
134
+ float geodesicTubeRadiusParam[num_geodesic_segments];
133
135
  int geodesicOffsets[##num_tets## + 1];
134
136
  };
137
+ #endif
138
+
139
+ #if !defined(num_eyeballs)
140
+ #define num_eyeballs 0
141
+ #endif
142
+
143
+ #if num_eyeballs > 0
144
+ layout (std140) uniform eyeballs
145
+ {
146
+ vec4 eyeballPositions[num_eyeballs];
147
+ mat4 eyeballInvEmbeddings[num_eyeballs];
148
+ mat4 eyeballEmbeddings[num_eyeballs];
149
+ int eyeballOffsets[##num_tets## + 1];
150
+ };
151
+ uniform float eyeballRadius;
152
+
153
+ #if eyeball_type == 2
154
+ float eyeballRadiusParam = cosh(eyeballRadius) * cosh(eyeballRadius);
155
+ #else
156
+ float space_ship_width = 0.4;
157
+ float space_ship_fold_width = 0.13;
158
+ float space_ship_fold_height = 0.3;
159
+
160
+ vec4 space_ship_top_plane = vec4(0.0, 0.0, -1.0, 0.0);
161
+ vec4 space_ship_edges[2] = vec4[2](
162
+ vec4(0.0, 1.0 / space_ship_width, 0.0, 1.0),
163
+ vec4(0.0, -1.0 / space_ship_width, 0.0, 1.0));
164
+ vec4 space_ship_folds[2] = vec4[2](
165
+ vec4(0.0, 1.0 / space_ship_fold_width, 1.0 / space_ship_fold_height, 1.0),
166
+ vec4(0.0, -1.0 / space_ship_fold_width, 1.0 / space_ship_fold_height, 1.0));
167
+ float b = length(vec2(space_ship_fold_height, 1.0));
168
+ vec4 space_ship_back_plane = vec4(sinh(eyeballRadius), 0.0, 0.0, -b * cosh(eyeballRadius));
169
+ #endif
135
170
 
136
171
  #endif
137
172
 
138
173
  uniform float horosphereScales[4 * ##num_tets##];
139
174
 
175
+ #if defined(num_additional_horospheres) && num_additional_horospheres > 0
176
+ layout (std140) uniform additionalHorospheres
177
+ {
178
+ vec4 horosphereVec[num_additional_horospheres];
179
+ int horosphereCuspIndex[num_additional_horospheres];
180
+ int horosphereOffsets[##num_tets## + 1];
181
+ };
182
+
183
+ #endif
184
+
185
+ #if defined(has_edge_midpoints)
186
+ layout (std140) uniform edgeMidpoints
187
+ {
188
+ vec4 edgeMidpointVec[6 * ##num_tets##];
189
+ };
190
+
191
+ uniform float edgeMidpointRadiusParam;
192
+ #endif
193
+
140
194
  // cosh(r)^2 where r is the radius of the sphere
141
195
  // about the center of the tetrahedron.
142
196
  uniform float insphereRadiusParams[##num_tets##];
@@ -150,7 +204,7 @@ layout (std140) uniform TetCuspMatrices
150
204
  };
151
205
 
152
206
  uniform vec2 logAdjustments[4 * ##num_tets##];
153
- uniform mat2 matLogs[4 * ##num_tets##];
207
+ uniform mat2 toStandardTorusMatrices[4 * ##num_tets##];
154
208
 
155
209
  const float peripheralCurveThickness = 0.015;
156
210
 
@@ -223,7 +277,7 @@ triangleBdryParam(vec4 samplePoint, int tetNum, int exit_face){
223
277
  float new_p = geodesicParameterPlanes(samplePoint, exit_dual_point, planes[index]);
224
278
  if(new_p < smallest_p){
225
279
  smallest_p = new_p;
226
- }
280
+ }
227
281
  }
228
282
  }
229
283
  return smallest_p;
@@ -233,18 +287,23 @@ triangleBdryParam(vec4 samplePoint, int tetNum, int exit_face){
233
287
 
234
288
  // Kind of object a ray hit.
235
289
 
236
- const int object_type_nothing = 0;
237
- const int object_type_face = 1;
238
- const int object_type_edge_cylinder_enter = 2;
239
- const int object_type_edge_cylinder_exit = 3;
240
- const int object_type_horosphere = 4;
241
- const int object_type_edge_fan = 5;
242
- const int object_type_insphere = 6;
243
- const int object_type_vertex_sphere = 7;
244
- const int object_type_margulis_tube = 8;
245
- const int object_type_elevation_enter = 9;
246
- const int object_type_elevation_exit = 10;
247
- const int object_type_geodesic_tube = 11;
290
+ const int object_type_nothing = 0;
291
+ const int object_type_face = 1;
292
+ const int object_type_edge_cylinder_enter = 2;
293
+ const int object_type_edge_cylinder_exit = 3;
294
+ const int object_type_horosphere_enter = 4;
295
+ const int object_type_horosphere_exit = 5;
296
+ const int object_type_edge_fan = 6;
297
+ const int object_type_insphere = 7;
298
+ const int object_type_vertex_sphere = 8;
299
+ const int object_type_margulis_tube_enter = 9;
300
+ const int object_type_margulis_tube_exit = 10;
301
+ const int object_type_elevation_enter = 11;
302
+ const int object_type_elevation_exit = 12;
303
+ const int object_type_geodesic_tube = 13;
304
+ const int object_type_additional_horosphere = 14;
305
+ const int object_type_eyeball = 15;
306
+ const int object_type_edge_midpoint = 16;
248
307
 
249
308
  // A ray consists of a point in the hyperbolid model and a
250
309
  // unit tangent vector dir orthogonal to the point with respect
@@ -271,8 +330,19 @@ struct RayHit
271
330
  // Index of object (within the tetrahedron), e.g.,
272
331
  // 0-3 for horospheres, 0-5 for edges.
273
332
  int object_index;
333
+
334
+ int object_subindex;
274
335
  };
275
336
 
337
+ bool traceInsideVertexNeighborhood()
338
+ {
339
+ #if num_eyeballs > 0
340
+ return eyeballOffsets[##num_tets##] > 0;
341
+ #else
342
+ return false;
343
+ #endif
344
+ }
345
+
276
346
  // We distinguish between:
277
347
  // - colored ray hits: the geometry is lit, e.g., the cylinder
278
348
  // about an edge reacts to light)
@@ -284,17 +354,15 @@ struct RayHit
284
354
  //
285
355
  bool isColored(RayHit ray_hit)
286
356
  {
287
- return
288
- ray_hit.object_type == object_type_vertex_sphere ||
289
- ray_hit.object_type == object_type_insphere ||
290
- ray_hit.object_type == object_type_horosphere ||
291
- ray_hit.object_type == object_type_edge_cylinder_enter ||
292
- ray_hit.object_type == object_type_edge_cylinder_exit ||
293
- ray_hit.object_type == object_type_margulis_tube ||
294
- ray_hit.object_type == object_type_edge_fan ||
295
- ray_hit.object_type == object_type_elevation_enter ||
296
- ray_hit.object_type == object_type_elevation_exit ||
297
- ray_hit.object_type == object_type_geodesic_tube;
357
+ return !(
358
+ ray_hit.object_type == object_type_nothing ||
359
+ ray_hit.object_type == object_type_face);
360
+ }
361
+
362
+ vec4
363
+ pointAdvancedByParam(Ray ray, float p)
364
+ {
365
+ return R13Normalise(ray.point + p * ray.dir );
298
366
  }
299
367
 
300
368
  // Advances ray by distance atanh(p).
@@ -304,7 +372,7 @@ bool isColored(RayHit ray_hit)
304
372
  void
305
373
  advanceRayByDistParam(inout Ray ray, float p)
306
374
  {
307
- ray.point = R13Normalise(ray.point + p * ray.dir );
375
+ ray.point = pointAdvancedByParam(ray, p);
308
376
  ray.dir = makeUnitTangentVector(ray.dir, ray.point);
309
377
  }
310
378
 
@@ -344,7 +412,7 @@ realRootsOfQuadratic(float a, float b, float c,
344
412
 
345
413
  // Intersection with plane.
346
414
  // The plane is given by all points such that the inner product
347
- // of the point and the planeEqn is zero.
415
+ // of the point and the planeEqn is zero.
348
416
  float
349
417
  distParamForPlaneIntersection(Ray ray,
350
418
  vec4 planeEqn)
@@ -364,11 +432,11 @@ distParamForPlaneIntersection(Ray ray,
364
432
  // The last parameter is the cosh(radius)^2.
365
433
  vec2
366
434
  distParamsForSphereIntersection(Ray ray,
367
- vec4 center, float sphereRadiusParam)
435
+ vec4 center, float sphereRadiusParam)
368
436
  {
369
437
  float startDot = R13Dot(center, ray.point);
370
438
  float dirDot = R13Dot(center, ray.dir);
371
-
439
+
372
440
  return realRootsOfQuadratic(
373
441
  dirDot * dirDot + sphereRadiusParam,
374
442
  2.0 * dirDot * startDot,
@@ -511,7 +579,7 @@ horosphereEqn(int index)
511
579
  return horosphereScales[index] * R13Vertices[index];
512
580
  }
513
581
 
514
- #if ##num_geodesic_segments## > 0
582
+ #if defined(num_geodesic_segments) && num_geodesic_segments > 0
515
583
  // The two endpoints of a geodesic
516
584
  vec4[2]
517
585
  endpointsForGeodesic(int index)
@@ -536,19 +604,31 @@ normalForRayHit(RayHit ray_hit)
536
604
  return normalForSphere(ray_hit.ray.point, vec4(1,0,0,0));
537
605
  }
538
606
 
539
- if(ray_hit.object_type == object_type_horosphere) {
607
+ if(ray_hit.object_type == object_type_horosphere_enter) {
540
608
  int index = 4 * ray_hit.tet_num + ray_hit.object_index;
541
609
  return horosphereEqn(index) - ray_hit.ray.point;
542
610
  }
543
611
 
544
- if(ray_hit.object_type == object_type_margulis_tube) {
612
+ if(ray_hit.object_type == object_type_horosphere_exit) {
613
+ int index = 4 * ray_hit.tet_num + ray_hit.object_index;
614
+ return ray_hit.ray.point - horosphereEqn(index);
615
+ }
616
+
617
+ if(ray_hit.object_type == object_type_margulis_tube_enter) {
545
618
  int index = 4 * ray_hit.tet_num + ray_hit.object_index;
546
619
  return normalForTube(
547
620
  ray_hit.ray.point,
548
621
  endpointsForMargulisTube(index));
549
622
  }
550
623
 
551
- #if ##num_geodesic_segments## > 0
624
+ if(ray_hit.object_type == object_type_margulis_tube_exit) {
625
+ int index = 4 * ray_hit.tet_num + ray_hit.object_index;
626
+ return - normalForTube(
627
+ ray_hit.ray.point,
628
+ endpointsForMargulisTube(index));
629
+ }
630
+
631
+ #if defined(num_geodesic_segments) && num_geodesic_segments > 0
552
632
  if (ray_hit.object_type == object_type_geodesic_tube) {
553
633
  return normalForTube(
554
634
  ray_hit.ray.point,
@@ -556,8 +636,44 @@ normalForRayHit(RayHit ray_hit)
556
636
  }
557
637
  #endif
558
638
 
639
+ #if defined(num_additional_horospheres) && num_additional_horospheres > 0
640
+ if (ray_hit.object_type == object_type_additional_horosphere) {
641
+ return horosphereVec[ray_hit.object_index] - ray_hit.ray.point;
642
+ }
643
+ #endif
644
+
645
+ #if num_eyeballs > 0
646
+ if (ray_hit.object_type == object_type_eyeball) {
647
+ #if eyeball_type == 2
648
+ return normalForSphere(
649
+ ray_hit.ray.point, eyeballPositions[ray_hit.object_index]);
650
+ #else
651
+ vec4 local_normal;
652
+ if (ray_hit.object_subindex == 0) {
653
+ local_normal = space_ship_top_plane;
654
+ } else {
655
+ local_normal = R13Normalise(space_ship_folds[ray_hit.object_subindex - 1]);
656
+ }
657
+ vec4 normal = local_normal * eyeballEmbeddings[ray_hit.object_index];
658
+
659
+ if (R13Dot(ray_hit.ray.dir, normal) > 0) {
660
+ return normal;
661
+ } else {
662
+ return -normal;
663
+ }
664
+ #endif
665
+ }
666
+ #endif
667
+
668
+ #if defined(has_edge_midpoints)
669
+ if (ray_hit.object_type == object_type_edge_midpoint) {
670
+ int index = 6 * ray_hit.tet_num + ray_hit.object_index;
671
+ return normalForSphere(ray_hit.ray.point, edgeMidpointVec[index]);
672
+ }
673
+ #endif
674
+
559
675
  #endif
560
-
676
+
561
677
  if(ray_hit.object_type == object_type_edge_fan ||
562
678
  ray_hit.object_type == object_type_elevation_enter ||
563
679
  ray_hit.object_type == object_type_elevation_exit) {
@@ -591,8 +707,8 @@ hyperboloidToUpperHalfspace(vec4 h)
591
707
  vec3 poincare = klein / (1.0 + sqrt(1.0 - dot(klein, klein)));
592
708
  vec3 denom_helper = vec3(poincare.x - 1.0, poincare.yz);
593
709
  float denom = dot(denom_helper, denom_helper);
594
-
595
- return vec3(2.0 * poincare.yz, 1.0 - dot(poincare, poincare)) / denom;
710
+
711
+ return vec3(2.0 * poincare.yz, 1.0 - dot(poincare, poincare)) / denom;
596
712
  }
597
713
 
598
714
  #if !##finiteTrig##
@@ -617,15 +733,35 @@ vec2
617
733
  MLCoordinatesForRayHit(RayHit rayHit)
618
734
  {
619
735
  int index = 4 * rayHit.tet_num + rayHit.object_index;
620
-
736
+
621
737
  vec3 pointUpperHalfspace = preferredUpperHalfspaceCoordinates(rayHit);
622
738
  vec2 z = pointUpperHalfspace.xy;
623
739
 
624
- if (rayHit.object_type == object_type_margulis_tube) {
740
+ if (rayHit.object_type == object_type_margulis_tube_enter ||
741
+ rayHit.object_type == object_type_margulis_tube_exit) {
625
742
  z = complexLog(z) + logAdjustments[index];
626
743
  }
627
744
 
628
- return z * matLogs[index];
745
+ return z * toStandardTorusMatrices[index];
746
+ }
747
+
748
+ int
749
+ peripheralCurveForMLCoordinates(vec2 ml_coordinates)
750
+ {
751
+ // Map R^2->torus
752
+ vec2 f = fract(ml_coordinates);
753
+
754
+ if ( f.y < peripheralCurveThickness ||
755
+ f.y > 1.0 - peripheralCurveThickness) {
756
+ return 2;
757
+ }
758
+
759
+ if ( f.x < peripheralCurveThickness ||
760
+ f.x > 1.0 - peripheralCurveThickness) {
761
+ return 1;
762
+ }
763
+
764
+ return 0;
629
765
  }
630
766
  #endif
631
767
 
@@ -637,7 +773,7 @@ mat4
637
773
  parabolicSO13(vec2 z)
638
774
  {
639
775
  float t = dot(z, z) / 2.0;
640
-
776
+
641
777
  return mat4( 1.0 + t, - t, z.x, z.y,
642
778
  t, 1.0 - t, z.x, z.y,
643
779
  z.x, -z.x, 1.0, 0.0,
@@ -661,18 +797,75 @@ ray_trace_through_hyperboloid_tet(inout RayHit ray_hit)
661
797
  {
662
798
  int entry_object_type = ray_hit.object_type;
663
799
  int entry_object_index = ray_hit.object_index;
664
-
800
+
665
801
  ///Given shape of a tet and a ray, find where the ray exits and through which face
666
802
  float smallest_p = 100000000.0;
667
803
 
804
+ float horosphere_exit_param = -unreachableDistParam;
805
+
806
+ #if !##finiteTrig##
807
+ for (int vertex = 0; vertex < 4; vertex++) {
808
+ int index = 4 * ray_hit.tet_num + vertex;
809
+ if ( horosphereScales[index] != 0.0 ||
810
+ margulisTubeRadiusParams[index] > 0.50001) {
811
+
812
+ vec2 params;
813
+ if (horosphereScales[index] != 0.0) {
814
+ params = distParamsForHorosphereIntersection(
815
+ ray_hit.ray,
816
+ horosphereEqn(index));
817
+ } else {
818
+ params = distParamsForTubeIntersection(
819
+ ray_hit.ray,
820
+ endpointsForMargulisTube(index),
821
+ margulisTubeRadiusParams[index],
822
+ 0.0);
823
+ }
824
+
825
+ if (params.x < smallest_p) {
826
+ smallest_p = params.x;
827
+ if (horosphereScales[index] != 0.0) {
828
+ ray_hit.object_type = object_type_horosphere_enter;
829
+ } else {
830
+ ray_hit.object_type = object_type_margulis_tube_enter;
831
+ }
832
+ ray_hit.object_index = vertex;
833
+ }
834
+
835
+ if (traceInsideVertexNeighborhood()) {
836
+ if (params.y < smallest_p) {
837
+ horosphere_exit_param = params.y;
838
+ ray_hit.distWhenLeavingCusp = ray_hit.dist + atanh(params.y);
839
+
840
+ RayHit new_hit = ray_hit;
841
+ new_hit.object_index = vertex;
842
+ advanceRayByDistParam(new_hit.ray, params.y);
843
+
844
+ if (peripheralCurveForMLCoordinates(
845
+ MLCoordinatesForRayHit(new_hit)) > 0) {
846
+ smallest_p = params.y;
847
+
848
+ if (horosphereScales[index] != 0.0) {
849
+ ray_hit.object_type = object_type_horosphere_exit;
850
+ } else {
851
+ ray_hit.object_type = object_type_margulis_tube_exit;
852
+ }
853
+ ray_hit.object_index = vertex;
854
+ }
855
+ }
856
+ }
857
+ }
858
+ }
859
+ #endif
860
+
668
861
  for(int face = 0; face < 4; face++) {
669
862
  if (entry_object_type != object_type_face || entry_object_index != face) {
670
863
  // find p when we hit that face
671
864
  int index = 4 * ray_hit.tet_num + face;
672
- if(R13Dot(ray_hit.ray.dir, planes[index]) > 0.0){
865
+ if(R13Dot(ray_hit.ray.dir, planes[index]) > 0.0){
673
866
  float p = distParamForPlaneIntersection(ray_hit.ray, planes[index]);
674
867
  // if ((-10000.0 <= p) && (p < smallest_p)) {
675
- if (p < smallest_p) {
868
+ if (p < smallest_p) {
676
869
  /// negative values are ok if we have to go backwards a little to get through the face we are a little the wrong side of
677
870
  /// Although this can apparently get caught in infinite loops in an edge
678
871
 
@@ -712,7 +905,8 @@ ray_trace_through_hyperboloid_tet(inout RayHit ray_hit)
712
905
  ray_hit.ray,
713
906
  vec4(1,0,0,0),
714
907
  r).x;
715
- if (p < smallest_p) {
908
+ if (p < smallest_p && (!traceInsideVertexNeighborhood() ||
909
+ p > horosphere_exit_param)) {
716
910
  smallest_p = p;
717
911
  ray_hit.object_type = object_type_insphere;
718
912
  ray_hit.object_index = 0;
@@ -720,34 +914,24 @@ ray_trace_through_hyperboloid_tet(inout RayHit ray_hit)
720
914
  }
721
915
  }
722
916
 
723
- for (int vertex = 0; vertex < 4; vertex++) {
724
- int index = 4 * ray_hit.tet_num + vertex;
725
- if (horosphereScales[index] != 0.0) {
726
- vec2 params = distParamsForHorosphereIntersection(ray_hit.ray,
727
- horosphereEqn(index));
728
- if (params.x < smallest_p) {
729
- smallest_p = params.x;
730
- ray_hit.object_type = object_type_horosphere;
731
- ray_hit.object_index = vertex;
732
- }
733
- }
734
-
735
- if (margulisTubeRadiusParams[index] > 0.50001) {
736
- vec2 params = distParamsForTubeIntersection(
737
- ray_hit.ray,
738
- endpointsForMargulisTube(index),
739
- margulisTubeRadiusParams[index],
740
- 0.0);
741
-
742
- if (params.x < smallest_p) {
743
- smallest_p = params.x;
744
- ray_hit.object_type = object_type_margulis_tube;
745
- ray_hit.object_index = vertex;
746
- }
747
- }
917
+ #if defined(has_edge_midpoints)
918
+ {
919
+ for (int edge = 0; edge < 6; edge++) {
920
+ int index = 6 * ray_hit.tet_num + edge;
921
+ float p = distParamsForSphereIntersection(
922
+ ray_hit.ray,
923
+ edgeMidpointVec[index],
924
+ edgeMidpointRadiusParam).x;
925
+ if (p < smallest_p) {
926
+ smallest_p = p;
927
+ ray_hit.object_type = object_type_edge_midpoint;
928
+ ray_hit.object_index = edge;
929
+ }
930
+ }
748
931
  }
932
+ #endif
749
933
 
750
- #if ##num_geodesic_segments## > 0
934
+ #if defined(num_geodesic_segments) && num_geodesic_segments > 0
751
935
  for (int index = geodesicOffsets[ray_hit.tet_num];
752
936
  index < geodesicOffsets[ray_hit.tet_num + 1];
753
937
  index++) {
@@ -758,7 +942,8 @@ ray_trace_through_hyperboloid_tet(inout RayHit ray_hit)
758
942
  geodesicTubeRadiusParam[index],
759
943
  0.0);
760
944
 
761
- if (params.x < smallest_p) {
945
+ if (params.x < smallest_p && (!traceInsideVertexNeighborhood() ||
946
+ params.x > horosphere_exit_param)) {
762
947
  smallest_p = params.x;
763
948
  ray_hit.object_type = object_type_geodesic_tube;
764
949
  ray_hit.object_index = index;
@@ -766,6 +951,87 @@ ray_trace_through_hyperboloid_tet(inout RayHit ray_hit)
766
951
  }
767
952
  #endif
768
953
 
954
+ #if defined(num_additional_horospheres) && num_additional_horospheres > 0
955
+ for (int index = horosphereOffsets[ray_hit.tet_num];
956
+ index < horosphereOffsets[ray_hit.tet_num + 1];
957
+ index++) {
958
+
959
+ vec2 params = distParamsForHorosphereIntersection(
960
+ ray_hit.ray,
961
+ horosphereVec[index]);
962
+
963
+ if (params.x < smallest_p) {
964
+ smallest_p = params.x;
965
+ ray_hit.object_type = object_type_additional_horosphere;
966
+ ray_hit.object_index = index;
967
+ }
968
+ }
969
+ #endif
970
+
971
+ #if num_eyeballs > 0
972
+ for (int index = eyeballOffsets[ray_hit.tet_num];
973
+ index < eyeballOffsets[ray_hit.tet_num + 1];
974
+ index++) {
975
+
976
+ #if eyeball_type == 2
977
+ vec2 params = distParamsForSphereIntersection(
978
+ ray_hit.ray,
979
+ eyeballPositions[index],
980
+ eyeballRadiusParam);
981
+
982
+ if (params.x < smallest_p) {
983
+ smallest_p = params.x;
984
+ ray_hit.object_type = object_type_eyeball;
985
+ ray_hit.object_index = index;
986
+ }
987
+ #else
988
+ Ray local_ray;
989
+ local_ray.point = ray_hit.ray.point * eyeballInvEmbeddings[index];
990
+ local_ray.dir = ray_hit.ray.dir * eyeballInvEmbeddings[index];
991
+
992
+ {
993
+ float param = distParamForPlaneIntersection(local_ray, vec4(0.0, 0.0, 1.0, 0.0));
994
+
995
+ if (param > 0 && param < smallest_p) {
996
+ if (ray_hit.dist + atanh(param) > 0.001) {
997
+ vec4 hit_point = pointAdvancedByParam(local_ray, param);
998
+ if ((dot(hit_point, space_ship_folds[0]) < 0.0 ||
999
+ dot(hit_point, space_ship_folds[1]) < 0.0) &&
1000
+ dot(hit_point, space_ship_back_plane) > 0.0 &&
1001
+ dot(hit_point, space_ship_edges[0]) > 0.0 &&
1002
+ dot(hit_point, space_ship_edges[1]) > 0.0) {
1003
+ smallest_p = param;
1004
+ ray_hit.object_type = object_type_eyeball;
1005
+ ray_hit.object_index = index;
1006
+ ray_hit.object_subindex = 0;
1007
+ }
1008
+ }
1009
+ }
1010
+ }
1011
+
1012
+ for (int s = 0; s < 2; s++) {
1013
+ float param = distParamForPlaneIntersection(local_ray, space_ship_folds[s]);
1014
+
1015
+ if (param > 0 && param < smallest_p) {
1016
+ if (ray_hit.dist + atanh(param) > 0.001) {
1017
+ vec4 hit_point = pointAdvancedByParam(local_ray, param);
1018
+
1019
+ if (dot(hit_point, space_ship_back_plane) > 0.0 &&
1020
+ dot(hit_point, space_ship_top_plane) > 0.0 &&
1021
+ dot(hit_point, space_ship_folds[1-s]) > 0.0) {
1022
+
1023
+ smallest_p = param;
1024
+ ray_hit.object_type = object_type_eyeball;
1025
+ ray_hit.object_index = index;
1026
+ ray_hit.object_subindex = 1 + s;
1027
+ }
1028
+ }
1029
+ }
1030
+ }
1031
+ #endif
1032
+ }
1033
+ #endif
1034
+
769
1035
  #endif
770
1036
 
771
1037
  if (edgeTubeRadiusParam > 0.500001) {
@@ -774,7 +1040,7 @@ ray_trace_through_hyperboloid_tet(inout RayHit ray_hit)
774
1040
  float backDistParam = 0.0;
775
1041
  #else
776
1042
  float backDistParam = tanh(ray_hit.distWhenLeavingCusp-ray_hit.dist);
777
- #endif
1043
+ #endif
778
1044
 
779
1045
  for (int edge = 0; edge < 6; edge++) {
780
1046
 
@@ -784,11 +1050,14 @@ ray_trace_through_hyperboloid_tet(inout RayHit ray_hit)
784
1050
  edgeTubeRadiusParam,
785
1051
  backDistParam);
786
1052
 
787
- if (params.x < smallest_p) {
1053
+ if (params.x < smallest_p && (!traceInsideVertexNeighborhood() ||
1054
+ params.x > horosphere_exit_param)) {
788
1055
  smallest_p = params.x;
789
1056
  ray_hit.object_type = object_type_edge_cylinder_enter;
790
1057
  ray_hit.object_index = edge;
791
- } else if (params.y < smallest_p) {
1058
+ }
1059
+ if (params.y < smallest_p && (!traceInsideVertexNeighborhood() ||
1060
+ params.y > horosphere_exit_param)) {
792
1061
  smallest_p = params.y;
793
1062
  ray_hit.object_type = object_type_edge_cylinder_exit;
794
1063
  ray_hit.object_index = edge;
@@ -799,10 +1068,13 @@ ray_trace_through_hyperboloid_tet(inout RayHit ray_hit)
799
1068
  ray_hit.dist += atanh(smallest_p);
800
1069
  advanceRayByDistParam(ray_hit.ray, smallest_p);
801
1070
 
802
- if(edgeThickness > 0.00001) {
1071
+ if(edgeThicknessParam > 0.00001) {
803
1072
  if (ray_hit.object_type == object_type_face) {
804
- if(triangleBdryParam(ray_hit.ray.point, ray_hit.tet_num, ray_hit.object_index) < edgeThickness) {
805
- ray_hit.object_type = object_type_edge_fan;
1073
+ if (!traceInsideVertexNeighborhood() ||
1074
+ smallest_p > horosphere_exit_param) {
1075
+ if(triangleBdryParam(ray_hit.ray.point, ray_hit.tet_num, ray_hit.object_index) < edgeThicknessParam) {
1076
+ ray_hit.object_type = object_type_edge_fan;
1077
+ }
806
1078
  }
807
1079
  }
808
1080
  }
@@ -844,7 +1116,7 @@ ray_trace(inout RayHit ray_hit) {
844
1116
  // positive values so we get correct behaviour by comparing without the sinh^2.
845
1117
  int index = 4 * ray_hit.tet_num + ray_hit.object_index;
846
1118
 
847
- float new_weight = ray_hit.weight + weights[ index ];
1119
+ float new_weight = ray_hit.weight + weights[ index ];
848
1120
 
849
1121
  if (showElevation) {
850
1122
  int elevation_object_type =
@@ -863,7 +1135,7 @@ ray_trace(inout RayHit ray_hit) {
863
1135
 
864
1136
  ray_hit.light_source = ray_hit.light_source * tsfm;
865
1137
  ray_hit.ray.point = ray_hit.ray.point * tsfm;
866
- ray_hit.ray.dir = R13Normalise( ray_hit.ray.dir * tsfm );
1138
+ ray_hit.ray.dir = R13Normalise( ray_hit.ray.dir * tsfm );
867
1139
  ray_hit.tet_num = otherTetNums[ index ];
868
1140
  }
869
1141
  }
@@ -928,11 +1200,13 @@ material_params(RayHit ray_hit)
928
1200
 
929
1201
  result.diffuse = hsv2rgb(vec3(float(color_index)/float(num_cusps), 0.25, 1.0));
930
1202
  result.ambient = 0.5 * result.diffuse;
931
- }
1203
+ }
932
1204
  #else
933
- if (ray_hit.object_type == object_type_horosphere ||
934
- ray_hit.object_type == object_type_margulis_tube) {
935
-
1205
+ if (ray_hit.object_type == object_type_horosphere_enter ||
1206
+ ray_hit.object_type == object_type_horosphere_exit ||
1207
+ ray_hit.object_type == object_type_margulis_tube_enter ||
1208
+ ray_hit.object_type == object_type_margulis_tube_exit) {
1209
+
936
1210
  int index = 4 * ray_hit.tet_num + ray_hit.object_index;
937
1211
  int color_index = vertex_color_indices[index];
938
1212
 
@@ -946,15 +1220,15 @@ material_params(RayHit ray_hit)
946
1220
  #endif
947
1221
  result.ambient = 0.5 * result.diffuse;
948
1222
 
949
- vec2 coords = fract(MLCoordinatesForRayHit(ray_hit));
950
-
951
- if (coords.x < peripheralCurveThickness ||
952
- coords.x > 1.0 - peripheralCurveThickness) {
1223
+ int peripheralCurve =
1224
+ peripheralCurveForMLCoordinates(
1225
+ MLCoordinatesForRayHit(ray_hit));
1226
+
1227
+ if (peripheralCurve == 1) {
953
1228
  result.diffuse = longitudeColor;
954
1229
  result.ambient = result.diffuse;
955
1230
  }
956
- if (coords.y < peripheralCurveThickness ||
957
- coords.y > 1.0 - peripheralCurveThickness) {
1231
+ if (peripheralCurve == 2) {
958
1232
  result.diffuse = meridianColor;
959
1233
  result.ambient = result.diffuse;
960
1234
  }
@@ -980,7 +1254,7 @@ material_params(RayHit ray_hit)
980
1254
  if (ray_hit.object_type == object_type_edge_cylinder_enter) {
981
1255
  int index = 6 * ray_hit.tet_num + ray_hit.object_index;
982
1256
  int color_index = edge_color_indices[index];
983
-
1257
+
984
1258
  //using num_tets = num_edges
985
1259
 
986
1260
  #if COLOR_SCHEME == 1
@@ -1001,7 +1275,7 @@ material_params(RayHit ray_hit)
1001
1275
  if (ray_hit.object_type == object_type_edge_cylinder_exit) {
1002
1276
  int index = 6 * ray_hit.tet_num + ray_hit.object_index;
1003
1277
  int color_index = edge_color_indices[index];
1004
-
1278
+
1005
1279
  //using num_tets = num_edges
1006
1280
  result.diffuse = 0.3 * hsv2rgb(vec3(float(color_index)/float(num_tets), 1.0, 1.0));
1007
1281
  result.ambient = 0.5 * result.diffuse;
@@ -1017,7 +1291,7 @@ material_params(RayHit ray_hit)
1017
1291
  result.ambient = 0.5 * result.diffuse;
1018
1292
  }
1019
1293
 
1020
- #if ##num_geodesic_segments## > 0
1294
+ #if defined(num_geodesic_segments) && num_geodesic_segments > 0
1021
1295
  if (ray_hit.object_type == object_type_geodesic_tube) {
1022
1296
  int index = geodesicIndex[ray_hit.object_index];
1023
1297
 
@@ -1040,6 +1314,44 @@ material_params(RayHit ray_hit)
1040
1314
  }
1041
1315
  #endif
1042
1316
 
1317
+ #if defined(num_additional_horospheres) && num_additional_horospheres > 0
1318
+ if (ray_hit.object_type == object_type_additional_horosphere) {
1319
+ int index = horosphereCuspIndex[ray_hit.object_index];
1320
+
1321
+ // Similar to geodesic colors.
1322
+ float goldenAngleBy2Pi = 0.3819660112501051;
1323
+
1324
+ result.diffuse = hsv2rgb(vec3(float(index) * goldenAngleBy2Pi + 0.3, 1.0, 1.0));
1325
+
1326
+ result.ambient = 0.5 * result.diffuse;
1327
+ }
1328
+ #endif
1329
+
1330
+ #if num_eyeballs > 0
1331
+ if (ray_hit.object_type == object_type_eyeball) {
1332
+
1333
+ #if eyeball_type == 2
1334
+ vec4 pt = ray_hit.ray.point * eyeballInvEmbeddings[ray_hit.object_index];
1335
+ vec3 d = normalize(pt.yzw);
1336
+
1337
+ vec2 tex_coords = vec2(0.5) + vec2(atan(d.x, -d.z) / 2, asin(d.y)) / radians(180);
1338
+
1339
+ result.diffuse = texture(eyeTexture, tex_coords).xyz;
1340
+ result.ambient = 0.5 * result.diffuse;
1341
+ #else
1342
+ result.diffuse = vec3(0.7, 0.7, 0.7);
1343
+ result.ambient = 0.8 * result.diffuse;
1344
+ #endif
1345
+ }
1346
+ #endif
1347
+
1348
+ #if defined(has_edge_midpoints)
1349
+ if (ray_hit.object_type == object_type_edge_midpoint) {
1350
+ result.diffuse = vec3(0.8,0.8,0.3);
1351
+ result.ambient = 0.5 * result.diffuse;
1352
+ }
1353
+ #endif
1354
+
1043
1355
  return result;
1044
1356
  }
1045
1357
 
@@ -1078,7 +1390,7 @@ vec3 colorForRayHit(RayHit ray_hit)
1078
1390
 
1079
1391
  vec4 light_dir_at_hit = makeUnitTangentVector(
1080
1392
  - light_position, ray_hit.ray.point);
1081
-
1393
+
1082
1394
  float normal_light = clamp(R13Dot(normal, light_dir_at_hit), 0, 1);
1083
1395
 
1084
1396
  vec4 half_angle = R13Normalise(light_dir_at_hit + ray_hit.ray.dir);
@@ -1150,7 +1462,7 @@ Ray get_ray_eye_space(vec2 xy)
1150
1462
  result.point = R13Normalise(vec4(1.0, 2.0 * xy, 0.0));
1151
1463
  result.dir = vec4(0.0, 0.0, 0.0, -1.0);
1152
1464
  }
1153
-
1465
+
1154
1466
  return result;
1155
1467
  }
1156
1468
 
@@ -1199,7 +1511,7 @@ leaveVertexNeighborhood(inout RayHit rayHit)
1199
1511
  //
1200
1512
  // The result is true if we are inside a horosphere AND
1201
1513
  // the ray is hitting a peripheral curve on the horosphere.
1202
- //
1514
+ //
1203
1515
  // For optimization, leaveVertexNeighborhood will also apply a
1204
1516
  // parabolic transformation to the ray trying to bring the
1205
1517
  // where we exit the horosphere closer to the entry point.
@@ -1220,7 +1532,7 @@ leaveVertexNeighborhood(inout RayHit rayHit)
1220
1532
  if (params.y < smallest_p) {
1221
1533
  // Remember this
1222
1534
  smallest_p = params.y;
1223
- rayHit.object_type = object_type_horosphere;
1535
+ rayHit.object_type = object_type_horosphere_exit;
1224
1536
  rayHit.object_index = vertex;
1225
1537
  }
1226
1538
  }
@@ -1233,13 +1545,13 @@ leaveVertexNeighborhood(inout RayHit rayHit)
1233
1545
  if (params.x == unreachableDistParam) {
1234
1546
  if (params.y < smallest_p) {
1235
1547
  smallest_p = params.y;
1236
- rayHit.object_type = object_type_margulis_tube;
1548
+ rayHit.object_type = object_type_margulis_tube_exit;
1237
1549
  rayHit.object_index = vertex;
1238
1550
  }
1239
1551
  }
1240
1552
  }
1241
1553
  }
1242
-
1554
+
1243
1555
  // We are in a horosphere.
1244
1556
  if (smallest_p < unreachableDistParam) {
1245
1557
 
@@ -1257,14 +1569,8 @@ leaveVertexNeighborhood(inout RayHit rayHit)
1257
1569
  // such that the cusp is at infinity
1258
1570
  // Use complex part ignoring height in upper halfspace
1259
1571
 
1260
- // Map R^2->torus
1261
- vec2 coords = fract(ml);
1262
-
1263
1572
  // Check whether we hit peripheral curve
1264
- if (coords.x < peripheralCurveThickness ||
1265
- coords.x > 1.0 - peripheralCurveThickness ||
1266
- coords.y < peripheralCurveThickness ||
1267
- coords.y > 1.0 - peripheralCurveThickness) {
1573
+ if (peripheralCurveForMLCoordinates(ml) > 0) {
1268
1574
  // Hit peripheral curve
1269
1575
  return true;
1270
1576
  }
@@ -1272,24 +1578,24 @@ leaveVertexNeighborhood(inout RayHit rayHit)
1272
1578
  // Compute suitable multiple of merdian and longitude translation
1273
1579
  // bringing the exit point into the fundamental parallelogram
1274
1580
  // near zero.
1275
- vec2 c = -round(ml) * inverse(matLogs[index]);
1581
+ vec2 c = -round(ml) * inverse(toStandardTorusMatrices[index]);
1276
1582
 
1277
1583
  mat4 tsfmCuspSpace =
1278
- (rayHit.object_type == object_type_horosphere)
1584
+ (rayHit.object_type == object_type_horosphere_exit)
1279
1585
  ? parabolicSO13(c)
1280
1586
  : loxodromicSO13(c);
1281
-
1587
+
1282
1588
  // Convert O13 matrix from space where cusp was at infinity
1283
1589
  // to space of tetrahedron
1284
1590
  mat4 tsfm =
1285
1591
  tetToCuspMatrices[index] *
1286
1592
  tsfmCuspSpace *
1287
1593
  cuspToTetMatrices[index];
1288
-
1594
+
1289
1595
  // And apply transformation to ray.
1290
1596
  rayHit.light_source = rayHit.light_source * tsfm;
1291
1597
  rayHit.ray.point = rayHit.ray.point * tsfm;
1292
- rayHit.ray.dir = R13Normalise( rayHit.ray.dir * tsfm );
1598
+ rayHit.ray.dir = R13Normalise( rayHit.ray.dir * tsfm );
1293
1599
 
1294
1600
  // If we are inside a horosphere, leaveVertexNeighborhood has computed
1295
1601
  // the point where we leave the horosphere. But that point
@@ -1323,18 +1629,19 @@ RayHit computeRayHit(vec2 xy){
1323
1629
  graph_trace(ray_tet_space);
1324
1630
  }
1325
1631
 
1326
- // Check whether we are in a horosphere and if yes,
1327
- // whether the ray hit a peripheral curve.
1328
- bool hitPeripheral = leaveVertexNeighborhood(ray_tet_space);
1329
-
1330
- if (hitPeripheral) {
1331
- // If we hit a peripheral curve, leaveVertexNeighborhood has given us
1332
- // the intersection point and we can immediately shade.
1333
- } else {
1334
- // In all other cases, we need to raytrace before we shade.
1335
- ray_trace(ray_tet_space);
1632
+ if (!traceInsideVertexNeighborhood()) {
1633
+ // Check whether we are in a horosphere or Margulis tube and if yes,
1634
+ // whether the ray hit a peripheral curve.
1635
+ if (leaveVertexNeighborhood(ray_tet_space)) {
1636
+ // If we hit a peripheral curve, leaveVertexNeighborhood has
1637
+ // given us the intersection point and we can immediately shade.
1638
+ return ray_tet_space;
1639
+ }
1336
1640
  }
1337
-
1641
+
1642
+ // In all other cases, we need to raytrace before we shade.
1643
+ ray_trace(ray_tet_space);
1644
+
1338
1645
  return ray_tet_space;
1339
1646
  }
1340
1647
 
@@ -1354,8 +1661,8 @@ vec3 sampleNonGeometricTexture(vec2 fragCoord)
1354
1661
 
1355
1662
 
1356
1663
  void main(){
1357
-
1358
- // Show text "Non-geoemtric"
1664
+
1665
+ // Show text "Non-geometric"
1359
1666
  if (isNonGeometric) {
1360
1667
  out_FragColor = vec4(sampleNonGeometricTexture(gl_FragCoord.xy), 1.0);
1361
1668
  return;
@@ -1383,14 +1690,14 @@ void main(){
1383
1690
  if (perspectiveType != perspectiveTypeHyperideal) {
1384
1691
  scaled_xy *= viewScale;
1385
1692
  }
1386
-
1693
+
1387
1694
  bool outsideView =
1388
1695
  perspectiveType == perspectiveTypeHyperideal &&
1389
1696
  length(scaled_xy) >= 0.5;
1390
1697
 
1391
1698
  if (outsideView) {
1392
1699
  total_color += vec3(1.0, 1.0, 1.0);
1393
- } else {
1700
+ } else {
1394
1701
  RayHit ray_hit = computeRayHit(scaled_xy);
1395
1702
  if (ray_hit.object_type != object_type_nothing) {
1396
1703
  min_depth = min(min_depth, tanh(ray_hit.dist));
@@ -1422,5 +1729,16 @@ void main(){
1422
1729
 
1423
1730
  // Divide by total number of subsamples.
1424
1731
  out_FragColor = vec4(total_color / float(subpixelCount * subpixelCount), 1);
1732
+
1733
+ if (crosshairs) {
1734
+ vec2 coord = gl_FragCoord.xy - floor(0.5 * screenResolution.xy) + vec2(0.5, 0.5);
1735
+ if (abs(coord.x) < 0.1 && abs(coord.y) < 0.1 * screenResolution.x) {
1736
+ out_FragColor.rgb = vec3(1.0) - out_FragColor.rgb;
1737
+ }
1738
+ if (abs(coord.y) < 0.1 && abs(coord.x) < 0.1 * screenResolution.x) {
1739
+ out_FragColor.rgb = vec3(1.0) - out_FragColor.rgb;
1740
+ }
1741
+ }
1742
+
1425
1743
  gl_FragDepth = min_depth;
1426
1744
  }