summaryrefslogtreecommitdiff
path: root/graphics/asymptote
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-30 03:00:43 +0000
committerNorbert Preining <norbert@preining.info>2019-09-30 03:00:43 +0000
commitbbbe8128e7ae9d816a221377dbf5ff3969bb203b (patch)
tree0283a521760b879b30e61872f14f235645745675 /graphics/asymptote
parent14ce8b68fe7df49e8a8891bb94c63b9a846da232 (diff)
CTAN sync 201909300300
Diffstat (limited to 'graphics/asymptote')
-rw-r--r--graphics/asymptote/ChangeLog1411
-rw-r--r--graphics/asymptote/GUI/icons_rc.py2962
-rw-r--r--graphics/asymptote/Makefile.in25
-rw-r--r--graphics/asymptote/README4
-rw-r--r--graphics/asymptote/ReleaseNotes15
-rw-r--r--graphics/asymptote/algebra3.cc1610
-rw-r--r--graphics/asymptote/algebra3.h480
-rw-r--r--graphics/asymptote/arcball.cc237
-rw-r--r--graphics/asymptote/arcball.h95
-rw-r--r--graphics/asymptote/asy-keywords.el2
-rw-r--r--graphics/asymptote/asy.list74
-rw-r--r--graphics/asymptote/asymptote.spec2
-rw-r--r--graphics/asymptote/base/plain_prethree.asy2
-rw-r--r--graphics/asymptote/base/shaders/fragment.glsl464
-rw-r--r--graphics/asymptote/base/shaders/vertex.glsl98
-rw-r--r--graphics/asymptote/base/three.asy5
-rw-r--r--graphics/asymptote/base/three_surface.asy90
-rw-r--r--graphics/asymptote/base/webgl/WebGLfooter.html10
-rw-r--r--graphics/asymptote/base/webgl/WebGLheader.html180
-rw-r--r--graphics/asymptote/base/webgl/asygl-1.00.js39
-rw-r--r--graphics/asymptote/bbox3.h104
-rw-r--r--graphics/asymptote/beziercurve.cc153
-rw-r--r--graphics/asymptote/beziercurve.h124
-rw-r--r--graphics/asymptote/bezierpatch.cc620
-rw-r--r--graphics/asymptote/bezierpatch.h231
-rw-r--r--graphics/asymptote/binaries/i386-windows/README4
-rw-r--r--graphics/asymptote/binaries/x86_64-windows/README4
-rw-r--r--graphics/asymptote/build-scripts/HOWTO-MSWindows8
-rwxr-xr-xgraphics/asymptote/build-scripts/build-asygl21
-rwxr-xr-xgraphics/asymptote/build-scripts/build-freeglut22
-rw-r--r--graphics/asymptote/config.h.in9
-rwxr-xr-xgraphics/asymptote/configure31
-rw-r--r--graphics/asymptote/configure.ac11
-rw-r--r--graphics/asymptote/doc/CAD.pdfbin67528 -> 167754 bytes
-rw-r--r--graphics/asymptote/doc/FAQ/asy-faq.info2
-rw-r--r--graphics/asymptote/doc/Makefile.in31
-rw-r--r--graphics/asymptote/doc/TeXShopAndAsymptote.pdfbin31566 -> 77408 bytes
-rw-r--r--graphics/asymptote/doc/asy-latex.pdfbin194549 -> 194549 bytes
-rw-r--r--graphics/asymptote/doc/asy.133
-rw-r--r--graphics/asymptote/doc/asyRefCard.pdfbin53680 -> 121144 bytes
-rw-r--r--graphics/asymptote/doc/asymptote.pdfbin1290552 -> 1294522 bytes
-rw-r--r--graphics/asymptote/doc/asymptote.texi170
-rw-r--r--graphics/asymptote/doc/png/Makefile.in4
-rw-r--r--graphics/asymptote/doc/png/asymptote.info925
-rw-r--r--graphics/asymptote/drawelement.h115
-rw-r--r--graphics/asymptote/drawpath3.cc181
-rw-r--r--graphics/asymptote/drawpath3.h36
-rw-r--r--graphics/asymptote/drawsurface.cc403
-rw-r--r--graphics/asymptote/drawsurface.h174
-rw-r--r--graphics/asymptote/examples/Klein.asy2
-rw-r--r--graphics/asymptote/examples/Sierpinski.asy2
-rw-r--r--graphics/asymptote/examples/SierpinskiSponge.asy11
-rw-r--r--graphics/asymptote/examples/logo3.asy4
-rw-r--r--graphics/asymptote/examples/pdb.asy4
-rw-r--r--graphics/asymptote/examples/shellmethod.asy2
-rw-r--r--graphics/asymptote/examples/triangles.asy4
-rw-r--r--graphics/asymptote/examples/vertexshading.asy5
-rw-r--r--graphics/asymptote/examples/washermethod.asy2
-rw-r--r--graphics/asymptote/fileio.h9
l---------graphics/asymptote/gl.js1
-rw-r--r--graphics/asymptote/glew.c4
-rw-r--r--graphics/asymptote/glrender.cc920
-rw-r--r--graphics/asymptote/glrender.h285
-rw-r--r--graphics/asymptote/jsfile.cc218
-rw-r--r--graphics/asymptote/jsfile.h55
-rw-r--r--graphics/asymptote/main.cc6
-rw-r--r--graphics/asymptote/material.h35
-rw-r--r--graphics/asymptote/pair.h21
-rw-r--r--graphics/asymptote/patches/README3
-rw-r--r--graphics/asymptote/patches/gl-matrix-2.4.0-pruned.patch608
-rw-r--r--graphics/asymptote/path3.h8
-rw-r--r--graphics/asymptote/pen.h6
-rw-r--r--graphics/asymptote/picture.cc205
-rw-r--r--graphics/asymptote/picture.h9
-rw-r--r--graphics/asymptote/pipestream.cc2
-rw-r--r--graphics/asymptote/prcfile.h1
-rw-r--r--graphics/asymptote/quaternion.h114
-rw-r--r--graphics/asymptote/revision.cc2
-rw-r--r--graphics/asymptote/runarray.cc516
-rw-r--r--graphics/asymptote/runarray.in48
-rw-r--r--graphics/asymptote/runmath.cc267
-rw-r--r--graphics/asymptote/runmath.in23
-rw-r--r--graphics/asymptote/runpicture.cc402
-rw-r--r--graphics/asymptote/runpicture.in12
-rw-r--r--graphics/asymptote/settings.cc36
-rw-r--r--graphics/asymptote/settings.h5
-rw-r--r--graphics/asymptote/shaders.cc8
-rw-r--r--graphics/asymptote/shaders.h5
-rw-r--r--graphics/asymptote/tr.cc7
-rw-r--r--graphics/asymptote/tr.h1
-rw-r--r--graphics/asymptote/triple.h97
-rw-r--r--graphics/asymptote/util.h2
-rw-r--r--graphics/asymptote/webgl/WebGLfooter.html17
-rw-r--r--graphics/asymptote/webgl/WebGLheader.html172
-rw-r--r--graphics/asymptote/webgl/arcball-0.01.js67
-rw-r--r--graphics/asymptote/webgl/arcball-min-0.01.js1
-rw-r--r--graphics/asymptote/webgl/arcball.js67
-rw-r--r--graphics/asymptote/webgl/data.js47
-rw-r--r--graphics/asymptote/webgl/gl-0.01.js738
-rw-r--r--graphics/asymptote/webgl/gl-matrix-min-2.3.2.js29
-rw-r--r--graphics/asymptote/webgl/gl.js2756
-rw-r--r--graphics/asymptote/webgl/glm-js-min-2.2.2.js273
102 files changed, 9803 insertions, 9562 deletions
diff --git a/graphics/asymptote/ChangeLog b/graphics/asymptote/ChangeLog
index e329086041..0730b26ab4 100644
--- a/graphics/asymptote/ChangeLog
+++ b/graphics/asymptote/ChangeLog
@@ -1,3 +1,1395 @@
+commit 1c26011ea8a7fdfba9725ae52ac308970bf2df24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 29 03:04:36 2019 -0600
+
+ Silence Apple's OpenGL deprecation warning.
+
+commit bd6cef0ac6a2e4bce49c92a8ecc792473286b7d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 29 03:02:07 2019 -0600
+
+ Silence Apple's OpenGL deprecation warning.
+
+commit 908bfa8c1114af3098367b8a87866f3a08951d02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 29 02:41:34 2019 -0600
+
+ If lighting is enabled, ignore specified vertex colors for PRC. To override
+ this backwards incompatibility and recover the previous behaviour,
+ manually disable lighting when drawing a surface s:
+ draw(s,prc() ? nolight : currentlight);
+
+commit 5beec3197c5692b45dfe487d55a1d6eaddeb0a6f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 29 01:22:14 2019 -0600
+
+ Ignore null surfaces; restore example.
+
+commit 7e2cf9efabb7506649c401ece5f80c4178177b73
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 28 23:09:43 2019 -0600
+
+ Port to MSDOS.
+
+commit bcf31e3f3e9ed3fb876312f793d89543f2e70d17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 28 02:42:53 2019 -0600
+
+ Install webgl files; clean up GUI files on uninstall.
+
+commit 1b6150e70bc601c65af304d12f286cc64363557f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 28 01:54:30 2019 -0600
+
+ Document WebGL interface.
+
+commit 8c94986e48dcb1d4ec88ff7c0c87f4ac4d5757d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 28 00:13:44 2019 -0600
+
+ Use aspect ratio for fitting; adjust arcball radius to account for viewportmargin; make interaction constants asy settings.
+
+commit 5c5ce0424f990db9fa8da644bab334b4b74cbe0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 28 00:13:16 2019 -0600
+
+ Update asygl.
+
+commit 3d1242fc2f31aac1d4e5e297feb403b8e1ca1a51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 27 18:12:02 2019 -0600
+
+ Define absolute in gl.js.
+
+commit 77deba7f33213ae0cba2c34b0d26878d0baf28ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 27 18:10:49 2019 -0600
+
+ Update asygl.
+
+commit 9c4690bf1114f9d0526c72619826176c74ad82da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 27 17:47:01 2019 -0600
+
+ Reduce size of asygl by including only required subset of gl-matrix.
+
+commit 1208b33104c5b5b7a2a6fc3f3ad9165dfea92909
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 27 17:43:13 2019 -0600
+
+ Update asygl.
+
+commit 77206a8af882bd1f7388df810c9c9c30e6b56f06
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 27 13:04:09 2019 -0600
+
+ Expand webgl viewport to fit window; remove webglscale; rename devicepixel to absolute; add WindowTrim.
+
+commit 0ca3d60f01986f0ea89ccfd328bf361f29d73680
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 27 13:02:49 2019 -0600
+
+ Update asygl.
+
+commit 34977d2b4808156d276bcbb976ed9c9ec5a8b97b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 27 02:55:05 2019 -0600
+
+ Add webglscale and devicepixels options; implement shrink/expand viewport keys.
+
+commit 1ddada67255f9e61349bb5d7f2ce667108bba9db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 27 02:54:17 2019 -0600
+
+ Update asygl.
+
+commit 9b0f5a6ae6cd37d337ae2637d1c71d289f239c15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 26 03:32:37 2019 -0600
+
+ Avoid dvipdf dependency for building documentation.
+
+commit ff4b38c9e101ece6d2c6ba21e93bc1f7d8c15364
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 26 03:10:01 2019 -0600
+
+ Support --disable-gl again; ignore settings.render for WebGL output; account for devicePixelRatio; increase default viewportmargin to 0.5.
+
+commit ff25ef4b12699218459b62273c775b421f8f0fe9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 26 03:06:38 2019 -0600
+
+ Update asygl.
+
+commit 19528ced5dec8cdb502fcb63ffa6ae0b457b2f04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 25 22:52:43 2019 -0600
+
+ Replace arcball with simpler version backported from webgl; fix RotateX and Y.
+
+commit b1f630df463467db272330d9136915681bf1e30c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 25 21:06:36 2019 -0600
+
+ Fix segmentation fault.
+
+commit b232cc52137473a9db16f56c2d275c96b9d7f748
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 25 19:22:57 2019 -0600
+
+ Change rotation matrix back to 4x4.
+
+commit 848376cb50be96143325607f05e0d7a081f0867c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 25 11:45:33 2019 -0600
+
+ Move webgl files to base directory.
+
+commit 0224793b9a347e5d2ca7985e76783bdee2bb598b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 25 11:15:59 2019 -0600
+
+ Fix vector length in normMouse; improve build-asygl.
+
+commit 8388736d5dffa20d4a10886de99a08a3e18dc6b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 25 03:32:59 2019 -0600
+
+ Add offline WebGL option.
+
+commit 37425ee28f676e2da11d9be7052b0dab28ea4c36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 25 03:03:22 2019 -0600
+
+ Combine javascript libaries for faster loading; remove obsolete files;
+ add asygl environment variable to specify asygl library.
+
+commit 9e815e6e659fa873ae5b665566ae3691c8caa57f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 25 02:59:36 2019 -0600
+
+ Add LGPL license; avoid multiple matrix creations; simplify arcball.
+
+commit 0f30a12889852d3d9dc83437ed0e19d048128230
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 24 14:48:39 2019 -0600
+
+ Simplify webgl output of indexed triangles.
+
+commit 994c14bb4ac4c6bc00b986b5297c267cdb98bb92
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 24 10:43:25 2019 -0600
+
+ By default, use vertex indices for normal and color indices of indexed triangles.
+
+commit f5c79f97e5dc64a3183e1e6fd0a8f2a7417c1f7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 24 01:06:04 2019 -0600
+
+ Include html comments.
+
+commit ca37df6f334784f278ac0edf708670c2bdcf49b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 24 00:12:45 2019 -0600
+
+ Add viewportmargin setting.
+
+commit e2aca7045e65c11e4a1250f99eb9002803ebcdf9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 23 23:20:01 2019 -0600
+
+ Add missing offscreen checks.
+
+commit 6defe942af805b4ff7659f56ea43784a5193ef7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 23 23:03:31 2019 -0600
+
+ Simplify code.
+
+commit 6fe7fc69fe8e49eed45b6acaa59bc2b1dee7ddc2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 23 22:48:09 2019 -0600
+
+ Add offscreen detection to indexed triangles.
+
+commit a8bc5263f72d87ca005d3d97f2a13037770b56ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 23 21:54:04 2019 -0600
+
+ Simplify code.
+
+commit 25b87d0dedc04180e36678963f59d6d0ed075cd2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 23 21:37:21 2019 -0600
+
+ Fix tiling.
+
+commit 1c442690870ffe6499012f799b97a41f6f6a8efc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 23 21:23:17 2019 -0600
+
+ Implement webgl indexed triangles.
+
+commit a05450337791d59966d12fedecb19e73bebc2415
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 23 03:11:35 2019 -0600
+
+ Implement faster WebGL and OpenGL rendering, with improved offscreen detection.
+
+commit 07ee50be15e9968de2e1a6f70c00392785bb5028
+Merge: 4dcd549b 5e911430
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 23 01:27:26 2019 -0600
+
+ Merge branch 'master' into webgl.
+
+commit 5e91143045a807b6c6ba60a125b4220dad6a65bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 23 01:11:37 2019 -0600
+
+ Fix default value of file word() and documentation.
+
+commit 4dcd549b91ff8afe8855ddc20e6756b1e9c9d42e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 20 23:01:28 2019 -0600
+
+ Simplify code.
+
+commit fe2cab3b8086e3de638efc1008f69325f6bac8de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 20 22:57:39 2019 -0600
+
+ Minor optimization.
+
+commit 6c30c8662563b66a724a1a0dddae20e60bd497ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 20 08:11:05 2019 -0600
+
+ Don't test for pow and sqrt which are sometimes implemented in hardware.
+
+commit 150d007d0a0c9e5fc40fd85f660a0377aab67b1f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 19 10:19:21 2019 -0600
+
+ Simplify code.
+
+commit 902fc9bf7e01b270492a2f51260646b3fdef06f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 19 09:32:18 2019 -0600
+
+ Optimize bbox2; rename norender to remesh and add missing return value.
+
+commit 077d8fd4e631da44cc93fb4a8c94f55841989dac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 19 02:49:28 2019 -0600
+
+ Fix offscreen detection; discard rendered data once it goes offscreen.
+
+commit 49e21b13812931778e1385d82412373723b3b1bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 17 23:39:07 2019 -0600
+
+ Shrink nonbillboard material buffer by 7%.
+
+commit 9177fba6a47e79f9e2c21c5f1f76c483e55a4d02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 16 16:46:26 2019 -0600
+
+ Conditionally view html file.
+
+commit a2bb8be9c68dc825477dd03db772b9a0abbeae02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 16 16:18:43 2019 -0600
+
+ Optimize bounding box computation.
+
+commit a0f04aa0c2971e89161e6c459829edb0aefdca7d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 16 13:52:35 2019 -0600
+
+ Improve OpenGL straight optimization for curves.
+
+commit 25a04e41dc579c5a2ef66110500aea587abd09b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 16 13:21:21 2019 -0600
+
+ Fix order of PRC and webgl quad colors.
+
+commit 73b8974d343dc370ec459acf0bc2718165313b71
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 16 00:03:39 2019 -0600
+
+ Optimize offscreen in bezierpatch.h; remove unused code.
+
+commit b9866ef6ab0faa0c713cab7b03fe276257cb5217
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 15 22:24:41 2019 -0600
+
+ Add interface to html viewer.
+
+commit 24a3e54cd3e06d89869444eb6c8e07487dafe911
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 15 21:43:45 2019 -0600
+
+ Reformat webgl header and footer.
+
+commit 573369c22e52e2b4d3424ef1e0e8e4607572f7b4
+Merge: e6580bf3 221e1542
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 15 18:52:46 2019 -0600
+
+ Merge branch 'webgl'.
+
+commit 221e154209664025595ab423df0220649c084b5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 15 18:50:45 2019 -0600
+
+ Optimize straight webgl lines.
+
+commit 7b36db5c4d07a7632a613c9652e5480ecaf022cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 15 18:33:14 2019 -0600
+
+ Fix webgl quad normal.
+
+commit 712af1c6a75d2d19d85e8b5a4cd71604bc5feb33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 15 18:14:40 2019 -0600
+
+ Add straight optimization to webgl.
+
+commit a33ade59a16fea0df08ee9b7bbc1d06440b0b859
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 15 16:28:34 2019 -0600
+
+ Implement webgl pixel shader.
+
+commit 75ec09fc0bb7195580b57e40657ec0e00d46064e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 15 12:20:22 2019 -0600
+
+ Remove duplicate code.
+
+commit e6580bf30d1ecd8f96a4b7e48adfcaa2a5d24fd5
+Merge: f40bd919 cc4115dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 15 01:03:28 2019 -0600
+
+ Merge branch 'webgl'.
+
+commit cc4115dd23fd4fb69951d5053ce615551b07cc86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 14 23:50:33 2019 -0600
+
+ Pass asy lighting parameters; don't composite canvas with background.
+
+commit f55f0def02b723db059ddc790d29db077986e1ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 14 23:46:31 2019 -0600
+
+ Use 4x4 viewMat again (for correct lighting under rotation).
+
+commit a9146b8722a727d1daa11580609189e2ba3a8bf0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 14 18:17:41 2019 -0600
+
+ Fix ViewPosition; use a 3x3 view matrix.
+
+commit 31d49e55e82774285ac015b16f8969579c43d7c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 14 11:09:55 2019 -0600
+
+ Add settings.digits to control default output file precision.
+
+commit bd8cd4877ebb7c73cb83a767721dfc858dfe8d57
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 14 01:00:33 2019 -0600
+
+ Standardize matrix names.
+
+commit 5ea4aaeae21c21e86535e5d5552a181be7222552
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 14 00:51:19 2019 -0600
+
+ Replace var by let.
+
+commit a1fdac350066487d3ffd66733ca59ce6dc11f6ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 14 00:49:53 2019 -0600
+
+ Further optimize Split3.
+
+commit a1a7a736a2e5ea3baaf66eec2d4df27984b2ba36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 14 00:46:40 2019 -0600
+
+ Optimize split.
+
+commit 8b46c31c8ae3d5d681f49d546e1bc8165ac96f0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 14 00:31:23 2019 -0600
+
+ Add webgl support for Bezier curves.
+
+commit 3975ba5416d9708e4c208ef508490571e7bdf985
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 13 17:42:45 2019 -0600
+
+ Detect navigator.vibrate.
+
+commit 381f82e9a2e7f220945d83b721832c157d4f4ac6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 13 02:51:20 2019 -0600
+
+ Indicate shift mode with vibration.
+
+commit 9d8b6c4f188ccc7539fb1ab4a6db2439e78567de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 12 09:59:01 2019 -0600
+
+ Remove unused arguments.
+
+commit f40bd919b1a2772f8ea696c0004b447ef6f21b11
+Merge: a6b55307 76978127
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 12 09:08:25 2019 -0600
+
+ Merge branch 'webgl'.
+
+commit 76978127a7d8b3dd68eb44e10ecf5c9c05c53972
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 12 09:07:57 2019 -0600
+
+ Allow for negative dot product.
+
+commit a6b5530720e91c8aa3b8ef2798ac24b0e814afec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 12 00:58:34 2019 -0600
+
+ Restore example.
+
+commit 56936ea472caf20f8e3d5e5420f35e8d35d62451
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 12 00:48:50 2019 -0600
+
+ Fix arcball radius; improve mobile interaction.
+
+commit 3b3b1b2efae71b494eadb4eb4b41fd0f1476d353
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 12 00:26:20 2019 -0600
+
+ Fix arcball numerical precision issues.
+
+commit e519ea37e36e4c1027b1b296b28a8d2e946c9f1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 11 23:16:09 2019 -0600
+
+ Add mobile shift; fix arcball normalization.
+
+commit 79abc5f0b321befc032d4eb7d15b75329d202b3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 11 19:34:02 2019 -0600
+
+ Improve zoom.
+
+commit 25e234d15a8ce05874f0951952aed0122532def8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 11 11:32:34 2019 -0600
+
+ Override scroll bar.
+
+commit 86de97f2460dc8a125e18772c31e750251481b22
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 11 11:08:39 2019 -0600
+
+ Implement pinch zoom.
+
+commit a9069b5771cf62effa2b6a5f46ac30b5766eb4ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 11 00:20:36 2019 -0600
+
+ Fix initial projection.
+
+commit f37794e9c12fbdd588f9afa8e2400f4c4cae3acd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 23:59:16 2019 -0600
+
+ Disable mobile scaling.
+
+commit 605c952986ab864f2d6ca8bea0b11fc5cd4ccb0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 23:58:03 2019 -0600
+
+ Disable mobile scaling.
+
+commit 2d0ed08cb4fabff9f7b5621feb3853902865d422
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 11:20:46 2019 -0600
+
+ Remove scroll bar.
+
+commit a3a319b856e16a71b228090ecf24dc735cc7248e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 10:44:59 2019 -0600
+
+ Remove webgl directory prefix from link to gl.js; add symbolic link.
+
+commit fcc609805e810ffe8e4775cc114297c60319a1de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 10:03:32 2019 -0600
+
+ Implement Bezier triangles in webgl.
+
+commit c532199499eec51b79c33a8a23d19daddceeeb93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 08:42:02 2019 -0600
+
+ Fix epsilon; move derivative and normal into BezierPatch.
+
+commit fa59a4840c2dcbdb54e8188f905460a32745576d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 08:27:53 2019 -0600
+
+ Fix undefined variable.
+
+commit 1341bf7f83a82780b98826c83f1619794a08a027
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 08:25:53 2019 -0600
+
+ Factor code.
+
+commit 99b00e26147feae6aff24b94ae83a5ac99c817e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 01:20:07 2019 -0600
+
+ Begin porting Bezier triangle code to webgl.
+
+commit 033ba1eb3a0aca3a46de957c89fad9c33ce8da4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 00:45:52 2019 -0600
+
+ Fix lighting after mode change.
+
+commit 2a174661224adc2fbc229b786baef60924761d74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 10 00:12:22 2019 -0600
+
+ Accumulate onscreen and partially offscreen triangles separately to avoid duplicate rendering.
+
+commit 49ea03ddbf861df3edcb3dcdae3922761cb5d785
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 9 19:40:59 2019 -0600
+
+ Clear buffers on construction.
+
+commit e3bd396ed745dae9171e44b89d2554ce67e5b0cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 9 18:30:00 2019 -0600
+
+ Simplify code.
+
+commit 5b1b569f3fb253000e7728419d2f9f9612fdc7e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 9 14:07:35 2019 -0600
+
+ Fix transparency bug; optimize colorShader and implement generalSHader.
+
+commit 61049a4ccd87e0aacd7498dd5c4d3c84960a7d18
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 9 11:51:27 2019 -0600
+
+ Sort transparent webgl triangles (based on centroid; to be improved).
+
+commit 0ec8f1841797c62a9a1ea83372f4fcb0880f3c00
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 9 09:34:28 2019 -0600
+
+ Fix missing initialization.
+
+commit 40ab227ba04a7e8ea1464af6864a074860e6fc3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 9 09:22:53 2019 -0600
+
+ Add transparent buffers.
+
+commit a401de1b5d3532f6d30c133eed0f4d07a0d8b182
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 23:40:43 2019 -0600
+
+ Fix webgl billboard labels.
+
+commit 503ba73bb4605ba5030f3d78c71f378ce654031b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 23:17:56 2019 -0600
+
+ Avoid depth check in offscreen computations.
+
+commit 5c4dcb69f3908b57333ee90af3408cbe857b891a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 21:50:08 2019 -0600
+
+ Optimize transpose away.
+
+commit a6132b5e1d7a93c43c37d4eb2e238900bc93ff0e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 17:47:34 2019 -0600
+
+ Update temporary hard-wired teapot light parameters.
+
+commit f2ffc7b52ed3d4a7e375d66fc827f25973afac39
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 17:29:20 2019 -0600
+
+ Standardize code.
+
+commit f008f017aa1cfce1bb9bb34d91ca8857a20cea7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 16:12:12 2019 -0600
+
+ Remove unwanted code.
+
+commit f8c22220b7dee93b97bca2a793df59e6e83ef664
+Merge: 4972f905 f1254f8d
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Sep 8 14:39:32 2019 -0600
+
+ Merge branch 'webgl' of github.com:vectorgraphics/asymptote into webgl
+
+commit 4972f90530c591c09030ae84e1f3118dff2d047d
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Sep 8 14:39:27 2019 -0600
+
+ Clean up gl.js again.
+
+commit f1254f8d7fa19053fc483231053d16103679a2e9
+Merge: cc7eb276 bad6b6d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 14:34:04 2019 -0600
+
+ Merge branch 'webgl' of github.com:vectorgraphics/asymptote into webgl.
+
+commit cc7eb276596404eba061fee63da9440db518ad03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 14:28:30 2019 -0600
+
+ Optimize bounding box computation; simplify code.
+
+commit bad6b6d57c23cddbe4fd823d6ca480997dab65c6
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Sep 8 14:25:09 2019 -0600
+
+ Minor fixes to norm matrix.
+
+commit 0c1da0e0dad92876e6254fec9d4625afb09c9614
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 02:36:18 2019 -0600
+
+ Batch calls to drawElements.
+
+commit 2106227eb55336e1189d99092258730b7583d403
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 8 01:03:59 2019 -0600
+
+ Prepare for batch drawing.
+
+commit 108509b7b304267883ac24081f8c7b8149773bab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 7 21:11:57 2019 -0600
+
+ Fix -noautobillboard.
+
+commit a9e980f35e2955ec58891850bac3258bb7b9b880
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 7 20:47:42 2019 -0600
+
+ Fix typos.
+
+commit 7ffa52cafeed9ff412a4c8dd79f894f6c001de5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 7 19:23:48 2019 -0600
+
+ Use separate material and center index for each vertex again (to support batch drawing and sorting).
+
+commit 17566e437c18c5cba8af049b03e064a0471006a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 7 14:24:13 2019 -0600
+
+ Use a 3x3 rotation matrix.
+
+commit b57b6298818cb7c561258c5f8f8e8d4724b1f0b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 7 03:52:50 2019 -0600
+
+ Simply billboard code and port to webgl.
+
+commit 9c34d1e914fc8033f0dce670db80017c40244f66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 6 15:08:28 2019 -0600
+
+ Enable webgl keyboard input.
+
+commit 4cddee557a7ee99117398522b64d532f8e34e9fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 6 14:31:46 2019 -0600
+
+ Standardize code.
+
+commit 3ad3e9447237dba8d2cbd643ecec931ce1c88aef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 6 13:05:09 2019 -0600
+
+ Fix conditional.
+
+commit b157bb70ab46e4e67060c838a7aa986c96a9a8a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 6 12:59:21 2019 -0600
+
+ Change shaders only when needed; remove duplicate code; improve OpenGL framerate calculation.
+
+commit 2b5a4e583a912357b95dd922a414590eae1ec421
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 6 10:57:51 2019 -0600
+
+ Remove extension requirement.
+
+commit 52e3053c3b2d9a78e54d24a456b5ac74f1f7f71b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 6 10:56:36 2019 -0600
+
+ Simplify code.
+
+commit 309bfd90f3d274d7763de078772faacd7151292a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 6 03:27:03 2019 -0600
+
+ Reduce size of webgl data buffers.
+
+commit c33716757576e0534bad2615b1a608bed98059f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 5 10:24:18 2019 -0600
+
+ Fix material index for explicit colors; standardize code.
+
+commit 1bd14971f286c5c83e0f1732523923d3da08b37f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 5 03:02:03 2019 -0600
+
+ Simplify code.
+
+commit f40c3eda4725acecd410cac7243e84053a78d233
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 5 02:53:35 2019 -0600
+
+ Support vertex shading.
+
+commit f2e5df6d331708c01f374feef5f70f0d75999c7d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 4 18:19:47 2019 -0600
+
+ Optimize webgl buffers.
+
+commit ef1cd85d7183d8399e150fdd8d4633fa8cb7adfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 3 22:09:30 2019 -0600
+
+ Simplify and optimize code.
+
+commit 7b3cd7101983c837c866eaa5540f26718b797d76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 3 18:58:12 2019 -0600
+
+ Recompute offscreen limits at every render.
+
+commit ee547cbd9facf472ea5ef6a504f7103f1aaec51b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 3 08:26:47 2019 -0600
+
+ Optimize shader communication.
+
+commit 68f921caf3a603603616f82175916eb768c2161b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 3 01:11:20 2019 -0600
+
+ Reimplement billboard labels to allow remesh suppression.
+
+commit 1e2d7c8f77dcd4dbf9cc0e3f7147ef1c492b51f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 3 01:02:10 2019 -0600
+
+ Fix typo.
+
+commit 7192656cca9bb3607ed5b62b7330e6a7e4e0e97e
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Sep 2 15:19:19 2019 -0600
+
+ Fix almost all problem, except for offscreen glitch.
+
+commit 173a2c40056c9a23470d2ad8e931a97251471a6e
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Sep 2 14:17:37 2019 -0600
+
+ Also reset ship.
+
+commit 1bde5bc6489562642c4eaf6e68ac92413ef4fcae
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Sep 2 14:16:54 2019 -0600
+
+ Fix zoom clipping issue alongside translation.
+
+commit fe8e538c7109073442967cb638af94279788fc86
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Sep 2 14:01:30 2019 -0600
+
+ Add in revised zoom from asy.
+
+commit 78044058c643aa5e66bed5c70b0db55a5953b919
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 1 23:50:54 2019 -0600
+
+ Simplify code.
+
+commit 144f4615291a6486fdd7c2f16026240f18216538
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 1 22:02:22 2019 -0600
+
+ Output field-of-view angle.
+
+commit 1c116f53a002b66b43b315fd2e2730dc1eed6d3e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 1 20:10:49 2019 -0600
+
+ Add missing offscreen code.
+
+commit c255024cc0a6d66dd3ce2e5279e1a65fb0b0e828
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 1 11:57:17 2019 -0600
+
+ Compute pMatrix from b and B bounds.
+
+commit faf496185b9b48688f9e68b0882f16ec01d5b806
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 1 11:36:40 2019 -0600
+
+ Fix duplicate multiply.
+
+commit eb75489e0f7d739b6f2ce707ae3ae7a9176ded19
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 1 11:35:04 2019 -0600
+
+ Port offscreen code to webgl.
+
+commit 7a2fe8d7e409f33d19f860083ee71060866d8304
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 1 03:53:55 2019 -0600
+
+ Re-enable remesh suppression with offscreen check.
+
+commit fb3e1aa648c78d0c8f3c156b8f68971049c77085
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 31 19:14:37 2019 -0600
+
+ Improve zoom.
+
+commit aa2f9e5bcdb6aaf4fc960a0448bbd04c6c174e53
+Merge: 11577411 11b7f3b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 31 14:21:25 2019 -0600
+
+ Merge branch 'master' into webgl.
+
+commit 11b7f3b4400f6c648ad2ccabe9ab06c275fd1f3f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 31 14:21:16 2019 -0600
+
+ Fix pipeclose (cf. 0d057d35cb30d52f33db9f155c880ed8f8a1d7d2).
+
+commit 115774110bd39a7609620600999c63eb0823ffb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 31 13:17:52 2019 -0600
+
+ Remove unused argument.
+
+commit 389543c6b829bab8b8aa1c3f852263d41101079c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 31 12:57:29 2019 -0600
+
+ Optimize and simplify OpenGL shaders.
+
+commit 9ce5cfef9a1c6ea054b1d141d8b7d766c0b8f3cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 31 03:13:24 2019 -0600
+
+ Port to webgl1.0.
+
+commit 26f329d066b8b291adf7b63b61301b6f69e288a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 31 00:45:49 2019 -0600
+
+ Remove duplicate constants.
+
+commit 16a912ce5563f6436094a0f8e2bbb878cadccd9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 31 00:39:34 2019 -0600
+
+ Support rendering on mobile devices.
+
+commit d0e14808336642f9eabc38d66d357bbf13486f4d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 30 14:38:21 2019 -0600
+
+ Fix normals.
+
+commit cbccb294ccc2f27a4d0924b3f7337c432e3b98b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 30 14:04:45 2019 -0600
+
+ Standardize code.
+
+commit 3d4ded0b3b871a6331dd14ae3479ebb1c15ceb8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 30 13:40:45 2019 -0600
+
+ Simplify normal code.
+
+commit b5a083516a854317e9e88e7def584a3f9a907c57
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 30 01:35:03 2019 -0600
+
+ Update normal code.
+
+commit 78e4ac384d904e09c05684da6d0eb723878f73bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 30 01:18:09 2019 -0600
+
+ Remove unused variable.
+
+commit 699dd53413ad111d211ed2f616bab85f6162f0cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 30 01:16:47 2019 -0600
+
+ Update subdivision crack code.
+
+commit 9958d795eead1be55e3014fec378695682b5b202
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 30 00:05:08 2019 -0600
+
+ Support webgl output with -V -threads.
+
+commit 385c61e1b211b019641c5cd50ce54b71551f7943
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 29 21:33:58 2019 -0600
+
+ Simplify code.
+
+commit 35442f0834befc227b88c26ed7deb79e14f7628a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 29 21:12:10 2019 -0600
+
+ Fix nMaterials; remove generated file.
+
+commit 1839307bfa3cb7521293ccdd05ec1507cf7ebe53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 29 19:47:01 2019 -0600
+
+ Revert broken commit "Add back nMaterials."
+
+ This reverts commit ef0b19a7d1ccd37b80705c0cbaf42f8eb5470b1c.
+
+commit ef0b19a7d1ccd37b80705c0cbaf42f8eb5470b1c
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 19:24:02 2019 -0600
+
+ Add back nMaterials.
+
+commit 71d59116a67658e8bb078c79f6f1e59fcf6e1060
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 19:15:54 2019 -0600
+
+ Update Author's name.
+
+commit 8964dd0782bff658a3f2d475e10c3c38964ef607
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 19:14:55 2019 -0600
+
+ Add in authors names.
+
+commit afc2a146dd755fc19adbdba7f7aa28aab5a9b45d
+Merge: 04feea56 306f6df4
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 19:08:19 2019 -0600
+
+ Merge branch 'webgl' of github.com:vectorgraphics/asymptote into webgl
+
+commit 04feea5687b53250825e77356b5aad4961f17884
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 19:08:14 2019 -0600
+
+ Fix vViewPosition.
+
+commit 306f6df4e77d854c9890d4a14f8679e7e16f4ebf
+Merge: 63fb75af ff8cc6d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 29 19:07:05 2019 -0600
+
+ Merge branch 'webgl' of github.com:vectorgraphics/asymptote into webgl
+
+commit 63fb75aff713b84b005076aa50d141b2c7d88f3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 29 19:06:55 2019 -0600
+
+ Move further parameters into BezierPatch class; fix index.
+
+commit ff8cc6d326d163de250f28a2557f61701788037c
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 19:05:07 2019 -0600
+
+ Add in orthographic/persp view directions.
+
+commit acb3196c4d37930b0ef6d3fb2bee214222789593
+Merge: 60dd5701 ce412f94
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 18:49:49 2019 -0600
+
+ Merge conflict.
+
+commit 60dd5701d70540245e36d6f3d39594db39f2def6
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 18:49:15 2019 -0600
+
+ Make res per class.
+
+commit ce412f946f8b4736bcabe6bf2b462dd76bd933e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 29 18:46:40 2019 -0600
+
+ Fix resolution.
+
+commit 80c920eb626193a2aec793c01a7fb81f405466c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 29 17:58:12 2019 -0600
+
+ Pass resolution data to webgl.
+
+commit f494c725fb05f8245d1d3833028edb74a23cd184
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 15:46:50 2019 -0600
+
+ Remove cpy2web.
+
+commit 3037b5620c6263a1b001c45c1bcc029f1e29ed0b
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 29 15:04:23 2019 -0600
+
+ Allow for custom vertex structures.
+
+commit 88d8ea20543c476bde8d41d8c9132e03b64078c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 29 11:06:17 2019 -0600
+
+ Support webgl output with threads.
+
+commit 5f47e4e35ddd76d7bcae651aa1ef956e200cb12f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 23:23:29 2019 -0600
+
+ Add in blend func.
+
+commit 072db3837ccd0526f6bbc3437ec411f1a12fab5d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 23:18:33 2019 -0600
+
+ Add in preliminary transparency.
+
+commit d1fdc0c19df823ab6bd79420b457197ffc6abcec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 23:10:25 2019 -0600
+
+ Remove diagnostic.
+
+commit 51c17fc6062f43818eb0e7456bd4e52941875fba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 23:03:01 2019 -0600
+
+ Add material index.
+
+commit c63b11b282a018eab64aebb87a22e96dbe1d6394
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 21:40:20 2019 -0600
+
+ Begin material support.
+
+commit 9a31b248de24ad18dc988ca9cbbcc536f4bc9f58
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 17:54:03 2019 -0600
+
+ FIx gitignore.
+
+commit 864ec8c2519da4a4576be291a554342a0eddd332
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 17:52:35 2019 -0600
+
+ Minor cleanups and enable emissive.
+
+commit ac2aa94fa9d59a879d84025ca74804812bcf7fa1
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 17:32:58 2019 -0600
+
+ Fix float arrays flag.
+
+commit 3de4371ce380c2185d7f483f02e2abd48abc55f1
+Merge: dc9692dd 2ad31cb3
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 17:31:23 2019 -0600
+
+ Merge branch 'webgl' of github.com:vectorgraphics/asymptote into webgl
+
+commit dc9692dde857f1e57fc097adee2041443a2b1134
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 17:31:10 2019 -0600
+
+ Only create array when needed.
+
+commit 2ad31cb325dc8106ce4dc8f711dd1864f3f1ddda
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 17:29:42 2019 -0600
+
+ Simplify code; remove generated file.
+
+commit 3b7616ab660d553032d4f0d35a21d0a4c47ca39d
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 17:03:15 2019 -0600
+
+ Add a DrawableObject for general drawables.
+
+commit 4c06bf02ebba1bd20d30fb00edea9afac2e1e408
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 16:59:05 2019 -0600
+
+ Even more refractoring of code.
+
+commit 3c831c65c004549b1ad50cf21aae0bb0bf658074
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 16:51:44 2019 -0600
+
+ More refractorings of gl.js.
+
+commit 00bda50add1752053360384b34a80b519060ee4b
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 16:31:59 2019 -0600
+
+ Refractor gl.js code.
+
+commit c62534e2dac23166a0905bff68a2956f64cc7600
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 15:50:45 2019 -0600
+
+ Clean up gl.js.
+
+commit f5068d75f0891a5968c98cfe53e352b4def86aef
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 15:01:52 2019 -0600
+
+ Expose model Matrix transformation and more docs.
+
+commit 3d48b756c0f593fb63e54a991ce5e4b1bd0da9ed
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 02:50:00 2019 -0600
+
+ Add in zooming back.
+
+commit 2d362a692aa7105cc7020bba15bde86508dc9006
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 28 02:20:09 2019 -0600
+
+ Reglue back translation routine.
+
+commit 53c16fcd22a2f19cbea8f07c7054d1d9519d4806
+Merge: 4c9342e9 df4b5699
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 01:41:15 2019 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote.
+
+commit 4c9342e9dd114f4baeb94612f7bc85755aaba0f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 01:40:03 2019 -0600
+
+ Fix last commit.
+
+commit df4b5699744d668ae4cb4367d2ab5f5cf039cc1b
+Merge: 5b876724 52d3e4d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 01:36:05 2019 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 5b87672473974e5dc32c2f11b2afd81ffdc22372
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 01:35:54 2019 -0600
+
+ Simplify glew compilation.
+
+commit b2a6fff4e97192c5bd42b5eed689d3aa0e0c7b14
+Merge: 64d3f620 52d3e4d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 01:07:42 2019 -0600
+
+ Remove DOS line terminators.
+
+commit 52d3e4d670a8ca843302280c7b02462eb672945d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 28 01:04:23 2019 -0600
+
+ Remove spurious DOS line terminators from shader files.
+
+commit 64d3f620dc2d49924b1ac9a14cc5c520d2d43d9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 27 22:44:54 2019 -0600
+
+ Output canvas dimensions; support threads.
+
+commit 78e5646fc84ec2609bbe22850ccb82eb568ee8d7
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 27 17:32:12 2019 -0600
+
+ Add in temporary canvas height/width.
+
+commit ac8cbda3cc382a0ceb632fe3930cb5351a50468f
+Merge: 8f7b2711 97e03e6d
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 27 17:27:08 2019 -0600
+
+ Merge branch 'webgl' of github.com:vectorgraphics/asymptote into webgl
+
+commit 8f7b271188a337569ed5510434cdef82c5c19503
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 27 17:27:03 2019 -0600
+
+ Allow dynamic setting of canvas size.
+
+commit 97e03e6de3b7599dc4d78f28438f956c327b94aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 27 17:26:32 2019 -0600
+
+ Output target to webgl.
+
+commit 601ebbadadb2ef652ec4b9062443e412b7a1f314
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 27 16:52:06 2019 -0600
+
+ Fix warning message.
+
+commit bff8f83e6b6b72a977a63576e27672d4cb445b8b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 27 16:36:30 2019 -0600
+
+ Compile glew library with -O1 to help out clang compiler.
+
+commit ebe09e1b398b244c3a1163e2dea804829fe2d63f
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 27 16:36:22 2019 -0600
+
+ Split jsfile into its own cc file.
+
+commit d7cfc3e099ff4b094a2b864c3f43559d7257b8ba
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 23 17:27:53 2019 -0600
+
+ Change jsfile to handle new p properly.
+
+commit 6fc0875e2ed6c3ef9108d0103615d8f1f5264ca7
+Merge: 2fe6c372 fa9cfab0
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 23 17:22:06 2019 -0600
+
+ Merge in jsfile changes.
+
+commit 2fe6c372d13a67e4da203aeeffec99c0a5725fd2
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 23 17:20:41 2019 -0600
+
+ Add multiple materials detection and shader generation.
+
+commit fa9cfab02ccda80ffae9de90f0dcd5291d1a6d14
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 23 17:16:32 2019 -0600
+
+ Add multiple patch support.
+
+commit 40aeca47850dd5dd3295abb77d8c3d5c06347624
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 23 16:10:38 2019 -0600
+
+ Add arcball rotation.
+
+commit 7325cd22c2ae15edc47dbc3685ea7bed775b1c86
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 23 14:45:42 2019 -0600
+
+ Add in material index data.
+
+commit 23846f565b4575b0ac410a9ec2d795ecb2978442
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 23 00:08:40 2019 -0600
+
+ Change resolution and minor cleanups.
+
+commit 85b3fd03061bcf3e8d0703295ec32d24a8792111
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 21 16:37:20 2019 -0600
+
+ Add webgl option to glrender.
+
+commit 9bfd0c90ef80dfcbd28422cc6348f1bf943a5cd7
+Merge: 05461c69 3d714156
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 21 16:28:09 2019 -0600
+
+ Merge branch 'webgl' of github.com:vectorgraphics/asymptote into webgl
+
+commit 05461c6965b795aec295c3d40bbdcb766b652bbf
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 21 16:27:10 2019 -0600
+
+ Update settings to prevent autoformat.
+
+commit 3d714156611362e7a919c7bdedee31eb52f51ef3
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 21 16:27:10 2019 -0600
+
+ Update .gitignore.
+
+commit 3ca5d56f78d8c559cd76f5e3b76b147e58203425
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 21 16:23:42 2019 -0600
+
+ Fix gl.js vertex function.
+
+commit 98a67e304b975c141ff16011fa9ea5eee15c671f
+Merge: 56076839 7f1fba23
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 21 15:58:08 2019 -0600
+
+ Update webgl files.
+
+commit 7f1fba235a28189d306312c09b43352e1d047932
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 21 10:47:38 2019 -0600
+
+ Generalize popcount to systems that lack 64-bit integers.
+
+commit 4500dd6b84fae216df649a32c57b70f225883fd1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 21 02:53:55 2019 -0600
+
+ Update HOWTO-MSWindows.
+
+commit c9ee6dc1dbb22d65311639c28ceb5c7bb1391431
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 21 01:36:17 2019 -0600
+
+ Increment version to 2.54.
+
commit 35867d43297d07045d52916bcd3d906f62f7b023
Author: John Bowman <bowman@ualberta.ca>
Date: Tue Aug 20 22:50:54 2019 -0600
@@ -52,12 +1444,25 @@ Date: Thu Aug 15 23:22:19 2019 -0600
Disable bulky and leaky OpenImageIO library by default.
+commit 56076839adb43e1a0bc99aa0019a4ff4c275f86b
+Merge: 46461352 94ac15f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 14 14:51:57 2019 -0600
+
+ Begin multiple patch support.
+
commit d84dd8cb79c8b0b85211643427eaa6ad1dba0a99
Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
Date: Wed Aug 14 12:15:13 2019 -0600
Add in development WebGL version.
+commit 4646135212088ec1c2572481c628b58f671b7ac8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 14 12:06:51 2019 -0600
+
+ Import webgl development files.
+
commit 94ac15f88e5723e38d4e4f3231944b538d8c17ec
Author: John Bowman <bowman@ualberta.ca>
Date: Wed Aug 14 01:36:04 2019 -0600
@@ -1766,6 +3171,12 @@ Date: Sat Sep 1 17:16:25 2018 -0600
Allow for proper buffer data transfer.
+commit 83c2b62df0132a310ce3d234fcc7be463b7795d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 31 22:11:50 2018 -0600
+
+ Begin development of webgl output.
+
commit adbb32fdd380304839cb401c76ea2ab662edfe65
Merge: 23c4bd2d df015058
Author: John Bowman <bowman@ualberta.ca>
diff --git a/graphics/asymptote/GUI/icons_rc.py b/graphics/asymptote/GUI/icons_rc.py
index d1b18d19f4..a49f69a1fd 100644
--- a/graphics/asymptote/GUI/icons_rc.py
+++ b/graphics/asymptote/GUI/icons_rc.py
@@ -9,160 +9,6 @@
from PyQt5 import QtCore
qt_resource_data = b"\
-\x00\x00\x03\x0c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x68\x65\x63\x6b\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\
-\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\
-\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\
-\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\
-\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\
-\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\
-\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
-\x4d\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x63\x2d\x30\
-\x2e\x34\x33\x35\x2c\x30\x2d\x30\x2e\x38\x34\x37\x2d\x30\x2e\x32\
-\x30\x33\x2d\x31\x2e\x31\x31\x31\x2d\x30\x2e\x35\x35\x33\x4c\x33\
-\x2e\x36\x31\x2c\x31\x31\x2e\x37\x32\x34\x63\x2d\x30\x2e\x34\x36\
-\x35\x2d\x30\x2e\x36\x31\x33\x2d\x30\x2e\x33\x34\x34\x2d\x31\x2e\
-\x34\x38\x36\x2c\x30\x2e\x32\x37\x2d\x31\x2e\x39\x35\x31\x0d\x0a\
-\x09\x63\x30\x2e\x36\x31\x35\x2d\x30\x2e\x34\x36\x37\x2c\x31\x2e\
-\x34\x38\x38\x2d\x30\x2e\x33\x34\x34\x2c\x31\x2e\x39\x35\x33\x2c\
-\x30\x2e\x32\x37\x6c\x32\x2e\x33\x35\x31\x2c\x33\x2e\x31\x30\x34\
-\x6c\x35\x2e\x39\x31\x31\x2d\x39\x2e\x34\x39\x32\x63\x30\x2e\x34\
-\x30\x37\x2d\x30\x2e\x36\x35\x32\x2c\x31\x2e\x32\x36\x37\x2d\x30\
-\x2e\x38\x35\x32\x2c\x31\x2e\x39\x32\x31\x2d\x30\x2e\x34\x34\x35\
-\x0d\x0a\x09\x63\x30\x2e\x36\x35\x33\x2c\x30\x2e\x34\x30\x36\x2c\
-\x30\x2e\x38\x35\x34\x2c\x31\x2e\x32\x36\x36\x2c\x30\x2e\x34\x34\
-\x36\x2c\x31\x2e\x39\x32\x4c\x39\x2e\x34\x37\x38\x2c\x31\x36\x2e\
-\x33\x34\x63\x2d\x30\x2e\x32\x34\x32\x2c\x30\x2e\x33\x39\x31\x2d\
-\x30\x2e\x36\x36\x31\x2c\x30\x2e\x36\x33\x35\x2d\x31\x2e\x31\x32\
-\x2c\x30\x2e\x36\x35\x36\x43\x38\x2e\x33\x33\x36\x2c\x31\x36\x2e\
-\x39\x39\x38\x2c\x38\x2e\x33\x31\x36\x2c\x31\x36\x2e\x39\x39\x38\
-\x2c\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x00\x6c\
-\x3c\
-\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\
-\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x3e\x3c\x70\x61\x74\x68\
-\x20\x64\x3d\x22\x4d\x31\x38\x20\x31\x32\x76\x31\x48\x38\x76\x35\
-\x6c\x2d\x36\x2d\x36\x20\x36\x2d\x36\x76\x35\x68\x38\x56\x32\x68\
-\x32\x7a\x22\x2f\x3e\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x03\x26\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x33\x38\
-\x38\x63\x2d\x37\x32\x2e\x35\x39\x37\x2c\x30\x2d\x31\x33\x32\x2d\
-\x35\x39\x2e\x34\x30\x35\x2d\x31\x33\x32\x2d\x31\x33\x32\x63\x30\
-\x2d\x37\x32\x2e\x36\x30\x31\x2c\x35\x39\x2e\x34\x30\x33\x2d\x31\
-\x33\x32\x2c\x31\x33\x32\x2d\x31\x33\x32\x63\x33\x36\x2e\x33\x2c\
-\x30\x2c\x36\x39\x2e\x32\x39\x39\x2c\x31\x35\x2e\x34\x2c\x39\x32\
-\x2e\x34\x30\x36\x2c\x33\x39\x2e\x36\x30\x31\x4c\x32\x37\x38\x2c\
-\x32\x33\x34\x68\x31\x35\x34\x56\x38\x30\x0d\x0a\x09\x09\x6c\x2d\
-\x35\x31\x2e\x36\x39\x38\x2c\x35\x31\x2e\x37\x30\x32\x43\x33\x34\
-\x38\x2e\x34\x30\x36\x2c\x39\x39\x2e\x37\x39\x38\x2c\x33\x30\x34\
-\x2e\x34\x30\x36\x2c\x38\x30\x2c\x32\x35\x36\x2c\x38\x30\x63\x2d\
-\x39\x36\x2e\x37\x39\x37\x2c\x30\x2d\x31\x37\x36\x2c\x37\x39\x2e\
-\x32\x30\x33\x2d\x31\x37\x36\x2c\x31\x37\x36\x73\x37\x38\x2e\x30\
-\x39\x34\x2c\x31\x37\x36\x2c\x31\x37\x36\x2c\x31\x37\x36\x0d\x0a\
-\x09\x09\x63\x38\x31\x2e\x30\x34\x35\x2c\x30\x2c\x31\x34\x38\x2e\
-\x32\x38\x37\x2d\x35\x34\x2e\x31\x33\x34\x2c\x31\x36\x39\x2e\x34\
-\x30\x31\x2d\x31\x32\x38\x48\x33\x37\x38\x2e\x38\x35\x43\x33\x36\
-\x30\x2e\x31\x30\x35\x2c\x33\x35\x33\x2e\x35\x36\x31\x2c\x33\x31\
-\x31\x2e\x37\x31\x32\x2c\x33\x38\x38\x2c\x32\x35\x36\x2c\x33\x38\
-\x38\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
-\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\x6c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x53\x61\x76\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
-\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
-\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
-\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
-\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\x3d\
-\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\x61\
-\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\
-\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x78\
-\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
-\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\
-\x31\x35\x2e\x31\x37\x33\x2c\x32\x48\x34\x43\x32\x2e\x38\x39\x39\
-\x2c\x32\x2c\x32\x2c\x32\x2e\x39\x2c\x32\x2c\x34\x76\x31\x32\x63\
-\x30\x2c\x31\x2e\x31\x2c\x30\x2e\x38\x39\x39\x2c\x32\x2c\x32\x2c\
-\x32\x68\x31\x32\x63\x31\x2e\x31\x30\x31\x2c\x30\x2c\x32\x2d\x30\
-\x2e\x39\x2c\x32\x2d\x32\x56\x35\x2e\x31\x32\x37\x4c\x31\x35\x2e\
-\x31\x37\x33\x2c\x32\x7a\x20\x4d\x31\x34\x2c\x38\x63\x30\x2c\x30\
-\x2e\x35\x34\x39\x2d\x30\x2e\x34\x35\x2c\x31\x2d\x31\x2c\x31\x48\
-\x37\x0d\x0a\x09\x43\x36\x2e\x34\x35\x2c\x39\x2c\x36\x2c\x38\x2e\
-\x35\x34\x39\x2c\x36\x2c\x38\x56\x33\x68\x38\x56\x38\x7a\x20\x4d\
-\x31\x33\x2c\x34\x68\x2d\x32\x76\x34\x68\x32\x56\x34\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
\x00\x00\x05\xca\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -258,85 +104,238 @@ qt_resource_data = b"\
\x36\x35\x2e\x32\x36\x36\x2c\x32\x38\x38\x2e\x30\x38\x2c\x34\x35\
\x30\x2e\x36\x37\x39\x2c\x32\x37\x33\x2e\x35\x7a\x22\x2f\x3e\x0d\
\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x04\xca\
+\x00\x00\x02\x7d\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\x72\
-\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\x75\
-\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x39\x2e\x32\x2e\x31\x2c\x20\
-\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\x2d\
-\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\x6e\
-\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\x20\
-\x20\x2d\x2d\x3e\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\x20\x73\
-\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\x57\x33\
-\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\x2f\x2f\
-\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\
-\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\x73\x2f\
-\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\x67\x31\
-\x31\x2e\x64\x74\x64\x22\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\
-\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x09\x20\x69\x64\x3d\
-\x22\x73\x76\x67\x34\x36\x31\x39\x22\x20\x69\x6e\x6b\x73\x63\x61\
-\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x31\
-\x2b\x64\x65\x76\x65\x6c\x2b\x6f\x73\x78\x6d\x65\x6e\x75\x20\x72\
-\x31\x32\x39\x31\x31\x22\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\
-\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x74\x72\x69\x61\x6e\x67\x6c\
-\x65\x2d\x73\x74\x72\x6f\x6b\x65\x64\x2d\x31\x35\x2e\x73\x76\x67\
-\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\
-\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\
-\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\x22\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\
-\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\
-\x73\x2f\x31\x2e\x31\x2f\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\
-\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
-\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\
-\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\
-\x61\x70\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x32\
+\x37\x2c\x32\x33\x34\x2e\x36\x32\x35\x48\x31\x36\x37\x2e\x32\x39\
+\x36\x6c\x31\x31\x39\x2e\x37\x30\x32\x2d\x31\x31\x39\x2e\x37\x30\
+\x32\x4c\x32\x35\x36\x2c\x38\x35\x4c\x38\x35\x2c\x32\x35\x36\x6c\
+\x31\x37\x31\x2c\x31\x37\x31\x6c\x32\x39\x2e\x39\x32\x32\x2d\x32\
+\x39\x2e\x39\x32\x34\x4c\x31\x36\x37\x2e\x32\x39\x36\x2c\x32\x37\
+\x37\x2e\x33\x37\x35\x48\x34\x32\x37\x56\x32\x33\x34\x2e\x36\x32\
+\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x65\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
+\x74\x3d\x27\x31\x38\x2e\x37\x35\x70\x74\x27\x20\x76\x65\x72\x73\
+\x69\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\
+\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\
+\x38\x33\x20\x31\x38\x2e\x37\x35\x20\x31\x38\x2e\x37\x35\x27\x20\
+\x77\x69\x64\x74\x68\x3d\x27\x31\x38\x2e\x37\x35\x70\x74\x27\x20\
+\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
+\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\
\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\
-\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x20\x78\x6d\x6c\
-\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\x74\
-\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\x75\
-\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\x44\
-\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\x22\
-\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\
-\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\
-\x30\x30\x2f\x73\x76\x67\x22\x0a\x09\x20\x78\x6d\x6c\x6e\x73\x3d\
+\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x27\x3e\x0a\x3c\
+\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\x3e\x0a\x3c\x67\
+\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
+\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x35\x2e\x37\x38\x34\x34\
+\x20\x36\x33\x2e\x32\x33\x33\x33\x29\x27\x3e\x0a\x3c\x70\x61\x74\
+\x68\x20\x64\x3d\x27\x4d\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x20\
+\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x38\x2e\x36\x35\x37\x33\x34\
+\x20\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x38\x2e\x36\x35\x37\x33\
+\x34\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x2d\x38\x2e\x36\
+\x35\x37\x33\x34\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x2d\
+\x38\x2e\x36\x35\x37\x33\x34\x20\x38\x2e\x36\x35\x37\x33\x34\x5a\
+\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\
+\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\
+\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\
+\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\
+\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\
+\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x35\x30\x35\x36\x32\x27\
+\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\
+\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\
+\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\
+\x36\x34\x20\x36\x35\x2e\x37\x38\x34\x34\x20\x36\x33\x2e\x32\x33\
+\x33\x33\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\
+\x20\x34\x2e\x33\x32\x38\x36\x37\x20\x30\x43\x20\x34\x2e\x33\x32\
+\x38\x36\x37\x20\x2d\x32\x2e\x33\x39\x30\x36\x36\x20\x32\x2e\x33\
+\x39\x30\x36\x36\x20\x2d\x34\x2e\x33\x32\x38\x36\x37\x20\x30\x20\
+\x2d\x34\x2e\x33\x32\x38\x36\x37\x43\x20\x2d\x32\x2e\x33\x39\x30\
+\x36\x36\x20\x2d\x34\x2e\x33\x32\x38\x36\x37\x20\x2d\x34\x2e\x33\
+\x32\x38\x36\x37\x20\x2d\x32\x2e\x33\x39\x30\x36\x36\x20\x2d\x34\
+\x2e\x33\x32\x38\x36\x37\x20\x2d\x30\x43\x20\x2d\x34\x2e\x33\x32\
+\x38\x36\x37\x20\x32\x2e\x33\x39\x30\x36\x36\x20\x2d\x32\x2e\x33\
+\x39\x30\x36\x36\x20\x34\x2e\x33\x32\x38\x36\x37\x20\x30\x20\x34\
+\x2e\x33\x32\x38\x36\x37\x43\x20\x32\x2e\x33\x39\x30\x36\x36\x20\
+\x34\x2e\x33\x32\x38\x36\x37\x20\x34\x2e\x33\x32\x38\x36\x37\x20\
+\x32\x2e\x33\x39\x30\x36\x36\x20\x34\x2e\x33\x32\x38\x36\x37\x20\
+\x30\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\
+\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\
+\x73\x76\x67\x3e\
+\x00\x00\x02\xbd\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x69\x72\x63\x6c\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\
\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\
\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\
\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\
\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\
\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\
-\x79\x3d\x22\x30\x70\x78\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x31\
-\x35\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x35\x70\
-\x78\x22\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\
-\x30\x20\x31\x35\x20\x31\x35\x22\x20\x73\x74\x79\x6c\x65\x3d\x22\
-\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
-\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\x31\x35\x20\x31\x35\x3b\
-\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\
-\x73\x65\x72\x76\x65\x22\x3e\x0a\x3c\x70\x61\x74\x68\x20\x69\x64\
-\x3d\x22\x72\x65\x63\x74\x33\x33\x33\x38\x22\x20\x69\x6e\x6b\x73\
-\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\
-\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x73\x6f\x64\
-\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\
-\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x64\
-\x3d\x22\x4d\x37\x2e\x35\x32\x34\x33\x2c\x31\x2e\x35\x30\x30\x34\
-\x0a\x09\x43\x37\x2e\x32\x34\x32\x39\x2c\x31\x2e\x34\x39\x31\x33\
-\x2c\x36\x2e\x39\x37\x38\x37\x2c\x31\x2e\x36\x34\x32\x33\x2c\x36\
-\x2e\x38\x33\x33\x36\x2c\x31\x2e\x38\x39\x35\x32\x6c\x2d\x35\x2e\
-\x35\x2c\x39\x2e\x38\x36\x39\x32\x43\x31\x2e\x30\x32\x31\x38\x2c\
-\x31\x32\x2e\x33\x30\x37\x38\x2c\x31\x2e\x33\x39\x35\x2c\x31\x32\
-\x2e\x39\x39\x39\x39\x2c\x32\x2c\x31\x33\x68\x31\x31\x0a\x09\x63\
-\x30\x2e\x36\x30\x35\x2d\x30\x2e\x30\x30\x30\x31\x2c\x30\x2e\x39\
-\x37\x38\x32\x2d\x30\x2e\x36\x39\x32\x32\x2c\x30\x2e\x36\x36\x36\
-\x34\x2d\x31\x2e\x32\x33\x35\x35\x6c\x2d\x35\x2e\x35\x2d\x39\x2e\
-\x38\x36\x39\x32\x43\x38\x2e\x30\x33\x30\x32\x2c\x31\x2e\x36\x35\
-\x37\x39\x2c\x37\x2e\x37\x38\x38\x34\x2c\x31\x2e\x35\x30\x39\x32\
-\x2c\x37\x2e\x35\x32\x34\x33\x2c\x31\x2e\x35\x30\x30\x34\x7a\x20\
-\x4d\x37\x2e\x35\x2c\x33\x2e\x38\x39\x39\x33\x6c\x34\x2e\x31\x32\
-\x36\x37\x2c\x37\x2e\x34\x37\x30\x34\x0a\x09\x48\x33\x2e\x33\x37\
-\x33\x33\x4c\x37\x2e\x35\x2c\x33\x2e\x38\x39\x39\x33\x7a\x22\x2f\
-\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
+\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\
+\x6f\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\
+\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\
+\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\
+\x22\x4d\x31\x30\x2c\x30\x2e\x34\x43\x34\x2e\x36\x39\x38\x2c\x30\
+\x2e\x34\x2c\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\x2c\x30\x2e\x34\
+\x2c\x31\x30\x43\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x32\x2c\x34\
+\x2e\x36\x39\x38\x2c\x31\x39\x2e\x36\x2c\x31\x30\x2c\x31\x39\x2e\
+\x36\x63\x35\x2e\x33\x30\x31\x2c\x30\x2c\x39\x2e\x36\x2d\x34\x2e\
+\x32\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x30\x31\x0d\x0a\x09\
+\x43\x31\x39\x2e\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\x33\
+\x30\x31\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\
+\x31\x30\x2c\x31\x37\x2e\x35\x39\x39\x63\x2d\x34\x2e\x31\x39\x37\
+\x2c\x30\x2d\x37\x2e\x36\x2d\x33\x2e\x34\x30\x32\x2d\x37\x2e\x36\
+\x2d\x37\x2e\x36\x53\x35\x2e\x38\x30\x32\x2c\x32\x2e\x34\x2c\x31\
+\x30\x2c\x32\x2e\x34\x63\x34\x2e\x31\x39\x37\x2c\x30\x2c\x37\x2e\
+\x36\x30\x31\x2c\x33\x2e\x34\x30\x32\x2c\x37\x2e\x36\x30\x31\x2c\
+\x37\x2e\x36\x0d\x0a\x09\x53\x31\x34\x2e\x31\x39\x37\x2c\x31\x37\
+\x2e\x35\x39\x39\x2c\x31\x30\x2c\x31\x37\x2e\x35\x39\x39\x7a\x22\
+\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x46\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x33\x37\x2e\x35\
+\x2c\x33\x38\x36\x2e\x36\x4c\x33\x30\x36\x2e\x39\x2c\x32\x35\x36\
+\x6c\x31\x33\x30\x2e\x36\x2d\x31\x33\x30\x2e\x36\x63\x31\x34\x2e\
+\x31\x2d\x31\x34\x2e\x31\x2c\x31\x34\x2e\x31\x2d\x33\x36\x2e\x38\
+\x2c\x30\x2d\x35\x30\x2e\x39\x63\x2d\x31\x34\x2e\x31\x2d\x31\x34\
+\x2e\x31\x2d\x33\x36\x2e\x38\x2d\x31\x34\x2e\x31\x2d\x35\x30\x2e\
+\x39\x2c\x30\x4c\x32\x35\x36\x2c\x32\x30\x35\x2e\x31\x4c\x31\x32\
+\x35\x2e\x34\x2c\x37\x34\x2e\x35\x0d\x0a\x09\x63\x2d\x31\x34\x2e\
+\x31\x2d\x31\x34\x2e\x31\x2d\x33\x36\x2e\x38\x2d\x31\x34\x2e\x31\
+\x2d\x35\x30\x2e\x39\x2c\x30\x63\x2d\x31\x34\x2e\x31\x2c\x31\x34\
+\x2e\x31\x2d\x31\x34\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x30\x2c\x35\
+\x30\x2e\x39\x4c\x32\x30\x35\x2e\x31\x2c\x32\x35\x36\x4c\x37\x34\
+\x2e\x35\x2c\x33\x38\x36\x2e\x36\x63\x2d\x31\x34\x2e\x31\x2c\x31\
+\x34\x2e\x31\x2d\x31\x34\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x30\x2c\
+\x35\x30\x2e\x39\x0d\x0a\x09\x63\x31\x34\x2e\x31\x2c\x31\x34\x2e\
+\x31\x2c\x33\x36\x2e\x38\x2c\x31\x34\x2e\x31\x2c\x35\x30\x2e\x39\
+\x2c\x30\x4c\x32\x35\x36\x2c\x33\x30\x36\x2e\x39\x6c\x31\x33\x30\
+\x2e\x36\x2c\x31\x33\x30\x2e\x36\x63\x31\x34\x2e\x31\x2c\x31\x34\
+\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x31\x34\x2e\x31\x2c\x35\x30\x2e\
+\x39\x2c\x30\x43\x34\x35\x31\x2e\x35\x2c\x34\x32\x33\x2e\x34\x2c\
+\x34\x35\x31\x2e\x35\x2c\x34\x30\x30\x2e\x36\x2c\x34\x33\x37\x2e\
+\x35\x2c\x33\x38\x36\x2e\x36\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\
+\x76\x67\x3e\x0d\x0a\
+\x00\x00\x01\xdd\
+\x00\
+\x00\x06\xe4\x78\x9c\xcd\x54\x4d\x6f\x9b\x40\x10\x3d\x13\x29\xff\
+\x61\xba\xb7\x4a\xec\x17\xc4\xd4\xa6\xa6\x51\xfd\x21\xcb\x52\x9a\
+\x58\x6a\xea\xaa\xa7\x0a\xc3\x16\x50\x28\x20\x58\xc0\xce\xaf\xef\
+\xee\x92\x54\x51\x95\xfa\x18\xfb\xb0\x33\xda\x79\x6f\xde\xbc\x65\
+\x24\xa6\xd7\xfb\xdf\x39\x74\xa2\x6e\xb2\xb2\x08\x10\x27\x0c\x81\
+\x28\xa2\x32\xce\x8a\x24\x40\xad\xfc\x85\xc7\xe8\xfa\xd3\xe5\xc5\
+\xf4\x1d\xc6\xb0\x12\x85\xa8\x43\x59\xd6\x3e\x7c\x8e\xcb\x9d\x80\
+\x75\x9e\xb7\x8d\x34\x25\xe0\x1e\x71\x08\xb7\xe1\xeb\x76\x05\xcb\
+\x7d\x55\xd6\x12\x36\x79\x9b\xe0\x75\x01\xc4\x14\xb7\xc3\x10\x1f\
+\x3c\xc2\x18\xcc\xda\x2c\x8f\x81\xbd\x07\xc0\xd8\xe8\x2f\xee\xe6\
+\xf7\x3f\x36\x4b\x68\xba\x04\x36\xdf\x66\x37\xeb\x39\x20\x4c\xe9\
+\x77\x77\x4e\xe9\xe2\x7e\x61\x24\x38\xe1\x94\x2e\x6f\x11\xa0\x54\
+\xca\xca\xa7\xb4\xef\x7b\xd2\xbb\xa4\xac\x13\xba\xaa\xc3\x2a\xcd\
+\xa2\x86\x2a\x22\xd5\x44\xd5\x44\x95\x18\xe7\x24\x96\x31\xd2\x33\
+\xb4\xf4\x8b\xa7\x72\x04\x59\x1c\xa0\x9b\xf0\x20\xea\x9f\xea\xa2\
+\xbe\x44\xd1\x04\xaf\x48\x3b\x8c\x31\x2d\xf5\x44\xf1\xf7\x79\x56\
+\x3c\xbc\x46\xe4\x93\xc9\x84\x1a\x54\x51\x03\xc4\xaa\x3d\x82\xc3\
+\x90\x2f\x2f\x2c\xe8\xb3\x58\xa6\x01\x1a\x71\x47\x03\xa9\xc8\x92\
+\x54\xfe\xbd\x76\x99\xe8\x67\xa5\xee\x02\x06\xaa\xa6\x0f\x82\x46\
+\x1e\x72\x11\x20\x51\x84\xbb\x5c\xe0\x5d\x18\x3d\x24\x75\xd9\x16\
+\xb1\x5f\x88\x1e\x5e\x30\x3f\x1a\x6f\x7e\x53\x85\x91\xa2\x57\xb5\
+\x68\x44\xdd\x09\xf3\xea\x44\x05\x6b\x88\xd6\xb4\x0a\x65\x0a\xea\
+\xd1\x5f\xb8\xc7\x6c\x3e\x72\x89\x1b\x31\xdb\x25\x1f\xb0\x6b\x7b\
+\x2a\xaa\xa3\x73\x8a\x47\x8c\x8c\x22\xac\x00\x9b\xe9\x22\x76\xf1\
+\x13\xdc\x0d\x10\x33\x98\xfb\xdc\xa0\x73\x6a\x00\xd3\xa2\x4b\xb6\
+\x51\xd4\x67\x6b\xe6\x3c\xea\x4f\x60\x59\xf4\x1f\x1f\xce\x78\x7c\
+\x16\x3e\xae\xb8\x77\x3a\x1f\x53\xfa\xff\x25\x39\x63\xfe\x26\xa6\
+\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x71\x6c\x49\x57\x6c\
+\xf2\x26\xa6\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x31\x2c\
+\xe9\x39\xaa\x7f\xb6\xca\x7f\x00\x99\x18\x96\x19\
\x00\x00\x03\x6c\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -467,7 +466,7 @@ qt_resource_data = b"\
\x33\x33\x33\x7a\x0d\x0a\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x3c\
\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
\x3e\x0d\x0a\
-\x00\x00\x04\x22\
+\x00\x00\x04\xbd\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
@@ -488,55 +487,64 @@ qt_resource_data = b"\
\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
-\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\
+\x37\x36\x35\x35\x20\x36\x39\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\
\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x2d\x39\x2e\x33\x39\
-\x31\x31\x38\x20\x2d\x30\x4c\x20\x2d\x36\x2e\x36\x34\x30\x35\x37\
-\x20\x2d\x31\x32\x2e\x30\x34\x35\x4c\x20\x38\x2e\x36\x37\x36\x33\
-\x32\x20\x2d\x36\x2e\x35\x31\x38\x37\x31\x4c\x20\x33\x2e\x33\x32\
-\x30\x32\x38\x20\x36\x2e\x30\x32\x32\x35\x27\x20\x66\x69\x6c\x6c\
-\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\
-\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
-\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\
-\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\
-\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\
-\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\
-\x3d\x27\x31\x2e\x37\x35\x36\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\
-\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
-\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
-\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
-\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\
-\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x2d\x39\x2e\x33\
-\x39\x31\x31\x38\x27\x20\x63\x79\x3d\x27\x2d\x30\x27\x20\x72\x3d\
+\x31\x31\x38\x20\x2d\x30\x43\x20\x2d\x39\x2e\x39\x36\x38\x36\x31\
+\x20\x2d\x33\x2e\x38\x33\x30\x30\x34\x20\x2d\x38\x2e\x35\x35\x37\
+\x30\x36\x20\x2d\x37\x2e\x35\x31\x39\x34\x34\x20\x2d\x36\x2e\x36\
+\x34\x30\x35\x37\x20\x2d\x31\x30\x2e\x32\x31\x37\x31\x43\x20\x2d\
+\x30\x2e\x34\x39\x31\x30\x38\x39\x20\x2d\x31\x38\x2e\x38\x37\x33\
+\x33\x20\x38\x2e\x33\x35\x36\x37\x36\x20\x2d\x31\x35\x2e\x31\x39\
+\x30\x36\x20\x38\x2e\x36\x37\x36\x33\x32\x20\x2d\x35\x2e\x35\x32\
+\x39\x34\x38\x43\x20\x38\x2e\x38\x33\x36\x20\x2d\x30\x2e\x37\x30\
+\x32\x30\x30\x38\x20\x36\x2e\x32\x33\x39\x36\x38\x20\x32\x2e\x39\
+\x34\x32\x30\x37\x20\x33\x2e\x33\x32\x30\x32\x38\x20\x35\x2e\x31\
+\x30\x38\x35\x37\x43\x20\x2d\x31\x2e\x39\x36\x38\x39\x31\x20\x39\
+\x2e\x30\x33\x33\x37\x31\x20\x2d\x38\x2e\x32\x36\x38\x39\x35\x20\
+\x37\x2e\x34\x34\x33\x37\x20\x2d\x39\x2e\x33\x39\x31\x31\x38\x20\
+\x2d\x30\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\
+\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\
+\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
+\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\
+\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\
+\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\
+\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x37\x35\x36\
+\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\
+\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\
+\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x39\
+\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\
+\x20\x63\x78\x3d\x27\x2d\x39\x2e\x33\x39\x31\x31\x38\x27\x20\x63\
+\x79\x3d\x27\x2d\x30\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\
+\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
+\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\
+\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\
+\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x39\x2e\x37\
+\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\
+\x78\x3d\x27\x2d\x36\x2e\x36\x34\x30\x35\x37\x27\x20\x63\x79\x3d\
+\x27\x2d\x31\x30\x2e\x32\x31\x37\x31\x27\x20\x72\x3d\x27\x33\x2e\
+\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\
+\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\
+\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\
+\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\
+\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\
+\x36\x39\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\
+\x6c\x65\x20\x63\x78\x3d\x27\x38\x2e\x36\x37\x36\x33\x32\x27\x20\
+\x63\x79\x3d\x27\x2d\x35\x2e\x35\x32\x39\x34\x38\x27\x20\x72\x3d\
\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\
\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\
-\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\x3c\x63\
-\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x2d\x36\x2e\x36\x34\x30\
-\x35\x37\x27\x20\x63\x79\x3d\x27\x2d\x31\x32\x2e\x30\x34\x35\x27\
-\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\
-\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\
-\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
-\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\
-\x2e\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\
-\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x38\x2e\x36\
-\x37\x36\x33\x32\x27\x20\x63\x79\x3d\x27\x2d\x36\x2e\x35\x31\x38\
-\x37\x31\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\
-\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\
-\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\
-\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\
-\x33\x2e\x33\x32\x30\x32\x38\x27\x20\x63\x79\x3d\x27\x36\x2e\x30\
-\x32\x32\x35\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\
-\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\
-\x3e\x0a\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\
-\x3e\
-\x00\x00\x03\x4c\
+\x35\x35\x20\x36\x39\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\
+\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x33\x32\x30\x32\
+\x38\x27\x20\x63\x79\x3d\x27\x35\x2e\x31\x30\x38\x35\x37\x27\x20\
+\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\
+\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\
+\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x02\xfc\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -568,75 +576,24 @@ qt_resource_data = b"\
\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x32\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
+\x22\x49\x63\x6f\x6e\x5f\x32\x30\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
-\x35\x36\x2c\x31\x35\x32\x63\x2d\x35\x37\x2e\x32\x2c\x30\x2d\x31\
-\x30\x34\x2c\x34\x36\x2e\x38\x2d\x31\x30\x34\x2c\x31\x30\x34\x73\
-\x34\x36\x2e\x38\x2c\x31\x30\x34\x2c\x31\x30\x34\x2c\x31\x30\x34\
-\x73\x31\x30\x34\x2d\x34\x36\x2e\x38\x2c\x31\x30\x34\x2d\x31\x30\
-\x34\x53\x33\x31\x33\x2e\x32\x2c\x31\x35\x32\x2c\x32\x35\x36\x2c\
-\x31\x35\x32\x7a\x20\x4d\x32\x35\x36\x2c\x34\x38\x0d\x0a\x09\x09\
-\x09\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x34\x38\x2c\
-\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\x35\x36\x73\x39\
-\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\x38\x2c\x32\x30\
-\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\
-\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\x2c\x34\x38\x2c\
-\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\x2c\x34\x32\x32\
-\x2e\x34\x0d\x0a\x09\x09\x09\x63\x2d\x39\x31\x2e\x35\x31\x38\x2c\
-\x30\x2d\x31\x36\x36\x2e\x34\x2d\x37\x34\x2e\x38\x38\x33\x2d\x31\
-\x36\x36\x2e\x34\x2d\x31\x36\x36\x2e\x34\x53\x31\x36\x34\x2e\x34\
-\x38\x32\x2c\x38\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\
-\x53\x34\x32\x32\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\
-\x32\x32\x2e\x34\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\
-\x2c\x34\x32\x32\x2e\x34\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x34\
+\x35\x36\x2c\x34\x38\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\
+\x2c\x34\x38\x2c\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\
+\x35\x36\x73\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\
+\x38\x2c\x32\x30\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\
+\x2c\x32\x30\x38\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\
+\x2c\x34\x38\x2c\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\
+\x2c\x34\x32\x32\x2e\x33\x39\x39\x0d\x0a\x09\x09\x09\x63\x2d\x39\
+\x31\x2e\x35\x31\x38\x2c\x30\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\
+\x37\x34\x2e\x38\x38\x32\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\x31\
+\x36\x36\x2e\x33\x39\x39\x53\x31\x36\x34\x2e\x34\x38\x32\x2c\x38\
+\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\x53\x34\x32\x32\
+\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\x32\x32\x2e\x34\
+\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\x2c\x34\x32\x32\
+\x2e\x33\x39\x39\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x33\x39\x39\
\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\xbd\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x69\x72\x63\x6c\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\
-\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\
-\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\
-\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\
-\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\
-\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\
-\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\
-\x6f\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\
-\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\
-\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\
-\x22\x4d\x31\x30\x2c\x30\x2e\x34\x43\x34\x2e\x36\x39\x38\x2c\x30\
-\x2e\x34\x2c\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\x2c\x30\x2e\x34\
-\x2c\x31\x30\x43\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x32\x2c\x34\
-\x2e\x36\x39\x38\x2c\x31\x39\x2e\x36\x2c\x31\x30\x2c\x31\x39\x2e\
-\x36\x63\x35\x2e\x33\x30\x31\x2c\x30\x2c\x39\x2e\x36\x2d\x34\x2e\
-\x32\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x30\x31\x0d\x0a\x09\
-\x43\x31\x39\x2e\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\x33\
-\x30\x31\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\
-\x31\x30\x2c\x31\x37\x2e\x35\x39\x39\x63\x2d\x34\x2e\x31\x39\x37\
-\x2c\x30\x2d\x37\x2e\x36\x2d\x33\x2e\x34\x30\x32\x2d\x37\x2e\x36\
-\x2d\x37\x2e\x36\x53\x35\x2e\x38\x30\x32\x2c\x32\x2e\x34\x2c\x31\
-\x30\x2c\x32\x2e\x34\x63\x34\x2e\x31\x39\x37\x2c\x30\x2c\x37\x2e\
-\x36\x30\x31\x2c\x33\x2e\x34\x30\x32\x2c\x37\x2e\x36\x30\x31\x2c\
-\x37\x2e\x36\x0d\x0a\x09\x53\x31\x34\x2e\x31\x39\x37\x2c\x31\x37\
-\x2e\x35\x39\x39\x2c\x31\x30\x2c\x31\x37\x2e\x35\x39\x39\x7a\x22\
-\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
\x00\x00\x05\xb7\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
@@ -731,7 +688,7 @@ qt_resource_data = b"\
\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x37\x35\
\x36\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\
\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x02\xb7\
+\x00\x00\x02\xf7\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -758,26 +715,109 @@ qt_resource_data = b"\
\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x35\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
-\x6e\x74\x73\x3d\x22\x34\x30\x35\x2c\x31\x33\x36\x2e\x37\x39\x38\
-\x20\x33\x37\x35\x2e\x32\x30\x32\x2c\x31\x30\x37\x20\x32\x35\x36\
-\x2c\x32\x32\x36\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
-\x2c\x31\x30\x37\x20\x31\x30\x37\x2c\x31\x33\x36\x2e\x37\x39\x38\
-\x20\x32\x32\x36\x2e\x32\x30\x32\x2c\x32\x35\x36\x20\x31\x30\x37\
-\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
-\x2c\x34\x30\x35\x20\x32\x35\x36\x2c\x32\x38\x35\x2e\x37\x39\x38\
-\x20\x0d\x0a\x09\x09\x09\x33\x37\x35\x2e\x32\x30\x32\x2c\x34\x30\
-\x35\x20\x34\x30\x35\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x32\x38\
-\x35\x2e\x37\x39\x38\x2c\x32\x35\x36\x20\x09\x09\x22\x2f\x3e\x0d\
-\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x31\x37\x2e\x34\
+\x2c\x32\x32\x34\x48\x32\x38\x38\x56\x39\x34\x2e\x36\x63\x30\x2d\
+\x31\x36\x2e\x39\x2d\x31\x34\x2e\x33\x2d\x33\x30\x2e\x36\x2d\x33\
+\x32\x2d\x33\x30\x2e\x36\x63\x2d\x31\x37\x2e\x37\x2c\x30\x2d\x33\
+\x32\x2c\x31\x33\x2e\x37\x2d\x33\x32\x2c\x33\x30\x2e\x36\x56\x32\
+\x32\x34\x48\x39\x34\x2e\x36\x43\x37\x37\x2e\x37\x2c\x32\x32\x34\
+\x2c\x36\x34\x2c\x32\x33\x38\x2e\x33\x2c\x36\x34\x2c\x32\x35\x36\
+\x0d\x0a\x09\x63\x30\x2c\x31\x37\x2e\x37\x2c\x31\x33\x2e\x37\x2c\
+\x33\x32\x2c\x33\x30\x2e\x36\x2c\x33\x32\x48\x32\x32\x34\x76\x31\
+\x32\x39\x2e\x34\x63\x30\x2c\x31\x36\x2e\x39\x2c\x31\x34\x2e\x33\
+\x2c\x33\x30\x2e\x36\x2c\x33\x32\x2c\x33\x30\x2e\x36\x63\x31\x37\
+\x2e\x37\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x37\x2c\x33\x32\x2d\
+\x33\x30\x2e\x36\x56\x32\x38\x38\x68\x31\x32\x39\x2e\x34\x63\x31\
+\x36\x2e\x39\x2c\x30\x2c\x33\x30\x2e\x36\x2d\x31\x34\x2e\x33\x2c\
+\x33\x30\x2e\x36\x2d\x33\x32\x0d\x0a\x09\x43\x34\x34\x38\x2c\x32\
+\x33\x38\x2e\x33\x2c\x34\x33\x34\x2e\x33\x2c\x32\x32\x34\x2c\x34\
+\x31\x37\x2e\x34\x2c\x32\x32\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\
\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\xfc\
+\x00\x00\x04\xca\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\x72\
+\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\x75\
+\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x39\x2e\x32\x2e\x31\x2c\x20\
+\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\x2d\
+\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\x6e\
+\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\x20\
+\x20\x2d\x2d\x3e\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\x20\x73\
+\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\x57\x33\
+\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\x2f\x2f\
+\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\
+\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\x73\x2f\
+\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\x67\x31\
+\x31\x2e\x64\x74\x64\x22\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\
+\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x09\x20\x69\x64\x3d\
+\x22\x73\x76\x67\x34\x36\x31\x39\x22\x20\x69\x6e\x6b\x73\x63\x61\
+\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x31\
+\x2b\x64\x65\x76\x65\x6c\x2b\x6f\x73\x78\x6d\x65\x6e\x75\x20\x72\
+\x31\x32\x39\x31\x31\x22\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\
+\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x74\x72\x69\x61\x6e\x67\x6c\
+\x65\x2d\x73\x74\x72\x6f\x6b\x65\x64\x2d\x31\x35\x2e\x73\x76\x67\
+\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\
+\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\
+\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\x22\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\
+\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\
+\x73\x2f\x31\x2e\x31\x2f\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\
+\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
+\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\
+\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\
+\x61\x70\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\
+\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x20\x78\x6d\x6c\
+\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\x74\
+\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\x75\
+\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\x44\
+\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\x22\
+\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\
+\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\
+\x30\x30\x2f\x73\x76\x67\x22\x0a\x09\x20\x78\x6d\x6c\x6e\x73\x3d\
+\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\
+\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\
+\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\
+\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\
+\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\
+\x79\x3d\x22\x30\x70\x78\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x31\
+\x35\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x35\x70\
+\x78\x22\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\
+\x30\x20\x31\x35\x20\x31\x35\x22\x20\x73\x74\x79\x6c\x65\x3d\x22\
+\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
+\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\x31\x35\x20\x31\x35\x3b\
+\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\
+\x73\x65\x72\x76\x65\x22\x3e\x0a\x3c\x70\x61\x74\x68\x20\x69\x64\
+\x3d\x22\x72\x65\x63\x74\x33\x33\x33\x38\x22\x20\x69\x6e\x6b\x73\
+\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\
+\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x73\x6f\x64\
+\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\
+\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x64\
+\x3d\x22\x4d\x37\x2e\x35\x32\x34\x33\x2c\x31\x2e\x35\x30\x30\x34\
+\x0a\x09\x43\x37\x2e\x32\x34\x32\x39\x2c\x31\x2e\x34\x39\x31\x33\
+\x2c\x36\x2e\x39\x37\x38\x37\x2c\x31\x2e\x36\x34\x32\x33\x2c\x36\
+\x2e\x38\x33\x33\x36\x2c\x31\x2e\x38\x39\x35\x32\x6c\x2d\x35\x2e\
+\x35\x2c\x39\x2e\x38\x36\x39\x32\x43\x31\x2e\x30\x32\x31\x38\x2c\
+\x31\x32\x2e\x33\x30\x37\x38\x2c\x31\x2e\x33\x39\x35\x2c\x31\x32\
+\x2e\x39\x39\x39\x39\x2c\x32\x2c\x31\x33\x68\x31\x31\x0a\x09\x63\
+\x30\x2e\x36\x30\x35\x2d\x30\x2e\x30\x30\x30\x31\x2c\x30\x2e\x39\
+\x37\x38\x32\x2d\x30\x2e\x36\x39\x32\x32\x2c\x30\x2e\x36\x36\x36\
+\x34\x2d\x31\x2e\x32\x33\x35\x35\x6c\x2d\x35\x2e\x35\x2d\x39\x2e\
+\x38\x36\x39\x32\x43\x38\x2e\x30\x33\x30\x32\x2c\x31\x2e\x36\x35\
+\x37\x39\x2c\x37\x2e\x37\x38\x38\x34\x2c\x31\x2e\x35\x30\x39\x32\
+\x2c\x37\x2e\x35\x32\x34\x33\x2c\x31\x2e\x35\x30\x30\x34\x7a\x20\
+\x4d\x37\x2e\x35\x2c\x33\x2e\x38\x39\x39\x33\x6c\x34\x2e\x31\x32\
+\x36\x37\x2c\x37\x2e\x34\x37\x30\x34\x0a\x09\x48\x33\x2e\x33\x37\
+\x33\x33\x4c\x37\x2e\x35\x2c\x33\x2e\x38\x39\x39\x33\x7a\x22\x2f\
+\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
+\x00\x00\x03\x52\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -808,46 +848,32 @@ qt_resource_data = b"\
\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x32\x30\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
-\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
-\x35\x36\x2c\x34\x38\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\
-\x2c\x34\x38\x2c\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\
-\x35\x36\x73\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\
-\x38\x2c\x32\x30\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\
-\x2c\x32\x30\x38\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\
-\x2c\x34\x38\x2c\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\
-\x2c\x34\x32\x32\x2e\x33\x39\x39\x0d\x0a\x09\x09\x09\x63\x2d\x39\
-\x31\x2e\x35\x31\x38\x2c\x30\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\
-\x37\x34\x2e\x38\x38\x32\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\x31\
-\x36\x36\x2e\x33\x39\x39\x53\x31\x36\x34\x2e\x34\x38\x32\x2c\x38\
-\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\x53\x34\x32\x32\
-\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\x32\x32\x2e\x34\
-\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\x2c\x34\x32\x32\
-\x2e\x33\x39\x39\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x33\x39\x39\
-\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x01\x20\
-\x3c\
-\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\
-\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x3e\x3c\x70\x61\x74\x68\
-\x20\x64\x3d\x22\x4d\x34\x2e\x33\x34\x20\x31\x35\x2e\x36\x36\x41\
-\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\x30\x20\x30\x20\x30\x20\
-\x39\x20\x31\x37\x2e\x39\x34\x56\x31\x30\x48\x35\x56\x38\x68\x34\
-\x56\x35\x2e\x38\x33\x61\x33\x20\x33\x20\x30\x20\x31\x20\x31\x20\
-\x32\x20\x30\x56\x38\x68\x34\x76\x32\x68\x2d\x34\x76\x37\x2e\x39\
-\x34\x61\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\x30\x20\x30\x20\
-\x30\x20\x34\x2e\x36\x36\x2d\x32\x2e\x32\x38\x6c\x2d\x31\x2e\x34\
-\x32\x2d\x31\x2e\x34\x32\x68\x35\x2e\x36\x36\x6c\x2d\x32\x2e\x38\
-\x33\x20\x32\x2e\x38\x33\x61\x31\x30\x20\x31\x30\x20\x30\x20\x30\
-\x20\x31\x2d\x31\x34\x2e\x31\x34\x20\x30\x4c\x2e\x31\x20\x31\x34\
-\x2e\x32\x34\x68\x35\x2e\x36\x36\x6c\x2d\x31\x2e\x34\x32\x20\x31\
-\x2e\x34\x32\x7a\x4d\x31\x30\x20\x34\x61\x31\x20\x31\x20\x30\x20\
-\x31\x20\x30\x20\x30\x2d\x32\x20\x31\x20\x31\x20\x30\x20\x30\x20\
-\x30\x20\x30\x20\x32\x7a\x22\x2f\x3e\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x07\x80\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
+\x64\x3d\x22\x4d\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x48\
+\x32\x35\x36\x2e\x30\x30\x36\x6c\x2d\x34\x32\x2e\x36\x36\x38\x2d\
+\x34\x38\x48\x37\x34\x2e\x36\x36\x36\x43\x35\x31\x2e\x31\x39\x37\
+\x2c\x39\x36\x2c\x33\x32\x2c\x31\x31\x35\x2e\x31\x39\x38\x2c\x33\
+\x32\x2c\x31\x33\x38\x2e\x36\x36\x37\x76\x32\x33\x34\x2e\x36\x36\
+\x36\x43\x33\x32\x2c\x33\x39\x36\x2e\x38\x30\x32\x2c\x35\x31\x2e\
+\x31\x39\x37\x2c\x34\x31\x36\x2c\x37\x34\x2e\x36\x36\x36\x2c\x34\
+\x31\x36\x68\x33\x36\x32\x2e\x36\x36\x38\x0d\x0a\x09\x43\x34\x36\
+\x30\x2e\x38\x30\x33\x2c\x34\x31\x36\x2c\x34\x38\x30\x2c\x33\x39\
+\x36\x2e\x38\x30\x32\x2c\x34\x38\x30\x2c\x33\x37\x33\x2e\x33\x33\
+\x33\x56\x31\x38\x36\x2e\x36\x36\x37\x43\x34\x38\x30\x2c\x31\x36\
+\x33\x2e\x31\x39\x38\x2c\x34\x36\x30\x2e\x38\x30\x33\x2c\x31\x34\
+\x34\x2c\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x7a\x20\x4d\
+\x34\x34\x38\x2c\x33\x37\x33\x2e\x33\x33\x33\x0d\x0a\x09\x63\x30\
+\x2c\x35\x2e\x37\x38\x32\x2d\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\
+\x36\x36\x37\x2d\x31\x30\x2e\x36\x36\x36\x2c\x31\x30\x2e\x36\x36\
+\x37\x48\x37\x34\x2e\x36\x36\x36\x43\x36\x38\x2e\x38\x38\x34\x2c\
+\x33\x38\x34\x2c\x36\x34\x2c\x33\x37\x39\x2e\x31\x31\x35\x2c\x36\
+\x34\x2c\x33\x37\x33\x2e\x33\x33\x33\x56\x31\x37\x36\x68\x33\x37\
+\x33\x2e\x33\x33\x34\x63\x35\x2e\x37\x38\x31\x2c\x30\x2c\x31\x30\
+\x2e\x36\x36\x36\x2c\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\x36\x36\
+\x36\x2c\x31\x30\x2e\x36\x36\x37\x0d\x0a\x09\x56\x33\x37\x33\x2e\
+\x33\x33\x33\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
+\x0a\
+\x00\x00\x03\x26\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -879,97 +905,28 @@ qt_resource_data = b"\
\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x39\x33\x2e\x34\x36\
-\x2c\x32\x34\x39\x2e\x30\x35\x36\x63\x33\x2e\x37\x32\x33\x2d\x30\
-\x2e\x36\x37\x2c\x37\x2e\x35\x38\x39\x2d\x31\x2e\x30\x34\x31\x2c\
-\x31\x31\x2e\x35\x38\x36\x2d\x31\x2e\x30\x34\x31\x4c\x32\x30\x31\
-\x2e\x39\x32\x34\x2c\x32\x34\x38\x68\x31\x30\x33\x2e\x38\x32\x33\
-\x63\x34\x2e\x35\x30\x33\x2c\x30\x2c\x38\x2e\x38\x30\x36\x2d\x30\
-\x2e\x36\x31\x37\x2c\x31\x32\x2e\x39\x30\x38\x2d\x31\x2e\x37\x35\
-\x34\x0d\x0a\x09\x09\x63\x31\x39\x2e\x33\x37\x2d\x35\x2e\x33\x36\
-\x33\x2c\x33\x33\x2e\x33\x34\x35\x2d\x32\x32\x2e\x35\x33\x37\x2c\
-\x33\x33\x2e\x33\x34\x35\x2d\x34\x33\x2e\x36\x36\x33\x76\x2d\x33\
-\x30\x2e\x38\x32\x32\x76\x2d\x35\x36\x2e\x34\x30\x32\x63\x30\x2d\
-\x32\x34\x2e\x38\x33\x32\x2d\x32\x31\x2e\x31\x35\x2d\x34\x33\x2e\
-\x34\x38\x34\x2d\x34\x36\x2e\x32\x38\x39\x2d\x34\x37\x2e\x36\x30\
-\x36\x0d\x0a\x09\x09\x63\x2d\x31\x35\x2e\x39\x33\x31\x2d\x32\x2e\
-\x36\x32\x34\x2d\x33\x39\x2e\x32\x35\x38\x2d\x33\x2e\x38\x32\x37\
-\x2d\x35\x35\x2e\x30\x38\x39\x2d\x33\x2e\x37\x34\x39\x63\x2d\x31\
-\x35\x2e\x38\x32\x39\x2c\x30\x2e\x30\x38\x36\x2d\x33\x30\x2e\x39\
-\x38\x31\x2c\x31\x2e\x34\x30\x34\x2d\x34\x34\x2e\x32\x37\x37\x2c\
-\x33\x2e\x37\x34\x39\x43\x31\x36\x37\x2e\x31\x34\x33\x2c\x37\x34\
-\x2e\x35\x37\x36\x2c\x31\x36\x30\x2c\x38\x38\x2e\x39\x32\x38\x2c\
-\x31\x36\x30\x2c\x31\x31\x35\x2e\x33\x35\x39\x56\x31\x34\x34\x68\
-\x39\x36\x0d\x0a\x09\x09\x76\x31\x36\x48\x31\x32\x38\x2e\x38\x32\
-\x63\x2d\x33\x35\x2e\x36\x32\x38\x2c\x30\x2d\x36\x34\x2e\x35\x33\
-\x38\x2c\x34\x32\x2e\x35\x37\x31\x2d\x36\x34\x2e\x38\x31\x33\x2c\
-\x39\x35\x2e\x32\x34\x32\x43\x36\x34\x2e\x30\x30\x35\x2c\x32\x35\
-\x35\x2e\x34\x39\x35\x2c\x36\x34\x2c\x32\x35\x35\x2e\x37\x34\x37\
-\x2c\x36\x34\x2c\x32\x35\x36\x63\x30\x2c\x39\x2e\x35\x32\x33\x2c\
-\x30\x2e\x39\x34\x2c\x31\x38\x2e\x37\x32\x2c\x32\x2e\x36\x38\x35\
-\x2c\x32\x37\x2e\x34\x30\x34\x0d\x0a\x09\x09\x43\x37\x34\x2e\x36\
-\x34\x38\x2c\x33\x32\x33\x2e\x30\x37\x2c\x39\x39\x2e\x34\x35\x31\
-\x2c\x33\x35\x32\x2c\x31\x32\x38\x2e\x38\x32\x2c\x33\x35\x32\x48\
-\x31\x34\x34\x76\x2d\x32\x2e\x36\x36\x32\x76\x2d\x34\x33\x2e\x32\
-\x37\x33\x43\x31\x34\x34\x2c\x32\x37\x39\x2e\x32\x33\x38\x2c\x31\
-\x36\x34\x2e\x31\x34\x36\x2c\x32\x35\x34\x2e\x33\x33\x32\x2c\x31\
-\x39\x33\x2e\x34\x36\x2c\x32\x34\x39\x2e\x30\x35\x36\x7a\x20\x4d\
-\x32\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x0d\
-\x0a\x09\x09\x63\x2d\x39\x2e\x35\x39\x32\x2c\x30\x2d\x31\x37\x2e\
-\x33\x38\x34\x2d\x37\x2e\x37\x38\x35\x2d\x31\x37\x2e\x33\x38\x34\
-\x2d\x31\x37\x2e\x34\x30\x33\x63\x30\x2d\x39\x2e\x36\x36\x34\x2c\
-\x37\x2e\x37\x37\x34\x2d\x31\x37\x2e\x35\x32\x2c\x31\x37\x2e\x33\
-\x38\x34\x2d\x31\x37\x2e\x35\x32\x63\x39\x2e\x35\x37\x34\x2c\x30\
-\x2c\x31\x37\x2e\x33\x39\x39\x2c\x37\x2e\x38\x35\x35\x2c\x31\x37\
-\x2e\x33\x39\x39\x2c\x31\x37\x2e\x35\x32\x0d\x0a\x09\x09\x43\x32\
-\x32\x31\x2e\x30\x35\x36\x2c\x31\x31\x39\x2e\x32\x31\x37\x2c\x32\
-\x31\x33\x2e\x32\x34\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x2c\x32\
-\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x7a\x22\
-\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
-\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\x35\x34\x33\x43\x34\
-\x33\x34\x2e\x37\x38\x2c\x31\x38\x36\x2e\x30\x32\x31\x2c\x34\x31\
-\x31\x2e\x30\x33\x33\x2c\x31\x36\x30\x2c\x33\x38\x33\x2e\x31\x38\
-\x2c\x31\x36\x30\x48\x33\x36\x38\x76\x32\x2e\x36\x32\x36\x76\x33\
-\x38\x2e\x30\x34\x36\x63\x30\x2c\x33\x33\x2e\x39\x31\x35\x2d\x32\
-\x32\x2e\x32\x38\x36\x2c\x35\x38\x2e\x34\x37\x34\x2d\x34\x39\x2e\
-\x34\x38\x39\x2c\x36\x32\x2e\x36\x38\x31\x0d\x0a\x09\x09\x63\x2d\
-\x32\x2e\x37\x33\x37\x2c\x30\x2e\x34\x32\x34\x2d\x35\x2e\x34\x38\
-\x33\x2c\x30\x2e\x36\x34\x36\x2d\x38\x2e\x33\x30\x31\x2c\x30\x2e\
-\x36\x34\x36\x48\x32\x30\x36\x2e\x33\x35\x31\x63\x2d\x34\x2e\x35\
-\x31\x38\x2c\x30\x2d\x38\x2e\x39\x30\x34\x2c\x30\x2e\x35\x38\x34\
-\x2d\x31\x33\x2e\x30\x34\x39\x2c\x31\x2e\x36\x37\x32\x43\x31\x37\
-\x34\x2e\x31\x38\x2c\x32\x37\x30\x2e\x36\x38\x39\x2c\x31\x36\x30\
-\x2c\x32\x38\x36\x2e\x36\x2c\x31\x36\x30\x2c\x33\x30\x37\x2e\x32\
-\x33\x36\x76\x33\x32\x2e\x39\x32\x32\x0d\x0a\x09\x09\x76\x35\x34\
-\x2e\x33\x30\x35\x63\x30\x2c\x32\x34\x2e\x38\x33\x32\x2c\x32\x34\
-\x2e\x39\x37\x37\x2c\x33\x39\x2e\x34\x32\x36\x2c\x34\x39\x2e\x34\
-\x38\x31\x2c\x34\x36\x2e\x35\x35\x31\x63\x32\x39\x2e\x33\x32\x37\
-\x2c\x38\x2e\x35\x33\x31\x2c\x36\x31\x2e\x32\x36\x37\x2c\x31\x30\
-\x2e\x30\x36\x38\x2c\x39\x36\x2e\x33\x36\x36\x2c\x30\x43\x33\x32\
-\x39\x2e\x31\x35\x2c\x34\x33\x34\x2e\x33\x35\x34\x2c\x33\x35\x32\
-\x2c\x34\x32\x30\x2e\x38\x39\x33\x2c\x33\x35\x32\x2c\x33\x39\x34\
-\x2e\x34\x36\x33\x56\x33\x36\x38\x0d\x0a\x09\x09\x68\x2d\x39\x36\
-\x76\x2d\x31\x36\x68\x31\x32\x37\x2e\x31\x38\x63\x32\x35\x2e\x32\
-\x34\x2c\x30\x2c\x34\x37\x2e\x31\x30\x37\x2d\x32\x31\x2e\x33\x36\
-\x35\x2c\x35\x37\x2e\x38\x31\x34\x2d\x35\x32\x2e\x35\x34\x39\x43\
-\x34\x34\x35\x2e\x34\x37\x34\x2c\x32\x38\x36\x2e\x34\x30\x34\x2c\
-\x34\x34\x38\x2c\x32\x37\x31\x2e\x36\x34\x31\x2c\x34\x34\x38\x2c\
-\x32\x35\x36\x0d\x0a\x09\x09\x43\x34\x34\x38\x2c\x32\x34\x34\x2e\
-\x32\x33\x32\x2c\x34\x34\x36\x2e\x35\x36\x37\x2c\x32\x33\x32\x2e\
-\x39\x36\x32\x2c\x34\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\
-\x35\x34\x33\x7a\x20\x4d\x33\x30\x37\x2e\x38\x36\x37\x2c\x33\x38\
-\x32\x2e\x38\x32\x63\x39\x2e\x35\x39\x2c\x30\x2c\x31\x37\x2e\x33\
-\x38\x31\x2c\x37\x2e\x37\x38\x35\x2c\x31\x37\x2e\x33\x38\x31\x2c\
-\x31\x37\x2e\x34\x0d\x0a\x09\x09\x63\x30\x2c\x39\x2e\x36\x35\x2d\
-\x37\x2e\x37\x39\x31\x2c\x31\x37\x2e\x35\x32\x31\x2d\x31\x37\x2e\
-\x33\x38\x31\x2c\x31\x37\x2e\x35\x32\x31\x63\x2d\x39\x2e\x35\x37\
-\x37\x2c\x30\x2d\x31\x37\x2e\x33\x39\x39\x2d\x37\x2e\x38\x37\x31\
-\x2d\x31\x37\x2e\x33\x39\x39\x2d\x31\x37\x2e\x35\x32\x31\x43\x32\
-\x39\x30\x2e\x34\x36\x38\x2c\x33\x39\x30\x2e\x35\x39\x2c\x32\x39\
-\x38\x2e\x32\x37\x34\x2c\x33\x38\x32\x2e\x38\x32\x2c\x33\x30\x37\
-\x2e\x38\x36\x37\x2c\x33\x38\x32\x2e\x38\x32\x7a\x22\x2f\x3e\x0d\
-\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\x7d\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x33\x38\
+\x38\x63\x2d\x37\x32\x2e\x35\x39\x37\x2c\x30\x2d\x31\x33\x32\x2d\
+\x35\x39\x2e\x34\x30\x35\x2d\x31\x33\x32\x2d\x31\x33\x32\x63\x30\
+\x2d\x37\x32\x2e\x36\x30\x31\x2c\x35\x39\x2e\x34\x30\x33\x2d\x31\
+\x33\x32\x2c\x31\x33\x32\x2d\x31\x33\x32\x63\x33\x36\x2e\x33\x2c\
+\x30\x2c\x36\x39\x2e\x32\x39\x39\x2c\x31\x35\x2e\x34\x2c\x39\x32\
+\x2e\x34\x30\x36\x2c\x33\x39\x2e\x36\x30\x31\x4c\x32\x37\x38\x2c\
+\x32\x33\x34\x68\x31\x35\x34\x56\x38\x30\x0d\x0a\x09\x09\x6c\x2d\
+\x35\x31\x2e\x36\x39\x38\x2c\x35\x31\x2e\x37\x30\x32\x43\x33\x34\
+\x38\x2e\x34\x30\x36\x2c\x39\x39\x2e\x37\x39\x38\x2c\x33\x30\x34\
+\x2e\x34\x30\x36\x2c\x38\x30\x2c\x32\x35\x36\x2c\x38\x30\x63\x2d\
+\x39\x36\x2e\x37\x39\x37\x2c\x30\x2d\x31\x37\x36\x2c\x37\x39\x2e\
+\x32\x30\x33\x2d\x31\x37\x36\x2c\x31\x37\x36\x73\x37\x38\x2e\x30\
+\x39\x34\x2c\x31\x37\x36\x2c\x31\x37\x36\x2c\x31\x37\x36\x0d\x0a\
+\x09\x09\x63\x38\x31\x2e\x30\x34\x35\x2c\x30\x2c\x31\x34\x38\x2e\
+\x32\x38\x37\x2d\x35\x34\x2e\x31\x33\x34\x2c\x31\x36\x39\x2e\x34\
+\x30\x31\x2d\x31\x32\x38\x48\x33\x37\x38\x2e\x38\x35\x43\x33\x36\
+\x30\x2e\x31\x30\x35\x2c\x33\x35\x33\x2e\x35\x36\x31\x2c\x33\x31\
+\x31\x2e\x37\x31\x32\x2c\x33\x38\x38\x2c\x32\x35\x36\x2c\x33\x38\
+\x38\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
+\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\xc9\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -996,22 +953,27 @@ qt_resource_data = b"\
\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x32\
-\x37\x2c\x32\x33\x34\x2e\x36\x32\x35\x48\x31\x36\x37\x2e\x32\x39\
-\x36\x6c\x31\x31\x39\x2e\x37\x30\x32\x2d\x31\x31\x39\x2e\x37\x30\
-\x32\x4c\x32\x35\x36\x2c\x38\x35\x4c\x38\x35\x2c\x32\x35\x36\x6c\
-\x31\x37\x31\x2c\x31\x37\x31\x6c\x32\x39\x2e\x39\x32\x32\x2d\x32\
-\x39\x2e\x39\x32\x34\x4c\x31\x36\x37\x2e\x32\x39\x36\x2c\x32\x37\
-\x37\x2e\x33\x37\x35\x48\x34\x32\x37\x56\x32\x33\x34\x2e\x36\x32\
-\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\xf7\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
+\x3d\x22\x34\x38\x30\x2c\x32\x35\x36\x20\x33\x38\x34\x2c\x31\x36\
+\x30\x20\x33\x38\x34\x2c\x32\x33\x36\x20\x32\x37\x36\x2c\x32\x33\
+\x36\x20\x32\x37\x36\x2c\x31\x32\x38\x20\x33\x35\x32\x2c\x31\x32\
+\x38\x20\x32\x35\x36\x2c\x33\x32\x20\x31\x36\x30\x2c\x31\x32\x38\
+\x20\x32\x33\x36\x2c\x31\x32\x38\x20\x32\x33\x36\x2c\x32\x33\x36\
+\x20\x31\x32\x38\x2c\x32\x33\x36\x20\x31\x32\x38\x2c\x31\x36\x30\
+\x20\x33\x32\x2c\x32\x35\x36\x20\x31\x32\x38\x2c\x33\x35\x32\x20\
+\x0d\x0a\x09\x31\x32\x38\x2c\x32\x37\x36\x20\x32\x33\x36\x2c\x32\
+\x37\x36\x20\x32\x33\x36\x2c\x33\x38\x34\x20\x31\x36\x30\x2c\x33\
+\x38\x34\x20\x32\x35\x36\x2c\x34\x38\x30\x20\x33\x35\x32\x2c\x33\
+\x38\x34\x20\x32\x37\x35\x2e\x38\x2c\x33\x38\x34\x20\x32\x37\x35\
+\x2e\x34\x2c\x32\x37\x35\x2e\x35\x20\x33\x38\x34\x2c\x32\x37\x35\
+\x2e\x38\x20\x33\x38\x34\x2c\x33\x35\x32\x20\x22\x2f\x3e\x0d\x0a\
+\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\x7f\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -1043,24 +1005,58 @@ qt_resource_data = b"\
\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x31\x37\x2e\x34\
-\x2c\x32\x32\x34\x48\x32\x38\x38\x56\x39\x34\x2e\x36\x63\x30\x2d\
-\x31\x36\x2e\x39\x2d\x31\x34\x2e\x33\x2d\x33\x30\x2e\x36\x2d\x33\
-\x32\x2d\x33\x30\x2e\x36\x63\x2d\x31\x37\x2e\x37\x2c\x30\x2d\x33\
-\x32\x2c\x31\x33\x2e\x37\x2d\x33\x32\x2c\x33\x30\x2e\x36\x56\x32\
-\x32\x34\x48\x39\x34\x2e\x36\x43\x37\x37\x2e\x37\x2c\x32\x32\x34\
-\x2c\x36\x34\x2c\x32\x33\x38\x2e\x33\x2c\x36\x34\x2c\x32\x35\x36\
-\x0d\x0a\x09\x63\x30\x2c\x31\x37\x2e\x37\x2c\x31\x33\x2e\x37\x2c\
-\x33\x32\x2c\x33\x30\x2e\x36\x2c\x33\x32\x48\x32\x32\x34\x76\x31\
-\x32\x39\x2e\x34\x63\x30\x2c\x31\x36\x2e\x39\x2c\x31\x34\x2e\x33\
-\x2c\x33\x30\x2e\x36\x2c\x33\x32\x2c\x33\x30\x2e\x36\x63\x31\x37\
-\x2e\x37\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x37\x2c\x33\x32\x2d\
-\x33\x30\x2e\x36\x56\x32\x38\x38\x68\x31\x32\x39\x2e\x34\x63\x31\
-\x36\x2e\x39\x2c\x30\x2c\x33\x30\x2e\x36\x2d\x31\x34\x2e\x33\x2c\
-\x33\x30\x2e\x36\x2d\x33\x32\x0d\x0a\x09\x43\x34\x34\x38\x2c\x32\
-\x33\x38\x2e\x33\x2c\x34\x33\x34\x2e\x33\x2c\x32\x32\x34\x2c\x34\
-\x31\x37\x2e\x34\x2c\x32\x32\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\
-\x73\x76\x67\x3e\x0d\x0a\
+\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
+\x3d\x22\x32\x38\x38\x2c\x39\x36\x20\x33\x33\x37\x2e\x39\x2c\x31\
+\x34\x35\x2e\x39\x20\x32\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x32\
+\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x31\x34\x35\x2e\x39\x2c\x33\
+\x33\x37\x2e\x39\x20\x39\x36\x2c\x32\x38\x38\x20\x39\x36\x2c\x34\
+\x31\x36\x20\x32\x32\x34\x2c\x34\x31\x36\x20\x31\x37\x34\x2e\x31\
+\x2c\x33\x36\x36\x2e\x31\x20\x33\x35\x37\x2e\x34\x2c\x31\x38\x32\
+\x2e\x39\x20\x33\x36\x36\x2e\x31\x2c\x31\x37\x34\x2e\x31\x20\x0d\
+\x0a\x09\x34\x31\x36\x2c\x32\x32\x34\x20\x34\x31\x36\x2c\x39\x36\
+\x20\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\x79\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x67\x3e\x0d\x0a\x09\x09\x09\x3c\x70\x6f\x6c\
+\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\x22\x31\x38\x36\
+\x2e\x33\x30\x31\x2c\x33\x33\x39\x2e\x38\x39\x33\x20\x39\x36\x2c\
+\x32\x34\x39\x2e\x34\x36\x31\x20\x36\x34\x2c\x32\x37\x39\x2e\x39\
+\x36\x38\x20\x31\x38\x36\x2e\x33\x30\x31\x2c\x34\x30\x32\x20\x34\
+\x34\x38\x2c\x31\x34\x30\x2e\x35\x30\x36\x20\x34\x31\x36\x2c\x31\
+\x31\x30\x20\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x09\x3c\x2f\x67\
+\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
+\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
\x00\x00\x03\x93\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -1121,13 +1117,13 @@ qt_resource_data = b"\
\x34\x2c\x31\x30\x2e\x36\x35\x32\x2c\x34\x2e\x30\x30\x34\x2c\x38\
\x2e\x32\x38\x37\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\
\x0d\x0a\
-\x00\x00\x03\x22\
+\x00\x00\x03\xc4\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
@@ -1139,42 +1135,143 @@ qt_resource_data = b"\
\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x22\x32\x35\x36\x22\
-\x20\x63\x79\x3d\x22\x32\x38\x30\x22\x20\x72\x3d\x22\x36\x33\x22\
-\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
-\x34\x30\x2c\x39\x36\x68\x2d\x38\x38\x6c\x2d\x33\x32\x2d\x33\x32\
-\x48\x31\x39\x32\x6c\x2d\x33\x32\x2c\x33\x32\x48\x37\x32\x63\x2d\
-\x32\x32\x2e\x30\x39\x32\x2c\x30\x2d\x34\x30\x2c\x31\x37\x2e\x39\
-\x30\x38\x2d\x34\x30\x2c\x34\x30\x76\x32\x37\x32\x63\x30\x2c\x32\
-\x32\x2e\x30\x39\x32\x2c\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2c\
-\x34\x30\x2c\x34\x30\x68\x33\x36\x38\x63\x32\x32\x2e\x30\x39\x32\
-\x2c\x30\x2c\x34\x30\x2d\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2d\
-\x34\x30\x0d\x0a\x09\x09\x56\x31\x33\x36\x43\x34\x38\x30\x2c\x31\
-\x31\x33\x2e\x39\x30\x38\x2c\x34\x36\x32\x2e\x30\x39\x32\x2c\x39\
-\x36\x2c\x34\x34\x30\x2c\x39\x36\x7a\x20\x4d\x32\x35\x36\x2c\x33\
-\x39\x32\x63\x2d\x36\x31\x2e\x38\x35\x35\x2c\x30\x2d\x31\x31\x32\
-\x2d\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2d\x31\x31\x32\x73\
-\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2c\x31\x31\x32\x2d\x31\
-\x31\x32\x73\x31\x31\x32\x2c\x35\x30\x2e\x31\x34\x35\x2c\x31\x31\
-\x32\x2c\x31\x31\x32\x0d\x0a\x09\x09\x53\x33\x31\x37\x2e\x38\x35\
-\x35\x2c\x33\x39\x32\x2c\x32\x35\x36\x2c\x33\x39\x32\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
-\x0a\
-\x00\x00\x05\x27\
+\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
+\x64\x5f\x6c\x65\x66\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
+\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
+\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
+\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
+\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\x61\
+\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\
+\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x78\
+\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
+\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\
+\x31\x31\x2e\x33\x30\x32\x2c\x36\x2e\x37\x37\x36\x63\x2d\x30\x2e\
+\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2d\x30\x2e\x35\x31\x35\x2d\
+\x30\x2e\x31\x39\x37\x2d\x30\x2e\x37\x31\x2c\x30\x4c\x37\x2e\x37\
+\x38\x35\x2c\x39\x2e\x36\x34\x31\x63\x2d\x30\x2e\x31\x39\x36\x2c\
+\x30\x2e\x31\x39\x39\x2d\x30\x2e\x31\x39\x36\x2c\x30\x2e\x35\x32\
+\x2c\x30\x2c\x30\x2e\x37\x31\x37\x6c\x32\x2e\x38\x30\x37\x2c\x32\
+\x2e\x38\x36\x34\x0d\x0a\x09\x63\x30\x2e\x31\x39\x35\x2c\x30\x2e\
+\x31\x39\x39\x2c\x30\x2e\x35\x31\x34\x2c\x30\x2e\x31\x39\x38\x2c\
+\x30\x2e\x37\x31\x2c\x30\x63\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\
+\x39\x37\x2c\x30\x2e\x31\x39\x36\x2d\x30\x2e\x35\x31\x38\x2c\x30\
+\x2d\x30\x2e\x37\x31\x37\x4c\x39\x2c\x31\x30\x6c\x32\x2e\x33\x30\
+\x32\x2d\x32\x2e\x35\x30\x36\x43\x31\x31\x2e\x34\x39\x38\x2c\x37\
+\x2e\x32\x39\x36\x2c\x31\x31\x2e\x34\x39\x38\x2c\x36\x2e\x39\x37\
+\x36\x2c\x31\x31\x2e\x33\x30\x32\x2c\x36\x2e\x37\x37\x36\x7a\x0d\
+\x0a\x09\x20\x4d\x31\x30\x2c\x30\x2e\x34\x63\x2d\x35\x2e\x33\x30\
+\x32\x2c\x30\x2d\x39\x2e\x36\x2c\x34\x2e\x32\x39\x38\x2d\x39\x2e\
+\x36\x2c\x39\x2e\x36\x63\x30\x2c\x35\x2e\x33\x30\x33\x2c\x34\x2e\
+\x32\x39\x38\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x73\
+\x39\x2e\x36\x2d\x34\x2e\x32\x39\x37\x2c\x39\x2e\x36\x2d\x39\x2e\
+\x36\x43\x31\x39\x2e\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\
+\x33\x30\x32\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\
+\x4d\x31\x30\x2c\x31\x38\x2e\x33\x35\x34\x0d\x0a\x09\x63\x2d\x34\
+\x2e\x36\x31\x35\x2c\x30\x2d\x38\x2e\x33\x35\x34\x2d\x33\x2e\x37\
+\x34\x2d\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x30\x2d\
+\x34\x2e\x36\x31\x34\x2c\x33\x2e\x37\x33\x39\x2d\x38\x2e\x33\x35\
+\x34\x2c\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x34\x2e\
+\x36\x31\x33\x2c\x30\x2c\x38\x2e\x33\x35\x34\x2c\x33\x2e\x37\x34\
+\x2c\x38\x2e\x33\x35\x34\x2c\x38\x2e\x33\x35\x34\x0d\x0a\x09\x43\
+\x31\x38\x2e\x33\x35\x34\x2c\x31\x34\x2e\x36\x31\x34\x2c\x31\x34\
+\x2e\x36\x31\x33\x2c\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\x31\
+\x38\x2e\x33\x35\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
+\x3e\x0d\x0a\
+\x00\x00\x00\x6c\
+\x3c\
+\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\
+\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x3e\x3c\x70\x61\x74\x68\
+\x20\x64\x3d\x22\x4d\x31\x38\x20\x31\x32\x76\x31\x48\x38\x76\x35\
+\x6c\x2d\x36\x2d\x36\x20\x36\x2d\x36\x76\x35\x68\x38\x56\x32\x68\
+\x32\x7a\x22\x2f\x3e\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x03\xb5\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
+\x64\x5f\x72\x69\x67\x68\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
+\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
+\x78\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\
+\x22\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\
+\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\
+\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\
+\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\
+\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\
+\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
+\x4d\x31\x31\x2c\x31\x30\x4c\x38\x2e\x36\x39\x38\x2c\x37\x2e\x34\
+\x39\x34\x63\x2d\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x38\x2d\
+\x30\x2e\x31\x39\x36\x2d\x30\x2e\x35\x31\x39\x2c\x30\x2d\x30\x2e\
+\x37\x31\x38\x63\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2c\
+\x30\x2e\x35\x31\x35\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\x37\x31\
+\x2c\x30\x6c\x32\x2e\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x0d\x0a\
+\x09\x63\x30\x2e\x31\x39\x36\x2c\x30\x2e\x31\x39\x39\x2c\x30\x2e\
+\x31\x39\x36\x2c\x30\x2e\x35\x32\x2c\x30\x2c\x30\x2e\x37\x31\x37\
+\x6c\x2d\x32\x2e\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x63\x2d\x30\
+\x2e\x31\x39\x35\x2c\x30\x2e\x31\x39\x39\x2d\x30\x2e\x35\x31\x34\
+\x2c\x30\x2e\x31\x39\x38\x2d\x30\x2e\x37\x31\x2c\x30\x63\x2d\x30\
+\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2d\x30\x2e\x31\x39\x36\
+\x2d\x30\x2e\x35\x31\x38\x2c\x30\x2d\x30\x2e\x37\x31\x37\x4c\x31\
+\x31\x2c\x31\x30\x7a\x20\x4d\x31\x30\x2c\x30\x2e\x34\x0d\x0a\x09\
+\x63\x35\x2e\x33\x30\x32\x2c\x30\x2c\x39\x2e\x36\x2c\x34\x2e\x32\
+\x39\x38\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x63\x30\x2c\x35\x2e\x33\
+\x30\x33\x2d\x34\x2e\x32\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\
+\x2c\x39\x2e\x36\x53\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x33\x2c\
+\x30\x2e\x34\x2c\x31\x30\x43\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\
+\x2c\x34\x2e\x36\x39\x38\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\
+\x34\x7a\x20\x4d\x31\x30\x2c\x31\x38\x2e\x33\x35\x34\x0d\x0a\x09\
+\x63\x34\x2e\x36\x31\x33\x2c\x30\x2c\x38\x2e\x33\x35\x34\x2d\x33\
+\x2e\x37\x34\x2c\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\
+\x30\x2d\x34\x2e\x36\x31\x34\x2d\x33\x2e\x37\x34\x31\x2d\x38\x2e\
+\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\
+\x2d\x34\x2e\x36\x31\x35\x2c\x30\x2d\x38\x2e\x33\x35\x34\x2c\x33\
+\x2e\x37\x34\x2d\x38\x2e\x33\x35\x34\x2c\x38\x2e\x33\x35\x34\x0d\
+\x0a\x09\x43\x31\x2e\x36\x34\x35\x2c\x31\x34\x2e\x36\x31\x34\x2c\
+\x35\x2e\x33\x38\x35\x2c\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\
+\x31\x38\x2e\x33\x35\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\
+\x67\x3e\x0d\x0a\
+\x00\x00\x01\x20\
+\x3c\
+\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\
+\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x3e\x3c\x70\x61\x74\x68\
+\x20\x64\x3d\x22\x4d\x34\x2e\x33\x34\x20\x31\x35\x2e\x36\x36\x41\
+\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\x30\x20\x30\x20\x30\x20\
+\x39\x20\x31\x37\x2e\x39\x34\x56\x31\x30\x48\x35\x56\x38\x68\x34\
+\x56\x35\x2e\x38\x33\x61\x33\x20\x33\x20\x30\x20\x31\x20\x31\x20\
+\x32\x20\x30\x56\x38\x68\x34\x76\x32\x68\x2d\x34\x76\x37\x2e\x39\
+\x34\x61\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\x30\x20\x30\x20\
+\x30\x20\x34\x2e\x36\x36\x2d\x32\x2e\x32\x38\x6c\x2d\x31\x2e\x34\
+\x32\x2d\x31\x2e\x34\x32\x68\x35\x2e\x36\x36\x6c\x2d\x32\x2e\x38\
+\x33\x20\x32\x2e\x38\x33\x61\x31\x30\x20\x31\x30\x20\x30\x20\x30\
+\x20\x31\x2d\x31\x34\x2e\x31\x34\x20\x30\x4c\x2e\x31\x20\x31\x34\
+\x2e\x32\x34\x68\x35\x2e\x36\x36\x6c\x2d\x31\x2e\x34\x32\x20\x31\
+\x2e\x34\x32\x7a\x4d\x31\x30\x20\x34\x61\x31\x20\x31\x20\x30\x20\
+\x31\x20\x30\x20\x30\x2d\x32\x20\x31\x20\x31\x20\x30\x20\x30\x20\
+\x30\x20\x30\x20\x32\x7a\x22\x2f\x3e\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x03\xeb\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -1201,65 +1298,45 @@ qt_resource_data = b"\
\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x31\x32\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
-\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
-\x35\x36\x2c\x36\x34\x43\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\
-\x2c\x36\x34\x2c\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\x2c\x32\
-\x35\x36\x63\x30\x2c\x31\x30\x35\x2e\x36\x30\x34\x2c\x38\x36\x2e\
-\x34\x30\x31\x2c\x31\x39\x32\x2c\x31\x39\x32\x2c\x31\x39\x32\x63\
-\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x38\
-\x36\x34\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\
-\x38\x2e\x35\x33\x31\x2d\x33\x2e\x31\x39\x38\x2d\x31\x36\x2d\x38\
-\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\x33\x33\x63\x2d\x35\x2e\x33\
-\x33\x33\x2d\x35\x2e\x33\x33\x34\x2d\x38\x2e\x35\x33\x31\x2d\x31\
-\x32\x2e\x38\x30\x33\x2d\x38\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\
-\x33\x34\x63\x30\x2d\x31\x38\x2e\x31\x33\x35\x2c\x31\x33\x2e\x38\
-\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x68\x33\x38\x2e\x33\
-\x39\x36\x0d\x0a\x09\x09\x09\x63\x35\x38\x2e\x36\x36\x37\x2c\x30\
-\x2c\x31\x30\x36\x2e\x36\x36\x37\x2d\x34\x38\x2c\x31\x30\x36\x2e\
-\x36\x36\x37\x2d\x31\x30\x36\x2e\x36\x36\x36\x43\x34\x34\x38\x2c\
-\x31\x34\x30\x2e\x38\x30\x32\x2c\x33\x36\x31\x2e\x36\x30\x34\x2c\
-\x36\x34\x2c\x32\x35\x36\x2c\x36\x34\x7a\x20\x4d\x31\x33\x38\x2e\
-\x36\x36\x37\x2c\x32\x35\x36\x63\x2d\x31\x38\x2e\x31\x33\x36\x2c\
-\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\
-\x32\x73\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\
-\x32\x0d\x0a\x09\x09\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\
-\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x53\
-\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x35\x36\x2c\x31\x33\x38\x2e\
-\x36\x36\x37\x2c\x32\x35\x36\x7a\x20\x4d\x32\x30\x32\x2e\x36\x36\
-\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\x2e\x31\x33\
-\x36\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\
-\x2d\x33\x32\x63\x30\x2d\x31\x38\x2e\x31\x33\x36\x2c\x31\x33\x2e\
-\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\
-\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\x33\x32\x2c\x31\x33\
-\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x32\x33\x34\x2e\x36\
-\x36\x37\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x32\x30\x2e\x38\
-\x30\x32\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x32\x30\x32\x2e\x36\
-\x36\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\x33\x30\x39\
-\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\
-\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\
-\x2d\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\x31\x38\
-\x2e\x31\x33\x36\x2c\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\x2c\x33\
-\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\
-\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x33\x34\
-\x31\x2e\x33\x33\x33\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x33\x32\
-\x37\x2e\x34\x36\x39\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x33\x30\
-\x39\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\
-\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x0d\x0a\x09\x09\x09\
-\x63\x2d\x31\x38\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\
-\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\x32\x73\x31\x33\x2e\x38\x36\
-\x35\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\
-\x36\x2c\x30\x2c\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\
-\x2c\x33\x32\x53\x33\x39\x31\x2e\x34\x36\x39\x2c\x32\x35\x36\x2c\
-\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x7a\x22\x2f\x3e\x0d\
-\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\xc9\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x67\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
+\x4d\x32\x35\x36\x2c\x31\x32\x38\x63\x2d\x38\x31\x2e\x39\x2c\x30\
+\x2d\x31\x34\x35\x2e\x37\x2c\x34\x38\x2e\x38\x2d\x32\x32\x34\x2c\
+\x31\x32\x38\x63\x36\x37\x2e\x34\x2c\x36\x37\x2e\x37\x2c\x31\x32\
+\x34\x2c\x31\x32\x38\x2c\x32\x32\x34\x2c\x31\x32\x38\x63\x39\x39\
+\x2e\x39\x2c\x30\x2c\x31\x37\x33\x2e\x34\x2d\x37\x36\x2e\x34\x2c\
+\x32\x32\x34\x2d\x31\x32\x36\x2e\x36\x0d\x0a\x09\x09\x43\x34\x32\
+\x38\x2e\x32\x2c\x31\x39\x38\x2e\x36\x2c\x33\x35\x34\x2e\x38\x2c\
+\x31\x32\x38\x2c\x32\x35\x36\x2c\x31\x32\x38\x7a\x20\x4d\x32\x35\
+\x36\x2c\x33\x34\x37\x2e\x33\x63\x2d\x34\x39\x2e\x34\x2c\x30\x2d\
+\x38\x39\x2e\x36\x2d\x34\x31\x2d\x38\x39\x2e\x36\x2d\x39\x31\x2e\
+\x33\x63\x30\x2d\x35\x30\x2e\x34\x2c\x34\x30\x2e\x32\x2d\x39\x31\
+\x2e\x33\x2c\x38\x39\x2e\x36\x2d\x39\x31\x2e\x33\x73\x38\x39\x2e\
+\x36\x2c\x34\x31\x2c\x38\x39\x2e\x36\x2c\x39\x31\x2e\x33\x0d\x0a\
+\x09\x09\x43\x33\x34\x35\x2e\x36\x2c\x33\x30\x36\x2e\x34\x2c\x33\
+\x30\x35\x2e\x34\x2c\x33\x34\x37\x2e\x33\x2c\x32\x35\x36\x2c\x33\
+\x34\x37\x2e\x33\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\
+\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\
+\x32\x32\x34\x63\x30\x2d\x37\x2e\x39\x2c\x32\x2e\x39\x2d\x31\x35\
+\x2e\x31\x2c\x37\x2e\x36\x2d\x32\x30\x2e\x37\x63\x2d\x32\x2e\x35\
+\x2d\x30\x2e\x34\x2d\x35\x2d\x30\x2e\x36\x2d\x37\x2e\x36\x2d\x30\
+\x2e\x36\x63\x2d\x32\x38\x2e\x38\x2c\x30\x2d\x35\x32\x2e\x33\x2c\
+\x32\x33\x2e\x39\x2d\x35\x32\x2e\x33\x2c\x35\x33\x2e\x33\x63\x30\
+\x2c\x32\x39\x2e\x34\x2c\x32\x33\x2e\x35\x2c\x35\x33\x2e\x33\x2c\
+\x35\x32\x2e\x33\x2c\x35\x33\x2e\x33\x0d\x0a\x09\x09\x09\x73\x35\
+\x32\x2e\x33\x2d\x32\x33\x2e\x39\x2c\x35\x32\x2e\x33\x2d\x35\x33\
+\x2e\x33\x63\x30\x2d\x32\x2e\x33\x2d\x30\x2e\x32\x2d\x34\x2e\x36\
+\x2d\x30\x2e\x34\x2d\x36\x2e\x39\x63\x2d\x35\x2e\x35\x2c\x34\x2e\
+\x33\x2d\x31\x32\x2e\x33\x2c\x36\x2e\x39\x2d\x31\x39\x2e\x38\x2c\
+\x36\x2e\x39\x43\x32\x37\x30\x2e\x33\x2c\x32\x35\x36\x2c\x32\x35\
+\x36\x2c\x32\x34\x31\x2e\x37\x2c\x32\x35\x36\x2c\x32\x32\x34\x7a\
+\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\
+\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\x7d\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -1286,26 +1363,21 @@ qt_resource_data = b"\
\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
-\x3d\x22\x34\x38\x30\x2c\x32\x35\x36\x20\x33\x38\x34\x2c\x31\x36\
-\x30\x20\x33\x38\x34\x2c\x32\x33\x36\x20\x32\x37\x36\x2c\x32\x33\
-\x36\x20\x32\x37\x36\x2c\x31\x32\x38\x20\x33\x35\x32\x2c\x31\x32\
-\x38\x20\x32\x35\x36\x2c\x33\x32\x20\x31\x36\x30\x2c\x31\x32\x38\
-\x20\x32\x33\x36\x2c\x31\x32\x38\x20\x32\x33\x36\x2c\x32\x33\x36\
-\x20\x31\x32\x38\x2c\x32\x33\x36\x20\x31\x32\x38\x2c\x31\x36\x30\
-\x20\x33\x32\x2c\x32\x35\x36\x20\x31\x32\x38\x2c\x33\x35\x32\x20\
-\x0d\x0a\x09\x31\x32\x38\x2c\x32\x37\x36\x20\x32\x33\x36\x2c\x32\
-\x37\x36\x20\x32\x33\x36\x2c\x33\x38\x34\x20\x31\x36\x30\x2c\x33\
-\x38\x34\x20\x32\x35\x36\x2c\x34\x38\x30\x20\x33\x35\x32\x2c\x33\
-\x38\x34\x20\x32\x37\x35\x2e\x38\x2c\x33\x38\x34\x20\x32\x37\x35\
-\x2e\x34\x2c\x32\x37\x35\x2e\x35\x20\x33\x38\x34\x2c\x32\x37\x35\
-\x2e\x38\x20\x33\x38\x34\x2c\x33\x35\x32\x20\x22\x2f\x3e\x0d\x0a\
-\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x38\x35\
+\x2c\x32\x37\x37\x2e\x33\x37\x35\x68\x32\x35\x39\x2e\x37\x30\x34\
+\x4c\x32\x32\x35\x2e\x30\x30\x32\x2c\x33\x39\x37\x2e\x30\x37\x37\
+\x4c\x32\x35\x36\x2c\x34\x32\x37\x6c\x31\x37\x31\x2d\x31\x37\x31\
+\x4c\x32\x35\x36\x2c\x38\x35\x6c\x2d\x32\x39\x2e\x39\x32\x32\x2c\
+\x32\x39\x2e\x39\x32\x34\x6c\x31\x31\x38\x2e\x36\x32\x36\x2c\x31\
+\x31\x39\x2e\x37\x30\x31\x48\x38\x35\x56\x32\x37\x37\x2e\x33\x37\
+\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
\x00\x00\x03\x36\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -1360,6 +1432,250 @@ qt_resource_data = b"\
\x2c\x34\x34\x38\x20\x31\x39\x32\x2c\x33\x39\x36\x2e\x37\x39\x35\
\x20\x09\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
\x76\x67\x3e\x0d\x0a\
+\x00\x00\x00\xdd\
+\x3c\
+\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x38\x22\
+\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x38\x22\x20\x76\x69\x65\x77\
+\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x38\x20\x38\x22\x3e\x0a\x20\
+\x20\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x30\x20\x30\x76\x32\
+\x68\x2e\x35\x63\x30\x2d\x2e\x35\x35\x2e\x34\x35\x2d\x31\x20\x31\
+\x2d\x31\x68\x31\x2e\x35\x76\x35\x2e\x35\x63\x30\x20\x2e\x32\x38\
+\x2d\x2e\x32\x32\x2e\x35\x2d\x2e\x35\x2e\x35\x68\x2d\x2e\x35\x76\
+\x31\x68\x34\x76\x2d\x31\x68\x2d\x2e\x35\x63\x2d\x2e\x32\x38\x20\
+\x30\x2d\x2e\x35\x2d\x2e\x32\x32\x2d\x2e\x35\x2d\x2e\x35\x76\x2d\
+\x35\x2e\x35\x68\x31\x2e\x35\x63\x2e\x35\x35\x20\x30\x20\x31\x20\
+\x2e\x34\x35\x20\x31\x20\x31\x68\x2e\x35\x76\x2d\x32\x68\x2d\x38\
+\x7a\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x03\x4c\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x32\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
+\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
+\x35\x36\x2c\x31\x35\x32\x63\x2d\x35\x37\x2e\x32\x2c\x30\x2d\x31\
+\x30\x34\x2c\x34\x36\x2e\x38\x2d\x31\x30\x34\x2c\x31\x30\x34\x73\
+\x34\x36\x2e\x38\x2c\x31\x30\x34\x2c\x31\x30\x34\x2c\x31\x30\x34\
+\x73\x31\x30\x34\x2d\x34\x36\x2e\x38\x2c\x31\x30\x34\x2d\x31\x30\
+\x34\x53\x33\x31\x33\x2e\x32\x2c\x31\x35\x32\x2c\x32\x35\x36\x2c\
+\x31\x35\x32\x7a\x20\x4d\x32\x35\x36\x2c\x34\x38\x0d\x0a\x09\x09\
+\x09\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x34\x38\x2c\
+\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\x35\x36\x73\x39\
+\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\x38\x2c\x32\x30\
+\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\
+\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\x2c\x34\x38\x2c\
+\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\x2c\x34\x32\x32\
+\x2e\x34\x0d\x0a\x09\x09\x09\x63\x2d\x39\x31\x2e\x35\x31\x38\x2c\
+\x30\x2d\x31\x36\x36\x2e\x34\x2d\x37\x34\x2e\x38\x38\x33\x2d\x31\
+\x36\x36\x2e\x34\x2d\x31\x36\x36\x2e\x34\x53\x31\x36\x34\x2e\x34\
+\x38\x32\x2c\x38\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\
+\x53\x34\x32\x32\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\
+\x32\x32\x2e\x34\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\
+\x2c\x34\x32\x32\x2e\x34\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x34\
+\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x07\x80\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x39\x33\x2e\x34\x36\
+\x2c\x32\x34\x39\x2e\x30\x35\x36\x63\x33\x2e\x37\x32\x33\x2d\x30\
+\x2e\x36\x37\x2c\x37\x2e\x35\x38\x39\x2d\x31\x2e\x30\x34\x31\x2c\
+\x31\x31\x2e\x35\x38\x36\x2d\x31\x2e\x30\x34\x31\x4c\x32\x30\x31\
+\x2e\x39\x32\x34\x2c\x32\x34\x38\x68\x31\x30\x33\x2e\x38\x32\x33\
+\x63\x34\x2e\x35\x30\x33\x2c\x30\x2c\x38\x2e\x38\x30\x36\x2d\x30\
+\x2e\x36\x31\x37\x2c\x31\x32\x2e\x39\x30\x38\x2d\x31\x2e\x37\x35\
+\x34\x0d\x0a\x09\x09\x63\x31\x39\x2e\x33\x37\x2d\x35\x2e\x33\x36\
+\x33\x2c\x33\x33\x2e\x33\x34\x35\x2d\x32\x32\x2e\x35\x33\x37\x2c\
+\x33\x33\x2e\x33\x34\x35\x2d\x34\x33\x2e\x36\x36\x33\x76\x2d\x33\
+\x30\x2e\x38\x32\x32\x76\x2d\x35\x36\x2e\x34\x30\x32\x63\x30\x2d\
+\x32\x34\x2e\x38\x33\x32\x2d\x32\x31\x2e\x31\x35\x2d\x34\x33\x2e\
+\x34\x38\x34\x2d\x34\x36\x2e\x32\x38\x39\x2d\x34\x37\x2e\x36\x30\
+\x36\x0d\x0a\x09\x09\x63\x2d\x31\x35\x2e\x39\x33\x31\x2d\x32\x2e\
+\x36\x32\x34\x2d\x33\x39\x2e\x32\x35\x38\x2d\x33\x2e\x38\x32\x37\
+\x2d\x35\x35\x2e\x30\x38\x39\x2d\x33\x2e\x37\x34\x39\x63\x2d\x31\
+\x35\x2e\x38\x32\x39\x2c\x30\x2e\x30\x38\x36\x2d\x33\x30\x2e\x39\
+\x38\x31\x2c\x31\x2e\x34\x30\x34\x2d\x34\x34\x2e\x32\x37\x37\x2c\
+\x33\x2e\x37\x34\x39\x43\x31\x36\x37\x2e\x31\x34\x33\x2c\x37\x34\
+\x2e\x35\x37\x36\x2c\x31\x36\x30\x2c\x38\x38\x2e\x39\x32\x38\x2c\
+\x31\x36\x30\x2c\x31\x31\x35\x2e\x33\x35\x39\x56\x31\x34\x34\x68\
+\x39\x36\x0d\x0a\x09\x09\x76\x31\x36\x48\x31\x32\x38\x2e\x38\x32\
+\x63\x2d\x33\x35\x2e\x36\x32\x38\x2c\x30\x2d\x36\x34\x2e\x35\x33\
+\x38\x2c\x34\x32\x2e\x35\x37\x31\x2d\x36\x34\x2e\x38\x31\x33\x2c\
+\x39\x35\x2e\x32\x34\x32\x43\x36\x34\x2e\x30\x30\x35\x2c\x32\x35\
+\x35\x2e\x34\x39\x35\x2c\x36\x34\x2c\x32\x35\x35\x2e\x37\x34\x37\
+\x2c\x36\x34\x2c\x32\x35\x36\x63\x30\x2c\x39\x2e\x35\x32\x33\x2c\
+\x30\x2e\x39\x34\x2c\x31\x38\x2e\x37\x32\x2c\x32\x2e\x36\x38\x35\
+\x2c\x32\x37\x2e\x34\x30\x34\x0d\x0a\x09\x09\x43\x37\x34\x2e\x36\
+\x34\x38\x2c\x33\x32\x33\x2e\x30\x37\x2c\x39\x39\x2e\x34\x35\x31\
+\x2c\x33\x35\x32\x2c\x31\x32\x38\x2e\x38\x32\x2c\x33\x35\x32\x48\
+\x31\x34\x34\x76\x2d\x32\x2e\x36\x36\x32\x76\x2d\x34\x33\x2e\x32\
+\x37\x33\x43\x31\x34\x34\x2c\x32\x37\x39\x2e\x32\x33\x38\x2c\x31\
+\x36\x34\x2e\x31\x34\x36\x2c\x32\x35\x34\x2e\x33\x33\x32\x2c\x31\
+\x39\x33\x2e\x34\x36\x2c\x32\x34\x39\x2e\x30\x35\x36\x7a\x20\x4d\
+\x32\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x0d\
+\x0a\x09\x09\x63\x2d\x39\x2e\x35\x39\x32\x2c\x30\x2d\x31\x37\x2e\
+\x33\x38\x34\x2d\x37\x2e\x37\x38\x35\x2d\x31\x37\x2e\x33\x38\x34\
+\x2d\x31\x37\x2e\x34\x30\x33\x63\x30\x2d\x39\x2e\x36\x36\x34\x2c\
+\x37\x2e\x37\x37\x34\x2d\x31\x37\x2e\x35\x32\x2c\x31\x37\x2e\x33\
+\x38\x34\x2d\x31\x37\x2e\x35\x32\x63\x39\x2e\x35\x37\x34\x2c\x30\
+\x2c\x31\x37\x2e\x33\x39\x39\x2c\x37\x2e\x38\x35\x35\x2c\x31\x37\
+\x2e\x33\x39\x39\x2c\x31\x37\x2e\x35\x32\x0d\x0a\x09\x09\x43\x32\
+\x32\x31\x2e\x30\x35\x36\x2c\x31\x31\x39\x2e\x32\x31\x37\x2c\x32\
+\x31\x33\x2e\x32\x34\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x2c\x32\
+\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x7a\x22\
+\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
+\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\x35\x34\x33\x43\x34\
+\x33\x34\x2e\x37\x38\x2c\x31\x38\x36\x2e\x30\x32\x31\x2c\x34\x31\
+\x31\x2e\x30\x33\x33\x2c\x31\x36\x30\x2c\x33\x38\x33\x2e\x31\x38\
+\x2c\x31\x36\x30\x48\x33\x36\x38\x76\x32\x2e\x36\x32\x36\x76\x33\
+\x38\x2e\x30\x34\x36\x63\x30\x2c\x33\x33\x2e\x39\x31\x35\x2d\x32\
+\x32\x2e\x32\x38\x36\x2c\x35\x38\x2e\x34\x37\x34\x2d\x34\x39\x2e\
+\x34\x38\x39\x2c\x36\x32\x2e\x36\x38\x31\x0d\x0a\x09\x09\x63\x2d\
+\x32\x2e\x37\x33\x37\x2c\x30\x2e\x34\x32\x34\x2d\x35\x2e\x34\x38\
+\x33\x2c\x30\x2e\x36\x34\x36\x2d\x38\x2e\x33\x30\x31\x2c\x30\x2e\
+\x36\x34\x36\x48\x32\x30\x36\x2e\x33\x35\x31\x63\x2d\x34\x2e\x35\
+\x31\x38\x2c\x30\x2d\x38\x2e\x39\x30\x34\x2c\x30\x2e\x35\x38\x34\
+\x2d\x31\x33\x2e\x30\x34\x39\x2c\x31\x2e\x36\x37\x32\x43\x31\x37\
+\x34\x2e\x31\x38\x2c\x32\x37\x30\x2e\x36\x38\x39\x2c\x31\x36\x30\
+\x2c\x32\x38\x36\x2e\x36\x2c\x31\x36\x30\x2c\x33\x30\x37\x2e\x32\
+\x33\x36\x76\x33\x32\x2e\x39\x32\x32\x0d\x0a\x09\x09\x76\x35\x34\
+\x2e\x33\x30\x35\x63\x30\x2c\x32\x34\x2e\x38\x33\x32\x2c\x32\x34\
+\x2e\x39\x37\x37\x2c\x33\x39\x2e\x34\x32\x36\x2c\x34\x39\x2e\x34\
+\x38\x31\x2c\x34\x36\x2e\x35\x35\x31\x63\x32\x39\x2e\x33\x32\x37\
+\x2c\x38\x2e\x35\x33\x31\x2c\x36\x31\x2e\x32\x36\x37\x2c\x31\x30\
+\x2e\x30\x36\x38\x2c\x39\x36\x2e\x33\x36\x36\x2c\x30\x43\x33\x32\
+\x39\x2e\x31\x35\x2c\x34\x33\x34\x2e\x33\x35\x34\x2c\x33\x35\x32\
+\x2c\x34\x32\x30\x2e\x38\x39\x33\x2c\x33\x35\x32\x2c\x33\x39\x34\
+\x2e\x34\x36\x33\x56\x33\x36\x38\x0d\x0a\x09\x09\x68\x2d\x39\x36\
+\x76\x2d\x31\x36\x68\x31\x32\x37\x2e\x31\x38\x63\x32\x35\x2e\x32\
+\x34\x2c\x30\x2c\x34\x37\x2e\x31\x30\x37\x2d\x32\x31\x2e\x33\x36\
+\x35\x2c\x35\x37\x2e\x38\x31\x34\x2d\x35\x32\x2e\x35\x34\x39\x43\
+\x34\x34\x35\x2e\x34\x37\x34\x2c\x32\x38\x36\x2e\x34\x30\x34\x2c\
+\x34\x34\x38\x2c\x32\x37\x31\x2e\x36\x34\x31\x2c\x34\x34\x38\x2c\
+\x32\x35\x36\x0d\x0a\x09\x09\x43\x34\x34\x38\x2c\x32\x34\x34\x2e\
+\x32\x33\x32\x2c\x34\x34\x36\x2e\x35\x36\x37\x2c\x32\x33\x32\x2e\
+\x39\x36\x32\x2c\x34\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\
+\x35\x34\x33\x7a\x20\x4d\x33\x30\x37\x2e\x38\x36\x37\x2c\x33\x38\
+\x32\x2e\x38\x32\x63\x39\x2e\x35\x39\x2c\x30\x2c\x31\x37\x2e\x33\
+\x38\x31\x2c\x37\x2e\x37\x38\x35\x2c\x31\x37\x2e\x33\x38\x31\x2c\
+\x31\x37\x2e\x34\x0d\x0a\x09\x09\x63\x30\x2c\x39\x2e\x36\x35\x2d\
+\x37\x2e\x37\x39\x31\x2c\x31\x37\x2e\x35\x32\x31\x2d\x31\x37\x2e\
+\x33\x38\x31\x2c\x31\x37\x2e\x35\x32\x31\x63\x2d\x39\x2e\x35\x37\
+\x37\x2c\x30\x2d\x31\x37\x2e\x33\x39\x39\x2d\x37\x2e\x38\x37\x31\
+\x2d\x31\x37\x2e\x33\x39\x39\x2d\x31\x37\x2e\x35\x32\x31\x43\x32\
+\x39\x30\x2e\x34\x36\x38\x2c\x33\x39\x30\x2e\x35\x39\x2c\x32\x39\
+\x38\x2e\x32\x37\x34\x2c\x33\x38\x32\x2e\x38\x32\x2c\x33\x30\x37\
+\x2e\x38\x36\x37\x2c\x33\x38\x32\x2e\x38\x32\x7a\x22\x2f\x3e\x0d\
+\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x0c\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x68\x65\x63\x6b\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
+\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
+\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\
+\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\
+\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\
+\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\
+\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\
+\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\
+\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
+\x4d\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x63\x2d\x30\
+\x2e\x34\x33\x35\x2c\x30\x2d\x30\x2e\x38\x34\x37\x2d\x30\x2e\x32\
+\x30\x33\x2d\x31\x2e\x31\x31\x31\x2d\x30\x2e\x35\x35\x33\x4c\x33\
+\x2e\x36\x31\x2c\x31\x31\x2e\x37\x32\x34\x63\x2d\x30\x2e\x34\x36\
+\x35\x2d\x30\x2e\x36\x31\x33\x2d\x30\x2e\x33\x34\x34\x2d\x31\x2e\
+\x34\x38\x36\x2c\x30\x2e\x32\x37\x2d\x31\x2e\x39\x35\x31\x0d\x0a\
+\x09\x63\x30\x2e\x36\x31\x35\x2d\x30\x2e\x34\x36\x37\x2c\x31\x2e\
+\x34\x38\x38\x2d\x30\x2e\x33\x34\x34\x2c\x31\x2e\x39\x35\x33\x2c\
+\x30\x2e\x32\x37\x6c\x32\x2e\x33\x35\x31\x2c\x33\x2e\x31\x30\x34\
+\x6c\x35\x2e\x39\x31\x31\x2d\x39\x2e\x34\x39\x32\x63\x30\x2e\x34\
+\x30\x37\x2d\x30\x2e\x36\x35\x32\x2c\x31\x2e\x32\x36\x37\x2d\x30\
+\x2e\x38\x35\x32\x2c\x31\x2e\x39\x32\x31\x2d\x30\x2e\x34\x34\x35\
+\x0d\x0a\x09\x63\x30\x2e\x36\x35\x33\x2c\x30\x2e\x34\x30\x36\x2c\
+\x30\x2e\x38\x35\x34\x2c\x31\x2e\x32\x36\x36\x2c\x30\x2e\x34\x34\
+\x36\x2c\x31\x2e\x39\x32\x4c\x39\x2e\x34\x37\x38\x2c\x31\x36\x2e\
+\x33\x34\x63\x2d\x30\x2e\x32\x34\x32\x2c\x30\x2e\x33\x39\x31\x2d\
+\x30\x2e\x36\x36\x31\x2c\x30\x2e\x36\x33\x35\x2d\x31\x2e\x31\x32\
+\x2c\x30\x2e\x36\x35\x36\x43\x38\x2e\x33\x33\x36\x2c\x31\x36\x2e\
+\x39\x39\x38\x2c\x38\x2e\x33\x31\x36\x2c\x31\x36\x2e\x39\x39\x38\
+\x2c\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
\x00\x00\x04\x8d\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
@@ -1435,135 +1751,6 @@ qt_resource_data = b"\
\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\
\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\
\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x03\x46\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x33\x37\x2e\x35\
-\x2c\x33\x38\x36\x2e\x36\x4c\x33\x30\x36\x2e\x39\x2c\x32\x35\x36\
-\x6c\x31\x33\x30\x2e\x36\x2d\x31\x33\x30\x2e\x36\x63\x31\x34\x2e\
-\x31\x2d\x31\x34\x2e\x31\x2c\x31\x34\x2e\x31\x2d\x33\x36\x2e\x38\
-\x2c\x30\x2d\x35\x30\x2e\x39\x63\x2d\x31\x34\x2e\x31\x2d\x31\x34\
-\x2e\x31\x2d\x33\x36\x2e\x38\x2d\x31\x34\x2e\x31\x2d\x35\x30\x2e\
-\x39\x2c\x30\x4c\x32\x35\x36\x2c\x32\x30\x35\x2e\x31\x4c\x31\x32\
-\x35\x2e\x34\x2c\x37\x34\x2e\x35\x0d\x0a\x09\x63\x2d\x31\x34\x2e\
-\x31\x2d\x31\x34\x2e\x31\x2d\x33\x36\x2e\x38\x2d\x31\x34\x2e\x31\
-\x2d\x35\x30\x2e\x39\x2c\x30\x63\x2d\x31\x34\x2e\x31\x2c\x31\x34\
-\x2e\x31\x2d\x31\x34\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x30\x2c\x35\
-\x30\x2e\x39\x4c\x32\x30\x35\x2e\x31\x2c\x32\x35\x36\x4c\x37\x34\
-\x2e\x35\x2c\x33\x38\x36\x2e\x36\x63\x2d\x31\x34\x2e\x31\x2c\x31\
-\x34\x2e\x31\x2d\x31\x34\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x30\x2c\
-\x35\x30\x2e\x39\x0d\x0a\x09\x63\x31\x34\x2e\x31\x2c\x31\x34\x2e\
-\x31\x2c\x33\x36\x2e\x38\x2c\x31\x34\x2e\x31\x2c\x35\x30\x2e\x39\
-\x2c\x30\x4c\x32\x35\x36\x2c\x33\x30\x36\x2e\x39\x6c\x31\x33\x30\
-\x2e\x36\x2c\x31\x33\x30\x2e\x36\x63\x31\x34\x2e\x31\x2c\x31\x34\
-\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x31\x34\x2e\x31\x2c\x35\x30\x2e\
-\x39\x2c\x30\x43\x34\x35\x31\x2e\x35\x2c\x34\x32\x33\x2e\x34\x2c\
-\x34\x35\x31\x2e\x35\x2c\x34\x30\x30\x2e\x36\x2c\x34\x33\x37\x2e\
-\x35\x2c\x33\x38\x36\x2e\x36\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\
-\x76\x67\x3e\x0d\x0a\
-\x00\x00\x04\x79\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x6f\x64\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
-\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
-\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
-\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
-\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\x3d\
-\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\x61\
-\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\
-\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x78\
-\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
-\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\
-\x35\x2e\x37\x31\x39\x2c\x31\x34\x2e\x37\x35\x63\x2d\x30\x2e\x32\
-\x33\x36\x2c\x30\x2d\x30\x2e\x34\x37\x34\x2d\x30\x2e\x30\x38\x33\
-\x2d\x30\x2e\x36\x36\x34\x2d\x30\x2e\x32\x35\x32\x4c\x2d\x30\x2e\
-\x30\x30\x35\x2c\x31\x30\x6c\x35\x2e\x33\x34\x31\x2d\x34\x2e\x37\
-\x34\x38\x43\x35\x2e\x37\x34\x38\x2c\x34\x2e\x38\x38\x37\x2c\x36\
-\x2e\x33\x38\x2c\x34\x2e\x39\x32\x32\x2c\x36\x2e\x37\x34\x37\x2c\
-\x35\x2e\x33\x33\x35\x0d\x0a\x09\x63\x30\x2e\x33\x36\x37\x2c\x30\
-\x2e\x34\x31\x33\x2c\x30\x2e\x33\x33\x2c\x31\x2e\x30\x34\x35\x2d\
-\x30\x2e\x30\x38\x33\x2c\x31\x2e\x34\x31\x32\x4c\x33\x2e\x30\x30\
-\x35\x2c\x31\x30\x6c\x33\x2e\x33\x37\x38\x2c\x33\x2e\x30\x30\x32\
-\x63\x30\x2e\x34\x31\x33\x2c\x30\x2e\x33\x36\x37\x2c\x30\x2e\x34\
-\x35\x2c\x30\x2e\x39\x39\x39\x2c\x30\x2e\x30\x38\x33\x2c\x31\x2e\
-\x34\x31\x32\x0d\x0a\x09\x43\x36\x2e\x32\x36\x39\x2c\x31\x34\x2e\
-\x36\x33\x37\x2c\x35\x2e\x39\x39\x34\x2c\x31\x34\x2e\x37\x35\x2c\
-\x35\x2e\x37\x31\x39\x2c\x31\x34\x2e\x37\x35\x7a\x20\x4d\x31\x34\
-\x2e\x36\x36\x34\x2c\x31\x34\x2e\x37\x34\x38\x4c\x32\x30\x2e\x30\
-\x30\x35\x2c\x31\x30\x6c\x2d\x35\x2e\x30\x36\x2d\x34\x2e\x34\x39\
-\x38\x63\x2d\x30\x2e\x34\x31\x33\x2d\x30\x2e\x33\x36\x37\x2d\x31\
-\x2e\x30\x34\x35\x2d\x30\x2e\x33\x33\x2d\x31\x2e\x34\x31\x31\x2c\
-\x30\x2e\x30\x38\x33\x0d\x0a\x09\x63\x2d\x30\x2e\x33\x36\x37\x2c\
-\x30\x2e\x34\x31\x33\x2d\x30\x2e\x33\x33\x2c\x31\x2e\x30\x34\x35\
-\x2c\x30\x2e\x30\x38\x33\x2c\x31\x2e\x34\x31\x32\x4c\x31\x36\x2e\
-\x39\x39\x35\x2c\x31\x30\x6c\x2d\x33\x2e\x36\x35\x39\x2c\x33\x2e\
-\x32\x35\x32\x63\x2d\x30\x2e\x34\x31\x33\x2c\x30\x2e\x33\x36\x37\
-\x2d\x30\x2e\x34\x35\x2c\x30\x2e\x39\x39\x39\x2d\x30\x2e\x30\x38\
-\x33\x2c\x31\x2e\x34\x31\x32\x43\x31\x33\x2e\x34\x35\x2c\x31\x34\
-\x2e\x38\x38\x37\x2c\x31\x33\x2e\x37\x32\x35\x2c\x31\x35\x2c\x31\
-\x34\x2c\x31\x35\x0d\x0a\x09\x43\x31\x34\x2e\x32\x33\x36\x2c\x31\
-\x35\x2c\x31\x34\x2e\x34\x37\x34\x2c\x31\x34\x2e\x39\x31\x37\x2c\
-\x31\x34\x2e\x36\x36\x34\x2c\x31\x34\x2e\x37\x34\x38\x7a\x20\x4d\
-\x39\x2e\x39\x38\x36\x2c\x31\x36\x2e\x31\x36\x35\x6c\x32\x2d\x31\
-\x32\x63\x30\x2e\x30\x39\x31\x2d\x30\x2e\x35\x34\x35\x2d\x30\x2e\
-\x32\x37\x37\x2d\x31\x2e\x30\x36\x2d\x30\x2e\x38\x32\x32\x2d\x31\
-\x2e\x31\x35\x31\x0d\x0a\x09\x63\x2d\x30\x2e\x35\x34\x37\x2d\x30\
-\x2e\x30\x39\x32\x2d\x31\x2e\x30\x36\x31\x2c\x30\x2e\x32\x37\x37\
-\x2d\x31\x2e\x31\x35\x2c\x30\x2e\x38\x32\x32\x6c\x2d\x32\x2c\x31\
-\x32\x63\x2d\x30\x2e\x30\x39\x31\x2c\x30\x2e\x35\x34\x35\x2c\x30\
-\x2e\x32\x37\x37\x2c\x31\x2e\x30\x36\x2c\x30\x2e\x38\x32\x32\x2c\
-\x31\x2e\x31\x35\x31\x43\x38\x2e\x38\x39\x32\x2c\x31\x36\x2e\x39\
-\x39\x36\x2c\x38\x2e\x39\x34\x36\x2c\x31\x37\x2c\x39\x2e\x30\x30\
-\x31\x2c\x31\x37\x0d\x0a\x09\x43\x39\x2e\x34\x38\x31\x2c\x31\x37\
-\x2c\x39\x2e\x39\x30\x35\x2c\x31\x36\x2e\x36\x35\x33\x2c\x39\x2e\
-\x39\x38\x36\x2c\x31\x36\x2e\x31\x36\x35\x7a\x22\x2f\x3e\x0d\x0a\
-\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
\x00\x00\x04\x30\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
@@ -1633,210 +1820,7 @@ qt_resource_data = b"\
\x35\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\
\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\
\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x01\xdd\
-\x00\
-\x00\x06\xe4\x78\x9c\xcd\x54\x4d\x6f\x9b\x40\x10\x3d\x13\x29\xff\
-\x61\xba\xb7\x4a\xec\x17\xc4\xd4\xa6\xa6\x51\xfd\x21\xcb\x52\x9a\
-\x58\x6a\xea\xaa\xa7\x0a\xc3\x16\x50\x28\x20\x58\xc0\xce\xaf\xef\
-\xee\x92\x54\x51\x95\xfa\x18\xfb\xb0\x33\xda\x79\x6f\xde\xbc\x65\
-\x24\xa6\xd7\xfb\xdf\x39\x74\xa2\x6e\xb2\xb2\x08\x10\x27\x0c\x81\
-\x28\xa2\x32\xce\x8a\x24\x40\xad\xfc\x85\xc7\xe8\xfa\xd3\xe5\xc5\
-\xf4\x1d\xc6\xb0\x12\x85\xa8\x43\x59\xd6\x3e\x7c\x8e\xcb\x9d\x80\
-\x75\x9e\xb7\x8d\x34\x25\xe0\x1e\x71\x08\xb7\xe1\xeb\x76\x05\xcb\
-\x7d\x55\xd6\x12\x36\x79\x9b\xe0\x75\x01\xc4\x14\xb7\xc3\x10\x1f\
-\x3c\xc2\x18\xcc\xda\x2c\x8f\x81\xbd\x07\xc0\xd8\xe8\x2f\xee\xe6\
-\xf7\x3f\x36\x4b\x68\xba\x04\x36\xdf\x66\x37\xeb\x39\x20\x4c\xe9\
-\x77\x77\x4e\xe9\xe2\x7e\x61\x24\x38\xe1\x94\x2e\x6f\x11\xa0\x54\
-\xca\xca\xa7\xb4\xef\x7b\xd2\xbb\xa4\xac\x13\xba\xaa\xc3\x2a\xcd\
-\xa2\x86\x2a\x22\xd5\x44\xd5\x44\x95\x18\xe7\x24\x96\x31\xd2\x33\
-\xb4\xf4\x8b\xa7\x72\x04\x59\x1c\xa0\x9b\xf0\x20\xea\x9f\xea\xa2\
-\xbe\x44\xd1\x04\xaf\x48\x3b\x8c\x31\x2d\xf5\x44\xf1\xf7\x79\x56\
-\x3c\xbc\x46\xe4\x93\xc9\x84\x1a\x54\x51\x03\xc4\xaa\x3d\x82\xc3\
-\x90\x2f\x2f\x2c\xe8\xb3\x58\xa6\x01\x1a\x71\x47\x03\xa9\xc8\x92\
-\x54\xfe\xbd\x76\x99\xe8\x67\xa5\xee\x02\x06\xaa\xa6\x0f\x82\x46\
-\x1e\x72\x11\x20\x51\x84\xbb\x5c\xe0\x5d\x18\x3d\x24\x75\xd9\x16\
-\xb1\x5f\x88\x1e\x5e\x30\x3f\x1a\x6f\x7e\x53\x85\x91\xa2\x57\xb5\
-\x68\x44\xdd\x09\xf3\xea\x44\x05\x6b\x88\xd6\xb4\x0a\x65\x0a\xea\
-\xd1\x5f\xb8\xc7\x6c\x3e\x72\x89\x1b\x31\xdb\x25\x1f\xb0\x6b\x7b\
-\x2a\xaa\xa3\x73\x8a\x47\x8c\x8c\x22\xac\x00\x9b\xe9\x22\x76\xf1\
-\x13\xdc\x0d\x10\x33\x98\xfb\xdc\xa0\x73\x6a\x00\xd3\xa2\x4b\xb6\
-\x51\xd4\x67\x6b\xe6\x3c\xea\x4f\x60\x59\xf4\x1f\x1f\xce\x78\x7c\
-\x16\x3e\xae\xb8\x77\x3a\x1f\x53\xfa\xff\x25\x39\x63\xfe\x26\xa6\
-\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x71\x6c\x49\x57\x6c\
-\xf2\x26\xa6\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x31\x2c\
-\xe9\x39\xaa\x7f\xb6\xca\x7f\x00\x99\x18\x96\x19\
-\x00\x00\x04\xbd\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
-\x74\x3d\x27\x32\x34\x70\x74\x27\x20\x76\x65\x72\x73\x69\x6f\x6e\
-\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x27\
-\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\x38\x33\x20\
-\x32\x34\x20\x32\x34\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x32\x34\
-\x70\x74\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
-\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
-\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
-\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\
-\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
-\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
-\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
-\x37\x36\x35\x35\x20\x36\x39\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x2d\x39\x2e\x33\x39\
-\x31\x31\x38\x20\x2d\x30\x43\x20\x2d\x39\x2e\x39\x36\x38\x36\x31\
-\x20\x2d\x33\x2e\x38\x33\x30\x30\x34\x20\x2d\x38\x2e\x35\x35\x37\
-\x30\x36\x20\x2d\x37\x2e\x35\x31\x39\x34\x34\x20\x2d\x36\x2e\x36\
-\x34\x30\x35\x37\x20\x2d\x31\x30\x2e\x32\x31\x37\x31\x43\x20\x2d\
-\x30\x2e\x34\x39\x31\x30\x38\x39\x20\x2d\x31\x38\x2e\x38\x37\x33\
-\x33\x20\x38\x2e\x33\x35\x36\x37\x36\x20\x2d\x31\x35\x2e\x31\x39\
-\x30\x36\x20\x38\x2e\x36\x37\x36\x33\x32\x20\x2d\x35\x2e\x35\x32\
-\x39\x34\x38\x43\x20\x38\x2e\x38\x33\x36\x20\x2d\x30\x2e\x37\x30\
-\x32\x30\x30\x38\x20\x36\x2e\x32\x33\x39\x36\x38\x20\x32\x2e\x39\
-\x34\x32\x30\x37\x20\x33\x2e\x33\x32\x30\x32\x38\x20\x35\x2e\x31\
-\x30\x38\x35\x37\x43\x20\x2d\x31\x2e\x39\x36\x38\x39\x31\x20\x39\
-\x2e\x30\x33\x33\x37\x31\x20\x2d\x38\x2e\x32\x36\x38\x39\x35\x20\
-\x37\x2e\x34\x34\x33\x37\x20\x2d\x39\x2e\x33\x39\x31\x31\x38\x20\
-\x2d\x30\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
-\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\
-\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
-\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\
-\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\
-\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x37\x35\x36\
-\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\
-\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
-\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\
-\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x39\
-\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\
-\x20\x63\x78\x3d\x27\x2d\x39\x2e\x33\x39\x31\x31\x38\x27\x20\x63\
-\x79\x3d\x27\x2d\x30\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\
-\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
-\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\
-\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\
-\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x39\x2e\x37\
-\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\
-\x78\x3d\x27\x2d\x36\x2e\x36\x34\x30\x35\x37\x27\x20\x63\x79\x3d\
-\x27\x2d\x31\x30\x2e\x32\x31\x37\x31\x27\x20\x72\x3d\x27\x33\x2e\
-\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\
-\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\
-\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\
-\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\
-\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\
-\x36\x39\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\
-\x6c\x65\x20\x63\x78\x3d\x27\x38\x2e\x36\x37\x36\x33\x32\x27\x20\
-\x63\x79\x3d\x27\x2d\x35\x2e\x35\x32\x39\x34\x38\x27\x20\x72\x3d\
-\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\
-\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
-\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\
-\x35\x35\x20\x36\x39\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\
-\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x33\x32\x30\x32\
-\x38\x27\x20\x63\x79\x3d\x27\x35\x2e\x31\x30\x38\x35\x37\x27\x20\
-\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\
-\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\
-\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x02\x20\
-\x00\
-\x00\x07\x7f\x78\x9c\xdd\x55\x3b\x6f\xdb\x30\x10\xde\xfb\x2b\xae\
-\xe8\xc0\x76\x20\x45\x52\x24\x45\x06\x51\x02\xd4\x40\xa7\x74\x4b\
-\x96\x6e\x6a\xcc\x48\x6c\x6c\xc9\x90\x54\xcb\xfd\xf7\x3d\xc5\xd6\
-\xc3\x56\xd0\x29\x43\x11\x69\xd0\x3d\x78\x77\xdf\x7d\xc7\x83\xae\
-\x6f\x0f\xdb\x0d\xec\x7d\xdd\x84\xaa\x4c\x89\x60\x9c\x80\x2f\x1f\
-\xab\x75\x28\xf3\x94\x3c\xdc\x7f\xa3\x96\xdc\xde\x7c\xb8\xfe\x48\
-\x29\xdc\x17\xa1\x81\xa7\xb0\xf1\xd0\x65\x0d\xe4\xbe\xf4\x75\xd6\
-\xfa\x35\xfc\xfc\x03\xeb\x7d\x68\xf6\xf9\x16\x24\x53\x40\x29\x9e\
-\x47\x0d\x0a\x1f\xf2\xa2\x4d\x89\x54\xbb\x96\xcc\x6b\x08\xd4\x82\
-\xef\xbe\x56\x87\x94\x68\xc3\x14\x77\x0a\x74\xcc\xac\xb6\x31\x08\
-\xcb\x54\x9c\x68\x90\x8a\x40\x17\xd6\x6d\x81\x01\x47\x53\x9f\x04\
-\xc1\x96\x4d\x4a\x8a\xb6\xdd\x5d\x45\x51\xd7\x75\xac\x8b\x59\x55\
-\xe7\x91\xe4\x9c\x47\x58\xf4\x74\xe4\xea\xb0\x09\xe5\xf3\x6b\x07\
-\x85\x73\x2e\x7a\xf1\x12\x84\x99\x43\x58\xa7\x64\x97\xe5\x5e\x1c\
-\xd5\xb6\xce\xca\xe6\xa9\xaa\xb7\x29\xd9\x66\x6d\x1d\x0e\x9f\x39\
-\x73\xce\x48\xa3\x80\xf7\xef\xa0\x18\xcd\x8c\xb4\x12\x12\xc5\x24\
-\x97\x5f\xfa\xe0\x5d\xd6\x16\x80\xd9\xbe\x03\xb5\x0c\xf1\x72\xa4\
-\x42\x33\x2e\x35\x97\x77\x33\x13\x9f\x2b\x02\x9b\x76\x26\xf6\x54\
-\xe8\xd5\x99\x59\xc6\x2e\xd1\xbd\x79\x66\x35\x4c\x38\x9b\x24\x68\
-\x35\xf3\x7c\xb3\x40\xc1\xb4\x12\x16\xa8\x42\x70\x28\xe1\x38\x12\
-\x27\x8c\x45\xe0\x27\x69\x05\x97\xae\x8b\xd0\x41\x45\x94\xaf\x88\
-\x53\x3f\x13\x54\xce\x38\x62\x9f\x74\x4c\xe4\x30\xd1\x50\x87\x0a\
-\xc9\xac\x12\x09\x62\x18\xc4\xd5\x04\x70\xf4\xd2\x45\x02\x7a\x5e\
-\xe2\x6e\xc9\xea\x0f\xd2\xdf\xc6\x4d\x4a\x3e\x59\xde\xbf\x24\xc2\
-\x29\x44\xf9\xdb\xcd\x71\x8e\x49\x18\x93\xcc\xdb\x44\xfe\xb8\xd5\
-\xb3\x36\x63\xe6\xb4\x55\x2f\x6d\x1e\xc5\xb3\x36\x4f\x5e\xba\x48\
-\x40\x97\x45\x26\x93\xc3\x78\xe5\xe4\x2c\xd1\x38\x94\x51\x9c\x46\
-\x3a\x3a\x17\xf1\x97\x35\x46\xe6\xca\xaa\xf4\x04\x9a\xb6\xae\x9e\
-\x3d\xf2\xc8\x5f\x9e\xc1\x40\x71\x4b\xfc\x63\xb6\x4b\x49\x5d\xfd\
-\x2e\xd7\x67\xe6\x5f\x55\x28\x2f\xed\xdb\xd0\xfa\x7a\x13\xf0\x83\
-\x3b\x8b\x33\xc3\x9a\xa3\x6f\x58\x65\x96\x68\xa3\xcd\x9b\x4f\x6a\
-\xc1\xe2\xbb\xd9\xb8\x53\x3f\xef\x6d\x60\xff\x5a\x2d\x8d\x44\x49\
-\x31\x5b\x2d\x77\x64\x8a\x8f\xe2\xd9\x6a\x9d\xbc\x74\x91\x60\x71\
-\x29\xfe\x13\x12\x8f\x44\xf6\x7f\xab\x9b\xbf\x3f\x45\xd8\x3d\
-\x00\x00\x03\x65\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
-\x74\x3d\x27\x31\x38\x2e\x37\x35\x70\x74\x27\x20\x76\x65\x72\x73\
-\x69\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\
-\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\
-\x38\x33\x20\x31\x38\x2e\x37\x35\x20\x31\x38\x2e\x37\x35\x27\x20\
-\x77\x69\x64\x74\x68\x3d\x27\x31\x38\x2e\x37\x35\x70\x74\x27\x20\
-\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
-\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x27\x3e\x0a\x3c\
-\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\x3e\x0a\x3c\x67\
-\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
-\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
-\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x35\x2e\x37\x38\x34\x34\
-\x20\x36\x33\x2e\x32\x33\x33\x33\x29\x27\x3e\x0a\x3c\x70\x61\x74\
-\x68\x20\x64\x3d\x27\x4d\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x20\
-\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x38\x2e\x36\x35\x37\x33\x34\
-\x20\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x38\x2e\x36\x35\x37\x33\
-\x34\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x2d\x38\x2e\x36\
-\x35\x37\x33\x34\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x2d\
-\x38\x2e\x36\x35\x37\x33\x34\x20\x38\x2e\x36\x35\x37\x33\x34\x5a\
-\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\
-\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\
-\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\
-\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\
-\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\
-\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\
-\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\
-\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x35\x30\x35\x36\x32\x27\
-\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\
-\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\
-\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\
-\x36\x34\x20\x36\x35\x2e\x37\x38\x34\x34\x20\x36\x33\x2e\x32\x33\
-\x33\x33\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\
-\x20\x34\x2e\x33\x32\x38\x36\x37\x20\x30\x43\x20\x34\x2e\x33\x32\
-\x38\x36\x37\x20\x2d\x32\x2e\x33\x39\x30\x36\x36\x20\x32\x2e\x33\
-\x39\x30\x36\x36\x20\x2d\x34\x2e\x33\x32\x38\x36\x37\x20\x30\x20\
-\x2d\x34\x2e\x33\x32\x38\x36\x37\x43\x20\x2d\x32\x2e\x33\x39\x30\
-\x36\x36\x20\x2d\x34\x2e\x33\x32\x38\x36\x37\x20\x2d\x34\x2e\x33\
-\x32\x38\x36\x37\x20\x2d\x32\x2e\x33\x39\x30\x36\x36\x20\x2d\x34\
-\x2e\x33\x32\x38\x36\x37\x20\x2d\x30\x43\x20\x2d\x34\x2e\x33\x32\
-\x38\x36\x37\x20\x32\x2e\x33\x39\x30\x36\x36\x20\x2d\x32\x2e\x33\
-\x39\x30\x36\x36\x20\x34\x2e\x33\x32\x38\x36\x37\x20\x30\x20\x34\
-\x2e\x33\x32\x38\x36\x37\x43\x20\x32\x2e\x33\x39\x30\x36\x36\x20\
-\x34\x2e\x33\x32\x38\x36\x37\x20\x34\x2e\x33\x32\x38\x36\x37\x20\
-\x32\x2e\x33\x39\x30\x36\x36\x20\x34\x2e\x33\x32\x38\x36\x37\x20\
-\x30\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\
-\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\
-\x73\x76\x67\x3e\
-\x00\x00\x02\x7d\
+\x00\x00\x05\x27\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -1868,79 +1852,66 @@ qt_resource_data = b"\
\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x38\x35\
-\x2c\x32\x37\x37\x2e\x33\x37\x35\x68\x32\x35\x39\x2e\x37\x30\x34\
-\x4c\x32\x32\x35\x2e\x30\x30\x32\x2c\x33\x39\x37\x2e\x30\x37\x37\
-\x4c\x32\x35\x36\x2c\x34\x32\x37\x6c\x31\x37\x31\x2d\x31\x37\x31\
-\x4c\x32\x35\x36\x2c\x38\x35\x6c\x2d\x32\x39\x2e\x39\x32\x32\x2c\
-\x32\x39\x2e\x39\x32\x34\x6c\x31\x31\x38\x2e\x36\x32\x36\x2c\x31\
-\x31\x39\x2e\x37\x30\x31\x48\x38\x35\x56\x32\x37\x37\x2e\x33\x37\
-\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\x52\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
-\x64\x3d\x22\x4d\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x48\
-\x32\x35\x36\x2e\x30\x30\x36\x6c\x2d\x34\x32\x2e\x36\x36\x38\x2d\
-\x34\x38\x48\x37\x34\x2e\x36\x36\x36\x43\x35\x31\x2e\x31\x39\x37\
-\x2c\x39\x36\x2c\x33\x32\x2c\x31\x31\x35\x2e\x31\x39\x38\x2c\x33\
-\x32\x2c\x31\x33\x38\x2e\x36\x36\x37\x76\x32\x33\x34\x2e\x36\x36\
-\x36\x43\x33\x32\x2c\x33\x39\x36\x2e\x38\x30\x32\x2c\x35\x31\x2e\
-\x31\x39\x37\x2c\x34\x31\x36\x2c\x37\x34\x2e\x36\x36\x36\x2c\x34\
-\x31\x36\x68\x33\x36\x32\x2e\x36\x36\x38\x0d\x0a\x09\x43\x34\x36\
-\x30\x2e\x38\x30\x33\x2c\x34\x31\x36\x2c\x34\x38\x30\x2c\x33\x39\
-\x36\x2e\x38\x30\x32\x2c\x34\x38\x30\x2c\x33\x37\x33\x2e\x33\x33\
-\x33\x56\x31\x38\x36\x2e\x36\x36\x37\x43\x34\x38\x30\x2c\x31\x36\
-\x33\x2e\x31\x39\x38\x2c\x34\x36\x30\x2e\x38\x30\x33\x2c\x31\x34\
-\x34\x2c\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x7a\x20\x4d\
-\x34\x34\x38\x2c\x33\x37\x33\x2e\x33\x33\x33\x0d\x0a\x09\x63\x30\
-\x2c\x35\x2e\x37\x38\x32\x2d\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\
-\x36\x36\x37\x2d\x31\x30\x2e\x36\x36\x36\x2c\x31\x30\x2e\x36\x36\
-\x37\x48\x37\x34\x2e\x36\x36\x36\x43\x36\x38\x2e\x38\x38\x34\x2c\
-\x33\x38\x34\x2c\x36\x34\x2c\x33\x37\x39\x2e\x31\x31\x35\x2c\x36\
-\x34\x2c\x33\x37\x33\x2e\x33\x33\x33\x56\x31\x37\x36\x68\x33\x37\
-\x33\x2e\x33\x33\x34\x63\x35\x2e\x37\x38\x31\x2c\x30\x2c\x31\x30\
-\x2e\x36\x36\x36\x2c\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\x36\x36\
-\x36\x2c\x31\x30\x2e\x36\x36\x37\x0d\x0a\x09\x56\x33\x37\x33\x2e\
-\x33\x33\x33\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
-\x0a\
-\x00\x00\x03\xc4\
+\x22\x49\x63\x6f\x6e\x5f\x31\x32\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
+\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
+\x35\x36\x2c\x36\x34\x43\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\
+\x2c\x36\x34\x2c\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\x2c\x32\
+\x35\x36\x63\x30\x2c\x31\x30\x35\x2e\x36\x30\x34\x2c\x38\x36\x2e\
+\x34\x30\x31\x2c\x31\x39\x32\x2c\x31\x39\x32\x2c\x31\x39\x32\x63\
+\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x38\
+\x36\x34\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\
+\x38\x2e\x35\x33\x31\x2d\x33\x2e\x31\x39\x38\x2d\x31\x36\x2d\x38\
+\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\x33\x33\x63\x2d\x35\x2e\x33\
+\x33\x33\x2d\x35\x2e\x33\x33\x34\x2d\x38\x2e\x35\x33\x31\x2d\x31\
+\x32\x2e\x38\x30\x33\x2d\x38\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\
+\x33\x34\x63\x30\x2d\x31\x38\x2e\x31\x33\x35\x2c\x31\x33\x2e\x38\
+\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x68\x33\x38\x2e\x33\
+\x39\x36\x0d\x0a\x09\x09\x09\x63\x35\x38\x2e\x36\x36\x37\x2c\x30\
+\x2c\x31\x30\x36\x2e\x36\x36\x37\x2d\x34\x38\x2c\x31\x30\x36\x2e\
+\x36\x36\x37\x2d\x31\x30\x36\x2e\x36\x36\x36\x43\x34\x34\x38\x2c\
+\x31\x34\x30\x2e\x38\x30\x32\x2c\x33\x36\x31\x2e\x36\x30\x34\x2c\
+\x36\x34\x2c\x32\x35\x36\x2c\x36\x34\x7a\x20\x4d\x31\x33\x38\x2e\
+\x36\x36\x37\x2c\x32\x35\x36\x63\x2d\x31\x38\x2e\x31\x33\x36\x2c\
+\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\
+\x32\x73\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\
+\x32\x0d\x0a\x09\x09\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\
+\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x53\
+\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x35\x36\x2c\x31\x33\x38\x2e\
+\x36\x36\x37\x2c\x32\x35\x36\x7a\x20\x4d\x32\x30\x32\x2e\x36\x36\
+\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\x2e\x31\x33\
+\x36\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\
+\x2d\x33\x32\x63\x30\x2d\x31\x38\x2e\x31\x33\x36\x2c\x31\x33\x2e\
+\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\
+\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\x33\x32\x2c\x31\x33\
+\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x32\x33\x34\x2e\x36\
+\x36\x37\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x32\x30\x2e\x38\
+\x30\x32\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x32\x30\x32\x2e\x36\
+\x36\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\x33\x30\x39\
+\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\
+\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\
+\x2d\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\x31\x38\
+\x2e\x31\x33\x36\x2c\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\x2c\x33\
+\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\
+\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x33\x34\
+\x31\x2e\x33\x33\x33\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x33\x32\
+\x37\x2e\x34\x36\x39\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x33\x30\
+\x39\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\
+\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x0d\x0a\x09\x09\x09\
+\x63\x2d\x31\x38\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\
+\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\x32\x73\x31\x33\x2e\x38\x36\
+\x35\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\
+\x36\x2c\x30\x2c\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\
+\x2c\x33\x32\x53\x33\x39\x31\x2e\x34\x36\x39\x2c\x32\x35\x36\x2c\
+\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x7a\x22\x2f\x3e\x0d\
+\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x04\x79\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
@@ -1952,68 +1923,63 @@ qt_resource_data = b"\
\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
-\x64\x5f\x6c\x65\x66\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
+\x3d\x22\x43\x6f\x64\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
-\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\x3d\
+\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\
\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\x61\
\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\
\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x78\
\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\
-\x31\x31\x2e\x33\x30\x32\x2c\x36\x2e\x37\x37\x36\x63\x2d\x30\x2e\
-\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2d\x30\x2e\x35\x31\x35\x2d\
-\x30\x2e\x31\x39\x37\x2d\x30\x2e\x37\x31\x2c\x30\x4c\x37\x2e\x37\
-\x38\x35\x2c\x39\x2e\x36\x34\x31\x63\x2d\x30\x2e\x31\x39\x36\x2c\
-\x30\x2e\x31\x39\x39\x2d\x30\x2e\x31\x39\x36\x2c\x30\x2e\x35\x32\
-\x2c\x30\x2c\x30\x2e\x37\x31\x37\x6c\x32\x2e\x38\x30\x37\x2c\x32\
-\x2e\x38\x36\x34\x0d\x0a\x09\x63\x30\x2e\x31\x39\x35\x2c\x30\x2e\
-\x31\x39\x39\x2c\x30\x2e\x35\x31\x34\x2c\x30\x2e\x31\x39\x38\x2c\
-\x30\x2e\x37\x31\x2c\x30\x63\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\
-\x39\x37\x2c\x30\x2e\x31\x39\x36\x2d\x30\x2e\x35\x31\x38\x2c\x30\
-\x2d\x30\x2e\x37\x31\x37\x4c\x39\x2c\x31\x30\x6c\x32\x2e\x33\x30\
-\x32\x2d\x32\x2e\x35\x30\x36\x43\x31\x31\x2e\x34\x39\x38\x2c\x37\
-\x2e\x32\x39\x36\x2c\x31\x31\x2e\x34\x39\x38\x2c\x36\x2e\x39\x37\
-\x36\x2c\x31\x31\x2e\x33\x30\x32\x2c\x36\x2e\x37\x37\x36\x7a\x0d\
-\x0a\x09\x20\x4d\x31\x30\x2c\x30\x2e\x34\x63\x2d\x35\x2e\x33\x30\
-\x32\x2c\x30\x2d\x39\x2e\x36\x2c\x34\x2e\x32\x39\x38\x2d\x39\x2e\
-\x36\x2c\x39\x2e\x36\x63\x30\x2c\x35\x2e\x33\x30\x33\x2c\x34\x2e\
-\x32\x39\x38\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x73\
-\x39\x2e\x36\x2d\x34\x2e\x32\x39\x37\x2c\x39\x2e\x36\x2d\x39\x2e\
-\x36\x43\x31\x39\x2e\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\
-\x33\x30\x32\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\
-\x4d\x31\x30\x2c\x31\x38\x2e\x33\x35\x34\x0d\x0a\x09\x63\x2d\x34\
-\x2e\x36\x31\x35\x2c\x30\x2d\x38\x2e\x33\x35\x34\x2d\x33\x2e\x37\
-\x34\x2d\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x30\x2d\
-\x34\x2e\x36\x31\x34\x2c\x33\x2e\x37\x33\x39\x2d\x38\x2e\x33\x35\
-\x34\x2c\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x34\x2e\
-\x36\x31\x33\x2c\x30\x2c\x38\x2e\x33\x35\x34\x2c\x33\x2e\x37\x34\
-\x2c\x38\x2e\x33\x35\x34\x2c\x38\x2e\x33\x35\x34\x0d\x0a\x09\x43\
-\x31\x38\x2e\x33\x35\x34\x2c\x31\x34\x2e\x36\x31\x34\x2c\x31\x34\
-\x2e\x36\x31\x33\x2c\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\x31\
-\x38\x2e\x33\x35\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
-\x3e\x0d\x0a\
-\x00\x00\x00\xdd\
-\x3c\
-\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x38\x22\
-\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x38\x22\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x38\x20\x38\x22\x3e\x0a\x20\
-\x20\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x30\x20\x30\x76\x32\
-\x68\x2e\x35\x63\x30\x2d\x2e\x35\x35\x2e\x34\x35\x2d\x31\x20\x31\
-\x2d\x31\x68\x31\x2e\x35\x76\x35\x2e\x35\x63\x30\x20\x2e\x32\x38\
-\x2d\x2e\x32\x32\x2e\x35\x2d\x2e\x35\x2e\x35\x68\x2d\x2e\x35\x76\
-\x31\x68\x34\x76\x2d\x31\x68\x2d\x2e\x35\x63\x2d\x2e\x32\x38\x20\
-\x30\x2d\x2e\x35\x2d\x2e\x32\x32\x2d\x2e\x35\x2d\x2e\x35\x76\x2d\
-\x35\x2e\x35\x68\x31\x2e\x35\x63\x2e\x35\x35\x20\x30\x20\x31\x20\
-\x2e\x34\x35\x20\x31\x20\x31\x68\x2e\x35\x76\x2d\x32\x68\x2d\x38\
-\x7a\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x03\xeb\
+\x35\x2e\x37\x31\x39\x2c\x31\x34\x2e\x37\x35\x63\x2d\x30\x2e\x32\
+\x33\x36\x2c\x30\x2d\x30\x2e\x34\x37\x34\x2d\x30\x2e\x30\x38\x33\
+\x2d\x30\x2e\x36\x36\x34\x2d\x30\x2e\x32\x35\x32\x4c\x2d\x30\x2e\
+\x30\x30\x35\x2c\x31\x30\x6c\x35\x2e\x33\x34\x31\x2d\x34\x2e\x37\
+\x34\x38\x43\x35\x2e\x37\x34\x38\x2c\x34\x2e\x38\x38\x37\x2c\x36\
+\x2e\x33\x38\x2c\x34\x2e\x39\x32\x32\x2c\x36\x2e\x37\x34\x37\x2c\
+\x35\x2e\x33\x33\x35\x0d\x0a\x09\x63\x30\x2e\x33\x36\x37\x2c\x30\
+\x2e\x34\x31\x33\x2c\x30\x2e\x33\x33\x2c\x31\x2e\x30\x34\x35\x2d\
+\x30\x2e\x30\x38\x33\x2c\x31\x2e\x34\x31\x32\x4c\x33\x2e\x30\x30\
+\x35\x2c\x31\x30\x6c\x33\x2e\x33\x37\x38\x2c\x33\x2e\x30\x30\x32\
+\x63\x30\x2e\x34\x31\x33\x2c\x30\x2e\x33\x36\x37\x2c\x30\x2e\x34\
+\x35\x2c\x30\x2e\x39\x39\x39\x2c\x30\x2e\x30\x38\x33\x2c\x31\x2e\
+\x34\x31\x32\x0d\x0a\x09\x43\x36\x2e\x32\x36\x39\x2c\x31\x34\x2e\
+\x36\x33\x37\x2c\x35\x2e\x39\x39\x34\x2c\x31\x34\x2e\x37\x35\x2c\
+\x35\x2e\x37\x31\x39\x2c\x31\x34\x2e\x37\x35\x7a\x20\x4d\x31\x34\
+\x2e\x36\x36\x34\x2c\x31\x34\x2e\x37\x34\x38\x4c\x32\x30\x2e\x30\
+\x30\x35\x2c\x31\x30\x6c\x2d\x35\x2e\x30\x36\x2d\x34\x2e\x34\x39\
+\x38\x63\x2d\x30\x2e\x34\x31\x33\x2d\x30\x2e\x33\x36\x37\x2d\x31\
+\x2e\x30\x34\x35\x2d\x30\x2e\x33\x33\x2d\x31\x2e\x34\x31\x31\x2c\
+\x30\x2e\x30\x38\x33\x0d\x0a\x09\x63\x2d\x30\x2e\x33\x36\x37\x2c\
+\x30\x2e\x34\x31\x33\x2d\x30\x2e\x33\x33\x2c\x31\x2e\x30\x34\x35\
+\x2c\x30\x2e\x30\x38\x33\x2c\x31\x2e\x34\x31\x32\x4c\x31\x36\x2e\
+\x39\x39\x35\x2c\x31\x30\x6c\x2d\x33\x2e\x36\x35\x39\x2c\x33\x2e\
+\x32\x35\x32\x63\x2d\x30\x2e\x34\x31\x33\x2c\x30\x2e\x33\x36\x37\
+\x2d\x30\x2e\x34\x35\x2c\x30\x2e\x39\x39\x39\x2d\x30\x2e\x30\x38\
+\x33\x2c\x31\x2e\x34\x31\x32\x43\x31\x33\x2e\x34\x35\x2c\x31\x34\
+\x2e\x38\x38\x37\x2c\x31\x33\x2e\x37\x32\x35\x2c\x31\x35\x2c\x31\
+\x34\x2c\x31\x35\x0d\x0a\x09\x43\x31\x34\x2e\x32\x33\x36\x2c\x31\
+\x35\x2c\x31\x34\x2e\x34\x37\x34\x2c\x31\x34\x2e\x39\x31\x37\x2c\
+\x31\x34\x2e\x36\x36\x34\x2c\x31\x34\x2e\x37\x34\x38\x7a\x20\x4d\
+\x39\x2e\x39\x38\x36\x2c\x31\x36\x2e\x31\x36\x35\x6c\x32\x2d\x31\
+\x32\x63\x30\x2e\x30\x39\x31\x2d\x30\x2e\x35\x34\x35\x2d\x30\x2e\
+\x32\x37\x37\x2d\x31\x2e\x30\x36\x2d\x30\x2e\x38\x32\x32\x2d\x31\
+\x2e\x31\x35\x31\x0d\x0a\x09\x63\x2d\x30\x2e\x35\x34\x37\x2d\x30\
+\x2e\x30\x39\x32\x2d\x31\x2e\x30\x36\x31\x2c\x30\x2e\x32\x37\x37\
+\x2d\x31\x2e\x31\x35\x2c\x30\x2e\x38\x32\x32\x6c\x2d\x32\x2c\x31\
+\x32\x63\x2d\x30\x2e\x30\x39\x31\x2c\x30\x2e\x35\x34\x35\x2c\x30\
+\x2e\x32\x37\x37\x2c\x31\x2e\x30\x36\x2c\x30\x2e\x38\x32\x32\x2c\
+\x31\x2e\x31\x35\x31\x43\x38\x2e\x38\x39\x32\x2c\x31\x36\x2e\x39\
+\x39\x36\x2c\x38\x2e\x39\x34\x36\x2c\x31\x37\x2c\x39\x2e\x30\x30\
+\x31\x2c\x31\x37\x0d\x0a\x09\x43\x39\x2e\x34\x38\x31\x2c\x31\x37\
+\x2c\x39\x2e\x39\x30\x35\x2c\x31\x36\x2e\x36\x35\x33\x2c\x39\x2e\
+\x39\x38\x36\x2c\x31\x36\x2e\x31\x36\x35\x7a\x22\x2f\x3e\x0d\x0a\
+\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\xb7\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -2040,45 +2006,26 @@ qt_resource_data = b"\
\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x67\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
-\x4d\x32\x35\x36\x2c\x31\x32\x38\x63\x2d\x38\x31\x2e\x39\x2c\x30\
-\x2d\x31\x34\x35\x2e\x37\x2c\x34\x38\x2e\x38\x2d\x32\x32\x34\x2c\
-\x31\x32\x38\x63\x36\x37\x2e\x34\x2c\x36\x37\x2e\x37\x2c\x31\x32\
-\x34\x2c\x31\x32\x38\x2c\x32\x32\x34\x2c\x31\x32\x38\x63\x39\x39\
-\x2e\x39\x2c\x30\x2c\x31\x37\x33\x2e\x34\x2d\x37\x36\x2e\x34\x2c\
-\x32\x32\x34\x2d\x31\x32\x36\x2e\x36\x0d\x0a\x09\x09\x43\x34\x32\
-\x38\x2e\x32\x2c\x31\x39\x38\x2e\x36\x2c\x33\x35\x34\x2e\x38\x2c\
-\x31\x32\x38\x2c\x32\x35\x36\x2c\x31\x32\x38\x7a\x20\x4d\x32\x35\
-\x36\x2c\x33\x34\x37\x2e\x33\x63\x2d\x34\x39\x2e\x34\x2c\x30\x2d\
-\x38\x39\x2e\x36\x2d\x34\x31\x2d\x38\x39\x2e\x36\x2d\x39\x31\x2e\
-\x33\x63\x30\x2d\x35\x30\x2e\x34\x2c\x34\x30\x2e\x32\x2d\x39\x31\
-\x2e\x33\x2c\x38\x39\x2e\x36\x2d\x39\x31\x2e\x33\x73\x38\x39\x2e\
-\x36\x2c\x34\x31\x2c\x38\x39\x2e\x36\x2c\x39\x31\x2e\x33\x0d\x0a\
-\x09\x09\x43\x33\x34\x35\x2e\x36\x2c\x33\x30\x36\x2e\x34\x2c\x33\
-\x30\x35\x2e\x34\x2c\x33\x34\x37\x2e\x33\x2c\x32\x35\x36\x2c\x33\
-\x34\x37\x2e\x33\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\
-\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\
-\x32\x32\x34\x63\x30\x2d\x37\x2e\x39\x2c\x32\x2e\x39\x2d\x31\x35\
-\x2e\x31\x2c\x37\x2e\x36\x2d\x32\x30\x2e\x37\x63\x2d\x32\x2e\x35\
-\x2d\x30\x2e\x34\x2d\x35\x2d\x30\x2e\x36\x2d\x37\x2e\x36\x2d\x30\
-\x2e\x36\x63\x2d\x32\x38\x2e\x38\x2c\x30\x2d\x35\x32\x2e\x33\x2c\
-\x32\x33\x2e\x39\x2d\x35\x32\x2e\x33\x2c\x35\x33\x2e\x33\x63\x30\
-\x2c\x32\x39\x2e\x34\x2c\x32\x33\x2e\x35\x2c\x35\x33\x2e\x33\x2c\
-\x35\x32\x2e\x33\x2c\x35\x33\x2e\x33\x0d\x0a\x09\x09\x09\x73\x35\
-\x32\x2e\x33\x2d\x32\x33\x2e\x39\x2c\x35\x32\x2e\x33\x2d\x35\x33\
-\x2e\x33\x63\x30\x2d\x32\x2e\x33\x2d\x30\x2e\x32\x2d\x34\x2e\x36\
-\x2d\x30\x2e\x34\x2d\x36\x2e\x39\x63\x2d\x35\x2e\x35\x2c\x34\x2e\
-\x33\x2d\x31\x32\x2e\x33\x2c\x36\x2e\x39\x2d\x31\x39\x2e\x38\x2c\
-\x36\x2e\x39\x43\x32\x37\x30\x2e\x33\x2c\x32\x35\x36\x2c\x32\x35\
-\x36\x2c\x32\x34\x31\x2e\x37\x2c\x32\x35\x36\x2c\x32\x32\x34\x7a\
-\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\
-\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\xa2\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x35\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
+\x6e\x74\x73\x3d\x22\x34\x30\x35\x2c\x31\x33\x36\x2e\x37\x39\x38\
+\x20\x33\x37\x35\x2e\x32\x30\x32\x2c\x31\x30\x37\x20\x32\x35\x36\
+\x2c\x32\x32\x36\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
+\x2c\x31\x30\x37\x20\x31\x30\x37\x2c\x31\x33\x36\x2e\x37\x39\x38\
+\x20\x32\x32\x36\x2e\x32\x30\x32\x2c\x32\x35\x36\x20\x31\x30\x37\
+\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
+\x2c\x34\x30\x35\x20\x32\x35\x36\x2c\x32\x38\x35\x2e\x37\x39\x38\
+\x20\x0d\x0a\x09\x09\x09\x33\x37\x35\x2e\x32\x30\x32\x2c\x34\x30\
+\x35\x20\x34\x30\x35\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x32\x38\
+\x35\x2e\x37\x39\x38\x2c\x32\x35\x36\x20\x09\x09\x22\x2f\x3e\x0d\
+\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x22\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -2110,61 +2057,96 @@ qt_resource_data = b"\
\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x32\x38\x2c\x34\x30\
-\x35\x2e\x34\x32\x39\x43\x31\x32\x38\x2c\x34\x32\x38\x2e\x38\x34\
-\x36\x2c\x31\x34\x37\x2e\x31\x39\x38\x2c\x34\x34\x38\x2c\x31\x37\
-\x30\x2e\x36\x36\x37\x2c\x34\x34\x38\x68\x31\x37\x30\x2e\x36\x36\
-\x37\x43\x33\x36\x34\x2e\x38\x30\x32\x2c\x34\x34\x38\x2c\x33\x38\
-\x34\x2c\x34\x32\x38\x2e\x38\x34\x36\x2c\x33\x38\x34\x2c\x34\x30\
-\x35\x2e\x34\x32\x39\x56\x31\x36\x30\x48\x31\x32\x38\x56\x34\x30\
-\x35\x2e\x34\x32\x39\x7a\x20\x4d\x34\x31\x36\x2c\x39\x36\x0d\x0a\
-\x09\x09\x68\x2d\x38\x30\x6c\x2d\x32\x36\x2e\x37\x38\x35\x2d\x33\
-\x32\x48\x32\x30\x32\x2e\x37\x38\x36\x4c\x31\x37\x36\x2c\x39\x36\
-\x48\x39\x36\x76\x33\x32\x68\x33\x32\x30\x56\x39\x36\x7a\x22\x2f\
+\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x22\x32\x35\x36\x22\
+\x20\x63\x79\x3d\x22\x32\x38\x30\x22\x20\x72\x3d\x22\x36\x33\x22\
+\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
+\x34\x30\x2c\x39\x36\x68\x2d\x38\x38\x6c\x2d\x33\x32\x2d\x33\x32\
+\x48\x31\x39\x32\x6c\x2d\x33\x32\x2c\x33\x32\x48\x37\x32\x63\x2d\
+\x32\x32\x2e\x30\x39\x32\x2c\x30\x2d\x34\x30\x2c\x31\x37\x2e\x39\
+\x30\x38\x2d\x34\x30\x2c\x34\x30\x76\x32\x37\x32\x63\x30\x2c\x32\
+\x32\x2e\x30\x39\x32\x2c\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2c\
+\x34\x30\x2c\x34\x30\x68\x33\x36\x38\x63\x32\x32\x2e\x30\x39\x32\
+\x2c\x30\x2c\x34\x30\x2d\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2d\
+\x34\x30\x0d\x0a\x09\x09\x56\x31\x33\x36\x43\x34\x38\x30\x2c\x31\
+\x31\x33\x2e\x39\x30\x38\x2c\x34\x36\x32\x2e\x30\x39\x32\x2c\x39\
+\x36\x2c\x34\x34\x30\x2c\x39\x36\x7a\x20\x4d\x32\x35\x36\x2c\x33\
+\x39\x32\x63\x2d\x36\x31\x2e\x38\x35\x35\x2c\x30\x2d\x31\x31\x32\
+\x2d\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2d\x31\x31\x32\x73\
+\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2c\x31\x31\x32\x2d\x31\
+\x31\x32\x73\x31\x31\x32\x2c\x35\x30\x2e\x31\x34\x35\x2c\x31\x31\
+\x32\x2c\x31\x31\x32\x0d\x0a\x09\x09\x53\x33\x31\x37\x2e\x38\x35\
+\x35\x2c\x33\x39\x32\x2c\x32\x35\x36\x2c\x33\x39\x32\x7a\x22\x2f\
\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
\x0a\
-\x00\x00\x02\x7f\
+\x00\x00\x04\x22\
\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
-\x3d\x22\x32\x38\x38\x2c\x39\x36\x20\x33\x33\x37\x2e\x39\x2c\x31\
-\x34\x35\x2e\x39\x20\x32\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x32\
-\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x31\x34\x35\x2e\x39\x2c\x33\
-\x33\x37\x2e\x39\x20\x39\x36\x2c\x32\x38\x38\x20\x39\x36\x2c\x34\
-\x31\x36\x20\x32\x32\x34\x2c\x34\x31\x36\x20\x31\x37\x34\x2e\x31\
-\x2c\x33\x36\x36\x2e\x31\x20\x33\x35\x37\x2e\x34\x2c\x31\x38\x32\
-\x2e\x39\x20\x33\x36\x36\x2e\x31\x2c\x31\x37\x34\x2e\x31\x20\x0d\
-\x0a\x09\x34\x31\x36\x2c\x32\x32\x34\x20\x34\x31\x36\x2c\x39\x36\
-\x20\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
+\x74\x3d\x27\x32\x34\x70\x74\x27\x20\x76\x65\x72\x73\x69\x6f\x6e\
+\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x27\
+\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\x38\x33\x20\
+\x32\x34\x20\x32\x34\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x32\x34\
+\x70\x74\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
+\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
+\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
+\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\
+\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
+\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
+\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
+\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x2d\x39\x2e\x33\x39\
+\x31\x31\x38\x20\x2d\x30\x4c\x20\x2d\x36\x2e\x36\x34\x30\x35\x37\
+\x20\x2d\x31\x32\x2e\x30\x34\x35\x4c\x20\x38\x2e\x36\x37\x36\x33\
+\x32\x20\x2d\x36\x2e\x35\x31\x38\x37\x31\x4c\x20\x33\x2e\x33\x32\
+\x30\x32\x38\x20\x36\x2e\x30\x32\x32\x35\x27\x20\x66\x69\x6c\x6c\
+\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\
+\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
+\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
+\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\
+\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\
+\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\
+\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\
+\x3d\x27\x31\x2e\x37\x35\x36\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\
+\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
+\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
+\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
+\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\
+\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x2d\x39\x2e\x33\
+\x39\x31\x31\x38\x27\x20\x63\x79\x3d\x27\x2d\x30\x27\x20\x72\x3d\
+\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\
+\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
+\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
+\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\
+\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\x3c\x63\
+\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x2d\x36\x2e\x36\x34\x30\
+\x35\x37\x27\x20\x63\x79\x3d\x27\x2d\x31\x32\x2e\x30\x34\x35\x27\
+\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\
+\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\
+\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
+\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\
+\x2e\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\
+\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x38\x2e\x36\
+\x37\x36\x33\x32\x27\x20\x63\x79\x3d\x27\x2d\x36\x2e\x35\x31\x38\
+\x37\x31\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\
+\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\
+\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
+\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\
+\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\
+\x33\x2e\x33\x32\x30\x32\x38\x27\x20\x63\x79\x3d\x27\x36\x2e\x30\
+\x32\x32\x35\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\
+\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\
+\x3e\x0a\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\
+\x3e\
\x00\x00\x04\x10\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
@@ -2232,7 +2214,43 @@ qt_resource_data = b"\
\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\
\x64\x74\x68\x3d\x27\x31\x2e\x35\x30\x35\x36\x32\x27\x2f\x3e\x0a\
\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x02\x79\
+\x00\x00\x02\x20\
+\x00\
+\x00\x07\x7f\x78\x9c\xdd\x55\x3b\x6f\xdb\x30\x10\xde\xfb\x2b\xae\
+\xe8\xc0\x76\x20\x45\x52\x24\x45\x06\x51\x02\xd4\x40\xa7\x74\x4b\
+\x96\x6e\x6a\xcc\x48\x6c\x6c\xc9\x90\x54\xcb\xfd\xf7\x3d\xc5\xd6\
+\xc3\x56\xd0\x29\x43\x11\x69\xd0\x3d\x78\x77\xdf\x7d\xc7\x83\xae\
+\x6f\x0f\xdb\x0d\xec\x7d\xdd\x84\xaa\x4c\x89\x60\x9c\x80\x2f\x1f\
+\xab\x75\x28\xf3\x94\x3c\xdc\x7f\xa3\x96\xdc\xde\x7c\xb8\xfe\x48\
+\x29\xdc\x17\xa1\x81\xa7\xb0\xf1\xd0\x65\x0d\xe4\xbe\xf4\x75\xd6\
+\xfa\x35\xfc\xfc\x03\xeb\x7d\x68\xf6\xf9\x16\x24\x53\x40\x29\x9e\
+\x47\x0d\x0a\x1f\xf2\xa2\x4d\x89\x54\xbb\x96\xcc\x6b\x08\xd4\x82\
+\xef\xbe\x56\x87\x94\x68\xc3\x14\x77\x0a\x74\xcc\xac\xb6\x31\x08\
+\xcb\x54\x9c\x68\x90\x8a\x40\x17\xd6\x6d\x81\x01\x47\x53\x9f\x04\
+\xc1\x96\x4d\x4a\x8a\xb6\xdd\x5d\x45\x51\xd7\x75\xac\x8b\x59\x55\
+\xe7\x91\xe4\x9c\x47\x58\xf4\x74\xe4\xea\xb0\x09\xe5\xf3\x6b\x07\
+\x85\x73\x2e\x7a\xf1\x12\x84\x99\x43\x58\xa7\x64\x97\xe5\x5e\x1c\
+\xd5\xb6\xce\xca\xe6\xa9\xaa\xb7\x29\xd9\x66\x6d\x1d\x0e\x9f\x39\
+\x73\xce\x48\xa3\x80\xf7\xef\xa0\x18\xcd\x8c\xb4\x12\x12\xc5\x24\
+\x97\x5f\xfa\xe0\x5d\xd6\x16\x80\xd9\xbe\x03\xb5\x0c\xf1\x72\xa4\
+\x42\x33\x2e\x35\x97\x77\x33\x13\x9f\x2b\x02\x9b\x76\x26\xf6\x54\
+\xe8\xd5\x99\x59\xc6\x2e\xd1\xbd\x79\x66\x35\x4c\x38\x9b\x24\x68\
+\x35\xf3\x7c\xb3\x40\xc1\xb4\x12\x16\xa8\x42\x70\x28\xe1\x38\x12\
+\x27\x8c\x45\xe0\x27\x69\x05\x97\xae\x8b\xd0\x41\x45\x94\xaf\x88\
+\x53\x3f\x13\x54\xce\x38\x62\x9f\x74\x4c\xe4\x30\xd1\x50\x87\x0a\
+\xc9\xac\x12\x09\x62\x18\xc4\xd5\x04\x70\xf4\xd2\x45\x02\x7a\x5e\
+\xe2\x6e\xc9\xea\x0f\xd2\xdf\xc6\x4d\x4a\x3e\x59\xde\xbf\x24\xc2\
+\x29\x44\xf9\xdb\xcd\x71\x8e\x49\x18\x93\xcc\xdb\x44\xfe\xb8\xd5\
+\xb3\x36\x63\xe6\xb4\x55\x2f\x6d\x1e\xc5\xb3\x36\x4f\x5e\xba\x48\
+\x40\x97\x45\x26\x93\xc3\x78\xe5\xe4\x2c\xd1\x38\x94\x51\x9c\x46\
+\x3a\x3a\x17\xf1\x97\x35\x46\xe6\xca\xaa\xf4\x04\x9a\xb6\xae\x9e\
+\x3d\xf2\xc8\x5f\x9e\xc1\x40\x71\x4b\xfc\x63\xb6\x4b\x49\x5d\xfd\
+\x2e\xd7\x67\xe6\x5f\x55\x28\x2f\xed\xdb\xd0\xfa\x7a\x13\xf0\x83\
+\x3b\x8b\x33\xc3\x9a\xa3\x6f\x58\x65\x96\x68\xa3\xcd\x9b\x4f\x6a\
+\xc1\xe2\xbb\xd9\xb8\x53\x3f\xef\x6d\x60\xff\x5a\x2d\x8d\x44\x49\
+\x31\x5b\x2d\x77\x64\x8a\x8f\xe2\xd9\x6a\x9d\xbc\x74\x91\x60\x71\
+\x29\xfe\x13\x12\x8f\x44\xf6\x7f\xab\x9b\xbf\x3f\x45\xd8\x3d\
+\x00\x00\x02\xa2\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -2263,18 +2281,21 @@ qt_resource_data = b"\
\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x67\x3e\x0d\x0a\x09\x09\x09\x3c\x70\x6f\x6c\
-\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\x22\x31\x38\x36\
-\x2e\x33\x30\x31\x2c\x33\x33\x39\x2e\x38\x39\x33\x20\x39\x36\x2c\
-\x32\x34\x39\x2e\x34\x36\x31\x20\x36\x34\x2c\x32\x37\x39\x2e\x39\
-\x36\x38\x20\x31\x38\x36\x2e\x33\x30\x31\x2c\x34\x30\x32\x20\x34\
-\x34\x38\x2c\x31\x34\x30\x2e\x35\x30\x36\x20\x34\x31\x36\x2c\x31\
-\x31\x30\x20\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x09\x3c\x2f\x67\
-\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
-\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\xb5\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x32\x38\x2c\x34\x30\
+\x35\x2e\x34\x32\x39\x43\x31\x32\x38\x2c\x34\x32\x38\x2e\x38\x34\
+\x36\x2c\x31\x34\x37\x2e\x31\x39\x38\x2c\x34\x34\x38\x2c\x31\x37\
+\x30\x2e\x36\x36\x37\x2c\x34\x34\x38\x68\x31\x37\x30\x2e\x36\x36\
+\x37\x43\x33\x36\x34\x2e\x38\x30\x32\x2c\x34\x34\x38\x2c\x33\x38\
+\x34\x2c\x34\x32\x38\x2e\x38\x34\x36\x2c\x33\x38\x34\x2c\x34\x30\
+\x35\x2e\x34\x32\x39\x56\x31\x36\x30\x48\x31\x32\x38\x56\x34\x30\
+\x35\x2e\x34\x32\x39\x7a\x20\x4d\x34\x31\x36\x2c\x39\x36\x0d\x0a\
+\x09\x09\x68\x2d\x38\x30\x6c\x2d\x32\x36\x2e\x37\x38\x35\x2d\x33\
+\x32\x48\x32\x30\x32\x2e\x37\x38\x36\x4c\x31\x37\x36\x2c\x39\x36\
+\x48\x39\x36\x76\x33\x32\x68\x33\x32\x30\x56\x39\x36\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
+\x0a\
+\x00\x00\x02\x6c\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -2292,50 +2313,29 @@ qt_resource_data = b"\
\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
-\x64\x5f\x72\x69\x67\x68\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\
-\x22\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\
-\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\
-\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\
-\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\
-\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\
-\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
-\x4d\x31\x31\x2c\x31\x30\x4c\x38\x2e\x36\x39\x38\x2c\x37\x2e\x34\
-\x39\x34\x63\x2d\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x38\x2d\
-\x30\x2e\x31\x39\x36\x2d\x30\x2e\x35\x31\x39\x2c\x30\x2d\x30\x2e\
-\x37\x31\x38\x63\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2c\
-\x30\x2e\x35\x31\x35\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\x37\x31\
-\x2c\x30\x6c\x32\x2e\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x0d\x0a\
-\x09\x63\x30\x2e\x31\x39\x36\x2c\x30\x2e\x31\x39\x39\x2c\x30\x2e\
-\x31\x39\x36\x2c\x30\x2e\x35\x32\x2c\x30\x2c\x30\x2e\x37\x31\x37\
-\x6c\x2d\x32\x2e\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x63\x2d\x30\
-\x2e\x31\x39\x35\x2c\x30\x2e\x31\x39\x39\x2d\x30\x2e\x35\x31\x34\
-\x2c\x30\x2e\x31\x39\x38\x2d\x30\x2e\x37\x31\x2c\x30\x63\x2d\x30\
-\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2d\x30\x2e\x31\x39\x36\
-\x2d\x30\x2e\x35\x31\x38\x2c\x30\x2d\x30\x2e\x37\x31\x37\x4c\x31\
-\x31\x2c\x31\x30\x7a\x20\x4d\x31\x30\x2c\x30\x2e\x34\x0d\x0a\x09\
-\x63\x35\x2e\x33\x30\x32\x2c\x30\x2c\x39\x2e\x36\x2c\x34\x2e\x32\
-\x39\x38\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x63\x30\x2c\x35\x2e\x33\
-\x30\x33\x2d\x34\x2e\x32\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\
-\x2c\x39\x2e\x36\x53\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x33\x2c\
-\x30\x2e\x34\x2c\x31\x30\x43\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\
-\x2c\x34\x2e\x36\x39\x38\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\
-\x34\x7a\x20\x4d\x31\x30\x2c\x31\x38\x2e\x33\x35\x34\x0d\x0a\x09\
-\x63\x34\x2e\x36\x31\x33\x2c\x30\x2c\x38\x2e\x33\x35\x34\x2d\x33\
-\x2e\x37\x34\x2c\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\
-\x30\x2d\x34\x2e\x36\x31\x34\x2d\x33\x2e\x37\x34\x31\x2d\x38\x2e\
-\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\
-\x2d\x34\x2e\x36\x31\x35\x2c\x30\x2d\x38\x2e\x33\x35\x34\x2c\x33\
-\x2e\x37\x34\x2d\x38\x2e\x33\x35\x34\x2c\x38\x2e\x33\x35\x34\x0d\
-\x0a\x09\x43\x31\x2e\x36\x34\x35\x2c\x31\x34\x2e\x36\x31\x34\x2c\
-\x35\x2e\x33\x38\x35\x2c\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\
-\x31\x38\x2e\x33\x35\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\
-\x67\x3e\x0d\x0a\
+\x3d\x22\x53\x61\x76\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
+\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
+\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
+\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
+\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\x3d\
+\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\x61\
+\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\
+\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x78\
+\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
+\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\
+\x31\x35\x2e\x31\x37\x33\x2c\x32\x48\x34\x43\x32\x2e\x38\x39\x39\
+\x2c\x32\x2c\x32\x2c\x32\x2e\x39\x2c\x32\x2c\x34\x76\x31\x32\x63\
+\x30\x2c\x31\x2e\x31\x2c\x30\x2e\x38\x39\x39\x2c\x32\x2c\x32\x2c\
+\x32\x68\x31\x32\x63\x31\x2e\x31\x30\x31\x2c\x30\x2c\x32\x2d\x30\
+\x2e\x39\x2c\x32\x2d\x32\x56\x35\x2e\x31\x32\x37\x4c\x31\x35\x2e\
+\x31\x37\x33\x2c\x32\x7a\x20\x4d\x31\x34\x2c\x38\x63\x30\x2c\x30\
+\x2e\x35\x34\x39\x2d\x30\x2e\x34\x35\x2c\x31\x2d\x31\x2c\x31\x48\
+\x37\x0d\x0a\x09\x43\x36\x2e\x34\x35\x2c\x39\x2c\x36\x2c\x38\x2e\
+\x35\x34\x39\x2c\x36\x2c\x38\x56\x33\x68\x38\x56\x38\x7a\x20\x4d\
+\x31\x33\x2c\x34\x68\x2d\x32\x76\x34\x68\x32\x56\x34\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
"
qt_resource_name = b"\
@@ -2343,33 +2343,31 @@ qt_resource_name = b"\
\x00\x6f\xa6\x53\
\x00\x69\
\x00\x63\x00\x6f\x00\x6e\x00\x73\
-\x00\x09\
-\x0b\x9e\x89\x07\
-\x00\x63\
-\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x15\
-\x0f\xc4\x59\xe7\
-\x00\x73\
-\x00\x75\x00\x62\x00\x64\x00\x69\x00\x72\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\x00\x79\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\
-\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x13\
-\x03\x24\x75\x47\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x65\x00\x66\x00\x72\x00\x65\x00\x73\x00\x68\x00\x2e\x00\x73\
-\x00\x76\x00\x67\
-\x00\x08\
-\x08\xc8\x55\xe7\
-\x00\x73\
-\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x10\
\x06\xe3\xaf\xe7\
\x00\x61\
\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x68\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x17\
-\x06\xc6\x02\xa7\
-\x00\x74\
-\x00\x72\x00\x69\x00\x61\x00\x6e\x00\x67\x00\x6c\x00\x65\x00\x2d\x00\x73\x00\x74\x00\x72\x00\x6f\x00\x6b\x00\x65\x00\x64\x00\x2d\
-\x00\x31\x00\x35\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x16\
+\x01\xfb\x76\x27\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x62\x00\x61\x00\x63\
+\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0a\
+\x0a\xc8\x62\x67\
+\x00\x63\
+\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0a\
+\x0a\x2d\x1b\xc7\
+\x00\x63\
+\x00\x69\x00\x72\x00\x63\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0f\
+\x09\x76\x60\xc7\
+\x00\x63\
+\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2d\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x08\xf7\x57\x07\
+\x00\x67\
+\x00\x72\x00\x69\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x08\
\x0b\x07\x57\xa7\
\x00\x65\
@@ -2380,198 +2378,200 @@ qt_resource_name = b"\
\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\
\x00\x67\
\x00\x0f\
-\x07\x0e\xc4\x87\
-\x00\x6f\
-\x00\x70\x00\x65\x00\x6e\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x1b\
-\x0e\xb5\x68\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
-\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0a\
-\x0a\x2d\x1b\xc7\
+\x04\xf2\xa7\x87\
\x00\x63\
-\x00\x69\x00\x72\x00\x63\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0a\
-\x01\xca\x6d\x87\
-\x00\x62\
-\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x11\
-\x0c\xdb\x38\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\
+\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x1c\
\x08\x8a\x79\x07\
\x00\x61\
\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x66\x00\x66\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x0a\
-\x0f\x68\x53\xe7\
-\x00\x61\
-\x00\x6e\x00\x63\x00\x68\x00\x6f\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x11\
-\x01\x60\xbc\x47\
-\x00\x73\
-\x00\x6f\x00\x63\x00\x69\x00\x61\x00\x6c\x00\x2d\x00\x70\x00\x79\x00\x74\x00\x68\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\
-\x00\x16\
-\x01\xfb\x76\x27\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x62\x00\x61\x00\x63\
-\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x01\xca\x6d\x87\
+\x00\x62\
+\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x0e\
\x0f\xcb\xd5\xc7\
\x00\x70\
\x00\x6c\x00\x75\x00\x73\x00\x2d\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x17\
+\x06\xc6\x02\xa7\
+\x00\x74\
+\x00\x72\x00\x69\x00\x61\x00\x6e\x00\x67\x00\x6c\x00\x65\x00\x2d\x00\x73\x00\x74\x00\x72\x00\x6f\x00\x6b\x00\x65\x00\x64\x00\x2d\
+\x00\x31\x00\x35\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x17\
+\x07\x87\x48\x27\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x66\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2d\x00\x6f\x00\x70\
+\x00\x65\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x13\
+\x03\x24\x75\x47\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x65\x00\x66\x00\x72\x00\x65\x00\x73\x00\x68\x00\x2e\x00\x73\
+\x00\x76\x00\x67\
+\x00\x0e\
+\x05\xed\x38\x67\
+\x00\x61\
+\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x10\
+\x0c\x57\x65\x47\
+\x00\x61\
+\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x72\x00\x65\x00\x73\x00\x69\x00\x7a\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x10\
+\x08\xe4\xaf\x47\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x64\x00\x6f\x00\x6e\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x14\
\x0f\xa5\xe0\xc7\
\x00\x6d\
\x00\x61\x00\x67\x00\x6e\x00\x69\x00\x66\x00\x79\x00\x69\x00\x6e\x00\x67\x00\x2d\x00\x67\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x2e\
\x00\x73\x00\x76\x00\x67\
-\x00\x12\
-\x08\x79\x97\xe7\
+\x00\x1c\
+\x04\x66\xe1\x67\
+\x00\x63\
+\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
+\x00\x6c\x00\x65\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x15\
+\x0f\xc4\x59\xe7\
+\x00\x73\
+\x00\x75\x00\x62\x00\x64\x00\x69\x00\x72\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\x00\x79\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\
+\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x1d\
+\x06\xec\xf4\xc7\
+\x00\x63\
+\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
+\x00\x6c\x00\x65\x00\x2d\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0a\
+\x0f\x68\x53\xe7\
\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x61\x00\x6d\x00\x65\x00\x72\x00\x61\x00\x2e\x00\x73\x00\x76\
-\x00\x67\
+\x00\x6e\x00\x63\x00\x68\x00\x6f\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x07\
+\x0c\xf8\x5a\x07\
+\x00\x65\
+\x00\x79\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x19\
-\x0f\xef\x7b\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6f\x00\x6c\x00\x6f\x00\x72\x00\x2d\x00\x70\x00\x61\x00\x6c\
-\x00\x65\x00\x74\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0e\
-\x05\xed\x38\x67\
+\x0a\x43\x45\xc7\
\x00\x61\
-\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x66\x00\x6f\x00\x72\
+\x00\x77\x00\x61\x00\x72\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x12\
\x04\xb2\x21\x47\
\x00\x61\
\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x65\x00\x78\x00\x70\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\
\x00\x67\
+\x00\x08\
+\x0c\xf7\x55\x87\
+\x00\x74\
+\x00\x65\x00\x78\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x1b\
+\x0e\xb5\x68\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
+\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x11\
+\x01\x60\xbc\x47\
+\x00\x73\
+\x00\x6f\x00\x63\x00\x69\x00\x61\x00\x6c\x00\x2d\x00\x70\x00\x79\x00\x74\x00\x68\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\
+\x00\x09\
+\x0b\x9e\x89\x07\
+\x00\x63\
+\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x0d\
\x05\x20\xce\x87\
\x00\x6f\
\x00\x70\x00\x65\x00\x6e\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0f\
-\x09\x76\x60\xc7\
+\x00\x11\
+\x0c\xa7\xc7\x47\
\x00\x63\
-\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2d\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\
+\x00\x19\
+\x0f\xef\x7b\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6f\x00\x6c\x00\x6f\x00\x72\x00\x2d\x00\x70\x00\x61\x00\x6c\
+\x00\x65\x00\x74\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x08\
\x05\xa8\x57\x87\
\x00\x63\
\x00\x6f\x00\x64\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x11\
-\x0c\xa7\xc7\x47\
-\x00\x63\
-\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x0c\xdb\x38\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
\
-\x00\x08\
-\x08\xf7\x57\x07\
+\x00\x12\
+\x08\x79\x97\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x61\x00\x6d\x00\x65\x00\x72\x00\x61\x00\x2e\x00\x73\x00\x76\
\x00\x67\
-\x00\x72\x00\x69\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x0f\
-\x04\xf2\xa7\x87\
+\x07\x0e\xc4\x87\
+\x00\x6f\
+\x00\x70\x00\x65\x00\x6e\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x10\
+\x08\x89\xfa\x47\
\x00\x63\
-\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x6f\x00\x72\x00\x69\x00\x67\x00\x69\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x10\
\x04\xa9\x22\xc7\
\x00\x66\
\x00\x69\x00\x6c\x00\x6c\x00\x65\x00\x64\x00\x62\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0a\
-\x0a\xc8\x62\x67\
-\x00\x63\
-\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x19\
-\x0a\x43\x45\xc7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x66\x00\x6f\x00\x72\
-\x00\x77\x00\x61\x00\x72\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x17\
-\x07\x87\x48\x27\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x66\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2d\x00\x6f\x00\x70\
-\x00\x65\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x1c\
-\x04\x66\xe1\x67\
-\x00\x63\
-\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
-\x00\x6c\x00\x65\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x08\
-\x0c\xf7\x55\x87\
-\x00\x74\
-\x00\x65\x00\x78\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x07\
-\x0c\xf8\x5a\x07\
-\x00\x65\
-\x00\x79\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x12\
\x08\x55\xef\xc7\
\x00\x61\
\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x64\x00\x65\x00\x6c\x00\x65\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\
\x00\x67\
-\x00\x10\
-\x0c\x57\x65\x47\
-\x00\x61\
-\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x72\x00\x65\x00\x73\x00\x69\x00\x7a\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x08\x89\xfa\x47\
-\x00\x63\
-\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x6f\x00\x72\x00\x69\x00\x67\x00\x69\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x08\xe4\xaf\x47\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x64\x00\x6f\x00\x6e\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x1d\
-\x06\xec\xf4\xc7\
-\x00\x63\
-\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
-\x00\x6c\x00\x65\x00\x2d\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x08\xc8\x55\xe7\
+\x00\x73\
+\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
"
qt_resource_struct_v1 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x29\x00\x00\x00\x02\
-\x00\x00\x02\x48\x00\x00\x00\x00\x00\x01\x00\x00\x32\x5f\
-\x00\x00\x01\xae\x00\x00\x00\x00\x00\x01\x00\x00\x25\xc5\
-\x00\x00\x02\x70\x00\x00\x00\x00\x00\x01\x00\x00\x39\xe3\
-\x00\x00\x00\x58\x00\x00\x00\x00\x00\x01\x00\x00\x03\x80\
-\x00\x00\x05\x08\x00\x00\x00\x00\x00\x01\x00\x00\x73\xe0\
-\x00\x00\x04\x5c\x00\x01\x00\x00\x00\x01\x00\x00\x68\x7c\
-\x00\x00\x03\x76\x00\x00\x00\x00\x00\x01\x00\x00\x4e\x14\
-\x00\x00\x04\x38\x00\x00\x00\x00\x00\x01\x00\x00\x63\xbb\
-\x00\x00\x03\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x51\x4e\
-\x00\x00\x03\xe4\x00\x00\x00\x00\x00\x01\x00\x00\x59\x29\
-\x00\x00\x03\x54\x00\x00\x00\x00\x00\x01\x00\x00\x4b\x47\
-\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xe8\
-\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x09\x1a\
-\x00\x00\x06\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x88\x32\
-\x00\x00\x01\x34\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x8e\
-\x00\x00\x04\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x70\x8a\
-\x00\x00\x05\x70\x00\x00\x00\x00\x00\x01\x00\x00\x7c\x78\
-\x00\x00\x02\xf2\x00\x00\x00\x00\x00\x01\x00\x00\x42\xf6\
-\x00\x00\x05\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x81\xa1\
-\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x2e\x3b\
-\x00\x00\x00\x84\x00\x00\x00\x00\x00\x01\x00\x00\x06\xaa\
-\x00\x00\x05\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x85\xb5\
-\x00\x00\x04\x22\x00\x01\x00\x00\x00\x01\x00\x00\x61\xda\
-\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x55\xdf\
-\x00\x00\x01\x94\x00\x00\x00\x00\x00\x01\x00\x00\x23\x04\
-\x00\x00\x04\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x09\
-\x00\x00\x04\x82\x00\x00\x00\x00\x00\x01\x00\x00\x6a\xa0\
-\x00\x00\x00\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x13\xb6\
+\x00\x00\x04\x74\x00\x00\x00\x00\x00\x01\x00\x00\x59\x95\
+\x00\x00\x01\x78\x00\x00\x00\x00\x00\x01\x00\x00\x23\x3d\
+\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x05\xce\
+\x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x34\x17\
+\x00\x00\x02\xe4\x00\x00\x00\x00\x00\x01\x00\x00\x42\xa5\
+\x00\x00\x05\xe6\x00\x01\x00\x00\x00\x01\x00\x00\x84\xb1\
+\x00\x00\x03\xf8\x00\x00\x00\x00\x00\x01\x00\x00\x52\x2a\
+\x00\x00\x01\x16\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x7c\
+\x00\x00\x04\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x64\x29\
+\x00\x00\x05\x34\x00\x00\x00\x00\x00\x01\x00\x00\x72\x19\
+\x00\x00\x02\x48\x00\x00\x00\x00\x00\x01\x00\x00\x37\x41\
+\x00\x00\x01\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x2b\xf3\
\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
-\x00\x00\x05\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x7f\x1e\
-\x00\x00\x01\x0a\x00\x00\x00\x00\x00\x01\x00\x00\x17\x26\
-\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x00\x5d\xa6\
-\x00\x00\x01\xc8\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x80\
-\x00\x00\x05\x46\x00\x00\x00\x00\x00\x01\x00\x00\x77\xa8\
-\x00\x00\x05\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x78\x89\
-\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\x1f\xb4\
-\x00\x00\x02\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x31\x3b\
-\x00\x00\x02\xc4\x00\x00\x00\x00\x00\x01\x00\x00\x3f\x5f\
-\x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x03\x10\
-\x00\x00\x02\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x64\
-\x00\x00\x03\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x46\x1c\
+\x00\x00\x03\x52\x00\x00\x00\x00\x00\x01\x00\x00\x46\xdd\
+\x00\x00\x05\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x7c\x77\
+\x00\x00\x01\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x30\xc1\
+\x00\x00\x06\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x86\xd5\
+\x00\x00\x05\x72\x00\x00\x00\x00\x00\x01\x00\x00\x79\x51\
+\x00\x00\x05\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x80\x9d\
+\x00\x00\x01\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x20\x3d\
+\x00\x00\x06\x36\x00\x00\x00\x00\x00\x01\x00\x00\x89\x7b\
+\x00\x00\x02\x90\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x91\
+\x00\x00\x00\xc0\x00\x01\x00\x00\x00\x01\x00\x00\x11\xc3\
+\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x0e\x79\
+\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x0b\xb8\
+\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x4f\xa9\
+\x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x08\x4f\
+\x00\x00\x00\xd6\x00\x00\x00\x00\x00\x01\x00\x00\x13\xa4\
+\x00\x00\x04\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x61\x19\
+\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x3a\x0e\
+\x00\x00\x00\xec\x00\x00\x00\x00\x00\x01\x00\x00\x17\x14\
+\x00\x00\x04\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x68\xba\
+\x00\x00\x05\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x76\x96\
+\x00\x00\x04\x22\x00\x00\x00\x00\x00\x01\x00\x00\x55\x64\
+\x00\x00\x03\xac\x00\x00\x00\x00\x00\x01\x00\x00\x4b\xba\
+\x00\x00\x04\x38\x00\x00\x00\x00\x00\x01\x00\x00\x56\x45\
+\x00\x00\x03\x92\x00\x00\x00\x00\x00\x01\x00\x00\x4a\x96\
+\x00\x00\x02\xb6\x00\x00\x00\x00\x00\x01\x00\x00\x3f\x0e\
+\x00\x00\x03\x22\x00\x00\x00\x00\x00\x01\x00\x00\x46\x6d\
+\x00\x00\x01\x92\x00\x00\x00\x00\x00\x01\x00\x00\x28\xf8\
+\x00\x00\x04\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x6c\xee\
"
qt_resource_struct_v2 = b"\
@@ -2579,88 +2579,88 @@ qt_resource_struct_v2 = b"\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x29\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
-\x00\x00\x02\x48\x00\x00\x00\x00\x00\x01\x00\x00\x32\x5f\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x01\xae\x00\x00\x00\x00\x00\x01\x00\x00\x25\xc5\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x02\x70\x00\x00\x00\x00\x00\x01\x00\x00\x39\xe3\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
-\x00\x00\x00\x58\x00\x00\x00\x00\x00\x01\x00\x00\x03\x80\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x05\x08\x00\x00\x00\x00\x00\x01\x00\x00\x73\xe0\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
-\x00\x00\x04\x5c\x00\x01\x00\x00\x00\x01\x00\x00\x68\x7c\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x03\x76\x00\x00\x00\x00\x00\x01\x00\x00\x4e\x14\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
-\x00\x00\x04\x38\x00\x00\x00\x00\x00\x01\x00\x00\x63\xbb\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
-\x00\x00\x03\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x51\x4e\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x03\xe4\x00\x00\x00\x00\x00\x01\x00\x00\x59\x29\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
-\x00\x00\x03\x54\x00\x00\x00\x00\x00\x01\x00\x00\x4b\x47\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xe8\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf7\
-\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x09\x1a\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x06\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x88\x32\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
-\x00\x00\x01\x34\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x8e\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x04\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x70\x8a\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x05\x70\x00\x00\x00\x00\x00\x01\x00\x00\x7c\x78\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
-\x00\x00\x02\xf2\x00\x00\x00\x00\x00\x01\x00\x00\x42\xf6\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
-\x00\x00\x05\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x81\xa1\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
-\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x2e\x3b\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x00\x84\x00\x00\x00\x00\x00\x01\x00\x00\x06\xaa\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x05\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x85\xb5\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
-\x00\x00\x04\x22\x00\x01\x00\x00\x00\x01\x00\x00\x61\xda\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x55\xdf\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
-\x00\x00\x01\x94\x00\x00\x00\x00\x00\x01\x00\x00\x23\x04\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
-\x00\x00\x04\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x09\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
-\x00\x00\x04\x82\x00\x00\x00\x00\x00\x01\x00\x00\x6a\xa0\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x00\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x13\xb6\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x04\x74\x00\x00\x00\x00\x00\x01\x00\x00\x59\x95\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x01\x78\x00\x00\x00\x00\x00\x01\x00\x00\x23\x3d\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x05\xce\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x34\x17\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x02\xe4\x00\x00\x00\x00\x00\x01\x00\x00\x42\xa5\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x05\xe6\x00\x01\x00\x00\x00\x01\x00\x00\x84\xb1\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x03\xf8\x00\x00\x00\x00\x00\x01\x00\x00\x52\x2a\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x01\x16\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x7c\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x04\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x64\x29\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x05\x34\x00\x00\x00\x00\x00\x01\x00\x00\x72\x19\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x02\x48\x00\x00\x00\x00\x00\x01\x00\x00\x37\x41\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x01\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x2b\xf3\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
-\x00\x00\x05\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x7f\x1e\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x01\x0a\x00\x00\x00\x00\x00\x01\x00\x00\x17\x26\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x00\x5d\xa6\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
-\x00\x00\x01\xc8\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x80\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
-\x00\x00\x05\x46\x00\x00\x00\x00\x00\x01\x00\x00\x77\xa8\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x05\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x78\x89\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\x1f\xb4\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
-\x00\x00\x02\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x31\x3b\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
-\x00\x00\x02\xc4\x00\x00\x00\x00\x00\x01\x00\x00\x3f\x5f\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x03\x10\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x02\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x64\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
-\x00\x00\x03\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x46\x1c\
-\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x03\x52\x00\x00\x00\x00\x00\x01\x00\x00\x46\xdd\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x05\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x7c\x77\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x01\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x30\xc1\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x06\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x86\xd5\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x05\x72\x00\x00\x00\x00\x00\x01\x00\x00\x79\x51\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x05\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x80\x9d\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x01\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x20\x3d\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x06\x36\x00\x00\x00\x00\x00\x01\x00\x00\x89\x7b\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x02\x90\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x91\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x00\xc0\x00\x01\x00\x00\x00\x01\x00\x00\x11\xc3\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x0e\x79\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x0b\xb8\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x4f\xa9\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x08\x4f\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x00\xd6\x00\x00\x00\x00\x00\x01\x00\x00\x13\xa4\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x04\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x61\x19\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x3a\x0e\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x00\xec\x00\x00\x00\x00\x00\x01\x00\x00\x17\x14\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x04\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x68\xba\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x05\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x76\x96\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x04\x22\x00\x00\x00\x00\x00\x01\x00\x00\x55\x64\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x03\xac\x00\x00\x00\x00\x00\x01\x00\x00\x4b\xba\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x04\x38\x00\x00\x00\x00\x00\x01\x00\x00\x56\x45\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x03\x92\x00\x00\x00\x00\x00\x01\x00\x00\x4a\x96\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
+\x00\x00\x02\xb6\x00\x00\x00\x00\x00\x01\x00\x00\x3f\x0e\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x03\x22\x00\x00\x00\x00\x00\x01\x00\x00\x46\x6d\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x01\x92\x00\x00\x00\x00\x00\x01\x00\x00\x28\xf8\
+\x00\x00\x01\x6d\x7c\x52\x86\xbd\
+\x00\x00\x04\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x6c\xee\
+\x00\x00\x01\x6d\x7c\x52\x86\xbc\
"
qt_version = [int(v) for v in QtCore.qVersion().split('.')]
diff --git a/graphics/asymptote/Makefile.in b/graphics/asymptote/Makefile.in
index 5728027c2d..4255146c89 100644
--- a/graphics/asymptote/Makefile.in
+++ b/graphics/asymptote/Makefile.in
@@ -43,7 +43,7 @@ COREFILES = $(CAMP) $(SYMBOL_FILES) env genv stm dec errormsg \
fftw++asy simpson coder coenv impdatum \
@getopt@ locate parser program application varinit fundec refaccess \
envcompleter process constructor array Delaunay predicates \
- $(PRC) glrender tr arcball algebra3 quaternion shaders
+ $(PRC) glrender tr shaders jsfile
FILES = $(COREFILES) main
@@ -69,7 +69,7 @@ ASY = ./asy -dir base -config "" -render=0
DEFS = @DEFS@ @OPTIONS@ @PTHREAD_CFLAGS@ -DFFTWPP_SINGLE_THREAD
CFLAGS = @CFLAGS@
OPTS = $(DEFS) @CPPFLAGS@ @CXXFLAGS@ $(CFLAGS)
-GLEWOPTS = $(DEFS) @CPPFLAGS@ $(CFLAGS) -D GLEW_NO_GLU
+GLEWOPTS = $(DEFS) @CPPFLAGS@ $(CFLAGS) -DGLEW_NO_GLU -DGLEW_BUILD -O1
# Options for compiling the object files for the shared library.
# gc has to be configured with the option --disable-threads in order to make a
@@ -95,6 +95,7 @@ datadir = $(DESTDIR)@datadir@
asydir = $(datadir)/asymptote
GUIdir = $(asydir)/GUI
shaderdir = $(asydir)/shaders
+webgldir = $(asydir)/webgl
docdir = $(DESTDIR)@docdir@
exampledir = $(docdir)/examples
animationsdir = $(exampledir)/animations
@@ -245,7 +246,8 @@ install-texhash: install-asy
install-asy: asy sty
${INSTALL} -d $(bindir) $(asydir) $(exampledir) $(animationsdir)
${INSTALL} -d $(GUIdir) $(GUIdir)/pyUIClass $(GUIdir)/configs \
- $(GUIdir)/res $(GUIdir)/res/icons $(shaderdir)
+ $(GUIdir)/res $(GUIdir)/res/icons $(shaderdir) \
+ $(webgldir)
-${INSTALL} -d $(latexdir)
-${INSTALL} -d $(contextdir)
${INSTALL} -p -m 755 $(NAME) $(bindir)
@@ -253,6 +255,7 @@ install-asy: asy sty
asy-keywords.el $(asydir)
${INSTALL} -p -m 755 GUI/*.py $(GUIdir)
${INSTALL} -p -m 755 base/shaders/*.glsl $(shaderdir)
+ ${INSTALL} -p -m 644 base/webgl/*.html base/webgl/*.js $(webgldir)
-${INSTALL} -p -m 644 GUI/pyUIClass/*.py $(GUIdir)/pyUIClass
${INSTALL} -p -m 644 GUI/configs/*.cson $(GUIdir)/configs
${INSTALL} -p -m 644 GUI/res/icons.qrc $(GUIdir)/res
@@ -285,9 +288,19 @@ uninstall-asy:
-cd $(exampledir) && rm -f $(EXEXTRA) $(DOCEXTRA)
-rmdir $(exampledir)
-cd $(GUIdir) && rm -f *.py
+ -cd $(GUIdir)/pyUIClass && rm -f *.py
+ -rmdir $(GUIdir)/pyUIClass
+ -cd $(GUIdir)/configs && rm -f *.cson
+ -rmdir $(GUIdir)/configs
+ -cd $(GUIdir)/res/icons && rm -f *.svg
+ -rmdir $(GUIdir)/res/icons
+ -cd $(GUIdir)/res && rm -f icons.qrc
+ -rmdir $(GUIdir)/res
-rmdir $(GUIdir)
-cd $(shaderdir) && rm -f *.glsl
-rmdir $(shaderdir)
+ -cd $(webgldir) && rm -f *.html *.js
+ -rmdir $(webgldir)
-cd $(asydir) && rm -f asy-keywords.el *.asy $(EXTRA)
-rmdir $(asydir)
-cd $(latexdir) && rm -f $(LATEXFILES)
@@ -338,11 +351,7 @@ check-all: asy FORCE
$(MAKE) -C tests all
glew.o: glew.c GL/glew.h
- if test -n "$(MSDOS)"; then \
- $(CC) -I. $(GLEWOPTS) -o glew.o -D_WIN32 -D GLEW_BUILD -c glew.c; \
- else \
- $(CC) -I. $(GLEWOPTS) -o glew.o -c glew.c; \
- fi
+ $(CC) -I. $(GLEWOPTS) -o glew.o -c glew.c
.SUFFIXES: .c .cc .o .d .ui .py
%.o: %.cc
diff --git a/graphics/asymptote/README b/graphics/asymptote/README
index 77e7edfb59..f153da76a8 100644
--- a/graphics/asymptote/README
+++ b/graphics/asymptote/README
@@ -60,7 +60,3 @@ under the CC-BY-SA 4.0 license:
http://www.entypo.com/
and under a CC license:
http://www.zondicons.com/zondicons.zip
-
-Uses OpenImageIO, which the source is available at
-https://github.com/OpenImageIO/oiio.
-Copyright 2008-2018 Larry Gritz et al. All Rights Reserved. \ No newline at end of file
diff --git a/graphics/asymptote/ReleaseNotes b/graphics/asymptote/ReleaseNotes
index 773543ee81..534427c362 100644
--- a/graphics/asymptote/ReleaseNotes
+++ b/graphics/asymptote/ReleaseNotes
@@ -1,3 +1,18 @@
+Release Notes for Version 2.54
+
+Support for generating and embedding interactive 3D WebGL vector graphics
+within an HTML file has been added, allowing Asymptote figures
+to be displayed on modern mobile and desktop browsers. The OpenGL rendering
+routines were further optimized, yielding higher frame rates and
+lower memory usage. The view position for perspective projection was fixed.
+The default value of file word() was fixed. Installation issues were
+addressed. A new digits setting controls the default output file precision.
+A hanging pipe was fixed. The popcount function was extended to
+systems that lack 64-bit integers. The order of PRC quad colours was fixed.
+If lighting is enabled, vertex colors are now ignored in PRC images;
+when drawing a surface s, use draw(s,prc() ? nolight : currentlight);
+to disable lighting manually and recover the old behaviour.
+
Release Notes for Version 2.53
A memory leak and antialiasing artifacts in the 3D rendering engine were fixed.
diff --git a/graphics/asymptote/algebra3.cc b/graphics/asymptote/algebra3.cc
deleted file mode 100644
index 4b76942815..0000000000
--- a/graphics/asymptote/algebra3.cc
+++ /dev/null
@@ -1,1610 +0,0 @@
-/*
-
- algebra3.cpp, algebra3.h - C++ Vector and Matrix Algebra routines
-
- GLUI User Interface Toolkit (LGPL)
- Copyright (c) 1998 Paul Rademacher
-
- WWW: http://sourceforge.net/projects/glui/
- Forums: http://sourceforge.net/forum/?group_id=92496
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-/**************************************************************************
-
- There are three vector classes and two matrix classes: vec2, vec3,
- vec4, mat3, and mat4.
-
- All the standard arithmetic operations are defined, with '*'
- for dot product of two vectors and multiplication of two matrices,
- and '^' for cross product of two vectors.
-
- Additional functions include length(), normalize(), homogenize for
- vectors, and print(), set(), apply() for all classes.
-
- There is a function transpose() for matrices, but note that it
- does not actually change the matrix,
-
- When multiplied with a matrix, a vector is treated as a row vector
- if it precedes the matrix (v*M), and as a column vector if it
- follows the matrix (M*v).
-
- Matrices are stored in row-major form.
-
- A vector of one dimension (2d, 3d, or 4d) can be cast to a vector
- of a higher or lower dimension. If casting to a higher dimension,
- the new component is set by default to 1.0, unless a value is
- specified:
- vec3 a(1.0, 2.0, 3.0 );
- vec4 b( a, 4.0 ); // now b == {1.0, 2.0, 3.0, 4.0};
- When casting to a lower dimension, the vector is homogenized in
- the lower dimension. E.g., if a 4d {X,Y,Z,W} is cast to 3d, the
- resulting vector is {X/W, Y/W, Z/W}. It is up to the user to
- insure the fourth component is not zero before casting.
-
- There are also the following function for building matrices:
- identity2D(), translation2D(), rotation2D(),
- scaling2D(), identity3D(), translation3D(),
- rotation3D(), rotation3Drad(), scaling3D(),
- perspective3D()
-
-
- ---------------------------------------------------------------------
-
- Author: Jean-Francois DOUEg
- Revised: Paul Rademacher
- Version 3.2 - Feb 1998
- Revised: Nigel Stewart (GLUI Code Cleaning)
-
-**************************************************************************/
-
-#include "algebra3.h"
-#include <cmath>
-
-static const double radians=std::acos(-1)/180.0;
-
-#ifdef VEC_ERROR_FATAL
-#ifndef VEC_ERROR
-#define VEC_ERROR(E) { printf( "VERROR %s\n", E ); exit(1); }
-#endif
-#else
-#ifndef VEC_ERROR
-#define VEC_ERROR(E) { printf( "VERROR %s\n", E ); }
-#endif
-#endif
-
-/****************************************************************
- * *
- * vec2 Member functions *
- * *
- ****************************************************************/
-
-/******************** vec2 CONSTRUCTORS ********************/
-
-vec2::vec2()
-{
- n[VX] = n[VY] = 0.0;
-}
-
-vec2::vec2(float x, float y)
-{
- n[VX] = x;
- n[VY] = y;
-}
-
-vec2::vec2(const vec2 &v)
-{
- n[VX] = v.n[VX];
- n[VY] = v.n[VY];
-}
-
-vec2::vec2(const vec3 &v) // it is up to caller to avoid divide-by-zero
-{
- n[VX] = v.n[VX]/v.n[VZ];
- n[VY] = v.n[VY]/v.n[VZ];
-}
-
-vec2::vec2(const vec3 &v, int dropAxis)
-{
- switch (dropAxis)
- {
- case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; break;
- case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; break;
- default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; break;
- }
-}
-
-/******************** vec2 ASSIGNMENT OPERATORS ******************/
-
-vec2 & vec2::operator=(const vec2 &v)
-{
- n[VX] = v.n[VX];
- n[VY] = v.n[VY];
- return *this;
-}
-
-vec2 & vec2::operator+=(const vec2 &v)
-{
- n[VX] += v.n[VX];
- n[VY] += v.n[VY];
- return *this;
-}
-
-vec2 & vec2::operator-=(const vec2 &v)
-{
- n[VX] -= v.n[VX];
- n[VY] -= v.n[VY];
- return *this;
-}
-
-vec2 &vec2::operator*=(float d)
-{
- n[VX] *= d;
- n[VY] *= d;
- return *this;
-}
-
-vec2 &vec2::operator/=(float d)
-{
- float d_inv = 1.0f/d;
- n[VX] *= d_inv;
- n[VY] *= d_inv;
- return *this;
-}
-
-float &vec2::operator[](int i)
-{
- if (i < VX || i > VY)
- //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("vec2 [] operator: illegal access" );
- return n[i];
-}
-
-const float &vec2::operator[](int i) const
-{
- if (i < VX || i > VY)
- //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("vec2 [] operator: illegal access" );
-
- return n[i];
-}
-
-/******************** vec2 SPECIAL FUNCTIONS ********************/
-
-float vec2::length() const
-{
- return (float) sqrt(length2());
-}
-
-float vec2::length2() const
-{
- return n[VX]*n[VX] + n[VY]*n[VY];
-}
-
-vec2 &vec2::normalize() // it is up to caller to avoid divide-by-zero
-{
- *this /= length();
- return *this;
-}
-
-vec2 &vec2::apply(V_FCT_PTR fct)
-{
- n[VX] = (*fct)(n[VX]);
- n[VY] = (*fct)(n[VY]);
- return *this;
-}
-
-void vec2::set( float x, float y )
-{
- n[VX] = x; n[VY] = y;
-}
-
-/******************** vec2 FRIENDS *****************************/
-
-vec2 operator-(const vec2 &a)
-{
- return vec2(-a.n[VX],-a.n[VY]);
-}
-
-vec2 operator+(const vec2 &a, const vec2& b)
-{
- return vec2(a.n[VX]+b.n[VX], a.n[VY]+b.n[VY]);
-}
-
-vec2 operator-(const vec2 &a, const vec2& b)
-{
- return vec2(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY]);
-}
-
-vec2 operator*(const vec2 &a, float d)
-{
- return vec2(d*a.n[VX], d*a.n[VY]);
-}
-
-vec2 operator*(float d, const vec2 &a)
-{
- return a*d;
-}
-
-vec2 operator*(const mat3 &a, const vec2 &v)
-{
- vec3 av;
-
- av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ];
- av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ];
- av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ];
-
- return av;
-}
-
-vec2 operator*(const vec2 &v, const mat3 &a)
-{
- return a.transpose() * v;
-}
-
-vec3 operator*(const mat3 &a, const vec3 &v)
-{
- vec3 av;
-
- av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ]*v.n[VZ];
- av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ]*v.n[VZ];
- av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ]*v.n[VZ];
-
- return av;
-}
-
-vec3 operator*(const vec3 &v, const mat3 &a)
-{
- return a.transpose() * v;
-}
-
-float operator*(const vec2 &a, const vec2 &b)
-{
- return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY];
-}
-
-vec2 operator/(const vec2 &a, float d)
-{
- float d_inv = 1.0f/d;
- return vec2(a.n[VX]*d_inv, a.n[VY]*d_inv);
-}
-
-vec3 operator^(const vec2 &a, const vec2 &b)
-{
- return vec3(0.0, 0.0, a.n[VX] * b.n[VY] - b.n[VX] * a.n[VY]);
-}
-
-int operator==(const vec2 &a, const vec2 &b)
-{
- return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]);
-}
-
-int operator!=(const vec2 &a, const vec2 &b)
-{
- return !(a == b);
-}
-
-/*ostream& operator << (ostream& s, vec2& v)
-{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << " |"; }
-*/
-
-/*istream& operator >> (istream& s, vec2& v) {
- vec2 v_tmp;
- char c = ' ';
-
- while (isspace(c))
- s >> c;
- // The vectors can be formatted either as x y or | x y |
- if (c == '|') {
- s >> v_tmp[VX] >> v_tmp[VY];
- while (s >> c && isspace(c)) ;
- if (c != '|')
- ;//s.set(_bad);
- }
- else {
- s.putback(c);
- s >> v_tmp[VX] >> v_tmp[VY];
- }
- if (s)
- v = v_tmp;
- return s;
-}
-*/
-
-void swap(vec2 &a, vec2 &b)
-{
- vec2 tmp(a);
- a = b;
- b = tmp;
-}
-
-vec2 min_vec(const vec2 &a, const vec2 &b)
-{
- return vec2(MIN(a.n[VX], b.n[VX]), MIN(a.n[VY], b.n[VY]));
-}
-
-vec2 max_vec(const vec2 &a, const vec2 &b)
-{
- return vec2(MAX(a.n[VX], b.n[VX]), MAX(a.n[VY], b.n[VY]));
-}
-
-vec2 prod(const vec2 &a, const vec2 &b)
-{
- return vec2(a.n[VX] * b.n[VX], a.n[VY] * b.n[VY]);
-}
-
-/****************************************************************
- * *
- * vec3 Member functions *
- * *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-vec3::vec3()
-{
- n[VX] = n[VY] = n[VZ] = 0.0;
-}
-
-vec3::vec3(float x, float y, float z)
-{
- n[VX] = x;
- n[VY] = y;
- n[VZ] = z;
-}
-
-vec3::vec3(const vec3 &v)
-{
- n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ];
-}
-
-vec3::vec3(const vec2 &v)
-{
- n[VX] = v.n[VX];
- n[VY] = v.n[VY];
- n[VZ] = 1.0;
-}
-
-vec3::vec3(const vec2 &v, float d)
-{
- n[VX] = v.n[VX];
- n[VY] = v.n[VY];
- n[VZ] = d;
-}
-
-vec3::vec3(const vec4 &v) // it is up to caller to avoid divide-by-zero
-{
- n[VX] = v.n[VX] / v.n[VW];
- n[VY] = v.n[VY] / v.n[VW];
- n[VZ] = v.n[VZ] / v.n[VW];
-}
-
-vec3::vec3(const vec4 &v, int dropAxis)
-{
- switch (dropAxis)
- {
- case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break;
- case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break;
- case VZ: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VW]; break;
- default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ]; break;
- }
-}
-
-
-// ASSIGNMENT OPERATORS
-
-vec3 &vec3::operator=(const vec3 &v)
-{
- n[VX] = v.n[VX];
- n[VY] = v.n[VY];
- n[VZ] = v.n[VZ];
- return *this;
-}
-
-vec3 &vec3::operator+=(const vec3 &v)
-{
- n[VX] += v.n[VX];
- n[VY] += v.n[VY];
- n[VZ] += v.n[VZ];
- return *this;
-}
-
-vec3 &vec3::operator-=(const vec3& v)
-{
- n[VX] -= v.n[VX];
- n[VY] -= v.n[VY];
- n[VZ] -= v.n[VZ];
- return *this;
-}
-
-vec3 &vec3::operator*=(float d)
-{
- n[VX] *= d;
- n[VY] *= d;
- n[VZ] *= d;
- return *this;
-}
-
-vec3 &vec3::operator/=(float d)
-{
- float d_inv = 1.0f/d;
- n[VX] *= d_inv;
- n[VY] *= d_inv;
- n[VZ] *= d_inv;
- return *this;
-}
-
-float &vec3::operator[](int i)
-{
- if (i < VX || i > VZ)
- //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("vec3 [] operator: illegal access" );
-
- return n[i];
-}
-
-const float &vec3::operator[](int i) const
-{
- if (i < VX || i > VZ)
- //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("vec3 [] operator: illegal access" );
-
- return n[i];
-}
-
-// SPECIAL FUNCTIONS
-
-float vec3::length() const
-{
- return (float) sqrt(length2());
-}
-
-float vec3::length2() const
-{
- return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ];
-}
-
-vec3 &vec3::normalize() // it is up to caller to avoid divide-by-zero
-{
- *this /= length();
- return *this;
-}
-
-vec3 &vec3::homogenize(void) // it is up to caller to avoid divide-by-zero
-{
- n[VX] /= n[VZ];
- n[VY] /= n[VZ];
- n[VZ] = 1.0;
- return *this;
-}
-
-vec3 &vec3::apply(V_FCT_PTR fct)
-{
- n[VX] = (*fct)(n[VX]);
- n[VY] = (*fct)(n[VY]);
- n[VZ] = (*fct)(n[VZ]);
- return *this;
-}
-
-void vec3::set(float x, float y, float z) // set vector
-{
- n[VX] = x;
- n[VY] = y;
- n[VZ] = z;
-}
-
-void vec3::print(FILE *file, const char *name) const // print vector to a file
-{
- fprintf( file, "%s: <%f, %f, %f>\n", name, n[VX], n[VY], n[VZ] );
-}
-
-// FRIENDS
-
-vec3 operator-(const vec3 &a)
-{
- return vec3(-a.n[VX],-a.n[VY],-a.n[VZ]);
-}
-
-vec3 operator+(const vec3 &a, const vec3 &b)
-{
- return vec3(a.n[VX]+ b.n[VX], a.n[VY] + b.n[VY], a.n[VZ] + b.n[VZ]);
-}
-
-vec3 operator-(const vec3 &a, const vec3 &b)
-{
- return vec3(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY], a.n[VZ]-b.n[VZ]);
-}
-
-vec3 operator*(const vec3 &a, float d)
-{
- return vec3(d*a.n[VX], d*a.n[VY], d*a.n[VZ]);
-}
-
-vec3 operator*(float d, const vec3 &a)
-{
- return a*d;
-}
-
-vec3 operator*(const mat4 &a, const vec3 &v)
-{
- return a*vec4(v);
-}
-
-vec3 operator*(const vec3 &v, mat4 &a)
-{
- return a.transpose()*v;
-}
-
-float operator*(const vec3 &a, const vec3 &b)
-{
- return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY] + a.n[VZ]*b.n[VZ];
-}
-
-vec3 operator/(const vec3 &a, float d)
-{
- float d_inv = 1.0f/d;
- return vec3(a.n[VX]*d_inv, a.n[VY]*d_inv, a.n[VZ]*d_inv);
-}
-
-vec3 operator^(const vec3 &a, const vec3 &b)
-{
- return
- vec3(a.n[VY]*b.n[VZ] - a.n[VZ]*b.n[VY],
- a.n[VZ]*b.n[VX] - a.n[VX]*b.n[VZ],
- a.n[VX]*b.n[VY] - a.n[VY]*b.n[VX]);
-}
-
-int operator==(const vec3 &a, const vec3 &b)
-{
- return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]) && (a.n[VZ] == b.n[VZ]);
-}
-
-int operator!=(const vec3 &a, const vec3 &b)
-{
- return !(a == b);
-}
-
-/*ostream& operator << (ostream& s, vec3& v)
-{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << " |"; }
-
-istream& operator >> (istream& s, vec3& v) {
- vec3 v_tmp;
- char c = ' ';
-
- while (isspace(c))
- s >> c;
- // The vectors can be formatted either as x y z or | x y z |
- if (c == '|') {
- s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ];
- while (s >> c && isspace(c)) ;
- if (c != '|')
- ;//s.set(_bad);
- }
- else {
- s.putback(c);
- s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ];
- }
- if (s)
- v = v_tmp;
- return s;
-}
-*/
-
-void swap(vec3 &a, vec3 &b)
-{
- vec3 tmp(a);
- a = b;
- b = tmp;
-}
-
-vec3 min_vec(const vec3 &a, const vec3 &b)
-{
- return vec3(
- MIN(a.n[VX], b.n[VX]),
- MIN(a.n[VY], b.n[VY]),
- MIN(a.n[VZ], b.n[VZ]));
-}
-
-vec3 max_vec(const vec3 &a, const vec3 &b)
-{
- return vec3(
- MAX(a.n[VX], b.n[VX]),
- MAX(a.n[VY], b.n[VY]),
- MAX(a.n[VZ], b.n[VZ]));
-}
-
-vec3 prod(const vec3 &a, const vec3 &b)
-{
- return vec3(a.n[VX]*b.n[VX], a.n[VY]*b.n[VY], a.n[VZ]*b.n[VZ]);
-}
-
-/****************************************************************
- * *
- * vec4 Member functions *
- * *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-vec4::vec4()
-{
- n[VX] = n[VY] = n[VZ] = 0.0;
- n[VW] = 1.0;
-}
-
-vec4::vec4(float x, float y, float z, float w)
-{
- n[VX] = x;
- n[VY] = y;
- n[VZ] = z;
- n[VW] = w;
-}
-
-vec4::vec4(const vec4 &v)
-{
- n[VX] = v.n[VX];
- n[VY] = v.n[VY];
- n[VZ] = v.n[VZ];
- n[VW] = v.n[VW];
-}
-
-vec4::vec4(const vec3 &v)
-{
- n[VX] = v.n[VX];
- n[VY] = v.n[VY];
- n[VZ] = v.n[VZ];
- n[VW] = 1.0;
-}
-
-vec4::vec4(const vec3 &v, float d)
-{
- n[VX] = v.n[VX];
- n[VY] = v.n[VY];
- n[VZ] = v.n[VZ];
- n[VW] = d;
-}
-
-// ASSIGNMENT OPERATORS
-
-vec4 &vec4::operator=(const vec4 &v)
-{
- n[VX] = v.n[VX];
- n[VY] = v.n[VY];
- n[VZ] = v.n[VZ];
- n[VW] = v.n[VW];
- return *this;
-}
-
-vec4 &vec4::operator+=(const vec4 &v)
-{
- n[VX] += v.n[VX];
- n[VY] += v.n[VY];
- n[VZ] += v.n[VZ];
- n[VW] += v.n[VW];
- return *this;
-}
-
-vec4 &vec4::operator-=(const vec4 &v)
-{
- n[VX] -= v.n[VX];
- n[VY] -= v.n[VY];
- n[VZ] -= v.n[VZ];
- n[VW] -= v.n[VW];
- return *this;
-}
-
-vec4 &vec4::operator*=(float d)
-{
- n[VX] *= d;
- n[VY] *= d;
- n[VZ] *= d;
- n[VW] *= d;
- return *this;
-}
-
-vec4 &vec4::operator/=(float d)
-{
- float d_inv = 1.0f/d;
- n[VX] *= d_inv;
- n[VY] *= d_inv;
- n[VZ] *= d_inv;
- n[VW] *= d_inv;
- return *this;
-}
-
-float &vec4::operator[](int i)
-{
- if (i < VX || i > VW)
- //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("vec4 [] operator: illegal access" );
-
- return n[i];
-}
-
-const float &vec4::operator[](int i) const
-{
- if (i < VX || i > VW)
- //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("vec4 [] operator: illegal access" );
-
- return n[i];
-}
-
-// SPECIAL FUNCTIONS
-
-float vec4::length() const
-{
- return (float) sqrt(length2());
-}
-
-float vec4::length2() const
-{
- return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ] + n[VW]*n[VW];
-}
-
-vec4 &vec4::normalize() // it is up to caller to avoid divide-by-zero
-{
- *this /= length();
- return *this;
-}
-
-vec4 &vec4::homogenize() // it is up to caller to avoid divide-by-zero
-{
- n[VX] /= n[VW];
- n[VY] /= n[VW];
- n[VZ] /= n[VW];
- n[VW] = 1.0;
- return *this;
-}
-
-vec4 &vec4::apply(V_FCT_PTR fct)
-{
- n[VX] = (*fct)(n[VX]);
- n[VY] = (*fct)(n[VY]);
- n[VZ] = (*fct)(n[VZ]);
- n[VW] = (*fct)(n[VW]);
- return *this;
-}
-
-void vec4::print(FILE *file, const char *name) const // print vector to a file
-{
- fprintf( file, "%s: <%f, %f, %f, %f>\n", name, n[VX], n[VY], n[VZ], n[VW]);
-}
-
-void vec4::set(float x, float y, float z, float a)
-{
- n[0] = x;
- n[1] = y;
- n[2] = z;
- n[3] = a;
-}
-
-
-// FRIENDS
-
-vec4 operator-(const vec4 &a)
-{
- return vec4(-a.n[VX],-a.n[VY],-a.n[VZ],-a.n[VW]);
-}
-
-vec4 operator+(const vec4 &a, const vec4 &b)
-{
- return vec4(
- a.n[VX] + b.n[VX],
- a.n[VY] + b.n[VY],
- a.n[VZ] + b.n[VZ],
- a.n[VW] + b.n[VW]);
-}
-
-vec4 operator-(const vec4 &a, const vec4 &b)
-{
- return vec4(
- a.n[VX] - b.n[VX],
- a.n[VY] - b.n[VY],
- a.n[VZ] - b.n[VZ],
- a.n[VW] - b.n[VW]);
-}
-
-vec4 operator*(const vec4 &a, float d)
-{
- return vec4(d*a.n[VX], d*a.n[VY], d*a.n[VZ], d*a.n[VW]);
-}
-
-vec4 operator*(float d, const vec4 &a)
-{
- return a*d;
-}
-
-vec4 operator*(const mat4 &a, const vec4 &v)
-{
- #define ROWCOL(i) \
- a.v[i].n[0]*v.n[VX] + \
- a.v[i].n[1]*v.n[VY] + \
- a.v[i].n[2]*v.n[VZ] + \
- a.v[i].n[3]*v.n[VW]
-
- return vec4(ROWCOL(0), ROWCOL(1), ROWCOL(2), ROWCOL(3));
-
- #undef ROWCOL
-}
-
-vec4 operator*(const vec4 &v, const mat4 &a)
-{
- return a.transpose()*v;
-}
-
-float operator*(const vec4 &a, const vec4 &b)
-{
- return
- a.n[VX]*b.n[VX] +
- a.n[VY]*b.n[VY] +
- a.n[VZ]*b.n[VZ] +
- a.n[VW]*b.n[VW];
-}
-
-vec4 operator/(const vec4 &a, float d)
-{
- float d_inv = 1.0f/d;
- return vec4(
- a.n[VX]*d_inv,
- a.n[VY]*d_inv,
- a.n[VZ]*d_inv,
- a.n[VW]*d_inv);
-}
-
-int operator==(const vec4 &a, const vec4 &b)
-{
- return
- (a.n[VX] == b.n[VX]) &&
- (a.n[VY] == b.n[VY]) &&
- (a.n[VZ] == b.n[VZ]) &&
- (a.n[VW] == b.n[VW]);
-}
-
-int operator!=(const vec4 &a, const vec4 &b)
-{
- return !(a == b);
-}
-
-/*ostream& operator << (ostream& s, vec4& v)
-{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << ' '
- << v.n[VW] << " |"; }
-
-istream& operator >> (istream& s, vec4& v) {
- vec4 v_tmp;
- char c = ' ';
-
- while (isspace(c))
- s >> c;
- // The vectors can be formatted either as x y z w or | x y z w |
- if (c == '|') {
- s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW];
- while (s >> c && isspace(c)) ;
- if (c != '|')
- ;//s.set(_bad);
- }
- else {
- s.putback(c);
- s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW];
- }
- if (s)
- v = v_tmp;
- return s;
-}
-*/
-
-void swap(vec4 &a, vec4 &b)
-{
- vec4 tmp(a);
- a = b;
- b = tmp;
-}
-
-vec4 min_vec(const vec4 &a, const vec4 &b)
-{
- return vec4(
- MIN(a.n[VX], b.n[VX]),
- MIN(a.n[VY], b.n[VY]),
- MIN(a.n[VZ], b.n[VZ]),
- MIN(a.n[VW], b.n[VW]));
-}
-
-vec4 max_vec(const vec4 &a, const vec4 &b)
-{
- return vec4(
- MAX(a.n[VX], b.n[VX]),
- MAX(a.n[VY], b.n[VY]),
- MAX(a.n[VZ], b.n[VZ]),
- MAX(a.n[VW], b.n[VW]));
-}
-
-vec4 prod(const vec4 &a, const vec4 &b)
-{
- return vec4(
- a.n[VX] * b.n[VX],
- a.n[VY] * b.n[VY],
- a.n[VZ] * b.n[VZ],
- a.n[VW] * b.n[VW]);
-}
-
-/****************************************************************
- * *
- * mat3 member functions *
- * *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-mat3::mat3()
-{
- *this = identity2D();
-}
-
-mat3::mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2)
-{
- set(v0, v1, v2);
-}
-
-mat3::mat3(const mat3 &m)
-{
- v[0] = m.v[0];
- v[1] = m.v[1];
- v[2] = m.v[2];
-}
-
-// ASSIGNMENT OPERATORS
-
-mat3 &mat3::operator=(const mat3 &m)
-{
- v[0] = m.v[0];
- v[1] = m.v[1];
- v[2] = m.v[2];
- return *this;
-}
-
-mat3 &mat3::operator+=(const mat3& m)
-{
- v[0] += m.v[0];
- v[1] += m.v[1];
- v[2] += m.v[2];
- return *this;
-}
-
-mat3 &mat3::operator-=(const mat3& m)
-{
- v[0] -= m.v[0];
- v[1] -= m.v[1];
- v[2] -= m.v[2];
- return *this;
-}
-
-mat3 &mat3::operator*=(float d)
-{
- v[0] *= d;
- v[1] *= d;
- v[2] *= d;
- return *this;
-}
-
-mat3 &mat3::operator/=(float d)
-{
- v[0] /= d;
- v[1] /= d;
- v[2] /= d;
- return *this;
-}
-
-vec3 &mat3::operator[](int i)
-{
- if (i < VX || i > VZ)
- //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("mat3 [] operator: illegal access" );
-
- return v[i];
-}
-
-const vec3 &mat3::operator[](int i) const
-{
- if (i < VX || i > VZ)
- //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("mat3 [] operator: illegal access" );
-
- return v[i];
-}
-
-void mat3::set(const vec3 &v0, const vec3 &v1, const vec3 &v2)
-{
- v[0] = v0;
- v[1] = v1;
- v[2] = v2;
-}
-
-// SPECIAL FUNCTIONS
-
-mat3 mat3::transpose() const
-{
- return mat3(
- vec3(v[0][0], v[1][0], v[2][0]),
- vec3(v[0][1], v[1][1], v[2][1]),
- vec3(v[0][2], v[1][2], v[2][2]));
-}
-
-mat3 mat3::inverse() const // Gauss-Jordan elimination with partial pivoting
-{
- mat3 a(*this); // As a evolves from original mat into identity
- mat3 b(identity2D()); // b evolves from identity into inverse(a)
- int i, j, i1;
-
- // Loop over cols of a from left to right, eliminating above and below diag
- for (j=0; j<3; j++) // Find largest pivot in column j among rows j..2
- {
- i1 = j; // Row with largest pivot candidate
- for (i=j+1; i<3; i++)
- if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
- i1 = i;
-
- // Swap rows i1 and j in a and b to put pivot on diagonal
- swap(a.v[i1], a.v[j]);
- swap(b.v[i1], b.v[j]);
-
- // Scale row j to have a unit diagonal
- if (a.v[j].n[j]==0.)
- VEC_ERROR("mat3::inverse: singular matrix; can't invert\n");
-
- b.v[j] /= a.v[j].n[j];
- a.v[j] /= a.v[j].n[j];
-
- // Eliminate off-diagonal elems in col j of a, doing identical ops to b
- for (i=0; i<3; i++)
- if (i!=j)
- {
- b.v[i] -= a.v[i].n[j]*b.v[j];
- a.v[i] -= a.v[i].n[j]*a.v[j];
- }
- }
-
- return b;
-}
-
-mat3 &mat3::apply(V_FCT_PTR fct)
-{
- v[VX].apply(fct);
- v[VY].apply(fct);
- v[VZ].apply(fct);
- return *this;
-}
-
-
-// FRIENDS
-
-mat3 operator-(const mat3 &a)
-{
- return mat3(-a.v[0], -a.v[1], -a.v[2]);
-}
-
-mat3 operator+(const mat3 &a, const mat3 &b)
-{
- return mat3(a.v[0]+b.v[0], a.v[1]+b.v[1], a.v[2]+b.v[2]);
-}
-
-mat3 operator-(const mat3 &a, const mat3 &b)
-{
- return mat3(a.v[0]-b.v[0], a.v[1]-b.v[1], a.v[2]-b.v[2]);
-}
-
-mat3 operator*(const mat3 &a, const mat3 &b)
-{
- #define ROWCOL(i, j) \
- a.v[i].n[0]*b.v[0][j] + a.v[i].n[1]*b.v[1][j] + a.v[i].n[2]*b.v[2][j]
-
- return mat3(
- vec3(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2)),
- vec3(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2)),
- vec3(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2)));
-
- #undef ROWCOL
-}
-
-mat3 operator*(const mat3 &a, float d)
-{
- return mat3(a.v[0]*d, a.v[1]*d, a.v[2]*d);
-}
-
-mat3 operator*(float d, const mat3 &a)
-{
- return a*d;
-}
-
-mat3 operator/(const mat3 &a, float d)
-{
- return mat3(a.v[0]/d, a.v[1]/d, a.v[2]/d);
-}
-
-int operator==(const mat3 &a, const mat3 &b)
-{
- return
- (a.v[0] == b.v[0]) &&
- (a.v[1] == b.v[1]) &&
- (a.v[2] == b.v[2]);
-}
-
-int operator!=(const mat3 &a, const mat3 &b)
-{
- return !(a == b);
-}
-
-/*ostream& operator << (ostream& s, mat3& m)
-{ return s << m.v[VX] << '\n' << m.v[VY] << '\n' << m.v[VZ]; }
-
-istream& operator >> (istream& s, mat3& m) {
- mat3 m_tmp;
-
- s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ];
- if (s)
- m = m_tmp;
- return s;
-}
-*/
-
-void swap(mat3 &a, mat3 &b)
-{
- mat3 tmp(a);
- a = b;
- b = tmp;
-}
-
-void mat3::print(FILE *file, const char *name) const
-{
- int i, j;
-
- fprintf( stderr, "%s:\n", name );
-
- for( i = 0; i < 3; i++ )
- {
- fprintf( stderr, " " );
- for( j = 0; j < 3; j++ )
- {
- fprintf( stderr, "%f ", v[i][j] );
- }
- fprintf( stderr, "\n" );
- }
-}
-
-
-
-/****************************************************************
- * *
- * mat4 member functions *
- * *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-mat4::mat4()
-{
- *this = identity3D();
-}
-
-mat4::mat4(const vec4& v0, const vec4& v1, const vec4& v2, const vec4& v3)
-{
- v[0] = v0;
- v[1] = v1;
- v[2] = v2;
- v[3] = v3;
-}
-
-mat4::mat4(const mat4 &m)
-{
- v[0] = m.v[0];
- v[1] = m.v[1];
- v[2] = m.v[2];
- v[3] = m.v[3];
-}
-
-mat4::mat4(
- float a00, float a01, float a02, float a03,
- float a10, float a11, float a12, float a13,
- float a20, float a21, float a22, float a23,
- float a30, float a31, float a32, float a33 )
-{
- v[0][0] = a00; v[0][1] = a01; v[0][2] = a02; v[0][3] = a03;
- v[1][0] = a10; v[1][1] = a11; v[1][2] = a12; v[1][3] = a13;
- v[2][0] = a20; v[2][1] = a21; v[2][2] = a22; v[2][3] = a23;
- v[3][0] = a30; v[3][1] = a31; v[3][2] = a32; v[3][3] = a33;
-}
-
-// ASSIGNMENT OPERATORS
-
-mat4 &mat4::operator=(const mat4 &m)
-{
- v[0] = m.v[0];
- v[1] = m.v[1];
- v[2] = m.v[2];
- v[3] = m.v[3];
- return *this;
-}
-
-mat4 &mat4::operator+=(const mat4 &m)
-{
- v[0] += m.v[0];
- v[1] += m.v[1];
- v[2] += m.v[2];
- v[3] += m.v[3];
- return *this;
-}
-
-mat4 &mat4::operator-=(const mat4 &m)
-{
- v[0] -= m.v[0];
- v[1] -= m.v[1];
- v[2] -= m.v[2];
- v[3] -= m.v[3];
- return *this;
-}
-
-mat4 &mat4::operator*=(float d)
-{
- v[0] *= d;
- v[1] *= d;
- v[2] *= d;
- v[3] *= d;
- return *this;
-}
-
-mat4 &mat4::operator/=(float d)
-{
- v[0] /= d;
- v[1] /= d;
- v[2] /= d;
- v[3] /= d;
- return *this;
-}
-
-vec4 &mat4::operator[](int i)
-{
- if (i < VX || i > VW)
- //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("mat4 [] operator: illegal access" );
- return v[i];
-}
-
-const vec4 &mat4::operator[](int i) const
-{
- if (i < VX || i > VW)
- //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << '\n')
- VEC_ERROR("mat4 [] operator: illegal access" );
- return v[i];
-}
-
-// SPECIAL FUNCTIONS;
-
-mat4 mat4::transpose() const
-{
- return mat4(
- vec4(v[0][0], v[1][0], v[2][0], v[3][0]),
- vec4(v[0][1], v[1][1], v[2][1], v[3][1]),
- vec4(v[0][2], v[1][2], v[2][2], v[3][2]),
- vec4(v[0][3], v[1][3], v[2][3], v[3][3]));
-}
-
-mat4 mat4::inverse() const // Gauss-Jordan elimination with partial pivoting
-{
- mat4 a(*this); // As a evolves from original mat into identity
- mat4 b(identity3D()); // b evolves from identity into inverse(a)
- int i, j, i1;
-
- // Loop over cols of a from left to right, eliminating above and below diag
- for (j=0; j<4; j++) // Find largest pivot in column j among rows j..3
- {
- i1 = j; // Row with largest pivot candidate
- for (i=j+1; i<4; i++)
- if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
- i1 = i;
-
- // Swap rows i1 and j in a and b to put pivot on diagonal
- swap(a.v[i1], a.v[j]);
- swap(b.v[i1], b.v[j]);
-
- // Scale row j to have a unit diagonal
- if (a.v[j].n[j]==0.)
- VEC_ERROR("mat4::inverse: singular matrix; can't invert\n");
-
- b.v[j] /= a.v[j].n[j];
- a.v[j] /= a.v[j].n[j];
-
- // Eliminate off-diagonal elems in col j of a, doing identical ops to b
- for (i=0; i<4; i++)
- if (i!=j)
- {
- b.v[i] -= a.v[i].n[j]*b.v[j];
- a.v[i] -= a.v[i].n[j]*a.v[j];
- }
- }
-
- return b;
-}
-
-mat4 &mat4::apply(V_FCT_PTR fct)
-{
- v[VX].apply(fct);
- v[VY].apply(fct);
- v[VZ].apply(fct);
- v[VW].apply(fct);
- return *this;
-}
-
-void mat4::print(FILE *file, const char *name) const
-{
- int i, j;
-
- fprintf( stderr, "%s:\n", name );
-
- for( i = 0; i < 4; i++ )
- {
- fprintf( stderr, " " );
- for( j = 0; j < 4; j++ )
- {
- fprintf( stderr, "%f ", v[i][j] );
- }
- fprintf( stderr, "\n" );
- }
-}
-
-void mat4::swap_rows(int i, int j)
-{
- vec4 t;
-
- t = v[i];
- v[i] = v[j];
- v[j] = t;
-}
-
-void mat4::swap_cols(int i, int j)
-{
- float t;
- int k;
-
- for (k=0; k<4; k++)
- {
- t = v[k][i];
- v[k][i] = v[k][j];
- v[k][j] = t;
- }
-}
-
-
-// FRIENDS
-
-mat4 operator-(const mat4 &a)
-{
- return mat4(-a.v[0],-a.v[1],-a.v[2],-a.v[3]);
-}
-
-mat4 operator+(const mat4 &a, const mat4 &b)
-{
- return mat4(
- a.v[0] + b.v[0],
- a.v[1] + b.v[1],
- a.v[2] + b.v[2],
- a.v[3] + b.v[3]);
-}
-
-mat4 operator-(const mat4 &a, const mat4 &b)
-{
- return mat4(
- a.v[0] - b.v[0],
- a.v[1] - b.v[1],
- a.v[2] - b.v[2],
- a.v[3] - b.v[3]);
-}
-
-mat4 operator*(const mat4 &a, const mat4 &b)
-{
- #define ROWCOL(i, j) \
- a.v[i].n[0]*b.v[0][j] + \
- a.v[i].n[1]*b.v[1][j] + \
- a.v[i].n[2]*b.v[2][j] + \
- a.v[i].n[3]*b.v[3][j]
-
- return mat4(
- vec4(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),
- vec4(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),
- vec4(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),
- vec4(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3))
- );
-
- #undef ROWCOL
-}
-
-mat4 operator*(const mat4 &a, float d)
-{
- return mat4(a.v[0]*d, a.v[1]*d, a.v[2]*d, a.v[3]*d);
-}
-
-mat4 operator*(float d, const mat4 &a)
-{
- return a*d;
-}
-
-mat4 operator/(const mat4 &a, float d)
-{
- return mat4(a.v[0]/d, a.v[1]/d, a.v[2]/d, a.v[3]/d);
-}
-
-int operator==(const mat4 &a, const mat4 &b)
-{
- return
- (a.v[0] == b.v[0]) &&
- (a.v[1] == b.v[1]) &&
- (a.v[2] == b.v[2]) &&
- (a.v[3] == b.v[3]);
-}
-
-int operator!=(const mat4 &a, const mat4 &b)
-{
- return !(a == b);
-}
-
-/*ostream& operator << (ostream& s, mat4& m)
-{ return s << m.v[VX] << '\n' << m.v[VY] << '\n' << m.v[VZ] << '\n' << m.v[VW]; }
-
-istream& operator >> (istream& s, mat4& m)
-{
- mat4 m_tmp;
-
- s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ] >> m_tmp[VW];
- if (s)
- m = m_tmp;
- return s;
-}
-*/
-
-void swap(mat4 &a, mat4 &b)
-{
- mat4 tmp(a);
- a = b;
- b = tmp;
-}
-
-/****************************************************************
- * *
- * 2D functions and 3D functions *
- * *
- ****************************************************************/
-
-mat3 identity2D()
-{
- return mat3(
- vec3(1.0, 0.0, 0.0),
- vec3(0.0, 1.0, 0.0),
- vec3(0.0, 0.0, 1.0));
-}
-
-mat3 translation2D(const vec2 &v)
-{
- return mat3(
- vec3(1.0, 0.0, v[VX]),
- vec3(0.0, 1.0, v[VY]),
- vec3(0.0, 0.0, 1.0));
-}
-
-mat3 rotation2D(const vec2 &Center, float angleDeg)
-{
- float angleRad = (float) (angleDeg * radians);
- float c = (float) cos(angleRad);
- float s = (float) sin(angleRad);
-
- return mat3(
- vec3(c, -s, Center[VX] * (1.0f-c) + Center[VY] * s),
- vec3(s, c, Center[VY] * (1.0f-c) - Center[VX] * s),
- vec3(0.0, 0.0, 1.0));
-}
-
-mat3 scaling2D(const vec2 &scaleVector)
-{
- return mat3(
- vec3(scaleVector[VX], 0.0, 0.0),
- vec3(0.0, scaleVector[VY], 0.0),
- vec3(0.0, 0.0, 1.0));
-}
-
-mat4 identity3D()
-{
- return mat4(
- vec4(1.0, 0.0, 0.0, 0.0),
- vec4(0.0, 1.0, 0.0, 0.0),
- vec4(0.0, 0.0, 1.0, 0.0),
- vec4(0.0, 0.0, 0.0, 1.0));
-}
-
-mat4 translation3D(const vec3 &v)
-{
- return mat4(
- vec4(1.0, 0.0, 0.0, v[VX]),
- vec4(0.0, 1.0, 0.0, v[VY]),
- vec4(0.0, 0.0, 1.0, v[VZ]),
- vec4(0.0, 0.0, 0.0, 1.0));
-}
-
-mat4 rotation3D(const vec3 &Axis, float angleDeg)
-{
- float angleRad = (float) (angleDeg * radians);
- float c = (float) cos(angleRad);
- float s = (float) sin(angleRad);
- float t = 1.0f - c;
-
- vec3 axis(Axis);
- axis.normalize();
-
- return mat4(
- vec4(t * axis[VX] * axis[VX] + c,
- t * axis[VX] * axis[VY] - s * axis[VZ],
- t * axis[VX] * axis[VZ] + s * axis[VY],
- 0.0),
- vec4(t * axis[VX] * axis[VY] + s * axis[VZ],
- t * axis[VY] * axis[VY] + c,
- t * axis[VY] * axis[VZ] - s * axis[VX],
- 0.0),
- vec4(t * axis[VX] * axis[VZ] - s * axis[VY],
- t * axis[VY] * axis[VZ] + s * axis[VX],
- t * axis[VZ] * axis[VZ] + c,
- 0.0),
- vec4(0.0, 0.0, 0.0, 1.0));
-}
-
-mat4 rotation3Drad(const vec3 &Axis, float angleRad)
-{
- float c = (float) cos(angleRad);
- float s = (float) sin(angleRad);
- float t = 1.0f - c;
-
- vec3 axis(Axis);
- axis.normalize();
-
- return mat4(
- vec4(t * axis[VX] * axis[VX] + c,
- t * axis[VX] * axis[VY] - s * axis[VZ],
- t * axis[VX] * axis[VZ] + s * axis[VY],
- 0.0),
- vec4(t * axis[VX] * axis[VY] + s * axis[VZ],
- t * axis[VY] * axis[VY] + c,
- t * axis[VY] * axis[VZ] - s * axis[VX],
- 0.0),
- vec4(t * axis[VX] * axis[VZ] - s * axis[VY],
- t * axis[VY] * axis[VZ] + s * axis[VX],
- t * axis[VZ] * axis[VZ] + c,
- 0.0),
- vec4(0.0, 0.0, 0.0, 1.0));
-}
-
-mat4 scaling3D(const vec3 &scaleVector)
-{
- return mat4(
- vec4(scaleVector[VX], 0.0, 0.0, 0.0),
- vec4(0.0, scaleVector[VY], 0.0, 0.0),
- vec4(0.0, 0.0, scaleVector[VZ], 0.0),
- vec4(0.0, 0.0, 0.0, 1.0));
-}
-
-mat4 perspective3D(float d)
-{
- return mat4(
- vec4(1.0f, 0.0f, 0.0f, 0.0f),
- vec4(0.0f, 1.0f, 0.0f, 0.0f),
- vec4(0.0f, 0.0f, 1.0f, 0.0f),
- vec4(0.0f, 0.0f, 1.0f/d, 0.0f));
-}
diff --git a/graphics/asymptote/algebra3.h b/graphics/asymptote/algebra3.h
deleted file mode 100644
index 7043ff3c75..0000000000
--- a/graphics/asymptote/algebra3.h
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
-
- algebra3.cc, algebra3.h - C++ Vector and Matrix Algebra routines
-
- GLUI User Interface Toolkit (LGPL)
- Copyright (c) 1998 Paul Rademacher
-
- WWW: http://sourceforge.net/projects/glui/
- Forums: http://sourceforge.net/forum/?group_id=92496
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-/**************************************************************************
-
- There are three vector classes and two matrix classes: vec2, vec3,
- vec4, mat3, and mat4.
-
- All the standard arithmetic operations are defined, with '*'
- for dot product of two vectors and multiplication of two matrices,
- and '^' for cross product of two vectors.
-
- Additional functions include length(), normalize(), homogenize for
- vectors, and print(), set(), apply() for all classes.
-
- There is a function transpose() for matrices, but note that it
- does not actually change the matrix,
-
- When multiplied with a matrix, a vector is treated as a row vector
- if it precedes the matrix (v*M), and as a column vector if it
- follows the matrix (M*v).
-
- Matrices are stored in row-major form.
-
- A vector of one dimension (2d, 3d, or 4d) can be cast to a vector
- of a higher or lower dimension. If casting to a higher dimension,
- the new component is set by default to 1.0, unless a value is
- specified:
- vec3 a(1.0, 2.0, 3.0 );
- vec4 b( a, 4.0 ); // now b == {1.0, 2.0, 3.0, 4.0};
- When casting to a lower dimension, the vector is homogenized in
- the lower dimension. E.g., if a 4d {X,Y,Z,W} is cast to 3d, the
- resulting vector is {X/W, Y/W, Z/W}. It is up to the user to
- insure the fourth component is not zero before casting.
-
- There are also the following function for building matrices:
- identity2D(), translation2D(), rotation2D(),
- scaling2D(), identity3D(), translation3D(),
- rotation3D(), rotation3Drad(), scaling3D(),
- perspective3D()
-
- NOTE: When compiling for Windows, include this file first, to avoid
- certain name conflicts
-
- ---------------------------------------------------------------------
-
- Author: Jean-Francois DOUEg
- Revised: Paul Rademacher
- Version 3.2 - Feb 1998
- Revised: Nigel Stewart (GLUI Code Cleaning)
-
-**************************************************************************/
-
-#ifndef GLUI_ALGEBRA3_H
-#define GLUI_ALGEBRA3_H
-
-#include <cmath>
-#include <cstdio>
-#include <cstdlib>
-
-#ifndef MAX
-#define MAX(a,b) ((a)>(b) ? (a) : (b))
-#define MIN(a,b) ((a)<(b) ? (a) : (b))
-#endif
-
-#define FUDGE .00001
-
-// this line defines a new type: pointer to a function which returns a
-// float and takes as argument a float
-typedef float (*V_FCT_PTR)(float);
-
-class vec2;
-class vec3;
-class vec4;
-class mat3;
-class mat4;
-
-enum axes {VX, VY, VZ, VW};
-/*
-enum planes {PA, PB, PC, PD};
-enum colors {RED, GREEN, BLUE, ALPHA};
-enum phong {KA, KD, KS, ES};
-*/
-
-/****************************************************************
- * *
- * 2D Vector *
- * *
- ****************************************************************/
-
-class vec2
-{
- friend class vec3;
-
-protected:
-
- float n[2];
-
-public:
-
- // Constructors
-
- vec2();
- vec2(float x, float y);
- vec2(const vec2 &v); // copy constructor
- vec2(const vec3 &v); // cast v3 to v2
- vec2(const vec3 &v, int dropAxis); // cast v3 to v2
-
- // Assignment operators
-
- vec2 &operator = (const vec2 &v); // assignment of a vec2
- vec2 &operator += (const vec2 &v); // incrementation by a vec2
- vec2 &operator -= (const vec2 &v); // decrementation by a vec2
- vec2 &operator *= (float d); // multiplication by a constant
- vec2 &operator /= (float d); // division by a constant
-
- // special functions
-
- float length() const; // length of a vec2
- float length2() const; // squared length of a vec2
- vec2 &normalize(); // normalize a vec2
- vec2 &apply(V_FCT_PTR fct); // apply a func. to each component
- void set(float x, float y); // set vector
-
- float &operator [] (int i); // indexing
- const float &operator [] (int i) const; // indexing
-
- // friends
-
- friend vec2 operator - (const vec2 &v); // -v1
- friend vec2 operator + (const vec2 &a, const vec2 &b); // v1 + v2
- friend vec2 operator - (const vec2 &a, const vec2 &b); // v1 - v2
- friend vec2 operator * (const vec2 &a, float d); // v1 * 3.0
- friend vec2 operator * (float d, const vec2 &a); // 3.0 * v1
- friend vec2 operator * (const mat3 &a, const vec2 &v); // M . v
- friend vec2 operator * (const vec2 &v, const mat3 &a); // v . M
- friend float operator * (const vec2 &a, const vec2 &b); // dot product
- friend vec2 operator / (const vec2 &a, float d); // v1 / 3.0
- friend vec3 operator ^ (const vec2 &a, const vec2 &b); // cross product
- friend int operator == (const vec2 &a, const vec2 &b); // v1 == v2 ?
- friend int operator != (const vec2 &a, const vec2 &b); // v1 != v2 ?
- //friend ostream& operator << (ostream& s, vec2& v); // output to stream
- //friend istream& operator >> (istream& s, vec2& v); // input from strm.
- friend void swap(vec2 &a, vec2 &b); // swap v1 & v2
- friend vec2 min_vec(const vec2 &a, const vec2 &b); // min(v1, v2)
- friend vec2 max_vec(const vec2 &a, const vec2 &b); // max(v1, v2)
- friend vec2 prod (const vec2 &a, const vec2 &b); // term by term *
-};
-
-/****************************************************************
- * *
- * 3D Vector *
- * *
- ****************************************************************/
-
-class vec3
-{
- friend class vec2;
- friend class vec4;
- friend class mat3;
-
-protected:
-
- float n[3];
-
-public:
-
- // Constructors
-
- vec3();
- vec3(float x, float y, float z);
- vec3(const vec3 &v); // copy constructor
- vec3(const vec2 &v); // cast v2 to v3
- vec3(const vec2 &v, float d); // cast v2 to v3
- vec3(const vec4 &v); // cast v4 to v3
- vec3(const vec4 &v, int dropAxis); // cast v4 to v3
-
- // Assignment operators
-
- vec3 &operator = (const vec3 &v); // assignment of a vec3
- vec3 &operator += (const vec3 &v); // incrementation by a vec3
- vec3 &operator -= (const vec3 &v); // decrementation by a vec3
- vec3 &operator *= (float d); // multiplication by a constant
- vec3 &operator /= (float d); // division by a constant
-
- // special functions
-
- float length() const; // length of a vec3
- float length2() const; // squared length of a vec3
- vec3& normalize(); // normalize a vec3
- vec3& homogenize(); // homogenize (div by Z)
- vec3& apply(V_FCT_PTR fct); // apply a func. to each component
- void set(float x, float y, float z); // set vector
-
- void print(FILE *file, const char *name) const; // print vector to a file
-
-
- float &operator [] (int i); // indexing
- const float &operator [] (int i) const; // indexing
-
- // friends
-
- friend vec3 operator - (const vec3 &v); // -v1
- friend vec3 operator + (const vec3 &a, const vec3 &b); // v1 + v2
- friend vec3 operator - (const vec3 &a, const vec3 &b); // v1 - v2
- friend vec3 operator * (const vec3 &a, float d); // v1 * 3.0
- friend vec3 operator * (float d, const vec3 &a); // 3.0 * v1
- friend vec3 operator * (const mat4 &a, const vec3 &v); // M . v
- friend vec3 operator * (const vec3 &v, const mat4 &a); // v . M
- friend float operator * (const vec3 &a, const vec3 &b); // dot product
- friend vec3 operator / (const vec3 &a, float d); // v1 / 3.0
- friend vec3 operator ^ (const vec3 &a, const vec3 &b); // cross product
- friend int operator == (const vec3 &a, const vec3 &b); // v1 == v2 ?
- friend int operator != (const vec3 &a, const vec3 &b); // v1 != v2 ?
- //friend ostream& operator << (ostream& s, vec3& v); // output to stream
- //friend istream& operator >> (istream& s, vec3& v); // input from strm.
- friend void swap(vec3 &a, vec3 &b); // swap v1 & v2
- friend vec3 min_vec(const vec3 &a, const vec3 &b); // min(v1, v2)
- friend vec3 max_vec(const vec3 &a, const vec3 &b); // max(v1, v2)
- friend vec3 prod(const vec3 &a, const vec3 &b); // term by term *
-
- // necessary friend declarations
-
- friend vec2 operator * (const mat3 &a, const vec2 &v); // linear transform
- friend vec3 operator * (const mat3 &a, const vec3 &v); // linear transform
- friend mat3 operator * (const mat3 &a, const mat3 &b); // matrix 3 product
-};
-
-/****************************************************************
- * *
- * 4D Vector *
- * *
- ****************************************************************/
-
-class vec4
-{
- friend class vec3;
- friend class mat4;
-
-protected:
-
- float n[4];
-
-public:
-
- // Constructors
-
- vec4();
- vec4(float x, float y, float z, float w);
- vec4(const vec4 &v); // copy constructor
- vec4(const vec3 &v); // cast vec3 to vec4
- vec4(const vec3 &v, float d); // cast vec3 to vec4
-
- // Assignment operators
-
- vec4 &operator = (const vec4 &v); // assignment of a vec4
- vec4 &operator += (const vec4 &v); // incrementation by a vec4
- vec4 &operator -= (const vec4 &v); // decrementation by a vec4
- vec4 &operator *= (float d); // multiplication by a constant
- vec4 &operator /= (float d); // division by a constant
-
- // special functions
-
- float length() const; // length of a vec4
- float length2() const; // squared length of a vec4
- vec4 &normalize(); // normalize a vec4
- vec4 &apply(V_FCT_PTR fct); // apply a func. to each component
- vec4 &homogenize();
-
- void print(FILE *file, const char *name) const; // print vector to a file
-
- void set(float x, float y, float z, float a);
-
- float &operator [] (int i); // indexing
- const float &operator [] (int i) const; // indexing
-
- // friends
-
- friend vec4 operator - (const vec4 &v); // -v1
- friend vec4 operator + (const vec4 &a, const vec4 &b); // v1 + v2
- friend vec4 operator - (const vec4 &a, const vec4 &b); // v1 - v2
- friend vec4 operator * (const vec4 &a, float d); // v1 * 3.0
- friend vec4 operator * (float d, const vec4 &a); // 3.0 * v1
- friend vec4 operator * (const mat4 &a, const vec4 &v); // M . v
- friend vec4 operator * (const vec4 &v, const mat4 &a); // v . M
- friend float operator * (const vec4 &a, const vec4 &b); // dot product
- friend vec4 operator / (const vec4 &a, float d); // v1 / 3.0
- friend int operator == (const vec4 &a, const vec4 &b); // v1 == v2 ?
- friend int operator != (const vec4 &a, const vec4 &b); // v1 != v2 ?
- //friend ostream& operator << (ostream& s, vec4& v); // output to stream
- //friend istream& operator >> (istream& s, vec4& v); // input from strm.
- friend void swap(vec4 &a, vec4 &b); // swap v1 & v2
- friend vec4 min_vec(const vec4 &a, const vec4 &b); // min(v1, v2)
- friend vec4 max_vec(const vec4 &a, const vec4 &b); // max(v1, v2)
- friend vec4 prod (const vec4 &a, const vec4 &b); // term by term *
-
- // necessary friend declarations
-
- friend vec3 operator * (const mat4 &a, const vec3 &v); // linear transform
- friend mat4 operator * (const mat4 &a, const mat4 &b); // matrix 4 product
-};
-
-/****************************************************************
- * *
- * 3x3 Matrix *
- * *
- ****************************************************************/
-
-class mat3
-{
-protected:
-
- vec3 v[3];
-
-public:
-
- // Constructors
-
- mat3();
- mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2);
- mat3(const mat3 &m);
-
- // Assignment operators
-
- mat3 &operator = (const mat3 &m); // assignment of a mat3
- mat3 &operator += (const mat3 &m); // incrementation by a mat3
- mat3 &operator -= (const mat3 &m); // decrementation by a mat3
- mat3 &operator *= (float d); // multiplication by a constant
- mat3 &operator /= (float d); // division by a constant
-
- // special functions
-
- mat3 transpose() const; // transpose
- mat3 inverse() const; // inverse
- mat3 &apply(V_FCT_PTR fct); // apply a func. to each element
-
- void print(FILE *file, const char *name ) const; // print matrix to a file
-
- void set(const vec3 &v0, const vec3 &v1, const vec3 &v2);
-
- vec3 &operator [] (int i); // indexing
- const vec3 &operator [] (int i) const; // indexing
-
- // friends
-
- friend mat3 operator - (const mat3 &a); // -m1
- friend mat3 operator + (const mat3 &a, const mat3 &b); // m1 + m2
- friend mat3 operator - (const mat3 &a, const mat3 &b); // m1 - m2
- friend mat3 operator * (const mat3 &a, const mat3 &b); // m1 * m2
- friend mat3 operator * (const mat3 &a, float d); // m1 * 3.0
- friend mat3 operator * (float d, const mat3 &a); // 3.0 * m1
- friend mat3 operator / (const mat3 &a, float d); // m1 / 3.0
- friend int operator == (const mat3 &a, const mat3 &b); // m1 == m2 ?
- friend int operator != (const mat3 &a, const mat3 &b); // m1 != m2 ?
- //friend ostream& operator << (ostream& s, mat3& m); // output to stream
- //friend istream& operator >> (istream& s, mat3& m); // input from strm.
- friend void swap(mat3 &a, mat3 &b); // swap m1 & m2
-
- // necessary friend declarations
-
- friend vec3 operator * (const mat3 &a, const vec3 &v); // linear transform
- friend vec2 operator * (const mat3 &a, const vec2 &v); // linear transform
-};
-
-/****************************************************************
- * *
- * 4x4 Matrix *
- * *
- ****************************************************************/
-
-class mat4
-{
-protected:
-
- vec4 v[4];
-
-public:
-
- // Constructors
-
- mat4();
- mat4(const vec4 &v0, const vec4 &v1, const vec4 &v2, const vec4 &v3);
- mat4(const mat4 &m);
- mat4(float a00, float a01, float a02, float a03,
- float a10, float a11, float a12, float a13,
- float a20, float a21, float a22, float a23,
- float a30, float a31, float a32, float a33 );
-
-
- // Assignment operators
-
- mat4 &operator = (const mat4 &m); // assignment of a mat4
- mat4 &operator += (const mat4 &m); // incrementation by a mat4
- mat4 &operator -= (const mat4 &m); // decrementation by a mat4
- mat4 &operator *= (float d); // multiplication by a constant
- mat4 &operator /= (float d); // division by a constant
-
- // special functions
-
- mat4 transpose() const; // transpose
- mat4 inverse() const; // inverse
- mat4 &apply(V_FCT_PTR fct); // apply a func. to each element
-
- void print(FILE *file, const char *name) const; // print matrix to a file
-
- vec4 &operator [] (int i); // indexing
- const vec4 &operator [] (int i) const; // indexing
-
- void swap_rows(int i, int j); // swap rows i and j
- void swap_cols(int i, int j); // swap cols i and j
-
- // friends
-
- friend mat4 operator - (const mat4 &a); // -m1
- friend mat4 operator + (const mat4 &a, const mat4 &b); // m1 + m2
- friend mat4 operator - (const mat4 &a, const mat4 &b); // m1 - m2
- friend mat4 operator * (const mat4 &a, const mat4 &b); // m1 * m2
- friend mat4 operator * (const mat4 &a, float d); // m1 * 4.0
- friend mat4 operator * (float d, const mat4 &a); // 4.0 * m1
- friend mat4 operator / (const mat4 &a, float d); // m1 / 3.0
- friend int operator == (const mat4 &a, const mat4 &b); // m1 == m2 ?
- friend int operator != (const mat4 &a, const mat4 &b); // m1 != m2 ?
- //friend ostream& operator << (ostream& s, mat4& m); // output to stream
- //friend istream& operator >> (istream& s, mat4& m); // input from strm.
- friend void swap(mat4 &a, mat4 &b); // swap m1 & m2
-
- // necessary friend declarations
-
- friend vec4 operator * (const mat4 &a, const vec4 &v); // linear transform
- //friend vec4 operator * (const vec4& v, const mat4& a); // linear transform
- friend vec3 operator * (const mat4 &a, const vec3 &v); // linear transform
- friend vec3 operator * (const vec3 &v, const mat4 &a); // linear transform
-};
-
-/****************************************************************
- * *
- * 2D functions and 3D functions *
- * *
- ****************************************************************/
-
-mat3 identity2D (); // identity 2D
-mat3 translation2D(const vec2 &v); // translation 2D
-mat3 rotation2D (const vec2 &Center, float angleDeg); // rotation 2D
-mat3 scaling2D (const vec2 &scaleVector); // scaling 2D
-mat4 identity3D (); // identity 3D
-mat4 translation3D(const vec3 &v); // translation 3D
-mat4 rotation3D (const vec3 &Axis, float angleDeg); // rotation 3D
-mat4 rotation3Drad(const vec3 &Axis, float angleRad); // rotation 3D
-mat4 scaling3D (const vec3 &scaleVector); // scaling 3D
-mat4 perspective3D(float d); // perspective 3D
-
-vec3 operator * (const vec3 &v, const mat3 &a);
-vec2 operator * (const vec2 &v, const mat3 &a);
-vec3 operator * (const vec3 &v, const mat4 &a);
-vec4 operator * (const vec4 &v, const mat4 &a);
-
-#endif
diff --git a/graphics/asymptote/arcball.cc b/graphics/asymptote/arcball.cc
deleted file mode 100644
index 358195597a..0000000000
--- a/graphics/asymptote/arcball.cc
+++ /dev/null
@@ -1,237 +0,0 @@
-/**********************************************************************
-
- arcball.cc
-
-
- --------------------------------------------------
-
- GLUI User Interface Toolkit (LGPL)
- Copyright (c) 1998 Paul Rademacher
- Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
- Oct 2003, Nigel Stewart - GLUI Code Cleaning
-
- WWW: http://sourceforge.net/projects/glui/
- Forums: http://sourceforge.net/forum/?group_id=92496
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-**********************************************************************/
-
-#include "arcball.h"
-
-#include <cstdio>
-
-
-/**************************************** Arcball::Arcball() ****/
-/* Default (void) constructor for Arcball */
-
-Arcball::Arcball()
-{
- rot_ptr = &rot;
- init();
-}
-
-/**************************************** Arcball::Arcball() ****/
-/* Takes as argument a mat4 to use instead of the internal rot */
-
-Arcball::Arcball(mat4 *mtx)
-{
- rot_ptr = mtx;
-}
-
-
-/**************************************** Arcball::Arcball() ****/
-/* A constructor that accepts the screen center and arcball radius*/
-
-Arcball::Arcball(const vec2 &_center, float _radius)
-{
- rot_ptr = &rot;
- init();
- set_params(_center, _radius);
-}
-
-
-/************************************** Arcball::set_params() ****/
-
-void Arcball::set_params(const vec2 &_center, float _radius)
-{
- center = _center;
- radius = _radius;
-}
-
-/*************************************** Arcball::init() **********/
-
-void Arcball::init()
-{
- center.set( 0.0, 0.0 );
- radius = 1.0;
- q_now = quat_identity();
- *rot_ptr = identity3D();
- q_increment = quat_identity();
- rot_increment = identity3D();
- is_mouse_down = false;
- is_spinning = false;
- damp_factor = 0.0;
- zero_increment = true;
-}
-
-/*********************************** Arcball::mouse_to_sphere() ****/
-
-vec3 Arcball::mouse_to_sphere(const vec2 &p)
-{
- float mag;
- vec2 v2 = (p - center) / radius;
- vec3 v3( v2[0], v2[1], 0.0 );
-
- mag = v2*v2;
-
- if ( mag > 1.0 )
- v3.normalize();
- else
- v3[VZ] = (float) sqrt( 1.0 - mag );
-
- /* Now we add constraints - X takes precedence over Y */
- if ( constraint_x )
- {
- v3 = constrain_vector( v3, vec3( 1.0, 0.0, 0.0 ));
- }
- else if ( constraint_y )
- {
- v3 = constrain_vector( v3, vec3( 0.0, 1.0, 0.0 ));
- }
-
- return v3;
-}
-
-
-/************************************ Arcball::constrain_vector() ****/
-
-vec3 Arcball::constrain_vector(const vec3 &vector, const vec3 &axis)
-{
- return (vector-(vector*axis)*axis).normalize();
-}
-
-/************************************ Arcball::mouse_down() **********/
-
-void Arcball::mouse_down(int x, int y)
-{
- down_pt.set( (float)x, (float) y );
- is_mouse_down = true;
-
- q_increment = quat_identity();
- rot_increment = identity3D();
- zero_increment = true;
-}
-
-
-/************************************ Arcball::mouse_up() **********/
-
-void Arcball::mouse_up()
-{
- q_now = q_drag * q_now;
- is_mouse_down = false;
-}
-
-
-/********************************** Arcball::mouse_motion() **********/
-
-void Arcball::mouse_motion(int x, int y, int shift, int ctrl, int alt)
-{
- /* Set the X constraint if CONTROL key is pressed, Y if ALT key */
- set_constraints( ctrl != 0, alt != 0 );
-
- vec2 new_pt( (float)x, (float) y );
- vec3 v0 = mouse_to_sphere( down_pt );
- vec3 v1 = mouse_to_sphere( new_pt );
-
- vec3 cross = v0^v1;
-
- q_drag.set( cross, v0 * v1 );
-
- // *rot_ptr = (q_drag * q_now).to_mat4();
- mat4 temp = q_drag.to_mat4();
- *rot_ptr = *rot_ptr * temp;
-
- down_pt = new_pt;
-
- /* We keep a copy of the current incremental rotation (= q_drag) */
- q_increment = q_drag;
- rot_increment = q_increment.to_mat4();
-
- set_constraints(false, false);
-
- if ( q_increment.s < .999999 )
- {
- is_spinning = true;
- zero_increment = false;
- }
- else
- {
- is_spinning = false;
- zero_increment = true;
- }
-}
-
-
-/********************************** Arcball::mouse_motion() **********/
-
-void Arcball::mouse_motion(int x, int y)
-{
- mouse_motion(x, y, 0, 0, 0);
-}
-
-
-/***************************** Arcball::set_constraints() **********/
-
-void Arcball::set_constraints(bool _constraint_x, bool _constraint_y)
-{
- constraint_x = _constraint_x;
- constraint_y = _constraint_y;
-}
-
-/***************************** Arcball::idle() *********************/
-
-void Arcball::idle()
-{
- if (is_mouse_down)
- {
- is_spinning = false;
- zero_increment = true;
- }
-
- if (damp_factor < 1.0f)
- q_increment.scale_angle(1.0f - damp_factor);
-
- rot_increment = q_increment.to_mat4();
-
- if (q_increment.s >= .999999f)
- {
- is_spinning = false;
- zero_increment = true;
- }
-}
-
-
-/************************ Arcball::set_damping() *********************/
-
-void Arcball::set_damping(float d)
-{
- damp_factor = d;
-}
-
-
-
-
-
diff --git a/graphics/asymptote/arcball.h b/graphics/asymptote/arcball.h
deleted file mode 100644
index 58bc3a8c6a..0000000000
--- a/graphics/asymptote/arcball.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/**********************************************************************
-
- arcball.h
-
- GLUI User Interface Toolkit (LGPL)
- Copyright (c) 1998 Paul Rademacher
- Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
- Oct 2003, Nigel Stewart - GLUI Code Cleaning
-
-
- WWW: http://sourceforge.net/projects/glui/
- Forums: http://sourceforge.net/forum/?group_id=92496
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------
-
- A C++ class that implements the Arcball, as described by Ken
- Shoemake in Graphics Gems IV.
- This class takes as input mouse events (mouse down, mouse drag,
- mouse up), and creates the appropriate quaternions and 4x4 matrices
- to represent the rotation given by the mouse.
-
- This class is used as follows:
- - initialize [either in the constructor or with set_params()], the
- center position (x,y) of the arcball on the screen, and the radius
- - on mouse down, call mouse_down(x,y) with the mouse position
- - as the mouse is dragged, repeatedly call mouse_motion() with the
- current x and y positions. One can optionally pass in the current
- state of the SHIFT, ALT, and CONTROL keys (passing zero if keys
- are not pressed, non-zero otherwise), which constrains
- the rotation to certain axes (X for CONTROL, Y for ALT).
- - when the mouse button is released, call mouse_up()
-
- Axis constraints can also be explicitly set with the
- set_constraints() function.
-
- The current rotation is stored in the 4x4 float matrix 'rot'.
- It is also stored in the quaternion 'q_now'.
-
-**********************************************************************/
-
-#ifndef GLUI_ARCBALL_H
-#define GLUI_ARCBALL_H
-
-#include "algebra3.h"
-#include "quaternion.h"
-
-class Arcball
-{
-public:
- Arcball();
- Arcball(mat4 *mtx);
- Arcball(const vec2 &center, float radius);
-
- void set_damping(float d);
- void idle();
- void mouse_down(int x, int y);
- void mouse_up();
- void mouse_motion(int x, int y, int shift, int ctrl, int alt);
- void mouse_motion(int x, int y);
- void set_constraints(bool constrain_x, bool constrain_y);
- void set_params(const vec2 &center, float radius);
- void init();
-
- vec3 constrain_vector(const vec3 &vector, const vec3 &axis);
- vec3 mouse_to_sphere(const vec2 &p);
-
- //public:
- int is_mouse_down; /* true for down, false for up */
- int is_spinning;
- quat q_now, q_down, q_drag, q_increment;
- vec2 down_pt;
- mat4 rot, rot_increment;
- mat4 *rot_ptr;
-
- bool constraint_x, constraint_y;
- vec2 center;
- float radius, damp_factor;
- int zero_increment;
-};
-
-#endif
diff --git a/graphics/asymptote/asy-keywords.el b/graphics/asymptote/asy-keywords.el
index 5cf87e595b..c54382a2b5 100644
--- a/graphics/asymptote/asy-keywords.el
+++ b/graphics/asymptote/asy-keywords.el
@@ -2,7 +2,7 @@
;; This file is automatically generated by asy-list.pl.
;; Changes will be overwritten.
;;
-(defvar asy-keywords-version "2.53")
+(defvar asy-keywords-version "2.54")
(defvar asy-keyword-name '(
and controls tension atleast curl if else while for do return break continue struct typedef new access import unravel from include quote static public private restricted this explicit true false null cycle newframe operator ))
diff --git a/graphics/asymptote/asy.list b/graphics/asymptote/asy.list
index 566f365a90..1394da858e 100644
--- a/graphics/asymptote/asy.list
+++ b/graphics/asymptote/asy.list
@@ -294,8 +294,8 @@ string getc(file f);
bool debugging;
void shipout(string prefix=<default>, frame f, string format=<default>, bool wait=<default>, bool view=<default>, string options=<default>, string script=<default>, light light=<default>, projection P=<default>, transform t=<default>);
void shipout(string prefix=<default>, picture pic=<default>, frame orientation(frame)=<default>, string format=<default>, bool wait=<default>, bool view=<default>, string options=<default>, string script=<default>, light light=<default>, projection P=<default>);
-void shipout3(string prefix, frame f, string format=<default>, real width, real height, real angle, real zoom, triple m, triple m, pair shift, real[][] t, real[] background, triple[] lights, real[][] diffuse, real[][] specular, bool view=<default>);
-void shipout3(string prefix, frame f);
+void shipout3(string prefix, frame f, string format=<default>, real width, real height, real angle, real zoom, triple m, triple m, pair shift, pair margin, real[][] t, real[] background, triple[] lights, real[][] diffuse, real[][] specular, bool view=<default>);
+void shipout3(string prefix, frame f, string format=<default>);
string getstring(string name=<default>, string default=<default>, string prompt=<default>, bool store=<default>);
int debuggerlines;
frame bbox(picture pic=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>);
@@ -403,8 +403,8 @@ real[] fabs(real[] a);
bool labels(frame f);
light light(pen diffuse=<default>, pen specular=<default>, pen background=<default>, real x, real y, real z);
light light(pen diffuse=<default>, pen specular=<default>, pen background=<default>, real specularfactor=<default> ... triple[] position);
-light light(explicit light light);
light light(pen[] diffuse, pen[] specular=<default>, pen background=<default>, real specularfactor=<default>, triple[] position);
+light light(explicit light light);
real remainder(real x, real y);
int byte(real x);
real camerafactor;
@@ -705,13 +705,13 @@ void add(picture dest=<default>, frame src, pair position, pair align, bool grou
void add(frame dest, frame src, pair position, pair align, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(picture src, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(picture pic=<default>, void d(frame f, transform t), bool exact=<default>);
+void add(picture pic=<default>, void d(frame f, real[][] t, picture pic, projection P), bool exact=<default>);
void add(picture pic=<default>, void d(picture, real[][]), bool exact=<default>);
void add(picture dest, picture src, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(picture dest, picture src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(picture dest=<default>, object F, pair position=<default>, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(frame dest, frame src, filltype filltype, bool above=<default>);
void add(frame dest, frame src, bool group, filltype filltype=<default>, bool above=<default>);
-void add(picture pic=<default>, void d(frame f, real[][] t, picture pic, projection P), bool exact=<default>);
void add(frame dest, frame src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(picture dest=<default>, frame src, pair position=<default>, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(picture pic=<default>, Label L);
@@ -974,28 +974,28 @@ bool alias(pair[][] a, pair[][] b);
bool alias(guide[] a, guide[] b);
bool alias(marginT a, marginT b);
bool alias(coord[] a, coord[] b);
-bool alias(autoscaleT a, autoscaleT b);
+bool alias(light a, light b);
bool alias(align a, align b);
bool alias(Legend[] a, Legend[] b);
bool alias(processtime a, processtime b);
bool alias(pair[] a, pair[] b);
bool alias(scaling a, scaling b);
bool alias(coord a, coord b);
-bool alias(transformation a, transformation b);
+bool alias(scaleT a, scaleT b);
bool alias(node a, node b);
bool alias(Label a, Label b);
bool alias(int[] a, int[] b);
bool alias(string[][] a, string[][] b);
bool alias(slice a, slice b);
bool alias(freezableBounds a, freezableBounds b);
-bool alias(projection a, projection b);
-bool alias(coords3 a, coords3 b);
+bool alias(transformation a, transformation b);
+bool alias(autoscaleT a, autoscaleT b);
bool alias(object[] a, object[] b);
bool alias(marker a, marker b);
bool alias(real[][] a, real[][] b);
bool alias(bool3 a, bool3 b);
bool alias(bool3[] a, bool3[] b);
-bool alias(light a, light b);
+bool alias(coords3 a, coords3 b);
bool alias(ScaleT a, ScaleT b);
bool alias(side a, side b);
bool alias(cputime a, cputime b);
@@ -1012,7 +1012,7 @@ bool alias(pen[][] a, pen[][] b);
bool alias(filltype a, filltype b);
bool alias(simplex a, simplex b);
bool alias(coord[] a, coord[] b);
-bool alias(scaleT a, scaleT b);
+bool alias(projection a, projection b);
bool alias(Label[] a, Label[] b);
bool alias(arrowhead a, arrowhead b);
bool alias(path[] a, path[] b);
@@ -1390,16 +1390,16 @@ pen operator init();
frame operator init();
file operator init();
marginT operator init();
-autoscaleT operator init();
+light operator init();
align operator init();
processtime operator init();
filltype operator init();
simplex operator init();
-scaleT operator init();
+projection operator init();
arrowhead operator init();
slice operator init();
-projection operator init();
-coords3 operator init();
+transformation operator init();
+autoscaleT operator init();
marker operator init();
hsv operator init();
coords2 operator init();
@@ -1410,7 +1410,7 @@ pairOrTriple operator init();
object operator init();
scaling operator init();
coord operator init();
-transformation operator init();
+scaleT operator init();
node operator init();
Label operator init();
coord operator init();
@@ -1418,7 +1418,7 @@ bounds operator init();
Legend operator init();
position operator init();
bool3 operator init();
-light operator init();
+coords3 operator init();
ScaleT operator init();
side operator init();
cputime operator init();
@@ -1594,7 +1594,7 @@ bool operator ==(file a, file b);
bool operator ==(path a, path b);
bool operator ==(path3 a, path3 b);
bool operator ==(bool3 a, bool3 b);
-bool operator ==(light a, light b);
+bool operator ==(coords3 a, coords3 b);
bool operator ==(ScaleT a, ScaleT b);
bool operator ==(side a, side b);
bool operator ==(cputime a, cputime b);
@@ -1604,7 +1604,7 @@ bool operator ==(pairOrTriple a, pairOrTriple b);
bool operator ==(object a, object b);
bool operator ==(filltype a, filltype b);
bool operator ==(simplex a, simplex b);
-bool operator ==(scaleT a, scaleT b);
+bool operator ==(projection a, projection b);
bool operator ==(arrowhead a, arrowhead b);
bool operator ==(coord a, coord b);
bool operator ==(bounds a, bounds b);
@@ -1615,19 +1615,19 @@ bool operator ==(coords2 a, coords2 b);
bool operator ==(picture a, picture b);
bool operator ==(bool3 a, bool b);
bool operator ==(marginT a, marginT b);
-bool operator ==(autoscaleT a, autoscaleT b);
+bool operator ==(light a, light b);
bool operator ==(align a, align b);
bool operator ==(processtime a, processtime b);
bool operator ==(scaling a, scaling b);
bool operator ==(coord a, coord b);
-bool operator ==(transformation a, transformation b);
+bool operator ==(scaleT a, scaleT b);
bool operator ==(node a, node b);
bool operator ==(Label a, Label b);
bool operator ==(bool a, bool3 b);
bool operator ==(slice a, slice b);
bool operator ==(freezableBounds a, freezableBounds b);
-bool operator ==(projection a, projection b);
-bool operator ==(coords3 a, coords3 b);
+bool operator ==(transformation a, transformation b);
+bool operator ==(autoscaleT a, autoscaleT b);
bool operator ==(marker a, marker b);
bool operator !=(bool a, bool b);
bool[] operator !=(bool a, bool[] b);
@@ -1666,7 +1666,7 @@ bool operator !=(file a, file b);
bool operator !=(path a, path b);
bool operator !=(path3 a, path3 b);
bool operator !=(bool3 a, bool3 b);
-bool operator !=(light a, light b);
+bool operator !=(coords3 a, coords3 b);
bool operator !=(ScaleT a, ScaleT b);
bool operator !=(side a, side b);
bool operator !=(cputime a, cputime b);
@@ -1676,7 +1676,7 @@ bool operator !=(pairOrTriple a, pairOrTriple b);
bool operator !=(object a, object b);
bool operator !=(filltype a, filltype b);
bool operator !=(simplex a, simplex b);
-bool operator !=(scaleT a, scaleT b);
+bool operator !=(projection a, projection b);
bool operator !=(arrowhead a, arrowhead b);
bool operator !=(coord a, coord b);
bool operator !=(bounds a, bounds b);
@@ -1687,19 +1687,19 @@ bool operator !=(coords2 a, coords2 b);
bool operator !=(picture a, picture b);
bool operator !=(bool3 a, bool b);
bool operator !=(marginT a, marginT b);
-bool operator !=(autoscaleT a, autoscaleT b);
+bool operator !=(light a, light b);
bool operator !=(align a, align b);
bool operator !=(processtime a, processtime b);
bool operator !=(scaling a, scaling b);
bool operator !=(coord a, coord b);
-bool operator !=(transformation a, transformation b);
+bool operator !=(scaleT a, scaleT b);
bool operator !=(node a, node b);
bool operator !=(Label a, Label b);
bool operator !=(bool a, bool3 b);
bool operator !=(slice a, slice b);
bool operator !=(freezableBounds a, freezableBounds b);
-bool operator !=(projection a, projection b);
-bool operator !=(coords3 a, coords3 b);
+bool operator !=(transformation a, transformation b);
+bool operator !=(autoscaleT a, autoscaleT b);
bool operator !=(marker a, marker b);
bool operator <(int a, int b);
bool[] operator <(int a, int[] b);
@@ -2550,8 +2550,8 @@ line complementary(explicit line l);
line[] complementary(explicit segment s);
arc complementary(arc a);
point ppoint(arc a, real x);
-path fromFocus(conic co, real angle1, real angle2, int n, bool direction);
bool between(point M, point O, point N);
+path fromFocus(conic co, real angle1, real angle2, int n, bool direction);
bool sameside(point M, point N, point O);
bool sameside(point M, point P, line l);
point[] sameside(point M, line l1, line l2);
@@ -2788,11 +2788,11 @@ real degrees(vector v, coordsys R=<default>, bool warn=<default>);
real degrees(line l, coordsys R=<default>);
real degrees(line l1, line l2);
real degrees(arc a);
-real linemargin;
-real linemargin();
segment segment(point A, point B);
segment segment(line l);
segment segment(explicit side side);
+real linemargin;
+real linemargin();
line Oy(coordsys R=<default>);
line Oy;
path fromCenter(conic co, real angle1, real angle2, int n, bool direction);
@@ -2873,10 +2873,10 @@ triangle tangential(triangle t);
triangle pedal(triangle t, point M);
line pedal(side side, point M);
string massformat(string format=<default>, string s, mass M);
-int relativesystem;
triangle cevian(triangle t, point P);
point cevian(side side, point P);
line cevian(vertex V, point P);
+int relativesystem;
void drawline(picture pic=<default>, triangle t, pen p=<default>);
void addMargins(picture pic=<default>, real lmargin=<default>, real bmargin=<default>, real rmargin=<default>, real tmargin=<default>, bool rigid=<default>, bool allObject=<default>);
triangle medial(triangle t);
@@ -3001,8 +3001,8 @@ pair Scale(picture pic=<default>, pair z);
real ScaleX(picture pic=<default>, real x);
real ScaleY(picture pic=<default>, real y);
void xaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
-tickvalues generateticks(int sign, Label F=<default>, string ticklabel(real)=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, real Size=<default>, real size=<default>, transform T, pair side, path g, real limit, pen p, ticklocate locate, int[] divisor, bool opposite);
void yaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
+tickvalues generateticks(int sign, Label F=<default>, string ticklabel(real)=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, real Size=<default>, real size=<default>, transform T, pair side, path g, real limit, pen p, ticklocate locate, int[] divisor, bool opposite);
void xaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>);
void yaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool autorotate=<default>);
void checkconditionlength(int x, int y);
@@ -3542,15 +3542,15 @@ pen titlepen;
real titleskip;
pair dateskip;
pair titlealign;
-pen titlepagepen;
pen authorpen;
+pen titlepagepen;
void titlepage(string title, string author, string institution=<default>, string date=<default>, string url=<default>, bool newslide=<default>);
pair titlepageposition;
pen codepen;
void erasestep(int erasenode);
bool checkposition();
-void setpens(pen red=<default>, pen blue=<default>, pen steppen=<default>);
string cropcode(string s);
+void setpens(pen red=<default>, pen blue=<default>, pen steppen=<default>);
void code(bool center=<default>, string s, pen p=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>);
transform tinv;
pair urlskip;
@@ -3727,8 +3727,8 @@ pen ForestGreen;
pen BurntOrange;
pen Tan;
pen Aquamarine;
-pen Brown;
pen Lavender;
+pen Brown;
pen RubineRed;
pen TealBlue;
pen White;
@@ -3848,8 +3848,8 @@ pen IndianRed;
pen Aqua;
pen Crimson;
pen Azure;
-pen LawnGreen;
pen Lavender;
+pen LawnGreen;
pen Brown;
pen BurlyWood;
pen Moccasin;
diff --git a/graphics/asymptote/asymptote.spec b/graphics/asymptote/asymptote.spec
index 87cabb3ff6..7df46acdb2 100644
--- a/graphics/asymptote/asymptote.spec
+++ b/graphics/asymptote/asymptote.spec
@@ -3,7 +3,7 @@
%global __python %{__python3}
Name: asymptote
-Version: 2.53
+Version: 2.54
Release: 1%{?dist}
Summary: Descriptive vector graphics language
diff --git a/graphics/asymptote/base/plain_prethree.asy b/graphics/asymptote/base/plain_prethree.asy
index bc40792cf0..968ae2943a 100644
--- a/graphics/asymptote/base/plain_prethree.asy
+++ b/graphics/asymptote/base/plain_prethree.asy
@@ -1,6 +1,6 @@
// Critical definitions for transform3 needed by projection and picture.
-pair viewportmargin=(0.1,0.1); // Horizontal and vertical 3D viewport margins.
+pair viewportmargin=settings.viewportmargin;
typedef real[][] transform3;
restricted transform3 identity4=identity(4);
diff --git a/graphics/asymptote/base/shaders/fragment.glsl b/graphics/asymptote/base/shaders/fragment.glsl
index 38a6a53fbb..b914f7f35a 100644
--- a/graphics/asymptote/base/shaders/fragment.glsl
+++ b/graphics/asymptote/base/shaders/fragment.glsl
@@ -1,237 +1,227 @@
-struct Material
-{
- vec4 diffuse,emissive,specular;
- vec4 parameters;
-};
-
-struct Light
-{
- vec4 direction;
- vec4 diffuse,specular;
-};
-
-uniform int nlights;
-uniform Light lights[Nlights];
-
-uniform MaterialBuffer {
- Material Materials[Nmaterials];
-};
-
-
-#ifdef NORMAL
-in vec3 Normal;
-vec3 normal;
-#endif
-
-#ifdef EXPLICIT_COLOR
-in vec4 Color;
-#endif
-
-flat in int materialIndex;
-out vec4 outColor;
-
-// PBR material parameters
-vec3 PBRBaseColor; // Diffuse for nonmetals, reflectance for metals.
-vec3 PBRSpecular; // Specular tint for nonmetals
-float PBRMetallic; // Metallic/Nonmetals switch flag
-float PBRF0; // Fresnel at zero for nonmetals
-float PBRRoughness; // Roughness.
-float PBRRoughnessSq; // used value of roughness, for a little bit more "smoothing"
-
-uniform sampler2D environmentMap;
-const float PI = acos(-1.0);
-#ifdef ENABLE_TEXTURE
-const float twopi=2*PI;
-const float halfpi=PI/2;
-
-const int numSamples=7;
-
-// (x,y,z) -> (r, theta, phi);
-// theta -> [0,\pi], "height" angle
-// phi -> [0, 2\pi], rotation agnle
-vec3 cart2spher(vec3 cart) {
- float x = cart.z;
- float y = cart.x;
- float z = cart.y;
-
- float r = length(cart);
- float phi = atan(y,x);
- float theta = acos(z/r);
-
- return vec3(r,phi,theta);
-}
-
-vec2 normalizedAngle(vec3 cartVec) {
- vec3 sphericalVec = cart2spher(cartVec);
- sphericalVec.y = sphericalVec.y / (2 * PI) - 0.25;
- sphericalVec.z = sphericalVec.z / PI;
- // sphericalVec.z = - sphericalVec.z;
- return sphericalVec.yz;
-}
-#endif
-
-#ifdef NORMAL
-// h is the halfway vector between normal and light direction
-// GGX Trowbridge-Reitz Approximation
-float NDF_TRG(vec3 h, float roughness) {
- float ndoth = max(dot(normal, h), 0);
- float alpha2 = PBRRoughnessSq * PBRRoughnessSq;
-
- float denom = pow(ndoth * ndoth * (alpha2-1) + 1, 2);
- return alpha2/denom;
-}
-
-float GGX_Geom(vec3 v) {
- float ndotv = max(dot(v,normal), 0);
- float ap = pow((1+PBRRoughness),2);
- float k = ap/8;
-
- return ndotv/((ndotv * (1-k)) + k);
-}
-
-float Geom(vec3 v, vec3 l) {
- return GGX_Geom(v) * GGX_Geom(l);
-}
-
-// Schlick's approximation
-float Fresnel(vec3 h, vec3 v, float F0) {
- float hdotv = max(dot(h,v), 0.0);
-
- return F0 + (1-F0)*pow((1-hdotv),5);
-}
-
-vec3 BRDF(vec3 viewDirection, vec3 lightDirection) {
- // Lambertian diffuse
- vec3 lambertian = PBRBaseColor;
- // Cook-Torrance model
- vec3 h = normalize(lightDirection + viewDirection);
-
- float omegain = max(dot(viewDirection, normal),0);
- float omegaln = max(dot(lightDirection, normal),0);
-
- float D = NDF_TRG(h, PBRRoughness);
- float G = Geom(viewDirection, lightDirection);
- float F = Fresnel(h, viewDirection, PBRF0);
-
- float denom=4*omegain*omegaln;
- float rawReflectance=denom > 0 ? (D*G)/denom : 0;
-
- vec3 dielectric = mix(lambertian, rawReflectance * PBRSpecular, F);
- vec3 metal = rawReflectance * PBRBaseColor;
-
- return mix(dielectric, metal, PBRMetallic);
-}
-#endif
-
-void main()
-{
-vec4 Diffuse;
-vec4 Emissive;
-vec4 Specular;
-vec4 parameters;
-
-#ifdef EXPLICIT_COLOR
- if(materialIndex < 0) {
- int index=-materialIndex-1;
- Material m=Materials[index];
- Diffuse=Color;
- Emissive=vec4(0);
- Specular=m.specular;
- parameters=m.parameters;
- } else {
- Material m=Materials[materialIndex];
- Diffuse=m.diffuse;
- Emissive=m.emissive;
- Specular=m.specular;
- parameters=m.parameters;
- }
-#else
- Material m=Materials[materialIndex];
- Diffuse=m.diffuse;
- Emissive=m.emissive;
- Specular=m.specular;
- parameters=m.parameters;
-#endif
-
- PBRRoughness=1-parameters[0];
- PBRMetallic=parameters[1];
- PBRF0=parameters[2];
-
- PBRBaseColor = Diffuse.rgb;
- PBRRoughnessSq = PBRRoughness * PBRRoughness;
- PBRSpecular = Specular.rgb;
-
- // Formally, the formula given a point x and direction \omega,
- // L_i = \int_{\Omega} f(x, \omega_i, \omega) L(x,\omega_i) (\hat{n}\cdot \omega_i) d \omega_i
- // where \Omega is the hemisphere covering a point, f is the BRDF function
- // L is the radiance from a given angle and position.
-
- vec3 color=Emissive.rgb;
-#ifdef NORMAL
- vec3 Z=vec3(0,0,1);
- vec3 pointLightRadiance=vec3(0,0,0);
-
- normal=normalize(Normal);
- normal=gl_FrontFacing ? normal : -normal;
- // as a finite point light, we have some simplification to the rendering equation.
- if(nlights > 0) {
- for(int i=0; i < nlights; ++i) {
- vec3 L = normalize(lights[i].direction.xyz);
- // what if we use the acutal view from (0,0,0) instead?
- // vec3 viewDirection = Z;
- vec3 viewDirection = -normalize(Z);
- float cosTheta = max(dot(normal, L), 0); // $\omega_i \cdot n$ term
- float attn = 1; // if we have a good light position.
- vec3 radiance = cosTheta * attn * lights[i].diffuse.rgb;
- pointLightRadiance += BRDF(Z, L) * radiance;
- }
- color += pointLightRadiance.rgb;
-
-#ifdef ENABLE_TEXTURE
-#ifndef EXPLICIT_COLOR
- // Experimental environment radiance using Riemann sums;
- // can also do importance sampling.
- vec3 envRadiance=vec3(0,0,0);
-
- vec3 normalPerp = vec3(-normal.y, normal.x, 0);
- if (length(normalPerp) == 0) { // x, y = 0.
-
- normalPerp = vec3(1, 0, 0);
- }
- // we now have a normal basis;
- normalPerp = normalize(normalPerp);
- vec3 normalPerp2 = normalize(cross(normal, normalPerp));
-
- const float step=1.0/numSamples;
- const float phistep=twopi*step;
- const float thetastep=halfpi*step;
- for (int iphi=0; iphi < numSamples; ++iphi) {
- float phi=iphi*phistep;
- for (int itheta=0; itheta < numSamples; ++itheta) {
- float theta=itheta*thetastep;
-
- vec3 azimuth=cos(phi)*normalPerp+sin(phi)*normalPerp2;
- vec3 L=sin(theta)*azimuth+cos(theta)*normal;
-
- vec3 rawRadiance=texture(environmentMap,normalizedAngle(L)).rgb;
- vec3 surfRefl=BRDF(Z,L);
- envRadiance += surfRefl*rawRadiance*sin(2.0*theta);
- }
- }
- envRadiance *= halfpi*step*step;
-
- // vec3 lightVector = normalize(reflect(-Z, normal));
- // vec2 anglemap = normalizedAngle(lightVector);
- // vec3 color = texture(environmentMap, anglemap).rgb;
- color += envRadiance.rgb;
-#endif
-#endif
- outColor=vec4(color,Diffuse.a);
- } else {
- outColor=Diffuse;
- }
-#else
- outColor=Emissive;
-#endif
-}
-
+struct Material
+{
+ vec4 diffuse,emissive,specular;
+ vec4 parameters;
+};
+
+struct Light
+{
+ vec3 direction;
+ vec3 color;
+};
+
+uniform int nlights;
+uniform Light lights[Nlights];
+
+uniform MaterialBuffer {
+ Material Materials[Nmaterials];
+};
+
+#ifdef NORMAL
+#ifndef ORTHOGRAPHIC
+in vec3 ViewPosition;
+#endif
+in vec3 Normal;
+vec3 normal;
+#endif
+
+#ifdef COLOR
+in vec4 Color;
+#endif
+
+flat in int materialIndex;
+out vec4 outColor;
+
+// PBR material parameters
+vec3 Diffuse; // Diffuse for nonmetals, reflectance for metals.
+vec3 Specular; // Specular tint for nonmetals
+float Metallic; // Metallic/Nonmetals parameter
+float Fresnel0; // Fresnel at zero for nonmetals
+float Roughness2; // roughness squared, for smoothing
+
+#ifdef ENABLE_TEXTURE
+uniform sampler2D environmentMap;
+const float PI=acos(-1.0);
+const float twopi=2*PI;
+const float halfpi=PI/2;
+
+const int numSamples=7;
+
+// (x,y,z) -> (r,theta,phi);
+// theta -> [0,\pi]: colatitude
+// phi -> [0, 2\pi]: longitude
+vec3 cart2sphere(vec3 cart)
+{
+ float x=cart.z;
+ float y=cart.x;
+ float z=cart.y;
+
+ float r=length(cart);
+ float phi=atan(y,x);
+ float theta=acos(z/r);
+
+ return vec3(r,phi,theta);
+}
+
+vec2 normalizedAngle(vec3 cartVec)
+{
+ vec3 sphericalVec=cart2sphere(cartVec);
+ sphericalVec.y=sphericalVec.y/(2*PI)-0.25;
+ sphericalVec.z=sphericalVec.z/PI;
+ return sphericalVec.yz;
+}
+#endif
+
+#ifdef NORMAL
+// h is the halfway vector between normal and light direction
+// GGX Trowbridge-Reitz Approximation
+float NDF_TRG(vec3 h)
+{
+ float ndoth=max(dot(normal,h),0.0);
+ float alpha2=Roughness2*Roughness2;
+ float denom=ndoth*ndoth*(alpha2-1.0)+1.0;
+ return denom != 0.0 ? alpha2/(denom*denom) : 0.0;
+}
+
+float GGX_Geom(vec3 v)
+{
+ float ndotv=max(dot(v,normal),0.0);
+ float ap=1.0+Roughness2;
+ float k=0.125*ap*ap;
+ return ndotv/((ndotv*(1.0-k))+k);
+}
+
+float Geom(vec3 v, vec3 l)
+{
+ return GGX_Geom(v)*GGX_Geom(l);
+}
+
+// Schlick's approximation
+float Fresnel(vec3 h, vec3 v, float fresnel0)
+{
+ float a=1.0-max(dot(h,v),0.0);
+ float b=a*a;
+ return fresnel0+(1.0-fresnel0)*b*b*a;
+}
+
+vec3 BRDF(vec3 viewDirection, vec3 lightDirection)
+{
+ vec3 lambertian=Diffuse;
+ // Cook-Torrance model
+ vec3 h=normalize(lightDirection+viewDirection);
+
+ float omegain=max(dot(viewDirection,normal),0.0);
+ float omegaln=max(dot(lightDirection,normal),0.0);
+
+ float D=NDF_TRG(h);
+ float G=Geom(viewDirection,lightDirection);
+ float F=Fresnel(h,viewDirection,Fresnel0);
+
+ float denom=4.0*omegain*omegaln;
+ float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;
+
+ vec3 dielectric=mix(lambertian,rawReflectance*Specular,F);
+ vec3 metal=rawReflectance*Diffuse;
+
+ return mix(dielectric,metal,Metallic);
+}
+#endif
+
+void main()
+{
+ vec4 diffuse;
+ vec4 emissive;
+ vec4 parameters;
+
+ Material m;
+#ifdef TRANSPARENT
+ m=Materials[abs(materialIndex)-1];
+ if(materialIndex >= 0) {
+ diffuse=m.diffuse;
+ emissive=m.emissive;
+ } else {
+ diffuse=Color;
+ emissive=vec4(0.0);
+ }
+#else
+ m=Materials[int(materialIndex)];
+#ifdef COLOR
+ diffuse=Color;
+ emissive=vec4(0.0);
+#else
+ diffuse=m.diffuse;
+ emissive=m.emissive;
+#endif
+#endif
+ Specular=m.specular.rgb;
+ parameters=m.parameters;
+ Roughness2=1.0-parameters[0];
+ Roughness2=Roughness2*Roughness2;
+ Metallic=parameters[1];
+ Fresnel0=parameters[2];
+ Diffuse=diffuse.rgb;
+
+ // Given a point x and direction \omega,
+ // L_i=\int_{\Omega}f(x,\omega_i,\omega) L(x,\omega_i)(\hat{n}\cdot \omega_i)
+ // d\omega_i, where \Omega is the hemisphere covering a point,
+ // f is the BRDF function, L is the radiance from a given angle and position.
+
+ vec3 color=emissive.rgb;
+#ifdef NORMAL
+ normal=normalize(Normal);
+ normal=gl_FrontFacing ? normal : -normal;
+#ifdef ORTHOGRAPHIC
+ vec3 viewDir=vec3(0.0,0.0,1.0);
+#else
+ vec3 viewDir=-normalize(ViewPosition);
+#endif
+ // For a finite point light, the rendering equation simplifies.
+ if(nlights > 0) {
+ for(int i=0; i < nlights; ++i) {
+ Light Li=lights[i];
+ vec3 L=Li.direction;
+ float cosTheta=max(dot(normal,L),0.0); // $\omega_i \cdot n$ term
+ vec3 radiance=cosTheta*Li.color;
+ color += BRDF(viewDir,L)*radiance;
+ }
+
+#ifdef ENABLE_TEXTURE
+#ifndef COLOR
+ // Experimental environment radiance using Riemann sums;
+ // can also do importance sampling.
+ vec3 envRadiance=vec3(0.0,0.0,0.0);
+
+ vec3 normalPerp=vec3(-normal.y,normal.x,0.0);
+ if(length(normalPerp) == 0.0)
+ normalPerp=vec3(1.0,0.0,0.0);
+
+ // we now have a normal basis;
+ normalPerp=normalize(normalPerp);
+ vec3 normalPerp2=normalize(cross(normal,normalPerp));
+
+ const float step=1.0/numSamples;
+ const float phistep=twopi*step;
+ const float thetastep=halfpi*step;
+ for (int iphi=0; iphi < numSamples; ++iphi) {
+ float phi=iphi*phistep;
+ for (int itheta=0; itheta < numSamples; ++itheta) {
+ float theta=itheta*thetastep;
+
+ vec3 azimuth=cos(phi)*normalPerp+sin(phi)*normalPerp2;
+ vec3 L=sin(theta)*azimuth+cos(theta)*normal;
+
+ vec3 rawRadiance=texture(environmentMap,normalizedAngle(L)).rgb;
+ vec3 surfRefl=BRDF(Z,L);
+ envRadiance += surfRefl*rawRadiance*sin(2.0*theta);
+ }
+ }
+ envRadiance *= halfpi*step*step;
+ color += envRadiance.rgb;
+#endif
+#endif
+ outColor=vec4(color,diffuse.a);
+ } else outColor=diffuse;
+#else
+ outColor=emissive;
+#endif
+}
diff --git a/graphics/asymptote/base/shaders/vertex.glsl b/graphics/asymptote/base/shaders/vertex.glsl
index 815145461e..9a54d3211c 100644
--- a/graphics/asymptote/base/shaders/vertex.glsl
+++ b/graphics/asymptote/base/shaders/vertex.glsl
@@ -1,49 +1,49 @@
-in vec3 position;
-
-#ifdef NORMAL
-in vec3 normal;
-#endif
-
-#ifdef EXPLICIT_COLOR
-in uint color;
-#endif
-
-#ifdef WIDTH
-in float width;
-#endif
-
-in int material;
-
-uniform mat4 projViewMat;
-uniform mat4 viewMat;
-uniform mat4 normMat;
-
-out vec3 ViewPosition;
-#ifdef NORMAL
-out vec3 Normal;
-#endif
-
-#ifdef EXPLICIT_COLOR
-out vec4 Color;
-#endif
-
-flat out int materialIndex;
-
-void main()
-{
- gl_Position=projViewMat*vec4(position,1.0);
- ViewPosition=(viewMat*vec4(position,1.0)).xyz;
-#ifdef NORMAL
- Normal=(normMat*vec4(normal,0)).xyz;
-#endif
-
-#ifdef EXPLICIT_COLOR
- Color=unpackUnorm4x8(color);
-#endif
-
-#ifdef WIDTH
- gl_PointSize=width;
-#endif
-
- materialIndex=material;
-}
+in vec3 position;
+
+uniform mat3 normMat;
+
+#ifdef NORMAL
+#ifndef ORTHOGRAPHIC
+out vec3 ViewPosition;
+#endif
+in vec3 normal;
+out vec3 Normal;
+#endif
+
+in int material;
+
+#ifdef COLOR
+in vec4 color;
+out vec4 Color;
+#endif
+
+#ifdef WIDTH
+in float width;
+#endif
+
+uniform mat4 projViewMat;
+uniform mat4 viewMat;
+
+flat out int materialIndex;
+
+void main()
+{
+ vec4 v=vec4(position,1.0);
+ gl_Position=projViewMat*v;
+#ifdef NORMAL
+#ifndef ORTHOGRAPHIC
+ ViewPosition=(viewMat*v).xyz;
+#endif
+ Normal=normal*normMat;
+#endif
+
+#ifdef COLOR
+ Color=color;
+#endif
+
+#ifdef WIDTH
+ gl_PointSize=width;
+#endif
+
+ materialIndex=material;
+}
diff --git a/graphics/asymptote/base/three.asy b/graphics/asymptote/base/three.asy
index 866137b1db..2b32fd1612 100644
--- a/graphics/asymptote/base/three.asy
+++ b/graphics/asymptote/base/three.asy
@@ -2887,10 +2887,13 @@ object embed(string prefix=outprefix(), string label=prefix,
m -= margin;
} else if(M.z >= 0) abort("camera too close");
+ if(settings.outformat == "html")
+ format="html";
+
shipout3(prefix,f,preview ? nativeformat() : format,
S.width-defaultrender.margin,S.height-defaultrender.margin,
P.infinity ? 0 : 2aTan(Tan(0.5*P.angle)*P.zoom),
- P.zoom,m,M,P.viewportshift,
+ P.zoom,m,M,P.viewportshift,S.viewportmargin,
tinv*inv*shift(0,0,zcenter),Light.background(),Light.position,
Light.diffuse,Light.specular,
view && !preview);
diff --git a/graphics/asymptote/base/three_surface.asy b/graphics/asymptote/base/three_surface.asy
index bdb56cb0ca..4ad31d6d2d 100644
--- a/graphics/asymptote/base/three_surface.asy
+++ b/graphics/asymptote/base/three_surface.asy
@@ -1402,15 +1402,20 @@ void draw3D(frame f, int type=0, patch s, triple center=O, material m,
light light=currentlight, interaction interaction=Embedded,
bool prc=true)
{
- if(s.colors.length > 0)
+ bool straight=s.straight && s.planar;
+ bool prc=prc();
+ if(s.colors.length > 0) {
+ if(prc && light.on())
+ straight=false; // PRC vertex colors (for quads only) ignore lighting
m=mean(s.colors);
+ }
m=material(m,light);
- real PRCshininess;
- if(prc())
- PRCshininess=PRCshininess(m.shininess);
+ real PRCshininess;
+ if(prc) PRCshininess=PRCshininess(m.shininess);
+
(s.triangular ? drawbeziertriangle : draw)
- (f,s.P,center,s.straight && s.planar,m.p,m.opacity,m.shininess,
+ (f,s.P,center,straight,m.p,m.opacity,m.shininess,
m.metallic,m.fresnel0,PRCshininess,s.colors,interaction.type,prc);
}
@@ -1435,7 +1440,7 @@ void draw(frame f, triple[] v, int[][] vi,
triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
int[][] pi={}, light light=currentlight)
{
- bool normals=ni.length > 0;
+ bool normals=n.length > 0;
if(!normals) {
ni=new int[vi.length][3];
normals=computeNormals(v,vi,n,ni) > 0;
@@ -1455,7 +1460,8 @@ void draw(picture pic=currentpicture, triple[] v, int[][] vi,
triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
int[][] pi={}, light light=currentlight)
{
- bool normals=ni.length > 0;
+ bool prc=prc();
+ bool normals=n.length > 0;
if(!normals) {
ni=new int[vi.length][3];
normals=computeNormals(v,vi,n,ni) > 0;
@@ -1501,7 +1507,7 @@ void draw(picture pic=currentpicture, triple[] v, int[][] vi,
project(v[vii[2]],P)--cycle;
pen p=color(n[ni[i][0]],m,light);
fill(pic,g,p);
- if(opacity(m.diffuse()) == 1) // Fill subdivision cracks
+ if(prc && opacity(m.diffuse()) == 1) // Fill subdivision cracks
draw(pic,g,p);
}
}
@@ -1843,6 +1849,7 @@ void label(frame f, Label L, triple position, align align=NoAlign,
interaction interaction=LabelInteraction(),
projection P=currentprojection)
{
+ bool prc=prc();
Label L=L.copy();
L.align(align);
L.p(p);
@@ -1873,7 +1880,7 @@ void label(frame f, Label L, triple position, align align=NoAlign,
S=centering*S;
draw3D(f3,S,position,L.p,light,interaction);
// Fill subdivision cracks
- if(render.labelfill && opacity(L.p) == 1 && !lighton)
+ if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
_draw(f3,S.external(),position,L.p,interaction.type);
}
endgroup3(f3);
@@ -1893,7 +1900,7 @@ void label(frame f, Label L, triple position, align align=NoAlign,
position;
draw3D(f,S,V,L.p,light,interaction);
// Fill subdivision cracks
- if(render.labelfill && opacity(L.p) == 1 && !lighton)
+ if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
_draw(f,S.external(),V,L.p,interaction.type);
}
endgroup3(f);
@@ -1927,6 +1934,7 @@ void label(picture pic=currentpicture, Label L, triple position,
pic.add(new void(frame f, transform3 t, picture pic2, projection P) {
// Handle relative projected 3D alignments.
+ bool prc=prc();
Label L=L.copy();
triple v=t*position;
if(!align.is3D && L.align.relative && L.align.dir3 != O &&
@@ -1942,44 +1950,46 @@ void label(picture pic=currentpicture, Label L, triple position,
if(is3D()) {
bool lighton=light.on();
if(name == "") name=L.s;
- if(prc() && interaction.type == Billboard.type) {
+ if(prc && interaction.type == Billboard.type) {
surface s=surface(texpath(L,bbox=P.bboxonly));
- transform3 centering=L.align.is3D ?
- alignshift(s,L.T3,v,L.align.dir3) : identity4;
- transform3 positioning=
- shift(L.align.is3D ? v+L.align.dir3*labelmargin(L.p) : v);
- frame f1,f2,f3;
- begingroup3(f1,name,render);
- if(L.defaulttransform3)
- begingroup3(f3,render,v,interaction.type);
- else {
- begingroup3(f2,render,v,interaction.type);
- begingroup3(f3,render,v);
- }
- for(patch S : s.s) {
- S=centering*S;
- draw3D(f3,S,v,L.p,light,interaction);
- // Fill subdivision cracks
- if(render.labelfill && opacity(L.p) == 1 && !lighton)
- _draw(f3,S.external(),v,L.p,interaction.type);
- }
- endgroup3(f3);
- if(L.defaulttransform3)
- add(f1,T*f3);
- else {
- add(f2,inverse(T)*L.T3*f3);
- endgroup3(f2);
- add(f1,T*f2);
+ if(s.s.length > 0) {
+ transform3 centering=L.align.is3D ?
+ alignshift(s,L.T3,v,L.align.dir3) : identity4;
+ transform3 positioning=
+ shift(L.align.is3D ? v+L.align.dir3*labelmargin(L.p) : v);
+ frame f1,f2,f3;
+ begingroup3(f1,name,render);
+ if(L.defaulttransform3)
+ begingroup3(f3,render,v,interaction.type);
+ else {
+ begingroup3(f2,render,v,interaction.type);
+ begingroup3(f3,render,v);
+ }
+ for(patch S : s.s) {
+ S=centering*S;
+ draw3D(f3,S,v,L.p,light,interaction);
+ // Fill subdivision cracks
+ if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
+ _draw(f3,S.external(),v,L.p,interaction.type);
+ }
+ endgroup3(f3);
+ if(L.defaulttransform3)
+ add(f1,T*f3);
+ else {
+ add(f2,inverse(T)*L.T3*f3);
+ endgroup3(f2);
+ add(f1,T*f2);
+ }
+ endgroup3(f1);
+ add(f,positioning*f1);
}
- endgroup3(f1);
- add(f,positioning*f1);
} else {
begingroup3(f,name,render);
for(patch S : surface(L,v,bbox=P.bboxonly).s) {
triple V=L.align.is3D ? v+L.align.dir3*labelmargin(L.p) : v;
draw3D(f,S,V,L.p,light,interaction);
// Fill subdivision cracks
- if(render.labelfill && opacity(L.p) == 1 && !lighton)
+ if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
_draw(f,S.external(),V,L.p,interaction.type);
}
endgroup3(f);
diff --git a/graphics/asymptote/base/webgl/WebGLfooter.html b/graphics/asymptote/base/webgl/WebGLfooter.html
new file mode 100644
index 0000000000..4aba96372e
--- /dev/null
+++ b/graphics/asymptote/base/webgl/WebGLfooter.html
@@ -0,0 +1,10 @@
+</script>
+
+</head>
+
+
+<body style="overflow: hidden;" onload="webGLStart();">
+<canvas id="Asymptote" style="border: none;" width="0" height="0" />
+</body>
+
+</html>
diff --git a/graphics/asymptote/base/webgl/WebGLheader.html b/graphics/asymptote/base/webgl/WebGLheader.html
new file mode 100644
index 0000000000..6eea5fd1be
--- /dev/null
+++ b/graphics/asymptote/base/webgl/WebGLheader.html
@@ -0,0 +1,180 @@
+<html>
+
+<head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+<meta name="viewport" content="user-scalable=no"/>
+
+<script id="vertex" type="x-shader/x-vertex">
+attribute vec3 position;
+#ifdef WIDTH
+attribute float width;
+#endif
+#ifdef NORMAL
+attribute vec3 normal;
+#endif
+attribute float materialIndex;
+#ifdef COLOR
+attribute vec4 color;
+#endif
+
+uniform mat3 normMat;
+uniform mat4 viewMat;
+uniform mat4 projViewMat;
+
+#ifdef NORMAL
+#ifndef ORTHOGRAPHIC
+varying vec3 ViewPosition;
+#endif
+varying vec3 Normal;
+#endif
+varying vec4 diffuse;
+varying vec3 specular;
+varying float roughness,metallic,fresnel0;
+varying vec4 emissive;
+
+struct Material {
+ vec4 diffuse,emissive,specular;
+ float shininess,metallic,fresnel0;
+};
+
+uniform Material Materials[nMaterials];
+
+void main(void)
+{
+ vec4 v=vec4(position,1.0);
+ gl_Position=projViewMat*v;
+#ifdef NORMAL
+#ifndef ORTHOGRAPHIC
+ ViewPosition=(viewMat*v).xyz;
+#endif
+ Normal=normal*normMat;
+
+ Material m;
+#ifdef TRANSPARENT
+ m=Materials[int(abs(materialIndex))-1];
+ if(materialIndex >= 0.0) {
+ diffuse=m.diffuse;
+ emissive=m.emissive;
+ } else {
+ diffuse=color;
+ emissive=vec4(0.0);
+ }
+#else
+ m=Materials[int(materialIndex)];
+#ifdef COLOR
+ diffuse=color;
+ emissive=vec4(0.0);
+#else
+ diffuse=m.diffuse;
+ emissive=m.emissive;
+#endif
+#endif
+ specular=m.specular.rgb;
+ roughness=1.0-m.shininess;
+ metallic=m.metallic;
+ fresnel0=m.fresnel0;
+#else
+ emissive=Materials[int(materialIndex)].emissive;
+#endif
+#ifdef WIDTH
+ gl_PointSize=width;
+#endif
+}
+</script>
+
+<script id="fragment" type="x-shader/x-fragment">
+#ifdef NORMAL
+#ifndef ORTHOGRAPHIC
+varying vec3 ViewPosition;
+#endif
+varying vec3 Normal;
+varying vec4 diffuse;
+varying vec3 specular;
+varying float roughness,metallic,fresnel0;
+
+float Roughness2;
+vec3 normal;
+
+struct Light {
+ vec3 direction;
+ vec3 color;
+};
+uniform Light Lights[nLights];
+
+float NDF_TRG(vec3 h)
+{
+ float ndoth=max(dot(normal,h),0.0);
+ float alpha2=Roughness2*Roughness2;
+ float denom=ndoth*ndoth*(alpha2-1.0)+1.0;
+ return denom != 0.0 ? alpha2/(denom*denom) : 0.0;
+}
+
+float GGX_Geom(vec3 v)
+{
+ float ndotv=max(dot(v,normal),0.0);
+ float ap=1.0+Roughness2;
+ float k=0.125*ap*ap;
+ return ndotv/((ndotv*(1.0-k))+k);
+}
+
+float Geom(vec3 v, vec3 l)
+{
+ return GGX_Geom(v)*GGX_Geom(l);
+}
+
+float Fresnel(vec3 h, vec3 v, float fresnel0)
+{
+ float a=1.0-max(dot(h,v),0.0);
+ float b=a*a;
+ return fresnel0+(1.0-fresnel0)*b*b*a;
+}
+
+// physical based shading using UE4 model.
+vec3 BRDF(vec3 viewDirection, vec3 lightDirection)
+{
+ vec3 lambertian=diffuse.rgb;
+ vec3 h=normalize(lightDirection+viewDirection);
+
+ float omegain=max(dot(viewDirection,normal),0.0);
+ float omegali=max(dot(lightDirection,normal),0.0);
+
+ float D=NDF_TRG(h);
+ float G=Geom(viewDirection,lightDirection);
+ float F=Fresnel(h,viewDirection,fresnel0);
+
+ float denom=4.0*omegain*omegali;
+ float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;
+
+ vec3 dielectric=mix(lambertian,rawReflectance*specular,F);
+ vec3 metal=rawReflectance*diffuse.rgb;
+
+ return mix(dielectric,metal,metallic);
+}
+#endif
+varying vec4 emissive;
+
+void main(void)
+{
+#ifdef NORMAL
+ normal=normalize(Normal);
+ normal=gl_FrontFacing ? normal : -normal;
+#ifdef ORTHOGRAPHIC
+ vec3 viewDir=vec3(0.0,0.0,1.0);
+#else
+ vec3 viewDir=-normalize(ViewPosition);
+#endif
+ Roughness2=roughness*roughness;
+ vec3 color=emissive.rgb;
+ for (int i=0; i < nLights; ++i) {
+ Light Li=Lights[i];
+ vec3 L=Li.direction;
+ float cosTheta=max(dot(normal,L),0.0);
+ vec3 radiance=cosTheta*Li.color;
+ color += BRDF(viewDir,L)*radiance;
+ }
+ gl_FragColor=vec4(color,diffuse.a);
+#else
+ gl_FragColor=emissive;
+#endif
+}
+</script>
diff --git a/graphics/asymptote/base/webgl/asygl-1.00.js b/graphics/asymptote/base/webgl/asygl-1.00.js
new file mode 100644
index 0000000000..cf29f41c21
--- /dev/null
+++ b/graphics/asymptote/base/webgl/asygl-1.00.js
@@ -0,0 +1,39 @@
+/*@license
+ gl.js: Render Bezier patches via subdivision with WebGL.
+ Copyright 2019: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
+ University of Alberta
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+let gl,canvas,canvasWidth,canvasHeight,halfCanvasWidth,halfCanvasHeight;!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var i=e();for(var r in i)("object"==typeof exports?exports:t)[r]=i[r]}}("undefined"!=typeof self?self:this,function(){return function(t){function e(r){if(i[r])return i[r].exports;var a=i[r]={i:r,l:!1,exports:{}};return t[r].call(a.exports,a,a.exports,e),a.l=!0,a.exports}var i={};return e.m=t,e.c=i,e.d=function(t,i,r){e.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(i,"a",i),i},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=1)}([function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setMatrixArrayType=function(t){e.ARRAY_TYPE=t},e.toRadian=function(t){return t*a},e.equals=function(t,e){return Math.abs(t-e)<=r*Math.max(1,Math.abs(t),Math.abs(e))};var r=e.EPSILON=1e-6,a=(e.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,e.RANDOM=Math.random,Math.PI/180)},function(t,e,i){"use strict";function r(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}Object.defineProperty(e,"__esModule",{value:!0}),e.mat4=e.mat3=void 0;var a=r(i(2)),s=r(i(3));e.mat3=a,e.mat4=s},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.create=function(){var t=new r.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t},e.invert=function(t,e){var i=e[0],r=e[1],a=e[2],s=e[3],n=e[4],o=e[5],h=e[6],l=e[7],c=e[8],d=c*n-o*l,m=-c*s+o*h,u=l*s-n*h,f=i*d+r*m+a*u;return f?(f=1/f,t[0]=d*f,t[1]=(-c*r+a*l)*f,t[2]=(o*r-a*n)*f,t[3]=m*f,t[4]=(c*i-a*h)*f,t[5]=(-o*i+a*s)*f,t[6]=u*f,t[7]=(-l*i+r*h)*f,t[8]=(n*i-r*s)*f,t):null};var r=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}(i(0))},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.create=function(){var t=new r.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.invert=function(t,e){var i=e[0],r=e[1],a=e[2],s=e[3],n=e[4],o=e[5],h=e[6],l=e[7],c=e[8],d=e[9],m=e[10],u=e[11],f=e[12],v=e[13],p=e[14],g=e[15],x=i*o-r*n,M=i*h-a*n,w=i*l-s*n,A=r*h-a*o,S=r*l-s*o,b=a*l-s*h,P=c*v-d*f,z=c*p-m*f,R=c*g-u*f,y=d*p-m*v,D=d*g-u*v,T=m*g-u*p,E=x*T-M*D+w*y+A*R-S*z+b*P;return E?(E=1/E,t[0]=(o*T-h*D+l*y)*E,t[1]=(a*D-r*T-s*y)*E,t[2]=(v*b-p*S+g*A)*E,t[3]=(m*S-d*b-u*A)*E,t[4]=(h*R-n*T-l*z)*E,t[5]=(i*T-a*R+s*z)*E,t[6]=(p*w-f*b-g*M)*E,t[7]=(c*b-m*w+u*M)*E,t[8]=(n*D-o*R+l*P)*E,t[9]=(r*R-i*D-s*P)*E,t[10]=(f*S-v*w+g*x)*E,t[11]=(d*w-c*S-u*x)*E,t[12]=(o*z-n*y-h*P)*E,t[13]=(i*y-r*z+a*P)*E,t[14]=(v*M-f*A-p*x)*E,t[15]=(c*A-d*M+m*x)*E,t):null},e.multiply=function(t,e,i){var r=e[0],a=e[1],s=e[2],n=e[3],o=e[4],h=e[5],l=e[6],c=e[7],d=e[8],m=e[9],u=e[10],f=e[11],v=e[12],p=e[13],g=e[14],x=e[15],M=i[0],w=i[1],A=i[2],S=i[3];return t[0]=M*r+w*o+A*d+S*v,t[1]=M*a+w*h+A*m+S*p,t[2]=M*s+w*l+A*u+S*g,t[3]=M*n+w*c+A*f+S*x,M=i[4],w=i[5],A=i[6],S=i[7],t[4]=M*r+w*o+A*d+S*v,t[5]=M*a+w*h+A*m+S*p,t[6]=M*s+w*l+A*u+S*g,t[7]=M*n+w*c+A*f+S*x,M=i[8],w=i[9],A=i[10],S=i[11],t[8]=M*r+w*o+A*d+S*v,t[9]=M*a+w*h+A*m+S*p,t[10]=M*s+w*l+A*u+S*g,t[11]=M*n+w*c+A*f+S*x,M=i[12],w=i[13],A=i[14],S=i[15],t[12]=M*r+w*o+A*d+S*v,t[13]=M*a+w*h+A*m+S*p,t[14]=M*s+w*l+A*u+S*g,t[15]=M*n+w*c+A*f+S*x,t},e.translate=function(t,e,i){var r=i[0],a=i[1],s=i[2],n=void 0,o=void 0,h=void 0,l=void 0,c=void 0,d=void 0,m=void 0,u=void 0,f=void 0,v=void 0,p=void 0,g=void 0;return e===t?(t[12]=e[0]*r+e[4]*a+e[8]*s+e[12],t[13]=e[1]*r+e[5]*a+e[9]*s+e[13],t[14]=e[2]*r+e[6]*a+e[10]*s+e[14],t[15]=e[3]*r+e[7]*a+e[11]*s+e[15]):(n=e[0],o=e[1],h=e[2],l=e[3],c=e[4],d=e[5],m=e[6],u=e[7],f=e[8],v=e[9],p=e[10],g=e[11],t[0]=n,t[1]=o,t[2]=h,t[3]=l,t[4]=c,t[5]=d,t[6]=m,t[7]=u,t[8]=f,t[9]=v,t[10]=p,t[11]=g,t[12]=n*r+c*a+f*s+e[12],t[13]=o*r+d*a+v*s+e[13],t[14]=h*r+m*a+p*s+e[14],t[15]=l*r+u*a+g*s+e[15]),t},e.rotate=function(t,e,i,a){var s=a[0],n=a[1],o=a[2],h=Math.sqrt(s*s+n*n+o*o),l=void 0,c=void 0,d=void 0,m=void 0,u=void 0,f=void 0,v=void 0,p=void 0,g=void 0,x=void 0,M=void 0,w=void 0,A=void 0,S=void 0,b=void 0,P=void 0,z=void 0,R=void 0,y=void 0,D=void 0,T=void 0,E=void 0,I=void 0,O=void 0;return Math.abs(h)<r.EPSILON?null:(s*=h=1/h,n*=h,o*=h,l=Math.sin(i),d=1-(c=Math.cos(i)),m=e[0],u=e[1],f=e[2],v=e[3],p=e[4],g=e[5],x=e[6],M=e[7],w=e[8],A=e[9],S=e[10],b=e[11],P=s*s*d+c,z=n*s*d+o*l,R=o*s*d-n*l,y=s*n*d-o*l,D=n*n*d+c,T=o*n*d+s*l,E=s*o*d+n*l,I=n*o*d-s*l,O=o*o*d+c,t[0]=m*P+p*z+w*R,t[1]=u*P+g*z+A*R,t[2]=f*P+x*z+S*R,t[3]=v*P+M*z+b*R,t[4]=m*y+p*D+w*T,t[5]=u*y+g*D+A*T,t[6]=f*y+x*D+S*T,t[7]=v*y+M*D+b*T,t[8]=m*E+p*I+w*O,t[9]=u*E+g*I+A*O,t[10]=f*E+x*I+S*O,t[11]=v*E+M*I+b*O,e!==t&&(t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]),t)},e.fromTranslation=function(t,e){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=e[0],t[13]=e[1],t[14]=e[2],t[15]=1,t},e.fromRotation=function(t,e,i){var a=i[0],s=i[1],n=i[2],o=Math.sqrt(a*a+s*s+n*n),h=void 0,l=void 0,c=void 0;return Math.abs(o)<r.EPSILON?null:(a*=o=1/o,s*=o,n*=o,h=Math.sin(e),c=1-(l=Math.cos(e)),t[0]=a*a*c+l,t[1]=s*a*c+n*h,t[2]=n*a*c-s*h,t[3]=0,t[4]=a*s*c-n*h,t[5]=s*s*c+l,t[6]=n*s*c+a*h,t[7]=0,t[8]=a*n*c+s*h,t[9]=s*n*c-a*h,t[10]=n*n*c+l,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.frustum=function(t,e,i,r,a,s,n){var o=1/(i-e),h=1/(a-r),l=1/(s-n);return t[0]=2*s*o,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*s*h,t[6]=0,t[7]=0,t[8]=(i+e)*o,t[9]=(a+r)*h,t[10]=(n+s)*l,t[11]=-1,t[12]=0,t[13]=0,t[14]=n*s*2*l,t[15]=0,t},e.ortho=function(t,e,i,r,a,s,n){var o=1/(e-i),h=1/(r-a),l=1/(s-n);return t[0]=-2*o,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*h,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*l,t[11]=0,t[12]=(e+i)*o,t[13]=(a+r)*h,t[14]=(n+s)*l,t[15]=1,t};var r=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}(i(0))}])});let Zoom,Zoom0,pixel=.75,BezierFactor=.4,FillFactor=.1,maxViewportWidth=window.innerWidth,maxViewportHeight=window.innerHeight,viewportmargin=0;const windowTrim=10;let zoomFactor,zoomPinchFactor,zoomPinchCap,zoomStep,shiftHoldDistance,shiftWaitTime,vibrateTime,lastzoom,H,zmin,zmax,size2,ArcballFactor,b,B,positionBuffer,materialBuffer,colorBuffer,indexBuffer,resizeStep=1.2,Fuzz2=1e3*Number.EPSILON,Fuzz4=Fuzz2*Fuzz2,third=1/3,P=[],Materials=[],Lights=[],Centers=[],absolute=!1,rotMat=mat4.create(),projMat=mat4.create(),viewMat=mat4.create(),projViewMat=mat4.create(),normMat=mat3.create(),viewMat3=mat3.create(),rotMats=mat4.create(),cjMatInv=mat4.create(),translMat=mat4.create(),center={x:0,y:0,z:0},shift={x:0,y:0},viewParam={xmin:0,xmax:0,ymin:0,ymax:0,zmin:0,zmax:0},redraw=!0,remesh=!0,mouseDownOrTouchActive=!1,lastMouseX=null,lastMouseY=null,touchID=null,Positions=[],Normals=[],Colors=[],Indices=[];class Material{constructor(t,e,i,r,a,s){this.diffuse=t,this.emissive=e,this.specular=i,this.shininess=r,this.metallic=a,this.fresnel0=s}setUniform(t,e,i=null){let r;r=null===i?i=>gl.getUniformLocation(t,e+"."+i):r=>gl.getUniformLocation(t,e+"["+i+"]."+r),gl.uniform4fv(r("diffuse"),new Float32Array(this.diffuse)),gl.uniform4fv(r("emissive"),new Float32Array(this.emissive)),gl.uniform4fv(r("specular"),new Float32Array(this.specular)),gl.uniform1f(r("shininess"),this.shininess),gl.uniform1f(r("metallic"),this.metallic),gl.uniform1f(r("fresnel0"),this.fresnel0)}}let enumPointLight=1,enumDirectionalLight=2;class Light{constructor(t,e){this.direction=t,this.color=e}setUniform(t,e,i){let r=r=>gl.getUniformLocation(t,e+"["+i+"]."+r);gl.uniform3fv(r("direction"),new Float32Array(this.direction)),gl.uniform3fv(r("color"),new Float32Array(this.color))}}function initGL(){try{gl=canvas.getContext("webgl",{alpha:!1})}catch(t){}gl||alert("Could not initialize WebGL")}function getShader(t,e,i=[]){let r=document.getElementById(e);if(!r)return null;let a=`#version 100\n#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n#else\n precision mediump float;\n#endif\n const int nLights=${Lights.length};\n const int nMaterials=${Materials.length};\n`;orthographic&&(a+="#define ORTHOGRAPHIC\n"),i.forEach(t=>a+="#define "+t+"\n");let s,n=r.firstChild;for(;n;)3==n.nodeType&&(a+=n.textContent),n=n.nextSibling;if("x-shader/x-fragment"==r.type)s=t.createShader(t.FRAGMENT_SHADER);else{if("x-shader/x-vertex"!=r.type)return null;s=t.createShader(t.VERTEX_SHADER)}return t.shaderSource(s,a),t.compileShader(s),t.getShaderParameter(s,t.COMPILE_STATUS)?s:(alert(t.getShaderInfoLog(s)),null)}function drawBuffer(t,e,i=t.indices){if(0==t.indices.length)return;let r=e==pixelShader,a=!r&&e!=noNormalShader;setUniforms(e),gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(t.vertices),gl.STATIC_DRAW),gl.vertexAttribPointer(e.vertexPositionAttribute,3,gl.FLOAT,!1,a?24:r?16:12,0),a?gl.vertexAttribPointer(e.vertexNormalAttribute,3,gl.FLOAT,!1,24,12):r&&gl.vertexAttribPointer(e.vertexWidthAttribute,1,gl.FLOAT,!1,16,12),gl.bindBuffer(gl.ARRAY_BUFFER,materialBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Int16Array(t.materials),gl.STATIC_DRAW),gl.vertexAttribPointer(e.vertexMaterialAttribute,1,gl.SHORT,!1,2,0),e!=colorShader&&e!=transparentShader||(gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Uint8Array(t.colors),gl.STATIC_DRAW),gl.vertexAttribPointer(e.vertexColorAttribute,4,gl.UNSIGNED_BYTE,!0,0,0)),gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer),gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexExt?new Uint32Array(i):new Uint16Array(i),gl.STATIC_DRAW),gl.drawElements(a?gl.TRIANGLES:r?gl.POINTS:gl.LINES,i.length,indexExt?gl.UNSIGNED_INT:gl.UNSIGNED_SHORT,0)}class vertexBuffer{constructor(){this.clear()}clear(){this.vertices=[],this.materials=[],this.colors=[],this.indices=[],this.nvertices=0}vertex(t,e){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.materials.push(materialIndex),this.nvertices++}Vertex(t,e,i=[0,0,0,0]){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.materials.push(materialIndex),this.colors.push(i[0]),this.colors.push(i[1]),this.colors.push(i[2]),this.colors.push(i[3]),this.nvertices++}vertex1(t){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.materials.push(materialIndex),this.nvertices++}vertex0(t,e){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e),this.materials.push(materialIndex),this.nvertices++}iVertex(t,e,i,r=[0,0,0,0]){let a=6*t;this.vertices[a]=e[0],this.vertices[a+1]=e[1],this.vertices[a+2]=e[2],this.vertices[a+3]=i[0],this.vertices[a+4]=i[1],this.vertices[a+5]=i[2],this.materials[t]=materialIndex;let s=4*t;this.colors[s]=r[0],this.colors[s+1]=r[1],this.colors[s+2]=r[2],this.colors[s+3]=r[3],this.indices.push(t)}append(t){append(this.vertices,t.vertices),append(this.materials,t.materials),append(this.colors,t.colors),appendOffset(this.indices,t.indices,this.nvertices),this.nvertices+=t.nvertices}}let materialIndex,material0Data=new vertexBuffer,material1Data=new vertexBuffer,materialData=new vertexBuffer,colorData=new vertexBuffer,transparentData=new vertexBuffer,triangleData=new vertexBuffer;function append(t,e){let i=t.length,r=e.length;t.length+=r;for(let a=0;a<r;++a)t[i+a]=e[a]}function appendOffset(t,e,i){let r=t.length,a=e.length;t.length+=e.length;for(let s=0;s<a;++s)t[r+s]=e[s]+i}class Geometry{constructor(){this.data=new vertexBuffer,this.Onscreen=!1,this.m=[]}offscreen(t){let e=projViewMat,i=t[0],r=i[0],a=i[1],s=i[2],n=1/(e[3]*r+e[7]*a+e[11]*s+e[15]);this.x=this.X=(e[0]*r+e[4]*a+e[8]*s+e[12])*n,this.y=this.Y=(e[1]*r+e[5]*a+e[9]*s+e[13])*n;for(let i=1,r=t.length;i<r;++i){let r=t[i],a=r[0],s=r[1],n=r[2],o=1/(e[3]*a+e[7]*s+e[11]*n+e[15]),h=(e[0]*a+e[4]*s+e[8]*n+e[12])*o,l=(e[1]*a+e[5]*s+e[9]*n+e[13])*o;h<this.x?this.x=h:h>this.X&&(this.X=h),l<this.y?this.y=l:l>this.Y&&(this.Y=l)}return(this.X<-1.01||this.x>1.01||this.Y<-1.01||this.y>1.01)&&(this.Onscreen=!1,!0)}T(t){let e=this.c[0],i=this.c[1],r=this.c[2],a=t[0]-e,s=t[1]-i,n=t[2]-r;return[a*normMat[0]+s*normMat[3]+n*normMat[6]+e,a*normMat[1]+s*normMat[4]+n*normMat[7]+i,a*normMat[2]+s*normMat[5]+n*normMat[8]+r]}Tcorners(t,e){return[this.T(t),this.T([t[0],t[1],e[2]]),this.T([t[0],e[1],t[2]]),this.T([t[0],e[1],e[2]]),this.T([e[0],t[1],t[2]]),this.T([e[0],t[1],e[2]]),this.T([e[0],e[1],t[2]]),this.T(e)]}render(){let t;if(0==this.CenterIndex?t=corners(this.Min,this.Max):(this.c=Centers[this.CenterIndex-1],t=this.Tcorners(this.Min,this.Max)),this.offscreen(t))return void this.data.clear();let e,i=this.controlpoints;if(0==this.CenterIndex){if(!remesh&&this.Onscreen)return void this.append();e=i}else{let t=i.length;e=Array(t);for(let r=0;r<t;++r)e[r]=this.T(i[r])}materialIndex=this.MaterialIndex;let r=orthographic?1:this.Min[2]/B[2],a=pixel*Math.hypot(r*(viewParam.xmax-viewParam.xmin),r*(viewParam.ymax-viewParam.ymin))/size2;this.res2=a*a,this.Epsilon=FillFactor*a,this.data.clear(),this.Onscreen=!0,this.process(e)}}class BezierPatch extends Geometry{constructor(t,e,i,r,a,s){super(),this.controlpoints=t,this.Min=r,this.Max=a,this.color=s,this.CenterIndex=e;let n=t.length;if(s){let t=s[0][3]+s[1][3]+s[2][3];this.transparent=16==n||4==n?t+s[3][3]<1020:t<765}else this.transparent=Materials[i].diffuse[3]<1;this.transparent?(this.MaterialIndex=s?-1-i:1+i,this.vertex=this.data.Vertex.bind(this.data)):(this.MaterialIndex=i,this.vertex=this.data.vertex.bind(this.data)),this.L2norm(this.controlpoints)}L2norm(t){let e=t[0];this.epsilon=0;let i=t.length;for(let r=1;r<i;++r)this.epsilon=Math.max(this.epsilon,abs2([t[r][0]-e[0],t[r][1]-e[1],t[r][2]-e[2]]));this.epsilon*=Fuzz4}processTriangle(t){let e=t[0],i=t[1],r=t[2],a=unit(cross([i[0]-e[0],i[1]-e[1],i[2]-e[2]],[r[0]-e[0],r[1]-e[1],r[2]-e[2]]));this.offscreen([e,i,r])||(this.color?(this.data.indices.push(this.data.Vertex(e,a,this.color[0])),this.data.indices.push(this.data.Vertex(i,a,this.color[1])),this.data.indices.push(this.data.Vertex(r,a,this.color[2]))):(this.data.indices.push(this.vertex(e,a)),this.data.indices.push(this.vertex(i,a)),this.data.indices.push(this.vertex(r,a))),this.append())}processQuad(t){let e=t[0],i=t[1],r=t[2],a=t[3],s=cross([i[0]-e[0],i[1]-e[1],i[2]-e[2]],[r[0]-i[0],r[1]-i[1],r[2]-i[2]]),n=cross([r[0]-a[0],r[1]-a[1],r[2]-a[2]],[a[0]-e[0],a[1]-e[1],a[2]-e[2]]),o=unit([s[0]+n[0],s[1]+n[1],s[2]+n[2]]);if(!this.offscreen([e,i,r,a])){let t,s,n,h;this.color?(t=this.data.Vertex(e,o,this.color[0]),s=this.data.Vertex(i,o,this.color[1]),n=this.data.Vertex(r,o,this.color[2]),h=this.data.Vertex(a,o,this.color[3])):(t=this.vertex(e,o),s=this.vertex(i,o),n=this.vertex(r,o),h=this.vertex(a,o)),this.data.indices.push(t),this.data.indices.push(s),this.data.indices.push(n),this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(h),this.append()}}process(t){if(10==t.length)return this.process3(t);if(3==t.length)return this.processTriangle(t);if(4==t.length)return this.processQuad(t);let e=t[0],i=t[3],r=t[12],a=t[15],s=this.normal(i,t[2],t[1],e,t[4],t[8],r);iszero(s)&&iszero(s=this.normal(i,t[2],t[1],e,t[13],t[14],a))&&(s=this.normal(a,t[11],t[7],i,t[4],t[8],r));let n=this.normal(e,t[4],t[8],r,t[13],t[14],a);iszero(n)&&iszero(n=this.normal(e,t[4],t[8],r,t[11],t[7],i))&&(n=this.normal(i,t[2],t[1],e,t[13],t[14],a));let o=this.normal(r,t[13],t[14],a,t[11],t[7],i);iszero(o)&&iszero(o=this.normal(r,t[13],t[14],a,t[2],t[1],e))&&(o=this.normal(e,t[4],t[8],r,t[11],t[7],i));let h=this.normal(a,t[11],t[7],i,t[2],t[1],e);if(iszero(h)&&iszero(h=this.normal(a,t[11],t[7],i,t[4],t[8],r))&&(h=this.normal(r,t[13],t[14],a,t[2],t[1],e)),this.color){let l=this.color[0],c=this.color[1],d=this.color[2],m=this.color[3],u=this.data.Vertex(e,s,l),f=this.data.Vertex(r,n,c),v=this.data.Vertex(a,o,d),p=this.data.Vertex(i,h,m);this.Render(t,u,f,v,p,e,r,a,i,!1,!1,!1,!1,l,c,d,m)}else{let l=this.vertex(e,s),c=this.vertex(r,n),d=this.vertex(a,o),m=this.vertex(i,h);this.Render(t,l,c,d,m,e,r,a,i,!1,!1,!1,!1)}this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):this.color?colorData.append(this.data):materialData.append(this.data)}Render(t,e,i,r,a,s,n,o,h,l,c,d,m,u,f,v,p){if(this.Distance(t)<this.res2)this.offscreen([s,n,o])||(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(r)),this.offscreen([s,o,h])||(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(a));else{if(this.offscreen(t))return;let g=t[0],x=t[3],M=t[12],w=t[15],A=new Split3(g,t[1],t[2],x),S=new Split3(t[4],t[5],t[6],t[7]),b=new Split3(t[8],t[9],t[10],t[11]),P=new Split3(M,t[13],t[14],w),z=new Split3(g,t[4],t[8],M),R=new Split3(A.m0,S.m0,b.m0,P.m0),y=new Split3(A.m3,S.m3,b.m3,P.m3),D=new Split3(A.m5,S.m5,b.m5,P.m5),T=new Split3(A.m4,S.m4,b.m4,P.m4),E=new Split3(A.m2,S.m2,b.m2,P.m2),I=new Split3(x,t[7],t[11],w),O=[g,A.m0,A.m3,A.m5,z.m0,R.m0,y.m0,D.m0,z.m3,R.m3,y.m3,D.m3,z.m5,R.m5,y.m5,D.m5],_=[z.m5,R.m5,y.m5,D.m5,z.m4,R.m4,y.m4,D.m4,z.m2,R.m2,y.m2,D.m2,M,P.m0,P.m3,P.m5],B=[D.m5,T.m5,E.m5,I.m5,D.m4,T.m4,E.m4,I.m4,D.m2,T.m2,E.m2,I.m2,P.m5,P.m4,P.m2,w],C=[A.m5,A.m4,A.m2,x,D.m0,T.m0,E.m0,I.m0,D.m3,T.m3,E.m3,I.m3,D.m5,T.m5,E.m5,I.m5],F=O[15],L=this.normal(O[0],O[4],O[8],O[12],O[13],O[14],O[15]);iszero(L)&&iszero(L=this.normal(O[0],O[4],O[8],O[12],O[11],O[7],O[3]))&&(L=this.normal(O[3],O[2],O[1],O[0],O[13],O[14],O[15]));let V=this.normal(_[12],_[13],_[14],_[15],_[11],_[7],_[3]);iszero(V)&&iszero(V=this.normal(_[12],_[13],_[14],_[15],_[2],_[1],_[0]))&&(V=this.normal(_[0],_[4],_[8],_[12],_[11],_[7],_[3]));let N=this.normal(B[15],B[11],B[7],B[3],B[2],B[1],B[0]);iszero(N)&&iszero(N=this.normal(B[15],B[11],B[7],B[3],B[4],B[8],B[12]))&&(N=this.normal(B[12],B[13],B[14],B[15],B[2],B[1],B[0]));let H=this.normal(C[3],C[2],C[1],C[0],C[4],C[8],C[12]);iszero(H)&&iszero(H=this.normal(C[3],C[2],C[1],C[0],C[13],C[14],C[15]))&&(H=this.normal(C[15],C[11],C[7],C[3],C[4],C[8],C[12]));let U=this.normal(B[3],B[2],B[1],F,B[4],B[8],B[12]),W=this.Epsilon,Y=[.5*(s[0]+n[0]),.5*(s[1]+n[1]),.5*(s[2]+n[2])];if(!l)if(l=Straightness(g,t[4],t[8],M)<this.res2){let t=unit(this.derivative(_[0],_[1],_[2],_[3]));Y=[Y[0]-W*t[0],Y[1]-W*t[1],Y[2]-W*t[2]]}else Y=O[12];let j=[.5*(n[0]+o[0]),.5*(n[1]+o[1]),.5*(n[2]+o[2])];if(!c)if(c=Straightness(M,t[13],t[14],w)<this.res2){let t=unit(this.derivative(B[12],B[8],B[4],B[0]));j=[j[0]-W*t[0],j[1]-W*t[1],j[2]-W*t[2]]}else j=_[15];let G=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])];if(!d)if(d=Straightness(w,t[11],t[7],x)<this.res2){let t=unit(this.derivative(C[15],B[14],B[13],_[12]));G=[G[0]-W*t[0],G[1]-W*t[1],G[2]-W*t[2]]}else G=B[3];let k=[.5*(h[0]+s[0]),.5*(h[1]+s[1]),.5*(h[2]+s[2])];if(!m)if(m=Straightness(g,t[1],t[2],x)<this.res2){let t=unit(this.derivative(O[3],O[7],O[11],O[15]));k=[k[0]-W*t[0],k[1]-W*t[1],k[2]-W*t[2]]}else k=C[0];if(u){let t=Array(4),g=Array(4),x=Array(4),M=Array(4),w=Array(4);for(let e=0;e<4;++e)t[e]=.5*(u[e]+f[e]),g[e]=.5*(f[e]+v[e]),x[e]=.5*(v[e]+p[e]),M[e]=.5*(p[e]+u[e]),w[e]=.5*(t[e]+x[e]);let A=this.data.Vertex(Y,L,t),S=this.data.Vertex(j,V,g),b=this.data.Vertex(G,N,x),P=this.data.Vertex(k,H,M),z=this.data.Vertex(F,U,w);this.Render(O,e,A,z,P,s,Y,F,k,l,!1,!1,m,u,t,w,M),this.Render(_,A,i,S,z,Y,n,j,F,l,c,!1,!1,t,f,g,w),this.Render(B,z,S,r,b,F,j,o,G,!1,c,d,!1,w,g,v,x),this.Render(C,P,z,b,a,k,F,G,h,!1,!1,d,m,M,w,x,p)}else{let t=this.vertex(Y,L),u=this.vertex(j,V),f=this.vertex(G,N),v=this.vertex(k,H),p=this.vertex(F,U);this.Render(O,e,t,p,v,s,Y,F,k,l,!1,!1,m),this.Render(_,t,i,u,p,Y,n,j,F,l,c,!1,!1),this.Render(B,p,u,r,f,F,j,o,G,!1,c,d,!1),this.Render(C,v,p,f,a,k,F,G,h,!1,!1,d,m)}}}process3(t){this.Res2=BezierFactor*BezierFactor*this.res2;let e=t[0],i=t[6],r=t[9],a=this.normal(r,t[5],t[2],e,t[1],t[3],i),s=this.normal(e,t[1],t[3],i,t[7],t[8],r),n=this.normal(i,t[7],t[8],r,t[5],t[2],e);if(this.color){let o=this.color[0],h=this.color[1],l=this.color[2],c=this.data.Vertex(e,a,o),d=this.data.Vertex(i,s,h),m=this.data.Vertex(r,n,l);this.Render3(t,c,d,m,e,i,r,!1,!1,!1,o,h,l)}else{let o=this.vertex(e,a),h=this.vertex(i,s),l=this.vertex(r,n);this.Render3(t,o,h,l,e,i,r,!1,!1,!1)}this.data.indices.length>0&&this.append()}Render3(t,e,i,r,a,s,n,o,h,l,c,d,m){if(this.Distance3(t)<this.Res2)this.offscreen([a,s,n])||(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(r));else{if(this.offscreen(t))return;let u=t[0],f=t[1],v=t[2],p=t[3],g=t[4],x=t[5],M=t[6],w=t[7],A=t[8],S=t[9],b=[.5*(S[0]+x[0]),.5*(S[1]+x[1]),.5*(S[2]+x[2])],P=[.5*(S[0]+A[0]),.5*(S[1]+A[1]),.5*(S[2]+A[2])],z=[.5*(x[0]+v[0]),.5*(x[1]+v[1]),.5*(x[2]+v[2])],R=[.5*(A[0]+g[0]),.5*(A[1]+g[1]),.5*(A[2]+g[2])],y=[.5*(A[0]+w[0]),.5*(A[1]+w[1]),.5*(A[2]+w[2])],D=[.5*(v[0]+g[0]),.5*(v[1]+g[1]),.5*(v[2]+g[2])],T=[.5*(v[0]+u[0]),.5*(v[1]+u[1]),.5*(v[2]+u[2])],E=[.5*(g[0]+p[0]),.5*(g[1]+p[1]),.5*(g[2]+p[2])],I=[.5*(w[0]+M[0]),.5*(w[1]+M[1]),.5*(w[2]+M[2])],O=[.5*(u[0]+f[0]),.5*(u[1]+f[1]),.5*(u[2]+f[2])],_=[.5*(f[0]+p[0]),.5*(f[1]+p[1]),.5*(f[2]+p[2])],B=[.5*(p[0]+M[0]),.5*(p[1]+M[1]),.5*(p[2]+M[2])],C=[.5*(b[0]+z[0]),.5*(b[1]+z[1]),.5*(b[2]+z[2])],F=[.5*(P[0]+y[0]),.5*(P[1]+y[1]),.5*(P[2]+y[2])],L=[.5*(z[0]+T[0]),.5*(z[1]+T[1]),.5*(z[2]+T[2])],V=[.5*R[0]+.25*(g[0]+f[0]),.5*R[1]+.25*(g[1]+f[1]),.5*R[2]+.25*(g[2]+f[2])],N=[.5*(y[0]+I[0]),.5*(y[1]+I[1]),.5*(y[2]+I[2])],H=[.5*D[0]+.25*(g[0]+w[0]),.5*D[1]+.25*(g[1]+w[1]),.5*D[2]+.25*(g[2]+w[2])],U=[.25*(x[0]+g[0])+.5*E[0],.25*(x[1]+g[1])+.5*E[1],.25*(x[2]+g[2])+.5*E[2]],W=[.5*(O[0]+_[0]),.5*(O[1]+_[1]),.5*(O[2]+_[2])],Y=[.5*(_[0]+B[0]),.5*(_[1]+B[1]),.5*(_[2]+B[2])],j=[.5*(H[0]+W[0]),.5*(H[1]+W[1]),.5*(H[2]+W[2])],G=[.5*(H[0]+Y[0]),.5*(H[1]+Y[1]),.5*(H[2]+Y[2])],k=[.5*(W[0]+Y[0]),.5*(W[1]+Y[1]),.5*(W[2]+Y[2])],X=[.5*(U[0]+N[0]),.5*(U[1]+N[1]),.5*(U[2]+N[2])],Z=[.5*(F[0]+U[0]),.5*(F[1]+U[1]),.5*(F[2]+U[2])],q=[.5*(F[0]+N[0]),.5*(F[1]+N[1]),.5*(F[2]+N[2])],K=[.5*(C[0]+V[0]),.5*(C[1]+V[1]),.5*(C[2]+V[2])],Q=[.5*(L[0]+V[0]),.5*(L[1]+V[1]),.5*(L[2]+V[2])],$=[.5*(C[0]+L[0]),.5*(C[1]+L[1]),.5*(C[2]+L[2])],J=[u,O,T,W,[.5*(D[0]+O[0]),.5*(D[1]+O[1]),.5*(D[2]+O[2])],L,k,j,Q,$],tt=[k,Y,G,B,[.5*(E[0]+I[0]),.5*(E[1]+I[1]),.5*(E[2]+I[2])],X,M,I,N,q],et=[$,K,C,Z,[.5*(b[0]+R[0]),.5*(b[1]+R[1]),.5*(b[2]+R[2])],b,q,F,P,S],it=[q,Z,X,K,[.25*(z[0]+y[0]+_[0]+g[0]),.25*(z[1]+y[1]+_[1]+g[1]),.25*(z[2]+y[2]+_[2]+g[2])],G,$,Q,j,k],rt=this.normal(k,G,X,q,Z,K,$),at=this.normal(q,Z,K,$,Q,j,k),st=this.normal($,Q,j,k,G,X,q),nt=this.Epsilon,ot=[.5*(s[0]+n[0]),.5*(s[1]+n[1]),.5*(s[2]+n[2])];if(!o)if(o=Straightness(M,w,A,S)<this.res2){let t=unit(this.sumderivative(it[0],it[2],it[5],it[9],it[1],it[3],it[6]));ot=[ot[0]-nt*t[0],ot[1]-nt*t[1],ot[2]-nt*t[2]]}else ot=q;let ht=[.5*(n[0]+a[0]),.5*(n[1]+a[1]),.5*(n[2]+a[2])];if(!h)if(h=Straightness(u,v,x,S)<this.res2){let t=unit(this.sumderivative(it[6],it[3],it[1],it[0],it[7],it[8],it[9]));ht=[ht[0]-nt*t[0],ht[1]-nt*t[1],ht[2]-nt*t[2]]}else ht=$;let lt=[.5*(a[0]+s[0]),.5*(a[1]+s[1]),.5*(a[2]+s[2])];if(!l)if(l=Straightness(u,f,p,M)<this.res2){let t=unit(this.sumderivative(it[9],it[8],it[7],it[6],it[5],it[2],it[0]));lt=[lt[0]-nt*t[0],lt[1]-nt*t[1],lt[2]-nt*t[2]]}else lt=k;if(c){let t=Array(4),u=Array(4),f=Array(4);for(let e=0;e<4;++e)t[e]=.5*(d[e]+m[e]),u[e]=.5*(m[e]+c[e]),f[e]=.5*(c[e]+d[e]);let v=this.data.Vertex(ot,rt,t),p=this.data.Vertex(ht,at,u),g=this.data.Vertex(lt,st,f);this.Render3(J,e,g,p,a,lt,ht,!1,h,l,c,f,u),this.Render3(tt,g,i,v,lt,s,ot,o,!1,l,f,d,t),this.Render3(et,p,v,r,ht,ot,n,o,h,!1,u,t,m),this.Render3(it,v,p,g,ot,ht,lt,!1,!1,!1,t,u,f)}else{let t=this.vertex(ot,rt),c=this.vertex(ht,at),d=this.vertex(lt,st);this.Render3(J,e,d,c,a,lt,ht,!1,h,l),this.Render3(tt,d,i,t,lt,s,ot,o,!1,l),this.Render3(et,c,t,r,ht,ot,n,o,h,!1),this.Render3(it,t,c,d,ot,ht,lt,!1,!1,!1)}}}Distance(t){let e=t[0],i=t[3],r=t[12],a=t[15],s=Distance2(a,e,this.normal(i,t[2],t[1],e,t[4],t[8],r));return s=Math.max(s,Straightness(e,t[1],t[2],i)),s=Math.max(s,Straightness(e,t[4],t[8],r)),s=Math.max(s,Straightness(i,t[7],t[11],a)),s=Math.max(s,Straightness(r,t[13],t[14],a)),s=Math.max(s,Straightness(t[4],t[5],t[6],t[7])),s=Math.max(s,Straightness(t[8],t[9],t[10],t[11])),s=Math.max(s,Straightness(t[1],t[5],t[9],t[13])),Math.max(s,Straightness(t[2],t[6],t[10],t[14]))}Distance3(t){let e=t[0],i=t[4],r=t[6],a=t[9],s=abs2([(e[0]+r[0]+a[0])*third-i[0],(e[1]+r[1]+a[1])*third-i[1],(e[2]+r[2]+a[2])*third-i[2]]);return s=Math.max(s,Straightness(e,t[1],t[3],r)),s=Math.max(s,Straightness(e,t[2],t[5],a)),Math.max(s,Straightness(r,t[7],t[8],a))}derivative(t,e,i,r){let a=[e[0]-t[0],e[1]-t[1],e[2]-t[2]];if(abs2(a)>this.epsilon)return a;let s=bezierPP(t,e,i);return abs2(s)>this.epsilon?s:bezierPPP(t,e,i,r)}sumderivative(t,e,i,r,a,s,n){let o=this.derivative(t,e,i,r),h=this.derivative(t,a,s,n);return[o[0]+h[0],o[1]+h[1],o[2]+h[2]]}normal(t,e,i,r,a,s,n){let o=a[0]-r[0],h=a[1]-r[1],l=a[2]-r[2],c=i[0]-r[0],d=i[1]-r[1],m=i[2]-r[2],u=[h*m-l*d,l*c-o*m,o*d-h*c];if(abs2(u)>this.epsilon)return unit(u);let f=[c,d,m],v=[o,h,l],p=bezierPP(r,i,e),g=bezierPP(r,a,s),x=cross(g,f),M=cross(v,p);if(abs2(u=[x[0]+M[0],x[1]+M[1],x[2]+M[2]])>this.epsilon)return unit(u);let w=bezierPPP(r,i,e,t),A=bezierPPP(r,a,s,n);x=cross(g,p),M=cross(v,w);let S=cross(A,f),b=cross(A,p),P=cross(g,w),z=cross(A,w);return unit([9*x[0]+3*(M[0]+S[0]+b[0]+P[0])+z[0],9*x[1]+3*(M[1]+S[1]+b[1]+P[1])+z[1],9*x[2]+3*(M[2]+S[2]+b[2]+P[2])+z[2]])}}class BezierCurve extends Geometry{constructor(t,e,i,r,a){super(),this.controlpoints=t,this.Min=r,this.Max=a,this.CenterIndex=e,this.MaterialIndex=i}processLine(t){let e=t[0],i=t[1];this.offscreen([e,i])||(this.data.indices.push(this.data.vertex1(e)),this.data.indices.push(this.data.vertex1(i)),this.append())}process(t){if(2==t.length)return this.processLine(t);let e=this.data.vertex1(t[0]),i=this.data.vertex1(t[3]);this.Render(t,e,i),this.data.indices.length>0&&this.append()}append(){material1Data.append(this.data)}Render(t,e,i){let r=t[0],a=t[1],s=t[2],n=t[3];if(Straightness(r,a,s,n)<this.res2)this.offscreen([r,n])||(this.data.indices.push(e),this.data.indices.push(i));else{if(this.offscreen(t))return;let o=[.5*(r[0]+a[0]),.5*(r[1]+a[1]),.5*(r[2]+a[2])],h=[.5*(a[0]+s[0]),.5*(a[1]+s[1]),.5*(a[2]+s[2])],l=[.5*(s[0]+n[0]),.5*(s[1]+n[1]),.5*(s[2]+n[2])],c=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])],d=[.5*(h[0]+l[0]),.5*(h[1]+l[1]),.5*(h[2]+l[2])],m=[.5*(c[0]+d[0]),.5*(c[1]+d[1]),.5*(c[2]+d[2])],u=[r,o,c,m],f=[m,d,l,n],v=this.data.vertex1(m);this.Render(u,e,v),this.Render(f,v,i)}}}class Pixel extends Geometry{constructor(t,e,i,r,a){super(),this.controlpoint=t,this.width=e,this.CenterIndex=0,this.MaterialIndex=i,this.Min=r,this.Max=a}process(t){this.data.indices.push(this.data.vertex0(this.controlpoint,this.width)),this.append()}append(){material0Data.append(this.data)}}class Triangles extends Geometry{constructor(t,e,i){super(),this.CenterIndex=0,this.MaterialIndex=t,this.Min=e,this.Max=i,this.Positions=Positions,this.Normals=Normals,this.Colors=Colors,this.Indices=Indices,Positions=[],Normals=[],Colors=[],Indices=[],this.transparent=Materials[t].diffuse[3]<1}process(t){for(let t=0,e=this.Indices.length;t<e;++t){let e=this.Indices[t],i=e[0],r=this.Positions[i[0]],a=this.Positions[i[1]],s=this.Positions[i[2]];if(!this.offscreen([r,a,s])){let t=e.length>1?e[1]:i;if(t&&0!=t.length||(t=i),this.Colors.length>0){let n=e.length>2?e[2]:i;n&&0!=n.length||(n=i);let o=this.Colors[n[0]],h=this.Colors[n[1]],l=this.Colors[n[2]];this.transparent|=o[3]+h[3]+l[3]<765,materialIndex=-1-this.MaterialIndex,this.data.iVertex(i[0],r,this.Normals[t[0]],o),this.data.iVertex(i[1],a,this.Normals[t[1]],h),this.data.iVertex(i[2],s,this.Normals[t[2]],l)}else materialIndex=1+this.MaterialIndex,this.data.iVertex(i[0],r,this.Normals[t[0]]),this.data.iVertex(i[1],a,this.Normals[t[1]]),this.data.iVertex(i[2],s,this.Normals[t[2]])}}this.data.nvertices=this.Positions.length,this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):triangleData.append(this.data)}}function home(){mat4.identity(rotMat),initProjection(),setProjection(),redraw=!0}function initShader(t=[]){let e=getShader(gl,"fragment",t),i=getShader(gl,"vertex",t),r=gl.createProgram();return gl.attachShader(r,i),gl.attachShader(r,e),gl.linkProgram(r),gl.getProgramParameter(r,gl.LINK_STATUS)||alert("Could not initialize shaders"),r}class Split3{constructor(t,e,i,r){this.m0=[.5*(t[0]+e[0]),.5*(t[1]+e[1]),.5*(t[2]+e[2])];let a=.5*(e[0]+i[0]),s=.5*(e[1]+i[1]),n=.5*(e[2]+i[2]);this.m2=[.5*(i[0]+r[0]),.5*(i[1]+r[1]),.5*(i[2]+r[2])],this.m3=[.5*(this.m0[0]+a),.5*(this.m0[1]+s),.5*(this.m0[2]+n)],this.m4=[.5*(a+this.m2[0]),.5*(s+this.m2[1]),.5*(n+this.m2[2])],this.m5=[.5*(this.m3[0]+this.m4[0]),.5*(this.m3[1]+this.m4[1]),.5*(this.m3[2]+this.m4[2])]}}function iszero(t){return 0==t[0]&&0==t[1]&&0==t[2]}function unit(t){let e=1/(Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2])||1);return[t[0]*e,t[1]*e,t[2]*e]}function abs2(t){return t[0]*t[0]+t[1]*t[1]+t[2]*t[2]}function dot(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function cross(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function bezierPP(t,e,i){return[t[0]+i[0]-2*e[0],t[1]+i[1]-2*e[1],t[2]+i[2]-2*e[2]]}function bezierPPP(t,e,i,r){return[r[0]-t[0]+3*(e[0]-i[0]),r[1]-t[1]+3*(e[1]-i[1]),r[2]-t[2]+3*(e[2]-i[2])]}function Straightness(t,e,i,r){let a=[third*(r[0]-t[0]),third*(r[1]-t[1]),third*(r[2]-t[2])];return Math.max(abs2([e[0]-a[0]-t[0],e[1]-a[1]-t[1],e[2]-a[2]-t[2]]),abs2([r[0]-a[0]-i[0],r[1]-a[1]-i[1],r[2]-a[2]-i[2]]))}function Distance2(t,e,i){let r=dot([t[0]-e[0],t[1]-e[1],t[2]-e[2]],i);return r*r}function corners(t,e){return[t,[t[0],t[1],e[2]],[t[0],e[1],t[2]],[t[0],e[1],e[2]],[e[0],t[1],t[2]],[e[0],t[1],e[2]],[e[0],e[1],t[2]],e]}function COBTarget(t,e){mat4.fromTranslation(translMat,[center.x,center.y,center.z]),mat4.invert(cjMatInv,translMat),mat4.multiply(t,e,cjMatInv),mat4.multiply(t,translMat,t)}function setUniforms(t){let e=t==pixelShader;gl.useProgram(t),t.vertexPositionAttribute=gl.getAttribLocation(t,"position"),gl.enableVertexAttribArray(t.vertexPositionAttribute),e&&(t.vertexWidthAttribute=gl.getAttribLocation(t,"width"),gl.enableVertexAttribArray(t.vertexWidthAttribute)),t==noNormalShader||e||(t.vertexNormalAttribute=gl.getAttribLocation(t,"normal"),gl.enableVertexAttribArray(t.vertexNormalAttribute)),t.vertexMaterialAttribute=gl.getAttribLocation(t,"materialIndex"),gl.enableVertexAttribArray(t.vertexMaterialAttribute),t.projViewMatUniform=gl.getUniformLocation(t,"projViewMat"),t.viewMatUniform=gl.getUniformLocation(t,"viewMat"),t.normMatUniform=gl.getUniformLocation(t,"normMat"),t!=colorShader&&t!=transparentShader||(t.vertexColorAttribute=gl.getAttribLocation(t,"color"),gl.enableVertexAttribArray(t.vertexColorAttribute));for(let e=0;e<Materials.length;++e)Materials[e].setUniform(t,"Materials",e);for(let e=0;e<Lights.length;++e)Lights[e].setUniform(t,"Lights",e);gl.uniformMatrix4fv(t.projViewMatUniform,!1,projViewMat),gl.uniformMatrix4fv(t.viewMatUniform,!1,viewMat),gl.uniformMatrix3fv(t.normMatUniform,!1,normMat)}function handleMouseDown(t){mouseDownOrTouchActive=!0,lastMouseX=t.clientX,lastMouseY=t.clientY}let pinchStart,touchStartTime,pinch=!1;function pinchDistance(t){return Math.hypot(t[0].pageX-t[1].pageX,t[0].pageY-t[1].pageY)}function handleTouchStart(t){t.preventDefault();let e=t.targetTouches;swipe=rotate=pinch=!1,zooming||(1!=e.length||mouseDownOrTouchActive||(touchStartTime=(new Date).getTime(),touchId=e[0].identifier,lastMouseX=e[0].pageX,lastMouseY=e[0].pageY),2!=e.length||mouseDownOrTouchActive||(touchId=e[0].identifier,pinchStart=pinchDistance(e),pinch=!0))}function handleMouseUpOrTouchEnd(t){mouseDownOrTouchActive=!1}function rotateScene(t,e,i,r,a){if(t==i&&e==r)return;let[s,n]=arcball([t,-e],[i,-r]);mat4.fromRotation(rotMats,2*a*ArcballFactor*s/lastzoom,n),mat4.multiply(rotMat,rotMats,rotMat)}function shiftScene(t,e,i,r){let a=1/lastzoom;shift.x+=(i-t)*a*halfCanvasWidth,shift.y-=(r-e)*a*halfCanvasHeight}function panScene(t,e,i,r){orthographic?shiftScene(t,e,i,r):(center.x+=(i-t)*(viewParam.xmax-viewParam.xmin),center.y-=(r-e)*(viewParam.ymax-viewParam.ymin))}function updateViewMatrix(){COBTarget(viewMat,rotMat),mat4.translate(viewMat,viewMat,[center.x,center.y,0]),mat3.fromMat4(viewMat3,viewMat),mat3.invert(normMat,viewMat3),mat4.multiply(projViewMat,projMat,viewMat)}function capzoom(){let t=Math.sqrt(Number.MAX_VALUE),e=1/t;Zoom<=e&&(Zoom=e),Zoom>=t&&(Zoom=t),Zoom!=lastzoom&&(remesh=!0),lastzoom=Zoom}function zoomImage(t){let e=zoomStep*halfCanvasHeight*t;const i=Math.log(.1*Number.MAX_VALUE)/Math.log(zoomFactor);Math.abs(e)<i&&(Zoom*=zoomFactor**e,capzoom())}function normMouse(t){let e=t[0],i=t[1],r=Math.hypot(e,i);return r>1&&(denom=1/r,e*=denom,i*=denom),[e,i,Math.sqrt(Math.max(1-i*i-e*e,0))]}function arcball(t,e){let i=normMouse(t),r=normMouse(e),a=dot(i,r);return a>1?a=1:a<-1&&(a=-1),[Math.acos(a),unit(cross(i,r))]}function zoomScene(t,e,i,r){zoomImage(e-r)}const DRAGMODE_ROTATE=1,DRAGMODE_SHIFT=2,DRAGMODE_ZOOM=3,DRAGMODE_PAN=4;function processDrag(t,e,i,r=1){let a;switch(i){case DRAGMODE_ROTATE:a=rotateScene;break;case DRAGMODE_SHIFT:a=shiftScene;break;case DRAGMODE_ZOOM:a=zoomScene;break;case DRAGMODE_PAN:a=panScene;break;default:a=((t,e,i,r)=>{})}a((lastMouseX-halfCanvasWidth)/halfCanvasWidth,(lastMouseY-halfCanvasHeight)/halfCanvasHeight,(t-halfCanvasWidth)/halfCanvasWidth,(e-halfCanvasHeight)/halfCanvasHeight,r),lastMouseX=t,lastMouseY=e,setProjection(),redraw=!0}function handleKey(t){let e=[];switch(t.key){case"x":e=[1,0,0];break;case"y":e=[0,1,0];break;case"z":e=[0,0,1];break;case"h":home();break;case"+":case"=":case">":expand();break;case"-":case"_":case"<":shrink()}e.length>0&&(mat4.rotate(rotMat,rotMat,.1,e),updateViewMatrix(),redraw=!0)}function handleMouseWheel(t){t.deltaY<0?Zoom*=zoomFactor:Zoom/=zoomFactor,capzoom(),setProjection(),redraw=!0}function handleMouseMove(t){if(!mouseDownOrTouchActive)return;let e;processDrag(t.clientX,t.clientY,e=t.getModifierState("Control")?DRAGMODE_SHIFT:t.getModifierState("Shift")?DRAGMODE_ZOOM:t.getModifierState("Alt")?DRAGMODE_PAN:DRAGMODE_ROTATE)}let indexExt,zooming=!1,swipe=!1,rotate=!1;function handleTouchMove(t){if(t.preventDefault(),zooming)return;let e=t.targetTouches;if(!pinch&&1==e.length&&touchId==e[0].identifier){let t=e[0].pageX,i=e[0].pageY,r=t-lastMouseX,a=i-lastMouseY,s=r*r+a*a<=shiftHoldDistance*shiftHoldDistance;if(s&&!swipe&&!rotate&&(new Date).getTime()-touchStartTime>shiftWaitTime&&(navigator.vibrate&&window.navigator.vibrate(vibrateTime),swipe=!0),swipe)processDrag(t,i,DRAGMODE_SHIFT);else if(!s){rotate=!0,processDrag(e[0].pageX,e[0].pageY,DRAGMODE_ROTATE,.5)}}if(pinch&&!swipe&&2==e.length&&touchId==e[0].identifier){let t=pinchDistance(e),i=t-pinchStart;zooming=!0,(i*=zoomPinchFactor)>zoomPinchCap&&(i=zoomPinchCap),i<-zoomPinchCap&&(i=-zoomPinchCap),zoomImage(i/size2),pinchStart=t,swipe=rotate=zooming=!1,setProjection(),redraw=!0}}function setBuffer(){positionBuffer=gl.createBuffer(),materialBuffer=gl.createBuffer(),colorBuffer=gl.createBuffer(),indexBuffer=gl.createBuffer(),indexExt=gl.getExtension("OES_element_index_uint")}let pixelShader,noNormalShader,materialShader,colorShader,transparentShader,zbuffer=[];function transformVertices(t){let e=viewMat[2],i=viewMat[6],r=viewMat[10];zbuffer.length=t.length;for(let a=0;a<t.length;++a){let s=6*a;zbuffer[a]=e*t[s]+i*t[s+1]+r*t[s+2]}}function draw(){gl.clearColor(1,1,1,1),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT),material0Data.clear(),material1Data.clear(),materialData.clear(),colorData.clear(),triangleData.clear(),transparentData.clear(),P.forEach(function(t){t.render()}),drawBuffer(material0Data,pixelShader),drawBuffer(material1Data,noNormalShader),drawBuffer(materialData,materialShader),drawBuffer(colorData,colorShader),drawBuffer(triangleData,transparentShader);let t=transparentData.indices;if(t.length>0){transformVertices(transparentData.vertices);let e=t.length/3,i=Array(e).fill().map((t,e)=>e);i.sort(function(e,i){let r=3*e;Ia=t[r],Ib=t[r+1],Ic=t[r+2];let a=3*i;return IA=t[a],IB=t[a+1],IC=t[a+2],zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic]<zbuffer[IA]+zbuffer[IB]+zbuffer[IC]?-1:1});let r=Array(t.length);for(let a=0;a<e;++a){let e=3*i[a];r[3*a]=t[e],r[3*a+1]=t[e+1],r[3*a+2]=t[e+2]}gl.depthMask(!1),drawBuffer(transparentData,transparentShader,r),gl.depthMask(!0)}remesh=!1}function tick(){requestAnimationFrame(tick),redraw&&(draw(),redraw=!1)}function setDimensions(t,e,i,r){let a=t/e,s=1/lastzoom,n=i/t*lastzoom,o=r/e*lastzoom;if(orthographic){let t=B[0]-b[0],e=B[1]-b[1];if(t<e*a){let t=.5*e*a*s,i=2*t*n,r=e*s*o;viewParam.xmin=-t-i,viewParam.xmax=t-i,viewParam.ymin=b[1]*s-r,viewParam.ymax=B[1]*s-r}else{let e=.5*t/(a*Zoom),i=t*s*n,r=2*e*o;viewParam.xmin=b[0]*s-i,viewParam.xmax=B[0]*s-i,viewParam.ymin=-e-r,viewParam.ymax=e-r}}else{let t=H*s,e=t*a,i=2*e*n,r=2*t*o;viewParam.xmin=-e-i,viewParam.xmax=e-i,viewParam.ymin=-t-r,viewParam.ymax=t-r}}function setProjection(){setDimensions(canvasWidth,canvasHeight,shift.x,shift.y),(orthographic?mat4.ortho:mat4.frustum)(projMat,viewParam.xmin,viewParam.xmax,viewParam.ymin,viewParam.ymax,-viewParam.zmax,-viewParam.zmin),updateViewMatrix()}function initProjection(){H=-Math.tan(.5*angle)*B[2],center.x=center.y=0,center.z=.5*(b[2]+B[2]),lastzoom=Zoom=Zoom0,viewParam.zmin=b[2],viewParam.zmax=B[2],shift.x=shift.y=0}function setViewport(){gl.viewportWidth=canvasWidth,gl.viewportHeight=canvasHeight,gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight),home()}function setCanvas(){canvas.width=canvasWidth,canvas.height=canvasHeight,size2=Math.hypot(canvasWidth,canvasHeight),halfCanvasWidth=.5*canvasWidth,halfCanvasHeight=.5*canvasHeight}function setsize(t,e){t>maxViewportWidth&&(t=maxViewportWidth),e>maxViewportHeight&&(e=maxViewportHeight),shift.x*=t/canvasWidth,shift.y*=e/canvasHeight,canvasWidth=t,canvasHeight=e,setCanvas(),setViewport()}function expand(){setsize(canvasWidth*resizeStep+.5,canvasHeight*resizeStep+.5)}function shrink(){setsize(Math.max(canvasWidth/resizeStep+.5,1),Math.max(canvasHeight/resizeStep+.5,1))}function webGLStart(){if(canvas=document.getElementById("Asymptote"),absolute)canvasWidth*=window.devicePixelRatio,canvasHeight*=window.devicePixelRatio;else{0==canvas.width&&(canvas.width=Math.max(window.innerWidth-windowTrim,windowTrim)),0==canvas.height&&(canvas.height=Math.max(window.innerHeight-windowTrim,windowTrim));let t=canvasWidth/canvasHeight;canvas.width>canvas.height*t?canvas.width=Math.min(canvas.height*t,canvas.width):canvas.height=Math.min(canvas.width/t,canvas.height),canvas.width>0&&(canvasWidth=canvas.width),canvas.height>0&&(canvasHeight=canvas.height)}setCanvas(),ArcballFactor=1+8*Math.hypot(viewportmargin[0],viewportmargin[1])/size2,initGL(),gl.enable(gl.BLEND),gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA),gl.enable(gl.DEPTH_TEST),setViewport(),noNormalShader=initShader(),pixelShader=initShader(["WIDTH"]),materialShader=initShader(["NORMAL"]),colorShader=initShader(["NORMAL","COLOR"]),transparentShader=initShader(["NORMAL","COLOR","TRANSPARENT"]),setBuffer(),canvas.onmousedown=handleMouseDown,document.onmouseup=handleMouseUpOrTouchEnd,document.onmousemove=handleMouseMove,canvas.onkeydown=handleKey,document.onwheel=handleMouseWheel,canvas.addEventListener("touchstart",handleTouchStart,!1),canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchmove",handleTouchMove,!1),document.addEventListener("keydown",handleKey,!1),tick()}
+/*@license for gl-matrix mat3 and mat4 functions:
+Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.*/ \ No newline at end of file
diff --git a/graphics/asymptote/bbox3.h b/graphics/asymptote/bbox3.h
index b531be4e91..aa50251637 100644
--- a/graphics/asymptote/bbox3.h
+++ b/graphics/asymptote/bbox3.h
@@ -10,6 +10,10 @@
#include "triple.h"
+// For CYGWIN
+#undef near
+#undef far
+
namespace camp {
// The box that encloses a path
@@ -17,43 +21,43 @@ struct bbox3 {
bool empty;
double left;
double bottom;
- double lower;
+ double near;
double right;
double top;
- double upper;
+ double far;
// Start bbox3 about the origin
bbox3()
- : empty(true), left(0.0), bottom(0.0), lower(0.0),
- right(0.0), top(0.0), upper(0.0)
+ : empty(true), left(0.0), bottom(0.0), near(0.0),
+ right(0.0), top(0.0), far(0.0)
{
}
- bbox3(double left, double bottom, double lower,
- double right, double top, double upper)
- : empty(false), left(left), bottom(bottom), lower(lower),
- right(right), top(top), upper(upper)
+ bbox3(double left, double bottom, double near,
+ double right, double top, double far)
+ : empty(false), left(left), bottom(bottom), near(near),
+ right(right), top(top), far(far)
{
}
// Start a bbox3 with a point
bbox3(double x, double y, double z)
- : empty(false), left(x), bottom(y), lower(z), right(x), top(y), upper(z)
+ : empty(false), left(x), bottom(y), near(z), right(x), top(y), far(z)
{
}
// Start a bbox3 with a point
bbox3(const triple& v)
- : empty(false), left(v.getx()), bottom(v.gety()), lower(v.getz()),
- right(v.getx()), top(v.gety()), upper(v.getz())
+ : empty(false), left(v.getx()), bottom(v.gety()), near(v.getz()),
+ right(v.getx()), top(v.gety()), far(v.getz())
{
}
// Start a bbox3 with 2 points
bbox3(const triple& m, const triple& M)
: empty(false),
- left(m.getx()), bottom(m.gety()), lower(m.getz()),
- right(M.getx()), top(M.gety()), upper(M.getz())
+ left(m.getx()), bottom(m.gety()), near(m.getz()),
+ right(M.getx()), top(M.gety()), far(M.getz())
{
}
@@ -68,7 +72,7 @@ struct bbox3 {
if (empty) {
left = right = x;
top = bottom = y;
- lower = upper = z;
+ near = far = z;
empty = false;
}
else {
@@ -80,10 +84,10 @@ struct bbox3 {
bottom = y;
else if(y > top)
top = y;
- if(z < lower)
- lower = z;
- else if(z > upper)
- upper = z;
+ if(z < near)
+ near = z;
+ else if(z > far)
+ far = z;
}
}
@@ -98,10 +102,25 @@ struct bbox3 {
bottom = y;
else if(y > top)
top = y;
- if(z < lower)
- lower = z;
- else if(z > upper)
- upper = z;
+ if(z < near)
+ near = z;
+ else if(z > far)
+ far = z;
+ }
+
+ // Add (x,y) pair to a nonempty bbox3
+ void addnonempty(pair v)
+ {
+ double x=v.getx();
+ if(x < left)
+ left = x;
+ else if(x > right)
+ right = x;
+ double y=v.gety();
+ if(y < bottom)
+ bottom = y;
+ else if(y > top)
+ top = y;
}
// Add a point to a nonempty bbox3
@@ -131,13 +150,13 @@ struct bbox3 {
top = y;
times.top = t;
}
- if(z < lower) {
- lower = z;
- times.lower=t;
+ if(z < near) {
+ near = z;
+ times.near=t;
}
- else if(z > upper) {
- upper = z;
- times.upper=t;
+ else if(z > far) {
+ far = z;
+ times.far=t;
}
}
@@ -148,32 +167,19 @@ struct bbox3 {
}
triple Min() const {
- return triple(left,bottom,lower);
+ return triple(left,bottom,near);
}
triple Max() const {
- return triple(right,top,upper);
+ return triple(right,top,far);
}
- // transform bbox3 by 4x4 matrix
- void transform(const double* m)
- {
- const double xmin = left;
- const double ymin = bottom;
- const double zmin = lower;
- const double xmax = right;
- const double ymax = top;
- const double zmax = upper;
-
- empty = true;
- add(m*triple(xmin,ymin,zmin));
- addnonempty(m*triple(xmin,ymin,zmax));
- addnonempty(m*triple(xmin,ymax,zmin));
- addnonempty(m*triple(xmin,ymax,zmax));
- addnonempty(m*triple(xmax,ymin,zmin));
- addnonempty(m*triple(xmax,ymin,zmax));
- addnonempty(m*triple(xmax,ymax,zmin));
- addnonempty(m*triple(xmax,ymax,zmax));
+ pair Min2() const {
+ return pair(left,bottom);
+ }
+
+ pair Max2() const {
+ return pair(right,top);
}
friend ostream& operator << (ostream& out, const bbox3& b)
diff --git a/graphics/asymptote/beziercurve.cc b/graphics/asymptote/beziercurve.cc
index ccf3267e6e..2b33d552a3 100644
--- a/graphics/asymptote/beziercurve.cc
+++ b/graphics/asymptote/beziercurve.cc
@@ -10,28 +10,30 @@
namespace camp {
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
-std::vector<vertexData1> BezierCurve::vertexbuffer;
-std::vector<GLuint> BezierCurve::indices;
-
-std::vector<pixelData> Pixel::vertexbuffer;
-
-GLuint BezierCurve::vertsBufferIndex;
-GLuint BezierCurve::elemBufferIndex;
-
-void BezierCurve::init(double res, const triple& Min, const triple& Max)
+void BezierCurve::init(double res)
{
this->res=res;
res2=res*res;
- this->Min=Min;
- this->Max=Max;
-
- const size_t nbuffer=10000;
- vertexbuffer.reserve(nbuffer);
- indices.reserve(nbuffer);
+
+ MaterialIndex=materialIndex;
}
+void BezierCurve::render(const triple *p, bool straight)
+{
+ GLuint i0=data.vertex1(p[0]);
+ GLuint i3=data.vertex1(p[3]);
+
+ if(straight) {
+ std::vector<GLuint> &q=data.indices;
+ q.push_back(i0);
+ q.push_back(i3);
+ } else
+ render(p,i0,i3);
+ append();
+}
+
// Use a uniform partition to draw a Bezier patch.
// p is an array of 4 triples representing the control points.
// Ii are the vertices indices.
@@ -41,11 +43,12 @@ void BezierCurve::render(const triple *p, GLuint I0, GLuint I1)
triple p1=p[1];
triple p2=p[2];
triple p3=p[3];
- if(Distance1(p0,p1,p2,p3) < res2) { // Segment is flat
+ if(Straightness(p0,p1,p2,p3) < res2) { // Segment is flat
triple P[]={p0,p3};
if(!offscreen(2,P)) {
- indices.push_back(I0);
- indices.push_back(I1);
+ std::vector<GLuint> &q=data.indices;
+ q.push_back(I0);
+ q.push_back(I1);
}
} else { // Segment is not flat
if(offscreen(4,p)) return;
@@ -59,123 +62,13 @@ void BezierCurve::render(const triple *p, GLuint I0, GLuint I1)
triple s0[]={p0,m0,m3,m5};
triple s1[]={m5,m4,m2,p3};
- GLuint i0=vertex(m5);
+ GLuint i0=data.vertex1(m5);
render(s0,I0,i0);
render(s1,i0,I1);
}
}
-void BezierCurve::render(const triple *p, bool straight)
-{
- GLuint i0=vertex(p[0]);
- GLuint i3=vertex(p[3]);
-
- if(straight) {
- indices.push_back(i0);
- indices.push_back(i3);
- } else
- render(p,i0,i3);
-}
-
-void BezierCurve::draw()
-{
- if(indices.size() == 0)
- return;
-
- const size_t size=sizeof(GLfloat);
- static const size_t bytestride=sizeof(vertexData1);
-
- GLuint vao;
- glGenVertexArrays(1,&vao);
- glBindVertexArray(vao);
- createBuffers();
-
- glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex);
-
- camp::setUniforms(noNormalShader);
-
- const GLint posAttrib=glGetAttribLocation(noNormalShader, "position");
- const GLint materialAttrib=glGetAttribLocation(noNormalShader,"material");
-
- glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,(void *) 0);
- glEnableVertexAttribArray(posAttrib);
-
- glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,(void *) (3*size));
- glEnableVertexAttribArray(materialAttrib);
-
- glFlush(); // Workaround broken MSWindows drivers for Intel GPU
- glDrawElements(GL_LINES,indices.size(),GL_UNSIGNED_INT,(void*)(0));
-
- glDisableVertexAttribArray(posAttrib);
- glDisableVertexAttribArray(materialAttrib);
-
- deleteUniforms();
-
- glBindBuffer(GL_ARRAY_BUFFER,0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
-
- glBindVertexArray(0);
- glDeleteVertexArrays(1,&vao);
-
- glDeleteBuffers(1,&vertsBufferIndex);
- glDeleteBuffers(1,&elemBufferIndex);
-}
-
-void Pixel::queue(const triple& p, double width)
-{
- vertex(p,width);
-}
-
-void Pixel::draw()
-{
- if(vertexbuffer.size() == 0)
- return;
-
- const size_t size=sizeof(GLfloat);
- static const size_t bytestride=sizeof(pixelData);
-
- GLuint vbo;
- glGenBuffers(1,&vbo);
-
- GLuint vao;
- glGenVertexArrays(1,&vao);
- glBindVertexArray(vao);
-
- glBindBuffer(GL_ARRAY_BUFFER,vbo);
- glBufferData(GL_ARRAY_BUFFER,bytestride*vertexbuffer.size(),
- vertexbuffer.data(),GL_STATIC_DRAW);
-
- camp::setUniforms(pixelShader);
-
- const GLint posAttrib=glGetAttribLocation(pixelShader, "position");
- const GLint materialAttrib=glGetAttribLocation(pixelShader,"material");
- const GLint widthAttrib=glGetAttribLocation(pixelShader,"width");
-
- glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,(void*)(0));
- glEnableVertexAttribArray(posAttrib);
-
- glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,(void *) (3*size));
- glEnableVertexAttribArray(materialAttrib);
-
- glVertexAttribPointer(widthAttrib,1,GL_FLOAT,GL_FALSE,bytestride,(void *) (4*size));
- glEnableVertexAttribArray(widthAttrib);
-
- glDrawArrays(GL_POINTS,0,vertexbuffer.size());
-
- glDisableVertexAttribArray(posAttrib);
- glDisableVertexAttribArray(materialAttrib);
- glDisableVertexAttribArray(widthAttrib);
-
- deleteUniforms();
-
- glBindBuffer(GL_ARRAY_BUFFER,0);
-
- glBindVertexArray(0);
- glDeleteVertexArrays(1,&vao);
-}
-
#endif
} //namespace camp
diff --git a/graphics/asymptote/beziercurve.h b/graphics/asymptote/beziercurve.h
index 573b48a792..e3c460e315 100644
--- a/graphics/asymptote/beziercurve.h
+++ b/graphics/asymptote/beziercurve.h
@@ -17,116 +17,66 @@ namespace camp {
extern const double Fuzz;
extern const double Fuzz2;
-class vertexData1 {
-public:
- GLfloat position[3];
- GLint material;
- vertexData1() {};
- vertexData1(const triple& v) {
- position[0]=v.getx();
- position[1]=v.gety();
- position[2]=v.getz();
- material=drawElement::materialIndex;
- }
-};
-
-class pixelData {
-public:
- GLfloat position[3];
- GLint material;
- GLfloat width;
- pixelData() {};
- pixelData(const triple& v, double width) : width(width) {
- position[0]=v.getx();
- position[1]=v.gety();
- position[2]=v.getz();
- material=drawElement::materialIndex;
- }
-};
-
struct BezierCurve
{
- static std::vector<vertexData1> vertexbuffer;
- static std::vector<GLuint> indices;
+ vertexBuffer data;
double res,res2;
- triple Min,Max;
-
- static GLuint vertsBufferIndex;
- static GLuint elemBufferIndex;
+ bool Onscreen;
- void init(double res, const triple& Min, const triple& Max);
+ void init(double res);
-// Store the vertex v in the buffer.
- static GLuint vertex(const triple &v) {
- size_t nvertices=vertexbuffer.size();
- vertexbuffer.push_back(vertexData1(v));
- return nvertices;
+ // Approximate bounds by bounding box of control polyhedron.
+ bool offscreen(size_t n, const triple *v) {
+ if(bbox2(n,v).offscreen()) {
+ Onscreen=false;
+ return true;
+ }
+ return false;
}
-
- void createBuffers() {
- glGenBuffers(1,&vertsBufferIndex);
- glGenBuffers(1,&elemBufferIndex);
- //vbo
- registerBuffer(vertexbuffer,vertsBufferIndex);
-
- //ebo
- registerBuffer(indices,elemBufferIndex);
- }
+ void render(const triple *p, bool straight);
+ void render(const triple *p, GLuint I0, GLuint I1);
-// Approximate bounds by bounding box of control polyhedron.
- bool offscreen(size_t n, const triple *v) {
- double x,y,z;
- double X,Y,Z;
+ void append() {
+ material1Data.append1(data);
- boundstriples(x,y,z,X,Y,Z,n,v);
- return
- X < Min.getx() || x > Max.getx() ||
- Y < Min.gety() || y > Max.gety() ||
- Z < Min.getz() || z > Max.getz();
- }
-
- static void clear() {
- vertexbuffer.clear();
- indices.clear();
+ if(material1Data.vertices1.size() >= gl::maxvertices) {
+ drawBuffer(material1Data,noNormalShader);
+ material1Data.clear();
+ gl::forceRemesh=true;
+ }
}
- ~BezierCurve() {}
-
- void render(const triple *p, GLuint I0, GLuint I1);
- void render(const triple *p, bool straight);
-
- void queue(const triple *g, bool straight, double ratio,
- const triple& Min, const triple& Max) {
- init(pixel*ratio,Min,Max);
+ void queue(const triple *g, bool straight, double ratio) {
+ data.clear();
+ Onscreen=true;
+ init(pixel*ratio);
render(g,straight);
}
- void draw();
- void draw(const triple *g, bool straight, double ratio,
- const triple& Min, const triple& Max) {
- queue(g,straight,ratio,Min,Max);
- draw();
- }
};
struct Pixel
{
- static std::vector<pixelData> vertexbuffer;
+ vertexBuffer data;
-// Store the vertex v in the buffer.
- static void vertex(const triple &v, double width) {
- vertexbuffer.push_back(pixelData(v,width));
+ void append() {
+ material0Data.append0(data);
+
+ if(material0Data.vertices0.size() >= gl::maxvertices) {
+ drawBuffer(material0Data,pixelShader);
+ material0Data.clear();
+ gl::forceRemesh=true;
+ }
}
- static void clear() {
- vertexbuffer.clear();
+ void queue(const triple& p, double width) {
+ data.clear();
+ MaterialIndex=materialIndex;
+ data.indices.push_back(data.vertex0(p,width));
+ append();
}
- Pixel() {}
- ~Pixel() {}
-
- void queue(const triple& p, double width);
void draw();
};
diff --git a/graphics/asymptote/bezierpatch.cc b/graphics/asymptote/bezierpatch.cc
index c97887ef64..e0cbf4788e 100644
--- a/graphics/asymptote/bezierpatch.cc
+++ b/graphics/asymptote/bezierpatch.cc
@@ -13,31 +13,20 @@ namespace camp {
using ::orient2d;
using ::orient3d;
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
-const size_t nbuffer=10000; // Initial size of dynamic buffers
+int MaterialIndex;
-std::vector<vertexData> BezierPatch::vertexbuffer;
-std::vector<VertexData> BezierPatch::Vertexbuffer;
-std::vector<VertexData> BezierPatch::tVertexbuffer;
-std::vector<GLuint> BezierPatch::indices;
-std::vector<GLuint> BezierPatch::Indices;
-std::vector<GLuint> BezierPatch::tIndices;
-
-GLuint BezierPatch::nvertices=0;
-GLuint BezierPatch::Nvertices=0;
-GLuint BezierPatch::Ntvertices=0;
-
-//std::vector<GLuint>& I=BezierPatch::tIndices;
-//std::vector<VertexData>& V=BezierPatch::tVertexbuffer;
+//std::vector<GLuint>& I=transparentData.Indices;
+//std::vector<VertexData>& V=transparentData.Vertices;
bool colors;
std::vector<GLfloat> zbuffer;
std::vector<GLfloat> xbuffer;
std::vector<GLfloat> ybuffer;
-std::vector<GLfloat> xmin,ymin,zmin;
-std::vector<GLfloat> xmax,ymax,zmax;
+//std::vector<GLfloat> xmin,ymin,zmin;
+//std::vector<GLfloat> xmax,ymax,zmax;
std::vector<GLfloat> zsum;
inline double min(double a, double b, double c)
@@ -272,11 +261,11 @@ void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic,
interp(cd,ca,cb,td);
interp(ce,ca,cc,te);
- id=BezierPatch::tVertex(d,nd,cd);
- ie=BezierPatch::tVertex(e,ne,ce);
+ id=data.Vertex(d,nd,cd);
+ ie=data.Vertex(e,ne,ce);
} else {
- id=BezierPatch::tVertex(d,nd);
- ie=BezierPatch::tVertex(e,ne);
+ id=data.Vertex(d,nd);
+ ie=data.Vertex(e,ne);
}
I[i3]=ia;
@@ -293,37 +282,96 @@ void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic,
}
#endif
-void BezierPatch::init(double res, const triple& Min, const triple& Max,
- bool transparent, GLfloat *colors)
+void BezierPatch::init(double res)
{
res2=res*res;
Res2=BezierFactor*BezierFactor*res2;
Epsilon=FillFactor*res;
- this->Min=Min;
- this->Max=Max;
+ MaterialIndex=transparent ?
+ (color ? -1-materialIndex : 1+materialIndex) : materialIndex;
+
+ pvertex=transparent ? &vertexBuffer::tvertex : &vertexBuffer::vertex;
+}
+
+void BezierPatch::render(const triple *p, bool straight, GLfloat *c0)
+{
+ triple p0=p[0];
+ epsilon=0;
+ for(unsigned i=1; i < 16; ++i)
+ epsilon=max(epsilon,abs2(p[i]-p0));
+ epsilon *= Fuzz4;
+
+ triple p3=p[3];
+ triple p12=p[12];
+ triple p15=p[15];
- if(transparent) {
- tVertexbuffer.reserve(nbuffer);
- tIndices.reserve(nbuffer);
- pindices=&tIndices;
- pvertex=&tvertex;
- pVertex=&tVertex;
+ triple n0=normal(p3,p[2],p[1],p0,p[4],p[8],p12);
+ if(n0 == 0.0) {
+ n0=normal(p3,p[2],p[1],p0,p[13],p[14],p15);
+ if(n0 == 0.0) n0=normal(p15,p[11],p[7],p3,p[4],p[8],p12);
+ }
+
+ triple n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15);
+ if(n1 == 0.0) {
+ n1=normal(p0,p[4],p[8],p12,p[11],p[7],p3);
+ if(n1 == 0.0) n1=normal(p3,p[2],p[1],p0,p[13],p[14],p15);
+ }
+
+ triple n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3);
+ if(n2 == 0.0) {
+ n2=normal(p12,p[13],p[14],p15,p[2],p[1],p0);
+ if(n2 == 0.0) n2=normal(p0,p[4],p[8],p12,p[11],p[7],p3);
+ }
+
+ triple n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0);
+ if(n3 == 0.0) {
+ n3=normal(p15,p[11],p[7],p3,p[4],p[8],p12);
+ if(n3 == 0.0) n3=normal(p12,p[13],p[14],p15,p[2],p[1],p0);
+ }
+
+ GLuint i0,i1,i2,i3;
+ if(color) {
+ GLfloat *c1=c0+4;
+ GLfloat *c2=c0+8;
+ GLfloat *c3=c0+12;
+
+ i0=data.Vertex(p0,n0,c0);
+ i1=data.Vertex(p12,n1,c1);
+ i2=data.Vertex(p15,n2,c2);
+ i3=data.Vertex(p3,n3,c3);
+
+ if(!straight)
+ render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false,
+ c0,c1,c2,c3);
} else {
- if(colors) {
- Vertexbuffer.reserve(nbuffer);
- Indices.reserve(nbuffer);
- pindices=&Indices;
- pVertex=&Vertex;
- } else {
- vertexbuffer.reserve(nbuffer);
- indices.reserve(nbuffer);
- pindices=&indices;
- pvertex=&vertex;
+ i0=(data.*pvertex)(p0,n0);
+ i1=(data.*pvertex)(p12,n1);
+ i2=(data.*pvertex)(p15,n2);
+ i3=(data.*pvertex)(p3,n3);
+
+ if(!straight)
+ render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false);
+ }
+
+ if(straight) {
+ std::vector<GLuint> &q=data.indices;
+ triple Pa[]={p0,p12,p15};
+ if(!offscreen(3,Pa)) {
+ q.push_back(i0);
+ q.push_back(i1);
+ q.push_back(i2);
+ }
+ triple Pb[]={p0,p15,p3};
+ if(!offscreen(3,Pb)) {
+ q.push_back(i0);
+ q.push_back(i2);
+ q.push_back(i3);
}
}
+ append();
}
-
+
// Use a uniform partition to draw a Bezier patch.
// p is an array of 16 triples representing the control points.
// Pi are the (possibly) adjusted vertices indexed by Ii.
@@ -334,19 +382,22 @@ void BezierPatch::render(const triple *p,
bool flat0, bool flat1, bool flat2, bool flat3,
GLfloat *C0, GLfloat *C1, GLfloat *C2, GLfloat *C3)
{
- if(Distance(p) < res2) { // Patch is flat
- triple P[]={P0,P1,P2,P3};
- if(!offscreen(4,P)) {
- std::vector<GLuint> &p=*pindices;
- p.push_back(I0);
- p.push_back(I1);
- p.push_back(I2);
- p.push_back(I0);
- p.push_back(I2);
- p.push_back(I3);
+ if(Distance(p) < res2) { // Bezier patch is flat
+ triple Pa[]={P0,P1,P2};
+ std::vector<GLuint> &q=data.indices;
+ if(!offscreen(3,Pa)) {
+ q.push_back(I0);
+ q.push_back(I1);
+ q.push_back(I2);
+ }
+ triple Pb[]={P0,P2,P3};
+ if(!offscreen(3,Pb)) {
+ q.push_back(I0);
+ q.push_back(I2);
+ q.push_back(I3);
}
} else { // Patch is not flat
- if(offscreen(16,p)) return;
+ if(offscreen(16,p)) return;
/* Control points are indexed as follows:
Coordinate
@@ -480,7 +531,7 @@ void BezierPatch::render(const triple *p,
else m3=s3[0];
}
- if(C0) {
+ if(color) {
GLfloat c0[4],c1[4],c2[4],c3[4],c4[4];
for(size_t i=0; i < 4; ++i) {
c0[i]=0.5*(C0[i]+C1[i]);
@@ -490,11 +541,12 @@ void BezierPatch::render(const triple *p,
c4[i]=0.5*(c0[i]+c2[i]);
}
- GLuint i0=pVertex(m0,n0,c0);
- GLuint i1=pVertex(m1,n1,c1);
- GLuint i2=pVertex(m2,n2,c2);
- GLuint i3=pVertex(m3,n3,c3);
- GLuint i4=pVertex(m4,n4,c4);
+ GLuint i0=data.Vertex(m0,n0,c0);
+ GLuint i1=data.Vertex(m1,n1,c1);
+ GLuint i2=data.Vertex(m2,n2,c2);
+ GLuint i3=data.Vertex(m3,n3,c3);
+ GLuint i4=data.Vertex(m4,n4,c4);
+
render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3,
C0,c0,c4,c3);
render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false,
@@ -504,11 +556,12 @@ void BezierPatch::render(const triple *p,
render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3,
c3,c4,c2,C3);
} else {
- GLuint i0=pvertex(m0,n0);
- GLuint i1=pvertex(m1,n1);
- GLuint i2=pvertex(m2,n2);
- GLuint i3=pvertex(m3,n3);
- GLuint i4=pvertex(m4,n4);
+ GLuint i0=(data.*pvertex)(m0,n0);
+ GLuint i1=(data.*pvertex)(m1,n1);
+ GLuint i2=(data.*pvertex)(m2,n2);
+ GLuint i3=(data.*pvertex)(m3,n3);
+ GLuint i4=(data.*pvertex)(m4,n4);
+
render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3);
render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false);
render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false);
@@ -517,68 +570,52 @@ void BezierPatch::render(const triple *p,
}
}
-void BezierPatch::render(const triple *p, bool straight, GLfloat *c0)
+void BezierTriangle::render(const triple *p, bool straight, GLfloat *c0)
{
triple p0=p[0];
epsilon=0;
- for(unsigned i=1; i < 16; ++i)
+ for(int i=1; i < 10; ++i)
epsilon=max(epsilon,abs2(p[i]-p0));
epsilon *= Fuzz4;
- triple p3=p[3];
- triple p12=p[12];
- triple p15=p[15];
-
- triple n0=normal(p3,p[2],p[1],p0,p[4],p[8],p12);
- if(n0 == 0.0) n0=normal(p3,p[2],p[1],p0,p[13],p[14],p15);
- if(n0 == 0.0) n0=normal(p15,p[11],p[7],p3,p[4],p[8],p12);
-
- triple n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15);
- if(n1 == 0.0) n1=normal(p0,p[4],p[8],p12,p[11],p[7],p3);
- if(n1 == 0.0) n1=normal(p3,p[2],p[1],p0,p[13],p[14],p15);
-
- triple n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3);
- if(n2 == 0.0) n2=normal(p12,p[13],p[14],p15,p[2],p[1],p0);
- if(n2 == 0.0) n2=normal(p0,p[4],p[8],p12,p[11],p[7],p3);
-
- triple n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0);
- if(n3 == 0.0) n3=normal(p15,p[11],p[7],p3,p[4],p[8],p12);
- if(n3 == 0.0) n3=normal(p12,p[13],p[14],p15,p[2],p[1],p0);
+ triple p6=p[6];
+ triple p9=p[9];
- GLuint I0,I1,I2,I3;
+ triple n0=normal(p9,p[5],p[2],p0,p[1],p[3],p6);
+ triple n1=normal(p0,p[1],p[3],p6,p[7],p[8],p9);
+ triple n2=normal(p6,p[7],p[8],p9,p[5],p[2],p0);
- if(c0) {
+ GLuint i0,i1,i2;
+ if(color) {
GLfloat *c1=c0+4;
GLfloat *c2=c0+8;
- GLfloat *c3=c0+12;
- I0=pVertex(p0,n0,c0);
- I1=pVertex(p12,n1,c1);
- I2=pVertex(p15,n2,c2);
- I3=pVertex(p3,n3,c3);
-
+ i0=data.Vertex(p0,n0,c0);
+ i1=data.Vertex(p6,n1,c1);
+ i2=data.Vertex(p9,n2,c2);
+
if(!straight)
- render(p,I0,I1,I2,I3,p0,p12,p15,p3,false,false,false,false,
- c0,c1,c2,c3);
+ render(p,i0,i1,i2,p0,p6,p9,false,false,false,c0,c1,c2);
} else {
- I0=pvertex(p0,n0);
- I1=pvertex(p12,n1);
- I2=pvertex(p15,n2);
- I3=pvertex(p3,n3);
+ i0=(data.*pvertex)(p0,n0);
+ i1=(data.*pvertex)(p6,n1);
+ i2=(data.*pvertex)(p9,n2);
if(!straight)
- render(p,I0,I1,I2,I3,p0,p12,p15,p3,false,false,false,false);
+ render(p,i0,i1,i2,p0,p6,p9,false,false,false);
}
if(straight) {
- pindices->push_back(I0);
- pindices->push_back(I1);
- pindices->push_back(I2);
- pindices->push_back(I0);
- pindices->push_back(I2);
- pindices->push_back(I3);
+ triple P[]={p0,p6,p9};
+ if(!offscreen(3,P)) {
+ std::vector<GLuint> &q=data.indices;
+ q.push_back(i0);
+ q.push_back(i1);
+ q.push_back(i2);
+ }
}
+ append();
}
// Use a uniform partition to draw a Bezier triangle.
@@ -591,13 +628,13 @@ void BezierTriangle::render(const triple *p,
bool flat0, bool flat1, bool flat2,
GLfloat *C0, GLfloat *C1, GLfloat *C2)
{
- if(Distance(p) < Res2) { // Triangle is flat
+ if(Distance(p) < Res2) { // Bezier triangle is flat
triple P[]={P0,P1,P2};
if(!offscreen(3,P)) {
- std::vector<GLuint> &p=*pindices;
- p.push_back(I0);
- p.push_back(I1);
- p.push_back(I2);
+ std::vector<GLuint> &q=data.indices;
+ q.push_back(I0);
+ q.push_back(I1);
+ q.push_back(I2);
}
} else { // Triangle is not flat
if(offscreen(10,p)) return;
@@ -723,103 +760,59 @@ void BezierTriangle::render(const triple *p,
// A kludge to remove subdivision cracks, only applied the first time
// an edge is found to be flat before the rest of the subpatch is.
- triple p0=0.5*(P1+P2);
+ triple m0=0.5*(P1+P2);
if(!flat0) {
if((flat0=Straightness(r300,p210,p120,u030) < res2))
- p0 -= Epsilon*unit(derivative(c[0],c[2],c[5],c[9])+
+ m0 -= Epsilon*unit(derivative(c[0],c[2],c[5],c[9])+
derivative(c[0],c[1],c[3],c[6]));
- else p0=r030;
+ else m0=r030;
}
- triple p1=0.5*(P2+P0);
+ triple m1=0.5*(P2+P0);
if(!flat1) {
if((flat1=Straightness(l003,p012,p021,u030) < res2))
- p1 -= Epsilon*unit(derivative(c[6],c[3],c[1],c[0])+
+ m1 -= Epsilon*unit(derivative(c[6],c[3],c[1],c[0])+
derivative(c[6],c[7],c[8],c[9]));
- else p1=l030;
+ else m1=l030;
}
- triple p2=0.5*(P0+P1);
+ triple m2=0.5*(P0+P1);
if(!flat2) {
if((flat2=Straightness(l003,p102,p201,r300) < res2))
- p2 -= Epsilon*unit(derivative(c[9],c[8],c[7],c[6])+
+ m2 -= Epsilon*unit(derivative(c[9],c[8],c[7],c[6])+
derivative(c[9],c[5],c[2],c[0]));
- else p2=l300;
+ else m2=l300;
}
- if(C0) {
+ if(color) {
GLfloat c0[4],c1[4],c2[4];
for(int i=0; i < 4; ++i) {
c0[i]=0.5*(C1[i]+C2[i]);
- c1[i]=0.5*(C0[i]+C2[i]);
+ c1[i]=0.5*(C2[i]+C0[i]);
c2[i]=0.5*(C0[i]+C1[i]);
}
- GLuint i0=pVertex(p0,n0,c0);
- GLuint i1=pVertex(p1,n1,c1);
- GLuint i2=pVertex(p2,n2,c2);
+ GLuint i0=data.Vertex(m0,n0,c0);
+ GLuint i1=data.Vertex(m1,n1,c1);
+ GLuint i2=data.Vertex(m2,n2,c2);
- render(l,I0,i2,i1,P0,p2,p1,false,flat1,flat2,C0,c2,c1);
- render(r,i2,I1,i0,p2,P1,p0,flat0,false,flat2,c2,C1,c0);
- render(u,i1,i0,I2,p1,p0,P2,flat0,flat1,false,c1,c0,C2);
- render(c,i0,i1,i2,p0,p1,p2,false,false,false,c0,c1,c2);
+ render(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2,C0,c2,c1);
+ render(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2,c2,C1,c0);
+ render(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false,c1,c0,C2);
+ render(c,i0,i1,i2,m0,m1,m2,false,false,false,c0,c1,c2);
} else {
- GLuint i0=pvertex(p0,n0);
- GLuint i1=pvertex(p1,n1);
- GLuint i2=pvertex(p2,n2);
+ GLuint i0=(data.*pvertex)(m0,n0);
+ GLuint i1=(data.*pvertex)(m1,n1);
+ GLuint i2=(data.*pvertex)(m2,n2);
- render(l,I0,i2,i1,P0,p2,p1,false,flat1,flat2);
- render(r,i2,I1,i0,p2,P1,p0,flat0,false,flat2);
- render(u,i1,i0,I2,p1,p0,P2,flat0,flat1,false);
- render(c,i0,i1,i2,p0,p1,p2,false,false,false);
+ render(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2);
+ render(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2);
+ render(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false);
+ render(c,i0,i1,i2,m0,m1,m2,false,false,false);
}
}
}
-void BezierTriangle::render(const triple *p, bool straight, GLfloat *c0)
-{
- triple p0=p[0];
- epsilon=0;
- for(int i=1; i < 10; ++i)
- epsilon=max(epsilon,abs2(p[i]-p0));
-
- epsilon *= Fuzz4;
-
- GLuint I0,I1,I2;
-
- triple p6=p[6];
- triple p9=p[9];
-
- triple n0=normal(p9,p[5],p[2],p0,p[1],p[3],p6);
- triple n1=normal(p0,p[1],p[3],p6,p[7],p[8],p9);
- triple n2=normal(p6,p[7],p[8],p9,p[5],p[2],p0);
-
- if(c0) {
- GLfloat *c1=c0+4;
- GLfloat *c2=c0+8;
-
- I0=pVertex(p0,n0,c0);
- I1=pVertex(p6,n1,c1);
- I2=pVertex(p9,n2,c2);
-
- if(!straight)
- render(p,I0,I1,I2,p0,p6,p9,false,false,false,c0,c1,c2);
- } else {
- I0=pvertex(p0,n0);
- I1=pvertex(p6,n1);
- I2=pvertex(p9,n2);
-
- if(!straight)
- render(p,I0,I1,I2,p0,p6,p9,false,false,false);
- }
-
- if(straight) {
- pindices->push_back(I0);
- pindices->push_back(I1);
- pindices->push_back(I2);
- }
-}
-
void transform(const std::vector<VertexData>& b)
{
unsigned n=b.size();
@@ -829,12 +822,11 @@ void transform(const std::vector<VertexData>& b)
for(unsigned i=0; i < n; ++i) {
const GLfloat *v=b[i].position;
-// xbuffer[i]=Tx[0]*b[j]+Tx[1]*b[j+1]+Tx[2]*b[j+2];
-// ybuffer[i]=Ty[0]*b[j]+Ty[1]*b[j+1]+Ty[2]*b[j+2];
- zbuffer[i]=Tz[0]*v[0]+Tz[1]*v[1]+Tz[2]*v[2];
+ zbuffer[i]=TransformZ(triple(v[0],v[1],v[2]),gl::dprojView);
}
}
+#if 0
// precompute min and max bounds of each triangle
void bounds(const std::vector<GLuint>& I)
{
@@ -882,224 +874,72 @@ void bounds(const std::vector<GLuint>& I)
zmax[i]=max(za,zb,zc);
}
}
+#endif
-void BezierPatch::drawMaterials()
+void sortTriangles()
{
- if(indices.size() == 0)
- return;
-
- static const size_t size=sizeof(GLfloat);
- static const size_t bytestride=sizeof(vertexData);
-
- GLuint vertsBufferIndex;
- GLuint elemBufferIndex;
-
- GLuint vao;
-
- glGenVertexArrays(1,&vao);
- glBindVertexArray(vao);
-
- glGenBuffers(1,&vertsBufferIndex);
- glGenBuffers(1,&elemBufferIndex);
-
- registerBuffer(vertexbuffer,vertsBufferIndex);
- registerBuffer(indices,elemBufferIndex);
-
- glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex);
-
- camp::setUniforms(materialShader);
-
- const GLint posAttrib=glGetAttribLocation(materialShader,"position");
- const GLint normalAttrib=glGetAttribLocation(materialShader,"normal");
- const GLint materialAttrib=glGetAttribLocation(materialShader,"material");
-
- glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,(void *) 0);
- glEnableVertexAttribArray(posAttrib);
-
- glVertexAttribPointer(normalAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
- (void *) (3*size));
- glEnableVertexAttribArray(normalAttrib);
-
- glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,
- (void *) (6*size));
- glEnableVertexAttribArray(materialAttrib);
-
- glFlush(); // Workaround broken MSWindows drivers for Intel GPU
- glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_INT,(void *) 0);
-
- glDisableVertexAttribArray(posAttrib);
- glDisableVertexAttribArray(normalAttrib);
- glDisableVertexAttribArray(materialAttrib);
-
- deleteUniforms();
-
- glBindBuffer(GL_ARRAY_BUFFER,0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
-
- glBindVertexArray(0);
- glDeleteVertexArrays(1,&vao);
-
- glDeleteBuffers(1,&vertsBufferIndex);
- glDeleteBuffers(1,&elemBufferIndex);
+ if(!transparentData.indices.empty()) {
+ transform(transparentData.Vertices);
+// bounds(tIndices);
+ qsort(&transparentData.indices[0],transparentData.indices.size()/3,
+ 3*sizeof(GLuint),compare);
+ }
}
-void BezierPatch::drawColors(GLuint& Nvertices,
- std::vector<VertexData>& Vertexbuffer,
- std::vector<GLuint>& Indices)
+void Triangles::queue(size_t nP, const triple* P, size_t nN, const triple* N,
+ size_t nC, const prc::RGBAColour* C, size_t nI,
+ const uint32_t (*PP)[3], const uint32_t (*NN)[3],
+ const uint32_t (*CC)[3], bool Transparent)
{
- if(Indices.size() == 0)
- return;
-
- static const size_t size=sizeof(GLfloat);
- static const size_t bytestride=sizeof(VertexData);
-
- GLuint vertsBufferIndex;
- GLuint elemBufferIndex;
-
- GLuint vao;
-
- glGenVertexArrays(1,&vao);
- glBindVertexArray(vao);
-
- glGenBuffers(1,&vertsBufferIndex);
- glGenBuffers(1,&elemBufferIndex);
-
- registerBuffer(Vertexbuffer,vertsBufferIndex);
- registerBuffer(Indices,elemBufferIndex);
+ if(!nN) return;
- glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex);
-
- camp::setUniforms(colorShader);
-
- const GLint posAttrib=glGetAttribLocation(colorShader,"position");
- const GLint normalAttrib=glGetAttribLocation(colorShader,"normal");
- const GLint colorAttrib=glGetAttribLocation(colorShader,"color");
- const GLint materialAttrib=glGetAttribLocation(colorShader,"material");
+ data.clear();
+ Onscreen=true;
+ transparent=Transparent;
- glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
- (void *) 0);
- glEnableVertexAttribArray(posAttrib);
-
- glVertexAttribPointer(normalAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
- (void *) (3*size));
- glEnableVertexAttribArray(normalAttrib);
-
- glVertexAttribIPointer(colorAttrib,1,GL_UNSIGNED_INT,bytestride,
- (void *) (6*size));
- glEnableVertexAttribArray(colorAttrib);
-
- glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,
- (void *) (6*size+sizeof(GLuint)));
- glEnableVertexAttribArray(materialAttrib);
-
- glFlush(); // Workaround broken MSWindows drivers for Intel GPU
- glDrawElements(GL_TRIANGLES,Indices.size(),GL_UNSIGNED_INT,(void *) 0);
-
- glDisableVertexAttribArray(posAttrib);
- glDisableVertexAttribArray(normalAttrib);
- glDisableVertexAttribArray(colorAttrib);
- glDisableVertexAttribArray(materialAttrib);
-
- deleteUniforms();
-
- glBindBuffer(GL_ARRAY_BUFFER,0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
-
- glBindVertexArray(0);
- glDeleteVertexArrays(1,&vao);
+ data.Vertices.resize(nP);
+ data.indices.resize(3*nI);
- glDeleteBuffers(1,&vertsBufferIndex);
- glDeleteBuffers(1,&elemBufferIndex);
-}
-
-void BezierPatch::sortTriangles()
-{
- if(Ntvertices > 0) {
- transform(tVertexbuffer);
- bounds(tIndices);
- qsort(&tIndices[0],tIndices.size()/3,3*sizeof(GLuint),compare);
- }
-}
-
-void Triangles::queue(size_t nP, triple* P, size_t nN, triple* N,
- size_t nC, prc::RGBAColour* C, size_t nI,
- uint32_t (*PI)[3], uint32_t (*NI)[3], uint32_t (*CI)[3],
- bool transparent)
-{
- if(!nN) return;
- const size_t indexstride=3;
- size_t nindices=indexstride*nI;
- size_t index0;
-
- if(transparent) {
- tVertexbuffer.reserve(nbuffer);
- tVertexbuffer.resize(Ntvertices+nP);
- tIndices.reserve(nbuffer);
- index0=tIndices.size();
- tIndices.resize(index0+nindices);
- } else {
- if(nC) {
- Vertexbuffer.reserve(nbuffer);
- Vertexbuffer.resize(Nvertices+nP);
- Indices.reserve(nbuffer);
- index0=Indices.size();
- Indices.resize(index0+nindices);
- } else {
- vertexbuffer.reserve(nbuffer);
- vertexbuffer.resize(nvertices+nP);
- indices.reserve(nbuffer);
- index0=indices.size();
- indices.resize(index0+nindices);
- }
- }
-
- uint32_t *P0=(uint32_t *) PI;
- uint32_t *N0=(uint32_t *) NI;
- uint32_t *C0=(uint32_t *) CI;
-
- if(transparent) {
- if(nC) {
- for(size_t i=0; i < nindices; ++i) {
- uint32_t i0=P0[i];
- prc::RGBAColour c=C[C0[i]];
- GLfloat c0[]={(GLfloat) c.R,(GLfloat) c.G,(GLfloat) c.B,(GLfloat) c.A};
- GLuint index=Ntvertices+i0;
- tVertexbuffer[index]=VertexData(P[i0],N[N0[i]],c0);
- tIndices[index0+i]=index;
- }
- } else {
- for(size_t i=0; i < nindices; ++i) {
- uint32_t i0=P0[i];
- GLuint index=Ntvertices+i0;
- tVertexbuffer[index]=VertexData(P[i0],N[N0[i]]);
- tIndices[index0+i]=index;
- }
- }
- Ntvertices += nP;
- } else {
- if(nC) {
- for(size_t i=0; i < nindices; ++i) {
- uint32_t i0=P0[i];
- prc::RGBAColour c=C[C0[i]];
- GLfloat c0[]={(GLfloat) c.R,(GLfloat) c.G,(GLfloat) c.B,
- (GLfloat) c.A};
- GLuint index=Nvertices+i0;
- Vertexbuffer[index]=VertexData(P[i0],N[N0[i]],c0);
- Indices[index0+i]=index;
- }
- Nvertices += nP;
- } else {
- for(size_t i=0; i < nindices; ++i) {
- uint32_t i0=P0[i];
- GLuint index=nvertices+i0;
- vertexbuffer[index]=vertexData(P[i0],N[N0[i]]);
- indices[index0+i]=index;
+ MaterialIndex=nC ? -1-materialIndex : 1+materialIndex;
+
+ for(size_t i=0; i < nI; ++i) {
+ const uint32_t *PI=PP[i];
+ uint32_t PI0=PI[0];
+ uint32_t PI1=PI[1];
+ uint32_t PI2=PI[2];
+ triple P0=P[PI0];
+ triple P1=P[PI1];
+ triple P2=P[PI2];
+ triple Q[]={P0,P1,P2};
+ if(!offscreen(3,Q)) {
+ const uint32_t *NI=NN[i];
+ if(nC) {
+ const uint32_t *CI=CC[i];
+ prc::RGBAColour C0=C[CI[0]];
+ prc::RGBAColour C1=C[CI[1]];
+ prc::RGBAColour C2=C[CI[2]];
+ GLfloat c0[]={(GLfloat) C0.R,(GLfloat) C0.G,(GLfloat) C0.B,
+ (GLfloat) C0.A};
+ GLfloat c1[]={(GLfloat) C1.R,(GLfloat) C1.G,(GLfloat) C1.B,
+ (GLfloat) C1.A};
+ GLfloat c2[]={(GLfloat) C2.R,(GLfloat) C2.G,(GLfloat) C2.B,
+ (GLfloat) C2.A};
+ transparent |= c0[3]+c1[3]+c2[3] < 765;
+ data.Vertices[PI0]=VertexData(P0,N[NI[0]],c0);
+ data.Vertices[PI1]=VertexData(P1,N[NI[1]],c1);
+ data.Vertices[PI2]=VertexData(P2,N[NI[2]],c2);
+ } else {
+ data.Vertices[PI0]=VertexData(P0,N[NI[0]]);
+ data.Vertices[PI1]=VertexData(P1,N[NI[1]]);
+ data.Vertices[PI2]=VertexData(P2,N[NI[2]]);
}
- nvertices += nP;
+ size_t i3=3*i;
+ data.indices[i3]=PI0;
+ data.indices[i3+1]=PI1;
+ data.indices[i3+2]=PI2;
}
}
+ append();
}
#endif
diff --git a/graphics/asymptote/bezierpatch.h b/graphics/asymptote/bezierpatch.h
index b8c23574d7..e637eef467 100644
--- a/graphics/asymptote/bezierpatch.h
+++ b/graphics/asymptote/bezierpatch.h
@@ -16,112 +16,23 @@ namespace camp {
extern const double Fuzz4;
-class vertexData {
-public:
- GLfloat position[3];
- GLfloat normal[3];
- GLint material;
- vertexData() {};
- vertexData(const triple& v, const triple& n) {
- position[0]=v.getx();
- position[1]=v.gety();
- position[2]=v.getz();
- normal[0]=n.getx();
- normal[1]=n.gety();
- normal[2]=n.getz();
- material=drawElement::materialIndex;
- }
-};
-
-class VertexData {
-public:
- GLfloat position[3];
- GLfloat normal[3];
- GLuint color;
- GLint material;
- VertexData() {};
- VertexData(const triple& v, const triple& n) {
- position[0]=v.getx();
- position[1]=v.gety();
- position[2]=v.getz();
- normal[0]=n.getx();
- normal[1]=n.gety();
- normal[2]=n.getz();
- color=0;
- material=drawElement::materialIndex;
- }
- VertexData(const triple& v, const triple& n, GLfloat *c) {
- position[0]=v.getx();
- position[1]=v.gety();
- position[2]=v.getz();
- normal[0]=n.getx();
- normal[1]=n.gety();
- normal[2]=n.getz();
- color=glm::packUnorm4x8(glm::vec4(c[0],c[1],c[2],c[3]));
- material=-(int) drawElement::materialIndex-1; // request explicit color
- }
-
-};
-
struct BezierPatch
{
- static std::vector<vertexData> vertexbuffer;
- static std::vector<VertexData> Vertexbuffer;
- static std::vector<VertexData> tVertexbuffer; // for transparent surfaces
- static std::vector<GLuint> indices;
- static std::vector<GLuint> Indices;
- static std::vector<GLuint> tIndices;
- static GLuint nvertices;
- static GLuint Nvertices;
- static GLuint Ntvertices;
-
- static GLuint vertsBufferIndex;
- static GLuint VertsBufferIndex;
- static GLuint tVertsBufferIndex;
-
- static GLuint elemBufferIndex;
- static GLuint ElemBufferIndex;
- static GLuint tElemBufferIndex;
-
- std::vector<GLuint> *pindices;
- triple u,v,w;
+ vertexBuffer data;
+
+ bool transparent;
+ bool color;
double epsilon;
double Epsilon;
double res2;
double Res2; // Reduced resolution for Bezier triangles flatness test.
- triple Min,Max;
- typedef GLuint vertexFunction(const triple &v, const triple& n);
- typedef GLuint VertexFunction(const triple &v, const triple& n, GLfloat *c);
- vertexFunction *pvertex;
- VertexFunction *pVertex;
-
- BezierPatch() {}
-
- void init(double res, const triple& Min, const triple& Max,
- bool transparent, GLfloat *colors=NULL);
+ typedef GLuint (vertexBuffer::*vertexFunction)(const triple &v,
+ const triple& n);
+ vertexFunction pvertex;
+ bool Onscreen;
+
+ void init(double res);
-// Store the vertex v and its normal vector n in the buffer.
- static GLuint vertex(const triple &v, const triple& n) {
- vertexbuffer.push_back(vertexData(v,n));
- return nvertices++;
- }
-
-// Store the vertex v and its normal vector n and colour c in the buffer.
- static GLuint Vertex(const triple& v, const triple& n, GLfloat *c) {
- Vertexbuffer.push_back(VertexData(v,n,c));
- return Nvertices++;
- }
-
- static GLuint tvertex(const triple &v, const triple& n) {
- tVertexbuffer.push_back(VertexData(v,n));
- return Ntvertices++;
- }
-
- static GLuint tVertex(const triple& v, const triple& n, GLfloat *c) {
- tVertexbuffer.push_back(VertexData(v,n,c));
- return Ntvertices++;
- }
-
triple normal(triple left3, triple left2, triple left1, triple middle,
triple right1, triple right2, triple right3) {
triple rp=right1-middle;
@@ -165,7 +76,7 @@ struct BezierPatch
triple p12=p[12];
triple p15=p[15];
- // Check the flatness of the quad.
+ // Check the flatness of a Bezier patch.
double d=Distance2(p15,p0,normal(p3,p[2],p[1],p0,p[4],p[8],p12));
// Determine how straight the edges are.
@@ -194,78 +105,52 @@ struct BezierPatch
}
};
-// Approximate bounds by bounding box of control polyhedron.
+ // Approximate bounds by bounding box of control polyhedron.
bool offscreen(size_t n, const triple *v) {
- double x,y,z;
- double X,Y,Z;
-
- boundstriples(x,y,z,X,Y,Z,n,v);
- return
- X < Min.getx() || x > Max.getx() ||
- Y < Min.gety() || y > Max.gety() ||
- Z < Min.getz() || z > Max.getz();
+ if(bbox2(n,v).offscreen()) {
+ Onscreen=false;
+ return true;
+ }
+ return false;
}
- static void clear() {
- nvertices=0;
- vertexbuffer.clear();
- indices.clear();
- }
-
- static void Clear() {
- Nvertices=0;
- Vertexbuffer.clear();
- Indices.clear();
- }
-
- static void tClear() {
- Ntvertices=0;
- tVertexbuffer.clear();
- tIndices.clear();
- }
-
- ~BezierPatch() {}
-
+ virtual void render(const triple *p, bool straight, GLfloat *c0=NULL);
void render(const triple *p,
GLuint I0, GLuint I1, GLuint I2, GLuint I3,
triple P0, triple P1, triple P2, triple P3,
bool flat0, bool flat1, bool flat2, bool flat3,
GLfloat *C0=NULL, GLfloat *C1=NULL, GLfloat *C2=NULL,
GLfloat *C3=NULL);
- virtual void render(const triple *p, bool straight, GLfloat *c0=NULL);
- void queue(const triple *g, bool straight, double ratio,
- const triple& Min, const triple& Max, bool transparent,
- GLfloat *colors=NULL) {
- init(pixel*ratio,Min,Max,transparent,colors);
- render(g,straight,colors);
- }
-
- void drawMaterials();
- void drawColors(GLuint& Nvertices,
- std::vector<VertexData>& Vertexbuffer,
- std::vector<GLuint>& Indices);
- void sortTriangles();
-
- void drawColors() {
- drawColors(Nvertices,Vertexbuffer,Indices);
- }
-
- void drawOpaque() {
- drawMaterials();
- drawColors();
- }
-
- void drawTransparent() {
- glDepthMask(GL_FALSE);
- sortTriangles();
- drawColors(Ntvertices,tVertexbuffer,tIndices);
- glDepthMask(GL_TRUE);
+ void append() {
+ if(transparent)
+ transparentData.Append(data);
+ else if(color) {
+ colorData.Append(data);
+ if(colorData.Vertices.size() >= gl::maxvertices) {
+ drawBuffer(colorData,colorShader);
+ colorData.clear();
+ gl::forceRemesh=true;
+ }
+ }
+ else {
+ materialData.append(data);
+ if(materialData.vertices.size() >= gl::maxvertices) {
+ drawBuffer(materialData,materialShader);
+ materialData.clear();
+ gl::forceRemesh=true;
+ }
+ }
}
- void draw() {
- drawOpaque();
- drawTransparent();
+ void queue(const triple *g, bool straight, double ratio, bool Transparent,
+ GLfloat *colors=NULL) {
+ data.clear();
+ Onscreen=true;
+ transparent=Transparent;
+ color=colors;
+ init(pixel*ratio);
+ render(g,straight,colors);
}
};
@@ -288,25 +173,39 @@ public:
return max(d,Straightness(p6,p[7],p[8],p9));
}
+ void render(const triple *p, bool straight, GLfloat *c0=NULL);
void render(const triple *p,
GLuint I0, GLuint I1, GLuint I2,
triple P0, triple P1, triple P2,
bool flat0, bool flat1, bool flat2,
GLfloat *C0=NULL, GLfloat *C1=NULL, GLfloat *C2=NULL);
- void render(const triple *p, bool straight, GLfloat *c0=NULL);
};
-
struct Triangles : public BezierPatch {
public:
Triangles() : BezierPatch() {}
- void queue(size_t nP, triple* P, size_t nN, triple* N,
- size_t nC, prc::RGBAColour* C, size_t nI,
- uint32_t (*PI)[3], uint32_t (*NI)[3], uint32_t (*CI)[3],
- bool transparent);
+ void queue(size_t nP, const triple* P, size_t nN, const triple* N,
+ size_t nC, const prc::RGBAColour* C, size_t nI,
+ const uint32_t (*PI)[3], const uint32_t (*NI)[3],
+ const uint32_t (*CI)[3], bool transparent);
+
+ void append() {
+ if(transparent)
+ transparentData.Append(data);
+ else {
+ triangleData.Append(data);
+ if(triangleData.Vertices.size() >= gl::maxvertices) {
+ drawBuffer(triangleData,transparentShader);
+ triangleData.clear();
+ gl::forceRemesh=true;
+ }
+ }
+ }
+
};
+extern void sortTriangles();
#endif
diff --git a/graphics/asymptote/binaries/i386-windows/README b/graphics/asymptote/binaries/i386-windows/README
index 77e7edfb59..f153da76a8 100644
--- a/graphics/asymptote/binaries/i386-windows/README
+++ b/graphics/asymptote/binaries/i386-windows/README
@@ -60,7 +60,3 @@ under the CC-BY-SA 4.0 license:
http://www.entypo.com/
and under a CC license:
http://www.zondicons.com/zondicons.zip
-
-Uses OpenImageIO, which the source is available at
-https://github.com/OpenImageIO/oiio.
-Copyright 2008-2018 Larry Gritz et al. All Rights Reserved. \ No newline at end of file
diff --git a/graphics/asymptote/binaries/x86_64-windows/README b/graphics/asymptote/binaries/x86_64-windows/README
index 77e7edfb59..f153da76a8 100644
--- a/graphics/asymptote/binaries/x86_64-windows/README
+++ b/graphics/asymptote/binaries/x86_64-windows/README
@@ -60,7 +60,3 @@ under the CC-BY-SA 4.0 license:
http://www.entypo.com/
and under a CC license:
http://www.zondicons.com/zondicons.zip
-
-Uses OpenImageIO, which the source is available at
-https://github.com/OpenImageIO/oiio.
-Copyright 2008-2018 Larry Gritz et al. All Rights Reserved. \ No newline at end of file
diff --git a/graphics/asymptote/build-scripts/HOWTO-MSWindows b/graphics/asymptote/build-scripts/HOWTO-MSWindows
index 609c6fd769..977501d658 100644
--- a/graphics/asymptote/build-scripts/HOWTO-MSWindows
+++ b/graphics/asymptote/build-scripts/HOWTO-MSWindows
@@ -50,12 +50,14 @@ cp /usr/bin/cygwin1.dll ~/dll/cygwin
mkdir ~/CTAN
cp -a ~/asymptote/build-scripts/README-binaries ~/CTAN
+cd ~/
GCVERSION=7.6.2
+ATOMICVERSION=7.6.10
wget http://hboehm.info/gc/gc_source/gc-$GCVERSION.tar.gz
-wget http://www.ivmaisoft.com/_bin/atomic_ops/libatomic_ops-$GCVERSION.tar.gz
+wget http://www.ivmaisoft.com/_bin/atomic_ops/libatomic_ops-$ATOMICVERSION.tar.gz
tar -zxf gc-$GCVERSION.tar.gz
-tar -zxf libatomic_ops-$GCVERSION.tar.gz
-mv libatomic_ops-$GCVERSION gc-$GCVERSION/libatomic_ops
+tar -zxf libatomic_ops-$ATOMICVERSION.tar.gz
+mv libatomic_ops-$ATOMICVERSION gc-$GCVERSION/libatomic_ops
cd gc-$GCVERSION
./configure --disable-shared
make check
diff --git a/graphics/asymptote/build-scripts/build-asygl b/graphics/asymptote/build-scripts/build-asygl
new file mode 100755
index 0000000000..d28bb85fa9
--- /dev/null
+++ b/graphics/asymptote/build-scripts/build-asygl
@@ -0,0 +1,21 @@
+#!/bin/sh
+if [ ! $# = 1 ]; then echo Usage: "$0 AsyGLVersion"; exit 1; fi
+GL_MATRIX_VERSION=2.4.0
+GL_MATRIX_DIR=gl-matrix-$GL_MATRIX_VERSION
+GL_MATRIX_DIR_PRUNED=$GL_MATRIX_DIR-pruned
+if test ! -r $GL_MATRIX_DIR_PRUNED; then \
+ TEMPDIR=`mktemp -d`
+ TARFILE=$TEMPDIR/$GL_MATRIX_DIR.tar.gz
+ wget https://github.com/toji/gl-matrix/archive/v$GL_MATRIX_VERSION.tar.gz --output-document=$TARFILE
+tar -zxf $TARFILE
+mv $GL_MATRIX_DIR $GL_MATRIX_DIR_PRUNED
+rm -r $TEMPDIR
+cd $GL_MATRIX_DIR_PRUNED
+patch -p1 < ../patches/$GL_MATRIX_DIR_PRUNED.patch
+npm install
+npm run build-all
+echo "/*@license for gl-matrix mat3 and mat4 functions:" > LICENSE.js
+echo "*/"| cat LICENSE.md - >> LICENSE.js
+cd ..
+fi
+cat $GL_MATRIX_DIR_PRUNED/dist/gl-matrix-min.js webgl/gl.js $GL_MATRIX_DIR_PRUNED/LICENSE.js | uglifyjs -m -c -o base/webgl/asygl-$1.js --comments
diff --git a/graphics/asymptote/build-scripts/build-freeglut b/graphics/asymptote/build-scripts/build-freeglut
deleted file mode 100755
index 95d4cbfb4b..0000000000
--- a/graphics/asymptote/build-scripts/build-freeglut
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh -x
-#Be sure to remove /usr/include/GL
-wget http://prdownloads.sourceforge.net/freeglut/freeglut-2.8.1.tar.gz
-ln -sf /usr/bin/cyggcc_s-1.dll /usr/lib/libgcc_s.a
-tar -zxf freeglut-2.8.1.tar.gz
-cd freeglut-2.8.1
-patch -p1 < ~/asymptote/patches/cygwin_freeglut-2.8.1.patch
-./configure --prefix=/usr --without-x
-make
-cd src
-gcc -s -static -shared -o freeglut.dll *.o -Wl,--out-implib=libfreeglut.a -lglu32 -lopengl32 -lgdi32 -lwinmm
-cp freeglut.dll /lib
-mkdir -p ~/dll
-cp freeglut.dll ~/dll
-gcc -s -shared -o freeglut.dll *.o -Wl,--out-implib=libfreeglut.a -lglu32 -lopengl32 -lgdi32 -lwinmm
-cp libfreeglut.a /lib
-cd ..
-cp -a include/GL/*.h /usr/include/w32api/GL/
-
-#OPTIONAL: To compile manually in src:
-#gcc -O2 -c -D_WIN32 -DHAVE_CONFIG_H -DFREEGLUT_EXPORTS *.c -I.. -I../include
-
diff --git a/graphics/asymptote/config.h.in b/graphics/asymptote/config.h.in
index a178b67d1c..0ef1ec3717 100644
--- a/graphics/asymptote/config.h.in
+++ b/graphics/asymptote/config.h.in
@@ -39,6 +39,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the `lgamma' function. */
+#undef HAVE_LGAMMA
+
/* Define to 1 if you have the `ncurses' library (-lncurses). */
#undef HAVE_LIBCURSES
@@ -108,9 +111,6 @@
/* Define to 1 if you have the <ncurses.h> header file. */
#undef HAVE_NCURSES_H
-/* Define to 1 if you have the `pow' function. */
-#undef HAVE_POW
-
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
@@ -123,9 +123,6 @@
/* Define to 1 if you have a working <tirpc/rpc/rpc.h> header. */
#undef HAVE_RPC_RPC_H
-/* Define to 1 if you have the `sqrt' function. */
-#undef HAVE_SQRT
-
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
diff --git a/graphics/asymptote/configure b/graphics/asymptote/configure
index e1cbe29de1..ea835748ff 100755
--- a/graphics/asymptote/configure
+++ b/graphics/asymptote/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Asymptote 2.53.
+# Generated by GNU Autoconf 2.69 for Asymptote 2.54.
#
# Report bugs to <http://sourceforge.net/projects/asymptote>.
#
@@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Asymptote'
PACKAGE_TARNAME='asymptote'
-PACKAGE_VERSION='2.53'
-PACKAGE_STRING='Asymptote 2.53'
+PACKAGE_VERSION='2.54'
+PACKAGE_STRING='Asymptote 2.54'
PACKAGE_BUGREPORT='http://sourceforge.net/projects/asymptote'
PACKAGE_URL=''
@@ -1285,7 +1285,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Asymptote 2.53 to adapt to many kinds of systems.
+\`configure' configures Asymptote 2.54 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1350,7 +1350,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Asymptote 2.53:";;
+ short | recursive ) echo "Configuration of Asymptote 2.54:";;
esac
cat <<\_ACEOF
@@ -1467,7 +1467,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Asymptote configure 2.53
+Asymptote configure 2.54
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2053,7 +2053,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Asymptote $as_me 2.53, which was
+It was created by Asymptote $as_me 2.54, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -7492,18 +7492,19 @@ if test "${enable_OpenImageIO+set}" = set; then :
fi
-if test "x$enable_gl" != "xno"; then
ac_fn_cxx_check_header_mongrel "$LINENO" "glm/glm.hpp" "ac_cv_header_glm_glm_hpp" "$ac_includes_default"
if test "x$ac_cv_header_glm_glm_hpp" = xyes; then :
$as_echo "#define HAVE_LIBGLM 1" >>confdefs.h
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find glm header files: will compile without OpenGL support ***" >&5
-$as_echo "$as_me: *** Could not find glm header files: will compile without OpenGL support ***" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find glm header files: will compile without WebGL or OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find glm header files: will compile without WebGL or OpenGL support ***" >&6;}
fi
+
+if test "x$enable_gl" != "xno"; then
for ac_header in ncurses/curses.h ncurses.h curses.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -7804,8 +7805,8 @@ _ACEOF
LIBS="-lglut $LIBS"
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libglut: will compile without GLUT support ***" >&5
-$as_echo "$as_me: *** Could not find libglut: will compile without GLUT support ***" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libglut: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find libglut: will compile without OpenGL support ***" >&6;}
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glDepthMask in -lGL" >&5
@@ -8333,7 +8334,7 @@ $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
fi
-for ac_func in dup2 floor memset pow sqrt strchr tgamma memrchr
+for ac_func in dup2 floor memset strchr tgamma lgamma memrchr
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -9029,7 +9030,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Asymptote $as_me 2.53, which was
+This file was extended by Asymptote $as_me 2.54, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9091,7 +9092,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Asymptote config.status 2.53
+Asymptote config.status 2.54
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/graphics/asymptote/configure.ac b/graphics/asymptote/configure.ac
index 92dd1ded2b..5b7e118645 100644
--- a/graphics/asymptote/configure.ac
+++ b/graphics/asymptote/configure.ac
@@ -3,7 +3,7 @@
# this file.
AC_PREREQ(2)
-AC_INIT([Asymptote],[2.53],[http://sourceforge.net/projects/asymptote])
+AC_INIT([Asymptote],[2.54],[http://sourceforge.net/projects/asymptote])
VERSION=$PACKAGE_VERSION
AC_SUBST(VERSION)
m4_include([ax_pthread.m4])
@@ -362,10 +362,11 @@ AC_ARG_ENABLE(offscreen,
AC_ARG_ENABLE(OpenImageIO,
[AS_HELP_STRING(--enable-openimageio[[[=no]]],enable experimental OpenImageIO Library)])
-if test "x$enable_gl" != "xno"; then
AC_CHECK_HEADER(glm/glm.hpp,
[AC_DEFINE(HAVE_LIBGLM,1,
- DEFINE([the <glm/glm.hpp> header]))],AC_MSG_NOTICE([*** Could not find glm header files: will compile without OpenGL support ***]))
+ DEFINE([the <glm/glm.hpp> header]))],AC_MSG_NOTICE([*** Could not find glm header files: will compile without WebGL or OpenGL support ***]))
+
+if test "x$enable_gl" != "xno"; then
AC_CHECK_HEADERS([ncurses/curses.h ncurses.h curses.h],[break])
if test "x$enable_openimageio" = "xyes"; then
AC_CHECK_HEADER([OpenEXR/ImathVec.h],
@@ -400,7 +401,7 @@ case "$OSTYPE" in
*)
AC_CHECK_LIB([gccpp],[GC_throw_bad_alloc])
AC_CHECK_LIB([glut], [glutMainLoop],,
- AC_MSG_NOTICE([*** Could not find libglut: will compile without GLUT support ***]))
+ AC_MSG_NOTICE([*** Could not find libglut: will compile without OpenGL support ***]))
AC_CHECK_LIB([GL], [glDepthMask],
[AC_DEFINE(HAVE_LIBGL,1,
DEFINE_LIB([GL]))
@@ -429,7 +430,7 @@ AC_DEFUN([ac_FUNC_STRPTIME], [
# Checks for library functions.
AC_FUNC_FORK
-AC_CHECK_FUNCS([dup2 floor memset pow sqrt strchr tgamma memrchr])
+AC_CHECK_FUNCS([dup2 floor memset strchr tgamma lgamma memrchr])
AC_FUNC_STRFTIME
ac_FUNC_STRPTIME
AC_FUNC_ERROR_AT_LINE
diff --git a/graphics/asymptote/doc/CAD.pdf b/graphics/asymptote/doc/CAD.pdf
index 84fbc4399e..08f0a0b4eb 100644
--- a/graphics/asymptote/doc/CAD.pdf
+++ b/graphics/asymptote/doc/CAD.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/FAQ/asy-faq.info b/graphics/asymptote/doc/FAQ/asy-faq.info
index 717734ca0b..543feac215 100644
--- a/graphics/asymptote/doc/FAQ/asy-faq.info
+++ b/graphics/asymptote/doc/FAQ/asy-faq.info
@@ -10,7 +10,7 @@ END-INFO-DIR-ENTRY
File: asy-faq.info, Node: Top, Next: Question 1.1, Up: (dir)
ASYMPTOTE FREQUENTLY ASKED QUESTIONS
- 20 Aug 2019
+ 29 Sep 2019
This is the list of Frequently Asked Questions about Asymptote (asy).
diff --git a/graphics/asymptote/doc/Makefile.in b/graphics/asymptote/doc/Makefile.in
index 58dfc179df..8888df0145 100644
--- a/graphics/asymptote/doc/Makefile.in
+++ b/graphics/asymptote/doc/Makefile.in
@@ -24,7 +24,7 @@ asymptote.sty:
dvi: doc asymptote.dvi
-doc: $(DOCFILES) asy.1 faq latexusage.eps
+doc: $(DOCFILES) asy.1 faq
cd png && $(MAKE) all
manpage: $(MANFILES)
@@ -41,19 +41,13 @@ faq:
%.pdf: %.asy
$(ASY) -f pdf -noprc $<
-latexusage.dvi: latexusage.tex asymptote.sty
+latexusage.pdf: latexusage.tex asymptote.sty
rm -f latexusage-*
rm -f latexusage.pre
rm -f latexusage.aux
- latex latexusage
+ pdflatex latexusage
$(ASY) -noprc latexusage-*.asy
- latex latexusage
-
-latexusage.eps: latexusage.dvi
- dvips -o latexusage.eps latexusage
-
-latexusage.pdf: latexusage.dvi
- dvipdf -P latexusage
+ pdflatex latexusage
options: ../settings.cc
$(ASY) -h 2>&1 | grep -iv Asymptote > options
@@ -72,19 +66,16 @@ asymptote.pdf: $(SOURCE) $(ASYFILES:.asy=.pdf) latexusage.pdf
-$(TEXI2DVI) --pdf asymptote.texi
CAD.pdf: CAD.tex CAD1.eps
- latex CAD
- latex CAD
- latex CAD
- dvipdf -P CAD
+ pdflatex CAD
+ pdflatex CAD
+ pdflatex CAD
TeXShopAndAsymptote.pdf: TeXShopAndAsymptote.tex
- latex TeXShopAndAsymptote
- latex TeXShopAndAsymptote
- dvipdf -P TeXShopAndAsymptote
+ pdflatex TeXShopAndAsymptote
+ pdflatex TeXShopAndAsymptote
asyRefCard.pdf: asyRefCard.tex
- tex asyRefCard
- dvipdf -P asyRefCard
+ pdftex asyRefCard
clean: FORCE
-rm -f asy-latex.{aux,idx,ins,log,toc}
@@ -112,7 +103,7 @@ install-prebuilt: install-man options
cd png && $(MAKE) install
cd FAQ && $(MAKE) install-prebuilt
-install-all: $(DOCFILES) $(MANFILES) faq latexusage.eps install-man
+install-all: $(DOCFILES) $(MANFILES) faq install-man
cd png && $(MAKE) install-all
cd FAQ && $(MAKE) install-info
diff --git a/graphics/asymptote/doc/TeXShopAndAsymptote.pdf b/graphics/asymptote/doc/TeXShopAndAsymptote.pdf
index 75708beb4e..a6387890ed 100644
--- a/graphics/asymptote/doc/TeXShopAndAsymptote.pdf
+++ b/graphics/asymptote/doc/TeXShopAndAsymptote.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asy-latex.pdf b/graphics/asymptote/doc/asy-latex.pdf
index 4d861a4e54..8458cebbf2 100644
--- a/graphics/asymptote/doc/asy-latex.pdf
+++ b/graphics/asymptote/doc/asy-latex.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asy.1 b/graphics/asymptote/doc/asy.1
index d9380da919..563f8a3cd6 100644
--- a/graphics/asymptote/doc/asy.1
+++ b/graphics/asymptote/doc/asy.1
@@ -34,6 +34,9 @@ description, see the Info files.
.B \-V,\-View
View output; command-line only.
.TP
+.B \-absolute
+Use absolute WebGL dimensions [false].
+.TP
.B \-a,\-align C|B|T|Z
Center, Bottom, Top, or Zero page alignment [C].
.TP
@@ -43,9 +46,6 @@ Directional page alignment (overrides align) [(0,0)].
.B \-antialias n
Antialiasing width for rasterized output [2].
.TP
-.B \-arcballradius pixels
-Arcball radius [750].
-.TP
.B \-auto3D
Automatically activate 3D scene [true].
.TP
@@ -91,12 +91,12 @@ Conserve memory at the expense of speed [false].
.B \-d,\-debug
Enable debugging messages [false].
.TP
+.B \-digits n
+Default output file precision [6].
+.TP
.B \-divisor n
Garbage collect using purge(divisor=n) [2].
.TP
-.B \-doubleclick ms
-Emulated double-click timeout [200].
-.TP
.B \-embed
Embed rendered preview image [true].
.TP
@@ -184,6 +184,9 @@ View output from multiple batch-mode files [false].
.B \-multisample n
Multisampling width for screen images [4].
.TP
+.B \-offline
+Produce offline html files [false].
+.TP
.B \-offscreen
Use offscreen rendering [false].
.TP
@@ -238,6 +241,12 @@ Disable system call [true].
.B \-scroll n
Scroll standard output n lines at a time [0].
.TP
+.B \-shiftHoldDistance n
+WebGL touch screen distance limit for shift mode [20].
+.TP
+.B \-shiftWaitTime ms
+WebGL touch screen shift mode delay [200].
+.TP
.B \-spinstep deg/s
Spin speed [60].
.TP
@@ -280,6 +289,12 @@ Increase verbosity level (can specify multiple times) [0].
.B \-version
Show version; command-line only.
.TP
+.B \-vibrateTime ms
+WebGL shift mode vibrate duration [25].
+.TP
+.B \-viewportmargin pair
+Horizontal and vertical 3D viewport margin [(0.5,0.5)].
+.TP
.B \-wait
Wait for child processes to finish before exiting [false].
.TP
@@ -292,6 +307,12 @@ Show where listed variables are declared [false].
.B \-xasy
Special interactive mode for xasy [false].
.TP
+.B \-zoomPinchCap limit
+WebGL maximum zoom pinch [100].
+.TP
+.B \-zoomPinchFactor n
+WebGL zoom pinch sensitivity [10].
+.TP
.B \-zoomfactor factor
Zoom step factor [1.05].
.TP
diff --git a/graphics/asymptote/doc/asyRefCard.pdf b/graphics/asymptote/doc/asyRefCard.pdf
index b439ce9f9a..65ff3e817f 100644
--- a/graphics/asymptote/doc/asyRefCard.pdf
+++ b/graphics/asymptote/doc/asyRefCard.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asymptote.pdf b/graphics/asymptote/doc/asymptote.pdf
index 06c2a69fc4..d6f6ecab14 100644
--- a/graphics/asymptote/doc/asymptote.pdf
+++ b/graphics/asymptote/doc/asymptote.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asymptote.texi b/graphics/asymptote/doc/asymptote.texi
index d231d55cd0..4a630d45e5 100644
--- a/graphics/asymptote/doc/asymptote.texi
+++ b/graphics/asymptote/doc/asymptote.texi
@@ -84,7 +84,7 @@ Installation
Tutorial
* Drawing in batch mode:: Run @code{Asymptote} on a text file
-* Drawing in interactive mode:: Running @code{Asymptote} interactively
+* Drawing in interactive mode:: Running @code{Asymptote} interactively
* Figure size:: Specifying the figure size
* Labels:: Adding @code{LaTeX} labels
* Paths:: Drawing lines and curves
@@ -221,6 +221,9 @@ as @TeX{}/@code{LaTeX} is the de-facto standard for typesetting equations.
@item @code{LaTeX} typesetting of labels, for overall document consistency;
+@item the ability to generate and embed 3D vector @acronym{WebGL}
+graphics within @acronym{HTML} files;
+
@item the ability to generate and embed 3D vector @acronym{PRC}
graphics within @acronym{PDF} files;
@@ -254,7 +257,7 @@ Many of the features of @code{Asymptote} are written in the
@code{Asymptote} language itself. While the stock version of
@code{Asymptote} is designed for mathematics typesetting needs, one can
write @code{Asymptote} modules that tailor it to specific
-applications. A scientific graphing module has already been written
+applications; for example, a scientific graphing module is available
(@pxref{graph}). Examples of @code{Asymptote} code and output,
including animations, are available at
@quotation
@@ -382,7 +385,7 @@ The @code{ImageMagick} package from
@url{http://www.imagemagick.org/script/binary-releases.php}
@noindent
-is required to support output formats other than @acronym{EPS},
+is required to support output formats other than @acronym{HTML},
@acronym{PDF}, @acronym{SVG}, and @acronym{PNG} (@pxref{convert}).
The @code{Python 3} interpreter from @url{http://www.python.org} is only required
if you wish to try out the graphical user interface (@pxref{GUI}).
@@ -396,15 +399,11 @@ subdirectory of the installation directory (by default,
@section Configuring
@cindex configuring
@cindex @code{-V}
-@cindex @code{psviewer}
-@cindex @code{pdfviewer}
-@cindex @code{gs}
In interactive mode, or when given the @code{-V} option (the default
when running @code{Asymptote} on a single file under @code{MSDOS}),
@code{Asymptote} will automatically invoke the @code{PostScript}
viewer @code{gv} (under @code{UNIX}) or @code{gsview} (under
-@code{MSDOS} to display graphical output. These defaults may be
-overridden with the configuration variable @code{psviewer}.
+@code{MSDOS} to display graphical output.
The @code{PostScript} viewer should be capable of automatically
redrawing whenever the output file is updated. The default @code{UNIX}
@code{PostScript} viewer @code{gv} supports this (via a @code{SIGHUP}
@@ -418,40 +417,58 @@ Users of @code{gsview} will need to enable @code{Options/Auto Redisplay}
@code{gsview} window; under @code{UNIX} one must manually redisplay by
pressing the @code{r} key).
+@cindex @code{psviewer}
+@cindex @code{pdfviewer}
+@cindex @code{htmlviewer}
+@cindex @code{gs}
+@cindex @code{display}
+@cindex @code{animate}
@cindex @code{settings}
@cindex configuration file
Configuration variables are most easily set as @code{Asymptote}
variables in an optional configuration file @code{config.asy}
@pxref{configuration file}).
-Here are the default values of several important configuration
-variables under @code{UNIX}:
+For example, the setting @code{pdfviewer} specifies the location of
+the @acronym{PDF} viewer. Here are the default values of several
+important configuration variables under @code{UNIX}:
@noindent
@verbatim
import settings;
-psviewer="gv";
pdfviewer="acroread";
+htmlviewer="google-chrome";
+psviewer="gv";
+display="display";
+animate="animate";
gs="gs";
+libgs="";
@end verbatim
@noindent
@cindex @code{cmd}
-Under @code{MSDOS}, the (installation-dependent) default values of
-these configuration variables are determined automatically from the
-@code{Microsoft Windows} registry. Viewer settings (such as
-@code{psviewer} and @code{pdfviewer}) can be set to the string
-@code{cmd} to request the application normally associated with the
-corresponding file type.
-
-For @acronym{PDF} format output, the @code{gs} setting specifies the
-location of the @code{PostScript}-to-@acronym{PDF} processor @code{Ghostscript},
-available from @url{http://downloads.ghostscript.com/public}.
-
-The setting @code{pdfviewer} specifies the location of the @acronym{PDF}
-viewer. On @code{UNIX} systems, to support automatic document
-reloading in @code{Adobe Reader}, we recommend copying the file
-@code{reload.js} from the @code{Asymptote} system directory (by default,
-@code{@value{Datadir}/asymptote} under @code{UNIX} to
+Under @code{MSDOS}, the viewer settings
+@code{htmlviewer}, @code{pdfviewer}, @code{psviewer},
+@code{display}, and @code{animate} default to the string @code{cmd},
+requesting the application normally associated with each file type.
+The (installation-dependent) default values of @code{gs}
+and @code{libgs} are determined automatically from the @code{Microsoft
+Windows} registry. The @code{gs} setting specifies the location of the
+@code{PostScript} processor @code{Ghostscript}, available from
+@url{https://www.ghostscript.com/}.
+
+@noindent
+@cindex @code{htmlviewer}
+The configuration variable @code{htmlviewer} specifies the
+browser to use to display 3D @code{WebGL} output.
+The default setting is @code{google-chrome} under @code{UNIX} and
+@code{cmd} under @code{Microsoft Windows}. Note that @code{Internet Explorer}
+does not support @code{WebGL}; @code{Microsoft Windows} users should set their
+default html browser to @code{chrome} or @code{microsoft-edge}.
+
+On @code{UNIX} systems, to support automatic document
+reloading of @code{PDF} files in @code{Adobe Reader}, we recommend
+copying the file @code{reload.js} from the @code{Asymptote} system
+directory (by default, @code{@value{Datadir}/asymptote} under @code{UNIX} to
@code{~/.adobe/Acrobat/x.x/JavaScripts/},
where @code{x.x} represents the appropriate @code{Adobe Reader}
version number. The automatic document reload feature must then be
@@ -485,22 +502,17 @@ configuration variables @code{paperwidth} and @code{paperheight}.
@cindex @code{texcommand}
@cindex @code{dvips}
@cindex @code{dvisvgm}
-@cindex @code{libgs}
@cindex @code{convert}
-@cindex @code{display}
-@cindex @code{animate}
@cindex @code{ImageMagick}
-The following configuration variables normally do not require adjustment:
+@cindex @code{asygl}
+These additional configuration variables normally do not require adjustment:
@verbatim
config
texpath
texcommand
dvips
dvisvgm
-libgs
convert
-display
-animate
@end verbatim
@noindent
@@ -777,7 +789,7 @@ make uninstall
@menu
* Drawing in batch mode:: Run @code{Asymptote} on a text file
-* Drawing in interactive mode:: Running @code{Asymptote} interactively
+* Drawing in interactive mode:: Running @code{Asymptote} interactively
* Figure size:: Specifying the figure size
* Labels:: Adding @code{LaTeX} labels
* Paths:: Drawing lines and curves
@@ -4384,7 +4396,7 @@ type of the result:
addition
@cindex @code{-}
@item -
-subtractiona
+subtraction
@cindex @code{*}
@item *
multiplication
@@ -5585,7 +5597,7 @@ real[] A=fin;
Another useful mode is comma-separated-value mode,
@code{file csv(bool b=true)}, which causes reads to respect comma delimiters:
@verbatim
-file fin=csv(input("test.txt"));
+file fin=input("test.txt").csv();
real[] A=fin;
@end verbatim
@@ -5594,7 +5606,7 @@ To restrict the number of values read, use the @code{file dimension(int)}
function:
@verbatim
file fin=input("test.txt");
-real[] A=dimension(fin,10);
+real[] A=fin.dimension(10);
@end verbatim
This reads 10 values into A, unless end-of-file (or end-of-line in line mode)
@@ -7863,14 +7875,16 @@ normals or vertex colors:
@cindex @code{tessellation}
@verbatim
void draw(picture pic=currentpicture, triple[] v, int[][] vi,
- triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
- int[][] pi={}, light light=currentlight);
+ triple[] n={}, int[][] ni=vi, material m=currentpen, pen[] p={},
+ int[][] pi=vi, light light=currentlight);
@end verbatim
-Here, the triple array @code{v} lists the distinct vertices, while
-the array @code{vi} lists integer arrays of length 3 containing
-the indices of @code{v} corresponding to the vertices of each
+Here, the triple array @code{v} lists the (typically distinct) vertices, while
+the array @code{vi} contains integer arrays of length 3 containing
+the indices of the elements in @code{v} that form the vertices of each
triangle. Similarly, the arguments @code{n} and @code{ni} contain
-optional normal data and @code{p} and @code{pi} contain optional pen vertex data.
+optional normal data and @code{p} and @code{pi} contain optional pen
+vertex data. If more than one normal or pen is specified for a vertex, the
+last one specified is used.
An example of this tessellation facility is given in @code{@uref{http://asymptote.sourceforge.net/gallery/triangles.pdf,,triangles}@uref{http://asymptote.sourceforge.net/gallery/triangles.asy,,.asy}}.
@cindex @code{thin}
@@ -7897,18 +7911,17 @@ parameter or the setting @code{thin} is set to @code{false}. The pens
also be used to override these defaults for specific draw commands.
@noindent
-There are four choices for viewing 3D @code{Asymptote} output:
+There are five choices for viewing 3D @code{Asymptote} output:
@enumerate
+
@cindex @code{OpenGL}
@cindex @code{render}
@cindex @code{outformat}
@cindex @code{multisample}
@item Use the native @code{Asymptote} adaptive @code{OpenGL}-based
renderer (with the command-line option @code{-V} and the default settings
-@code{outformat=""} and @code{render=-1}). If you encounter warnings
-from your graphics card driver, try specifying @code{-glOptions=-indirect}
-on the command line. On @code{UNIX} systems with graphics support for
-multisampling, the sample width can be
+@code{outformat=""} and @code{render=-1}). On @code{UNIX} systems with
+graphics support for multisampling, the sample width can be
controlled with the setting @code{multisample}. An initial screen
position can be specified with the pair setting @code{position}, where
negative values are interpreted as relative to the corresponding
@@ -7961,6 +7974,40 @@ The keyboard shortcuts are:
@item Ctrl-q: exit
@end itemize
+@cindex @code{WebGL}
+@cindex @code{HTML5}
+@cindex @code{mobile browser}
+@item Generate @code{WebGL} interactive vector graphics
+output with the the command-line option and @code{-f html}
+(or the setting @code{outformat="html"}). The resulting
+3D @acronym{HTML} file can then be viewed directly in any modern desktop or
+mobile browser, or even embedded within another web page:
+@verbatim
+<div>
+<object data="logo3.html"
+ style="width:210;height:140;position:relative;top:0;left:0;">
+</object>
+</div>
+@end verbatim
+
+Normally, @code{WebGL} files generated by @code{Asymptote} are
+dynamically remeshed to fit the browser window dimensions.
+However, the setting @code{absolute=true} can be used to force the image to be
+rendered at its designed size (accounting for multiple device pixels
+per @code{css} pixel). This setting should not be used when
+embedding a @code{WebGL} file within another @acronym{HTML} document.
+
+The interactive @code{WebGL} files produced by @code{Asymptote} use the
+default mouse and (many of the same) key bindings as the @code{OpenGL}
+renderer.
+
+By default, viewing the 3D @acronym{HTML} files generated by Asymptote requires
+network access to download the @code{asygl} rendering library, which
+is normally cached by the browser for future use.
+However, the setting @code{offline=true} can be used to embed this
+small (about 42kB) library within a stand-alone @acronym{HTML} file
+that can be viewed offline.
+
@cindex @code{antialias}
@cindex @code{maxviewport}
@cindex @code{maxtile}
@@ -7985,8 +8032,6 @@ setting @code{maxviewport}, which restricts the maximum width and
height of the viewport. On @code{UNIX} systems some graphics
drivers support batch mode (@code{-noV}) rendering in an
iconified window; this can be enabled with the setting @code{iconify=true}.
-Some (broken) @code{UNIX} graphics drivers may require the command line setting
-@code{-glOptions=-indirect}, which requests (slower) indirect rendering.
@cindex @code{prc}
@cindex @code{views}
@@ -8033,7 +8078,7 @@ void size3(picture pic=currentpicture, real x, real y=x, real z=y,
@cindex margins
@cindex @code{viewportmargin}
@cindex @code{viewportsize}
-The resulting simplex linear programming problem is then solved to
+A simplex linear programming problem is then solved to
produce a 3D version of a frame (actually implemented as a 3D picture).
The result is then fit with another application of deferred drawing
to the viewport dimensions corresponding to the usual two-dimensional
@@ -9227,6 +9272,7 @@ variables may also be changed at runtime.
@cindex @code{hyperrefOptions}
@cindex @code{convertOptions}
@cindex @code{gsOptions}
+@cindex @code{htmlviewerOptions}
@cindex @code{psviewerOptions}
@cindex @code{pdfviewerOptions}
@cindex @code{pdfreloadOptions}
@@ -9234,7 +9280,8 @@ variables may also be changed at runtime.
@cindex @code{dvisvgmOptions}
The advanced configuration variables @code{dvipsOptions},
@code{hyperrefOptions}, @code{convertOptions}, @code{gsOptions},
-@code{psviewerOptions}, @code{pdfviewerOptions}, @code{pdfreloadOptions},
+@code{htmlviewerOptions}, @code{psviewerOptions},
+@code{pdfviewerOptions}, @code{pdfreloadOptions},
@code{glOptions}, and @code{dvisvgmOptions} allow specialized options
to be passed as a string to the respective applications or
libraries. The default value of @code{hyperrefOptions} is
@@ -9510,7 +9557,7 @@ pip3 install cson numpy pyqt5 PyQt5.sip
@end verbatim
Pictures are deconstructed into the @acronym{SVG} image format.
-Since @code{Qt5} does not suport @code{SVG} clipping, you will need
+Since @code{Qt5} does not support @code{SVG} clipping, you will need
the @code{rsvg-convert} utility, which is part of the
@code{librsvg2-tools} package on @code{UNIX} systems
and the @code{librsvg} package on @code{MacOS}; under
@@ -9945,10 +9992,21 @@ Martin Wiebusch, Stefan Knorr, and Supakorn ``Jamie'' Rassameemasmuang.
@c LocalWords: 5unit 144x144 aligndir smoothcontour3 's 3D 2D cmake
@c LocalWords: 'load 'asy 'lasy 'auto 5bp 1cm 4g 2S 100pt 3t nan 3x
@c LocalWords: 12pt 5mm 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x Ai
-@c LocalWords: Ai Ai Ai Ai Ai Ai Ai 5E 5cm 2N 2E 2n 100d 5z 5y nz
+@c LocalWords: Ai Ai Ai Ai Ai Ai Ai 5E 5cm 2N 2E 2n 100d 5z 5y nz '
@c LocalWords: 5unit Staats implicitsurface overlapedges maxdepth
@c LocalWords: through'' genustwo 144x144 0pt 1filll 's 3D 2D 'load
@c LocalWords: 'asy 'lasy 'auto 5bp 1cm 4g 2S 100pt 3t 12pt 5mm 3x
@c LocalWords: 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x Ai Ai Ai Ai
@c LocalWords: Ai Ai Ai Ai 5E 5cm 2N 2E 2n 100d 5z 5y 5unit 144x144
-@c LocalWords: Frohlich
+@c LocalWords: Frohlich codequoteundirected center 0pt 1filll 's 3D
+@c LocalWords: acknowledgments Colors 2D Color WebGL uref x86 dnf
+@c LocalWords: htmlviewer asygl CPPFLAGS 'load 'asy 'lasy 'auto 5bp
+@c LocalWords: 1cm labeling dotfilltype 4g color colors centered 2S
+@c LocalWords: 100pt 3t forcemath gray colorless miter 12pt 5mm 3x
+@c LocalWords: zeroTransform 25cm Python3 popcount bitreverse 5x 3y
+@c LocalWords: 602e 2x 2y 3sin 10cm 204e 10x Ai Ai Ai Ai Ai Ai Ai
+@c LocalWords: Ai findall ax 5a centers 5E 5cm 2N 2E 2n HTML5 html
+@c LocalWords: logo3 remeshed css 42kB 100d 5z 5y 5unit colored Qt5
+@c LocalWords: behavior beveled usetriangles htmlviewerOptions cson
+@c LocalWords: 144x144 pyqt5 numpy pip3 PyQt5 rsvg librsvg2
+@c LocalWords: librsvg Supakorn Jamie'' Rassameemasmuang
diff --git a/graphics/asymptote/doc/png/Makefile.in b/graphics/asymptote/doc/png/Makefile.in
index 44e3fbdf4a..fc36836b01 100644
--- a/graphics/asymptote/doc/png/Makefile.in
+++ b/graphics/asymptote/doc/png/Makefile.in
@@ -13,9 +13,9 @@ all: html info
%.png: ../%.asy
cd .. && $(ASY) -f png -o png/ $(notdir $<)
-latexusage.png: ../latexusage.eps
+latexusage.png: ../latexusage.pdf
gs -q -dNOPAUSE -dBATCH -sDEVICE=pngalpha -dEPSCrop -dSAFER -r72x72 \
- -sOutputFile=latexusage.png ../latexusage.eps
+ -sOutputFile=latexusage.png ../latexusage.pdf
index.html: $(SOURCE) $(ASYFILES:.asy=.png) latexusage.png
makeinfo --html ../asymptote -o .
diff --git a/graphics/asymptote/doc/png/asymptote.info b/graphics/asymptote/doc/png/asymptote.info
index eefb40a447..3dc55bfaab 100644
--- a/graphics/asymptote/doc/png/asymptote.info
+++ b/graphics/asymptote/doc/png/asymptote.info
@@ -1,7 +1,7 @@
This is asymptote.info, produced by makeinfo version 6.5 from
asymptote.texi.
-This file documents 'Asymptote', version 2.53.
+This file documents 'Asymptote', version 2.54.
<http://asymptote.sourceforge.net>
@@ -22,7 +22,7 @@ File: asymptote.info, Node: Top, Next: Description, Prev: (dir), Up: (dir)
Asymptote
*********
-This file documents 'Asymptote', version 2.53.
+This file documents 'Asymptote', version 2.54.
<http://asymptote.sourceforge.net>
@@ -68,7 +68,7 @@ Installation
Tutorial
* Drawing in batch mode:: Run 'Asymptote' on a text file
-* Drawing in interactive mode:: Running 'Asymptote' interactively
+* Drawing in interactive mode:: Running 'Asymptote' interactively
* Figure size:: Specifying the figure size
* Labels:: Adding 'LaTeX' labels
* Paths:: Drawing lines and curves
@@ -203,6 +203,9 @@ weaker syntax and capabilities) called 'MetaPost'.
* 'LaTeX' typesetting of labels, for overall document consistency;
+ * the ability to generate and embed 3D vector WebGL graphics within
+ HTML files;
+
* the ability to generate and embed 3D vector PRC graphics within PDF
files;
@@ -234,8 +237,8 @@ weaker syntax and capabilities) called 'MetaPost'.
Many of the features of 'Asymptote' are written in the 'Asymptote'
language itself. While the stock version of 'Asymptote' is designed for
mathematics typesetting needs, one can write 'Asymptote' modules that
-tailor it to specific applications. A scientific graphing module has
-already been written (*note graph::). Examples of 'Asymptote' code and
+tailor it to specific applications; for example, a scientific graphing
+module is available (*note graph::). Examples of 'Asymptote' code and
output, including animations, are available at
<http://asymptote.sourceforge.net/gallery/>
Clicking on an example file name in this manual, like 'Pythagoras', will
@@ -338,7 +341,7 @@ available from <http://www.cs.wisc.edu/~ghost/gsview/>.
The 'ImageMagick' package from
<http://www.imagemagick.org/script/binary-releases.php>
-is required to support output formats other than EPS, PDF, SVG, and PNG
+is required to support output formats other than HTML, PDF, SVG, and PNG
(*note convert::). The 'Python 3' interpreter from
<http://www.python.org> is only required if you wish to try out the
graphical user interface (*note GUI::).
@@ -356,43 +359,51 @@ File: asymptote.info, Node: Configuring, Next: Search paths, Prev: Microsoft
In interactive mode, or when given the '-V' option (the default when
running 'Asymptote' on a single file under 'MSDOS'), 'Asymptote' will
automatically invoke the 'PostScript' viewer 'gv' (under 'UNIX') or
-'gsview' (under 'MSDOS' to display graphical output. These defaults may
-be overridden with the configuration variable 'psviewer'. The
-'PostScript' viewer should be capable of automatically redrawing
-whenever the output file is updated. The default 'UNIX' 'PostScript'
-viewer 'gv' supports this (via a 'SIGHUP' signal). Version 'gv-3.6.3'
-or later (from <http://ftp.gnu.org/gnu/gv/>) is required for interactive
-mode to work properly. Users of 'ggv' will need to enable 'Watch file'
-under 'Edit/Postscript Viewer Preferences'. Users of 'gsview' will need
-to enable 'Options/Auto Redisplay' (however, under 'MSDOS' it is still
+'gsview' (under 'MSDOS' to display graphical output. The 'PostScript'
+viewer should be capable of automatically redrawing whenever the output
+file is updated. The default 'UNIX' 'PostScript' viewer 'gv' supports
+this (via a 'SIGHUP' signal). Version 'gv-3.6.3' or later (from
+<http://ftp.gnu.org/gnu/gv/>) is required for interactive mode to work
+properly. Users of 'ggv' will need to enable 'Watch file' under
+'Edit/Postscript Viewer Preferences'. Users of 'gsview' will need to
+enable 'Options/Auto Redisplay' (however, under 'MSDOS' it is still
necessary to click on the 'gsview' window; under 'UNIX' one must
manually redisplay by pressing the 'r' key).
Configuration variables are most easily set as 'Asymptote' variables
in an optional configuration file 'config.asy' *note configuration
-file::). Here are the default values of several important configuration
-variables under 'UNIX':
+file::). For example, the setting 'pdfviewer' specifies the location of
+the PDF viewer. Here are the default values of several important
+configuration variables under 'UNIX':
import settings;
-psviewer="gv";
pdfviewer="acroread";
+htmlviewer="google-chrome";
+psviewer="gv";
+display="display";
+animate="animate";
gs="gs";
-
-Under 'MSDOS', the (installation-dependent) default values of these
-configuration variables are determined automatically from the 'Microsoft
-Windows' registry. Viewer settings (such as 'psviewer' and 'pdfviewer')
-can be set to the string 'cmd' to request the application normally
-associated with the corresponding file type.
-
- For PDF format output, the 'gs' setting specifies the location of the
-'PostScript'-to-PDF processor 'Ghostscript', available from
-<http://downloads.ghostscript.com/public>.
-
- The setting 'pdfviewer' specifies the location of the PDF viewer. On
-'UNIX' systems, to support automatic document reloading in 'Adobe
-Reader', we recommend copying the file 'reload.js' from the 'Asymptote'
-system directory (by default, '/usr/local/share/asymptote' under 'UNIX'
-to '~/.adobe/Acrobat/x.x/JavaScripts/', where 'x.x' represents the
+libgs="";
+
+Under 'MSDOS', the viewer settings 'htmlviewer', 'pdfviewer',
+'psviewer', 'display', and 'animate' default to the string 'cmd',
+requesting the application normally associated with each file type. The
+(installation-dependent) default values of 'gs' and 'libgs' are
+determined automatically from the 'Microsoft Windows' registry. The
+'gs' setting specifies the location of the 'PostScript' processor
+'Ghostscript', available from <https://www.ghostscript.com/>.
+
+The configuration variable 'htmlviewer' specifies the browser to use to
+display 3D 'WebGL' output. The default setting is 'google-chrome' under
+'UNIX' and 'cmd' under 'Microsoft Windows'. Note that 'Internet
+Explorer' does not support 'WebGL'; 'Microsoft Windows' users should set
+their default html browser to 'chrome' or 'microsoft-edge'.
+
+ On 'UNIX' systems, to support automatic document reloading of 'PDF'
+files in 'Adobe Reader', we recommend copying the file 'reload.js' from
+the 'Asymptote' system directory (by default,
+'/usr/local/share/asymptote' under 'UNIX' to
+'~/.adobe/Acrobat/x.x/JavaScripts/', where 'x.x' represents the
appropriate 'Adobe Reader' version number. The automatic document
reload feature must then be explicitly enabled by putting
import settings;
@@ -411,17 +422,14 @@ changed to 'a4' with the configuration variable 'papertype'. Alignment
to other paper sizes can be obtained by setting the configuration
variables 'paperwidth' and 'paperheight'.
- The following configuration variables normally do not require
+ These additional configuration variables normally do not require
adjustment:
config
texpath
texcommand
dvips
dvisvgm
-libgs
convert
-display
-animate
Warnings (such as "unbounded" and "offaxis") may be enabled or
disabled with the functions
@@ -634,7 +642,7 @@ File: asymptote.info, Node: Tutorial, Next: Drawing commands, Prev: Installat
* Menu:
* Drawing in batch mode:: Run 'Asymptote' on a text file
-* Drawing in interactive mode:: Running 'Asymptote' interactively
+* Drawing in interactive mode:: Running 'Asymptote' interactively
* Figure size:: Specifying the figure size
* Labels:: Adding 'LaTeX' labels
* Paths:: Drawing lines and curves
@@ -3447,7 +3455,7 @@ same type, which will also be the type of the result:
'+'
addition
'-'
- subtractiona
+ subtraction
'*'
multiplication
'/'
@@ -4320,13 +4328,13 @@ real[] A=fin;
Another useful mode is comma-separated-value mode, 'file csv(bool
b=true)', which causes reads to respect comma delimiters:
-file fin=csv(input("test.txt"));
+file fin=input("test.txt").csv();
real[] A=fin;
To restrict the number of values read, use the 'file dimension(int)'
function:
file fin=input("test.txt");
-real[] A=dimension(fin,10);
+real[] A=fin.dimension(10);
This reads 10 values into A, unless end-of-file (or end-of-line in
line mode) occurs first. Attempting to read beyond the end of the file
@@ -6847,14 +6855,15 @@ bounded by cyclic paths of length '4' or less.
composed of many 3D triangles, with specified vertices, and optional
normals or vertex colors:
void draw(picture pic=currentpicture, triple[] v, int[][] vi,
- triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
- int[][] pi={}, light light=currentlight);
- Here, the triple array 'v' lists the distinct vertices, while the
-array 'vi' lists integer arrays of length 3 containing the indices of
-'v' corresponding to the vertices of each triangle. Similarly, the
-arguments 'n' and 'ni' contain optional normal data and 'p' and 'pi'
-contain optional pen vertex data. An example of this tessellation
-facility is given in 'triangles.asy'.
+ triple[] n={}, int[][] ni=vi, material m=currentpen, pen[] p={},
+ int[][] pi=vi, light light=currentlight);
+ Here, the triple array 'v' lists the (typically distinct) vertices,
+while the array 'vi' contains integer arrays of length 3 containing the
+indices of the elements in 'v' that form the vertices of each triangle.
+Similarly, the arguments 'n' and 'ni' contain optional normal data and
+'p' and 'pi' contain optional pen vertex data. If more than one normal
+or pen is specified for a vertex, the last one specified is used. An
+example of this tessellation facility is given in 'triangles.asy'.
Arbitrary thick three-dimensional curves and line caps (which the
'OpenGL' standard does not require implementations to provide) are
@@ -6872,17 +6881,16 @@ given in the pen parameter or the setting 'thin' is set to 'false'. The
pens 'thin()' and 'thick()' defined in 'plain_pens.asy' can also be used
to override these defaults for specific draw commands.
-There are four choices for viewing 3D 'Asymptote' output:
+There are five choices for viewing 3D 'Asymptote' output:
+
1. Use the native 'Asymptote' adaptive 'OpenGL'-based renderer (with
the command-line option '-V' and the default settings
- 'outformat=""' and 'render=-1'). If you encounter warnings from
- your graphics card driver, try specifying '-glOptions=-indirect' on
- the command line. On 'UNIX' systems with graphics support for
- multisampling, the sample width can be controlled with the setting
- 'multisample'. An initial screen position can be specified with
- the pair setting 'position', where negative values are interpreted
- as relative to the corresponding maximum screen dimension. The
- default settings
+ 'outformat=""' and 'render=-1'). On 'UNIX' systems with graphics
+ support for multisampling, the sample width can be controlled with
+ the setting 'multisample'. An initial screen position can be
+ specified with the pair setting 'position', where negative values
+ are interpreted as relative to the corresponding maximum screen
+ dimension. The default settings
import settings;
leftbutton=new string[] {"rotate","zoom","shift","pan"};
middlebutton=new string[] {""};
@@ -6923,7 +6931,36 @@ There are four choices for viewing 3D 'Asymptote' output:
* q: exit
* Ctrl-q: exit
- 2. Render the scene to a specified rasterized format 'outformat' at
+ 2. Generate 'WebGL' interactive vector graphics output with the the
+ command-line option and '-f html' (or the setting
+ 'outformat="html"'). The resulting 3D HTML file can then be viewed
+ directly in any modern desktop or mobile browser, or even embedded
+ within another web page:
+ <div>
+ <object data="logo3.html"
+ style="width:210;height:140;position:relative;top:0;left:0;">
+ </object>
+ </div>
+
+ Normally, 'WebGL' files generated by 'Asymptote' are dynamically
+ remeshed to fit the browser window dimensions. However, the
+ setting 'absolute=true' can be used to force the image to be
+ rendered at its designed size (accounting for multiple device
+ pixels per 'css' pixel). This setting should not be used when
+ embedding a 'WebGL' file within another HTML document.
+
+ The interactive 'WebGL' files produced by 'Asymptote' use the
+ default mouse and (many of the same) key bindings as the 'OpenGL'
+ renderer.
+
+ By default, viewing the 3D HTML files generated by Asymptote
+ requires network access to download the 'asygl' rendering library,
+ which is normally cached by the browser for future use. However,
+ the setting 'offline=true' can be used to embed this small (about
+ 42kB) library within a stand-alone HTML file that can be viewed
+ offline.
+
+ 3. Render the scene to a specified rasterized format 'outformat' at
the resolution of 'n' pixels per 'bp', as specified by the setting
'render=n'. A negative value of 'n' is interpreted as '|2n|' for
EPS and PDF formats and '|n|' for other formats. The default value
@@ -6939,12 +6976,9 @@ There are four choices for viewing 3D 'Asymptote' output:
limited by the setting 'maxviewport', which restricts the maximum
width and height of the viewport. On 'UNIX' systems some graphics
drivers support batch mode ('-noV') rendering in an iconified
- window; this can be enabled with the setting 'iconify=true'. Some
- (broken) 'UNIX' graphics drivers may require the command line
- setting '-glOptions=-indirect', which requests (slower) indirect
- rendering.
+ window; this can be enabled with the setting 'iconify=true'.
- 3. Embed the 3D PRC format in a PDF file and view the resulting PDF
+ 4. Embed the 3D PRC format in a PDF file and view the resulting PDF
file with version '9.0' or later of 'Adobe Reader'. In addition to
the default 'settings.prc=true', this requires
'settings.outformat="pdf"', which can be specified by the command
@@ -6965,7 +6999,7 @@ There are four choices for viewing 3D 'Asymptote' output:
The open-source PRC specification is available from
<http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/>.
- 4. Project the scene to a two-dimensional vector (EPS or PDF) format
+ 5. Project the scene to a two-dimensional vector (EPS or PDF) format
with 'render=0'. Only limited hidden surface removal facilities
are currently available with this approach (*note PostScript3D::).
@@ -6975,12 +7009,12 @@ each of the three dimensions can optionally be specified with the
routine
void size3(picture pic=currentpicture, real x, real y=x, real z=y,
bool keepAspect=pic.keepAspect);
-The resulting simplex linear programming problem is then solved to
-produce a 3D version of a frame (actually implemented as a 3D picture).
-The result is then fit with another application of deferred drawing to
-the viewport dimensions corresponding to the usual two-dimensional
-picture 'size' parameters. The global pair 'viewportmargin' may be used
-to add horizontal and vertical margins to the viewport dimensions.
+A simplex linear programming problem is then solved to produce a 3D
+version of a frame (actually implemented as a 3D picture). The result
+is then fit with another application of deferred drawing to the viewport
+dimensions corresponding to the usual two-dimensional picture 'size'
+parameters. The global pair 'viewportmargin' may be used to add
+horizontal and vertical margins to the viewport dimensions.
Alternatively, a minimum 'viewportsize' may be specified. A 3D picture
'pic' can be explicitly fit to a 3D frame by calling
frame pic.fit3(projection P=currentprojection);
@@ -8053,10 +8087,10 @@ Usage: ../asy [options] [file ...]
Options (negate by replacing - with -no):
-V,-View View output; command-line only
+-absolute Use absolute WebGL dimensions [false]
-a,-align C|B|T|Z Center, Bottom, Top, or Zero page alignment [C]
-aligndir pair Directional page alignment (overrides align) [(0,0)]
-antialias n Antialiasing width for rasterized output [2]
--arcballradius pixels Arcball radius [750]
-auto3D Automatically activate 3D scene [true]
-autobillboard 3D labels always face viewer by default [true]
-autoimport string Module to automatically import
@@ -8072,8 +8106,8 @@ Options (negate by replacing - with -no):
-c,-command string Command to autoexecute
-compact Conserve memory at the expense of speed [false]
-d,-debug Enable debugging messages [false]
+-digits n Default output file precision [6]
-divisor n Garbage collect using purge(divisor=n) [2]
--doubleclick ms Emulated double-click timeout [200]
-embed Embed rendered preview image [true]
-envmap Enable environment map image-based lighting (Experimental) [false]
-exitonEOF Exit interactive mode on EOF [true]
@@ -8103,6 +8137,7 @@ Options (negate by replacing - with -no):
-multiline Input code over multiple lines at the prompt [false]
-multipleView View output from multiple batch-mode files [false]
-multisample n Multisampling width for screen images [4]
+-offline Produce offline html files [false]
-offscreen Use offscreen rendering [false]
-O,-offset pair PostScript offset [(0,0)]
-f,-outformat format Convert each output file to specified format
@@ -8121,6 +8156,8 @@ Options (negate by replacing - with -no):
-rgb Convert cmyk colors to rgb [false]
-safe Disable system call [true]
-scroll n Scroll standard output n lines at a time [0]
+-shiftHoldDistance n WebGL touch screen distance limit for shift mode [20]
+-shiftWaitTime ms WebGL touch screen shift mode delay [200]
-spinstep deg/s Spin speed [60]
-svgemulation Emulate unimplemented SVG shading [false]
-tabcompletion Interactive prompt auto-completion [true]
@@ -8135,10 +8172,14 @@ Options (negate by replacing - with -no):
-u,-user string General purpose user string
-v,-verbose Increase verbosity level (can specify multiple times) [0]
-version Show version; command-line only
+-vibrateTime ms WebGL shift mode vibrate duration [25]
+-viewportmargin pair Horizontal and vertical 3D viewport margin [(0.5,0.5)]
-wait Wait for child processes to finish before exiting [false]
-warn string Enable warning; command-line only
-where Show where listed variables are declared [false]
-xasy Special interactive mode for xasy [false]
+-zoomPinchCap limit WebGL maximum zoom pinch [100]
+-zoomPinchFactor n WebGL zoom pinch sensitivity [10]
-zoomfactor factor Zoom step factor [1.05]
-zoomstep step Mouse motion zoom step [0.1]
@@ -8177,11 +8218,11 @@ interactiveMask=true;
Command-line options override these defaults. Most configuration
variables may also be changed at runtime. The advanced configuration
variables 'dvipsOptions', 'hyperrefOptions', 'convertOptions',
-'gsOptions', 'psviewerOptions', 'pdfviewerOptions', 'pdfreloadOptions',
-'glOptions', and 'dvisvgmOptions' allow specialized options to be passed
-as a string to the respective applications or libraries. The default
-value of 'hyperrefOptions' is 'setpagesize=false,unicode,pdfborder=0 0
-0'.
+'gsOptions', 'htmlviewerOptions', 'psviewerOptions', 'pdfviewerOptions',
+'pdfreloadOptions', 'glOptions', and 'dvisvgmOptions' allow specialized
+options to be passed as a string to the respective applications or
+libraries. The default value of 'hyperrefOptions' is
+'setpagesize=false,unicode,pdfborder=0 0 0'.
If you insert
import plain;
@@ -8377,7 +8418,7 @@ packages 'pyqt5', 'cson', and 'numpy':
pip3 install cson numpy pyqt5 PyQt5.sip
Pictures are deconstructed into the SVG image format. Since 'Qt5'
-does not suport 'SVG' clipping, you will need the 'rsvg-convert'
+does not support 'SVG' clipping, you will need the 'rsvg-convert'
utility, which is part of the 'librsvg2-tools' package on 'UNIX' systems
and the 'librsvg' package on 'MacOS'; under 'Microsoft Windows', it is
available as
@@ -8595,9 +8636,9 @@ Index
* ---: Bezier curves. (line 84)
* -=: Self & prefix operators.
(line 6)
-* -c: Options. (line 186)
-* -l: Options. (line 205)
-* -u: Options. (line 196)
+* -c: Options. (line 193)
+* -l: Options. (line 212)
+* -u: Options. (line 203)
* -V: Configuring. (line 6)
* -V <1>: Drawing in batch mode.
(line 16)
@@ -8610,7 +8651,7 @@ Index
* 2D graphs: graph. (line 6)
* 3D graphs: graph3. (line 6)
* 3D grids: grid3. (line 6)
-* 3D PostScript: three. (line 580)
+* 3D PostScript: three. (line 606)
* :: Arithmetic & logical.
(line 61)
* ::: Bezier curves. (line 70)
@@ -8638,14 +8679,14 @@ Index
(line 53)
* ||: Arithmetic & logical.
(line 51)
-* a4: Configuring. (line 58)
+* a4: Configuring. (line 66)
* abort: Data types. (line 363)
* abs: Data types. (line 65)
* abs <1>: Mathematical functions.
(line 35)
* accel: Paths and guides. (line 126)
* accel <1>: Paths and guides. (line 132)
-* accel <2>: three. (line 481)
+* accel <2>: three. (line 507)
* access: Import. (line 6)
* acknowledgments: Credits. (line 6)
* acos: Mathematical functions.
@@ -8658,8 +8699,8 @@ Index
(line 212)
* add <1>: Frames and pictures.
(line 228)
-* add <2>: three. (line 253)
-* addViews: three. (line 374)
+* add <2>: three. (line 279)
+* addViews: three. (line 400)
* adjust: Pens. (line 123)
* Ai: Mathematical functions.
(line 48)
@@ -8670,35 +8711,35 @@ Index
* alias: Structures. (line 62)
* alias <1>: Arrays. (line 174)
* Align: label. (line 12)
-* aligndir: Options. (line 178)
+* aligndir: Options. (line 185)
* all: Arrays. (line 325)
* Allow: Pens. (line 347)
* and: Bezier curves. (line 56)
* AND: Arithmetic & logical.
(line 68)
* angle: Data types. (line 73)
-* animate: Configuring. (line 64)
+* animate: Configuring. (line 20)
* animate <1>: Files. (line 155)
* animate <2>: animation. (line 12)
* animation: animation. (line 6)
* animation <1>: animation. (line 6)
* annotate: annotate. (line 6)
-* antialias: three. (line 192)
-* antialias <1>: Options. (line 149)
+* antialias: three. (line 221)
+* antialias <1>: Options. (line 156)
* append: Files. (line 36)
* append <1>: Arrays. (line 39)
* arc: Paths and guides. (line 24)
* Arc: Paths and guides. (line 37)
-* arc <1>: three. (line 264)
+* arc <1>: three. (line 290)
* ArcArrow: draw. (line 26)
-* ArcArrow3: three. (line 547)
+* ArcArrow3: three. (line 573)
* ArcArrows: draw. (line 26)
-* ArcArrows3: three. (line 547)
+* ArcArrows3: three. (line 573)
* arclength: Paths and guides. (line 153)
-* arclength <1>: three. (line 481)
+* arclength <1>: three. (line 507)
* arcpoint: Paths and guides. (line 163)
* arctime: Paths and guides. (line 157)
-* arctime <1>: three. (line 481)
+* arctime <1>: three. (line 507)
* arguments: Default arguments. (line 6)
* arithmetic operators: Arithmetic & logical.
(line 6)
@@ -8712,10 +8753,10 @@ Index
* arrow keys: Drawing in interactive mode.
(line 11)
* arrow keys <1>: GUI usage. (line 6)
-* Arrow3: three. (line 547)
+* Arrow3: three. (line 573)
* arrows: draw. (line 26)
* Arrows: draw. (line 26)
-* Arrows3: three. (line 547)
+* Arrows3: three. (line 573)
* as: Import. (line 67)
* ascii: Data types. (line 308)
* ascii <1>: Data types. (line 308)
@@ -8733,10 +8774,11 @@ Index
* asy <1>: Import. (line 101)
* asy-mode: Editing modes. (line 6)
* asy.vim: Editing modes. (line 32)
+* asygl: Configuring. (line 72)
* asyinclude: LaTeX usage. (line 45)
* asymptote.sty: LaTeX usage. (line 6)
* asymptote.xml: Editing modes. (line 48)
-* ASYMPTOTE_CONFIG: Options. (line 120)
+* ASYMPTOTE_CONFIG: Options. (line 127)
* atan: Mathematical functions.
(line 6)
* aTan: Mathematical functions.
@@ -8750,8 +8792,8 @@ Index
(line 273)
* attach <1>: LaTeX usage. (line 50)
* attach <2>: graph. (line 407)
-* autoadjust: three. (line 339)
-* autoimport: Options. (line 116)
+* autoadjust: three. (line 365)
+* autoimport: Options. (line 123)
* automatic scaling: graph. (line 691)
* automatic scaling <1>: graph. (line 691)
* axialshade: fill. (line 43)
@@ -8763,11 +8805,11 @@ Index
* babel: babel. (line 6)
* background color: Frames and pictures.
(line 180)
-* BackView: three. (line 367)
+* BackView: three. (line 393)
* Bar: draw. (line 19)
-* Bar3: three. (line 547)
+* Bar3: three. (line 573)
* Bars: draw. (line 19)
-* Bars3: three. (line 547)
+* Bars3: three. (line 573)
* barsize: draw. (line 19)
* base modules: Base modules. (line 6)
* basealign: Pens. (line 181)
@@ -8776,18 +8818,18 @@ Index
(line 6)
* beep: Data types. (line 381)
* BeginArcArrow: draw. (line 26)
-* BeginArcArrow3: three. (line 547)
+* BeginArcArrow3: three. (line 573)
* BeginArrow: draw. (line 26)
-* BeginArrow3: three. (line 547)
+* BeginArrow3: three. (line 573)
* BeginBar: draw. (line 19)
-* BeginBar3: three. (line 547)
+* BeginBar3: three. (line 573)
* BeginDotMargin: draw. (line 42)
-* BeginDotMargin3: three. (line 563)
+* BeginDotMargin3: three. (line 589)
* BeginMargin: draw. (line 42)
-* BeginMargin3: three. (line 563)
+* BeginMargin3: three. (line 589)
* BeginPenMargin: draw. (line 42)
-* BeginPenMargin2: three. (line 563)
-* BeginPenMargin3: three. (line 563)
+* BeginPenMargin2: three. (line 589)
+* BeginPenMargin3: three. (line 589)
* BeginPoint: label. (line 55)
* Bessel: Mathematical functions.
(line 48)
@@ -8799,7 +8841,7 @@ Index
* bezulate: three. (line 106)
* Bi: Mathematical functions.
(line 48)
-* Billboard: three. (line 451)
+* Billboard: three. (line 477)
* binary: Files. (line 76)
* binary format: Files. (line 76)
* binary operators: Arithmetic & logical.
@@ -8807,7 +8849,7 @@ Index
* binarytree: binarytree. (line 6)
* Bi_deriv: Mathematical functions.
(line 48)
-* black stripes: three. (line 192)
+* black stripes: three. (line 221)
* Blank: draw. (line 26)
* block.bottom: flowchart. (line 19)
* block.bottomleft: flowchart. (line 19)
@@ -8826,7 +8868,7 @@ Index
(line 6)
* Bottom: graph. (line 132)
* BottomTop: graph. (line 138)
-* BottomView: three. (line 367)
+* BottomView: three. (line 393)
* bounding box: Frames and pictures.
(line 180)
* Bounds: graph3. (line 21)
@@ -8834,8 +8876,8 @@ Index
(line 25)
* box <1>: Frames and pictures.
(line 130)
-* box <2>: three. (line 286)
-* box <3>: three. (line 288)
+* box <2>: three. (line 312)
+* box <3>: three. (line 314)
* bp: Drawing in batch mode.
(line 23)
* brace: Paths and guides. (line 51)
@@ -8853,7 +8895,7 @@ Index
* CAD: CAD. (line 6)
* calculateTransform: Frames and pictures.
(line 118)
-* camera: three. (line 333)
+* camera: three. (line 359)
* casts: Casts. (line 6)
* cbrt: Mathematical functions.
(line 6)
@@ -8861,7 +8903,7 @@ Index
* ceil: Mathematical functions.
(line 26)
* Center: label. (line 60)
-* center: three. (line 316)
+* center: three. (line 342)
* checker: Pens. (line 269)
* Chinese: unicode. (line 12)
* choose: Mathematical functions.
@@ -8870,7 +8912,7 @@ Index
(line 48)
* circle: Paths and guides. (line 10)
* Circle: Paths and guides. (line 18)
-* circle <1>: three. (line 260)
+* circle <1>: three. (line 286)
* circle <2>: flowchart. (line 61)
* circlebarframe: markers. (line 18)
* CJK: unicode. (line 12)
@@ -8881,7 +8923,7 @@ Index
* CLZ: Arithmetic & logical.
(line 68)
* cm: Figure size. (line 18)
-* cmd: Configuring. (line 31)
+* cmd: Configuring. (line 35)
* cmyk: Pens. (line 38)
* colatitude: Data types. (line 158)
* color: Pens. (line 23)
@@ -8892,7 +8934,7 @@ Index
* colors: Pens. (line 54)
* comma: Files. (line 61)
* comma-separated-value mode: Arrays. (line 357)
-* command-line options: Configuring. (line 83)
+* command-line options: Configuring. (line 88)
* command-line options <1>: Options. (line 6)
* comment character: Files. (line 16)
* compass directions: Labels. (line 18)
@@ -8903,14 +8945,14 @@ Index
* conditional: Programming. (line 26)
* conditional <1>: Arithmetic & logical.
(line 61)
-* config: Configuring. (line 64)
-* config <1>: Options. (line 120)
-* configuration file: Configuring. (line 21)
-* configuration file <1>: Options. (line 120)
+* config: Configuring. (line 72)
+* config <1>: Options. (line 127)
+* configuration file: Configuring. (line 20)
+* configuration file <1>: Options. (line 127)
* configuring: Configuring. (line 6)
* conj: Data types. (line 62)
* constructors: Structures. (line 91)
-* context: Options. (line 149)
+* context: Options. (line 156)
* continue: Programming. (line 48)
* continue <1>: Debugger. (line 31)
* contour: contour. (line 6)
@@ -8918,11 +8960,11 @@ Index
* controls: Bezier curves. (line 45)
* controls <1>: three. (line 6)
* controlSpecifier: Paths and guides. (line 396)
-* convert: Configuring. (line 64)
+* convert: Configuring. (line 72)
* convert <1>: Files. (line 155)
* convert <2>: animation. (line 6)
-* convert <3>: Options. (line 149)
-* convertOptions: Options. (line 135)
+* convert <3>: Options. (line 156)
+* convertOptions: Options. (line 142)
* Coons shading: fill. (line 77)
* copy: Arrays. (line 167)
* cos: Mathematical functions.
@@ -8947,7 +8989,7 @@ Index
* curl <1>: three. (line 6)
* curlSpecifier: Paths and guides. (line 408)
* currentpen: Pens. (line 6)
-* currentprojection: three. (line 364)
+* currentprojection: three. (line 390)
* curve: slopefield. (line 20)
* custom axis types: graph. (line 141)
* custom mark routine: graph. (line 578)
@@ -8959,7 +9001,7 @@ Index
* cyclic: Paths and guides. (line 85)
* cyclic <1>: Paths and guides. (line 376)
* cyclic <2>: Arrays. (line 39)
-* cyclic <3>: three. (line 481)
+* cyclic <3>: three. (line 507)
* Cyrillic: unicode. (line 7)
* dashdotted: Pens. (line 102)
* dashed: Pens. (line 102)
@@ -8973,7 +9015,7 @@ Index
* default arguments: Default arguments. (line 6)
* defaultformat: graph. (line 175)
* DefaultHead: draw. (line 26)
-* DefaultHead3: three. (line 547)
+* DefaultHead3: three. (line 573)
* defaultpen: Pens. (line 49)
* defaultpen <1>: Pens. (line 122)
* defaultpen <2>: Pens. (line 127)
@@ -8998,12 +9040,12 @@ Index
* dir <1>: Data types. (line 90)
* dir <2>: Data types. (line 180)
* dir <3>: Paths and guides. (line 109)
-* dir <4>: three. (line 481)
+* dir <4>: three. (line 507)
* direction specifier: Bezier curves. (line 6)
* directory: Files. (line 25)
* dirSpecifier: Paths and guides. (line 390)
* dirtime: Paths and guides. (line 166)
-* display: Configuring. (line 64)
+* display: Configuring. (line 20)
* do: Programming. (line 48)
* DOSendl: Files. (line 61)
* DOSnewl: Files. (line 61)
@@ -9013,11 +9055,11 @@ Index
* dot <3>: Arrays. (line 254)
* dot <4>: Arrays. (line 257)
* DotMargin: draw. (line 42)
-* DotMargin3: three. (line 563)
+* DotMargin3: three. (line 589)
* DotMargins: draw. (line 42)
-* DotMargins3: three. (line 563)
+* DotMargins3: three. (line 589)
* dotted: Pens. (line 102)
-* double deferred drawing: three. (line 238)
+* double deferred drawing: three. (line 264)
* double precision: Files. (line 76)
* draw: Drawing commands. (line 31)
* draw <1>: draw. (line 6)
@@ -9029,11 +9071,11 @@ Index
* drawing commands: Drawing commands. (line 6)
* drawline: math. (line 9)
* drawtree: drawtree. (line 6)
-* dvips: Configuring. (line 64)
-* dvipsOptions: Options. (line 135)
-* dvisvgm: Configuring. (line 64)
-* dvisvgm <1>: Options. (line 154)
-* dvisvgmOptions: Options. (line 135)
+* dvips: Configuring. (line 72)
+* dvipsOptions: Options. (line 142)
+* dvisvgm: Configuring. (line 72)
+* dvisvgm <1>: Options. (line 161)
+* dvisvgmOptions: Options. (line 142)
* E: Labels. (line 18)
* E <1>: Mathematical functions.
(line 48)
@@ -9048,33 +9090,33 @@ Index
* else: Programming. (line 26)
* emacs: Editing modes. (line 6)
* embed: embed. (line 6)
-* Embedded: three. (line 451)
+* Embedded: three. (line 477)
* empty: Frames and pictures.
(line 7)
* EndArcArrow: draw. (line 26)
-* EndArcArrow3: three. (line 547)
+* EndArcArrow3: three. (line 573)
* EndArrow: draw. (line 26)
-* EndArrow3: three. (line 547)
+* EndArrow3: three. (line 573)
* EndBar: draw. (line 19)
-* EndBar3: three. (line 547)
+* EndBar3: three. (line 573)
* EndDotMargin: draw. (line 42)
-* EndDotMargin3: three. (line 563)
+* EndDotMargin3: three. (line 589)
* endl: Files. (line 61)
* EndMargin: draw. (line 42)
-* EndMargin3: three. (line 563)
+* EndMargin3: three. (line 589)
* EndPenMargin: draw. (line 42)
-* EndPenMargin2: three. (line 563)
-* EndPenMargin3: three. (line 563)
+* EndPenMargin2: three. (line 589)
+* EndPenMargin3: three. (line 589)
* EndPoint: label. (line 55)
* envelope: Frames and pictures.
(line 25)
-* environment variables: Configuring. (line 87)
+* environment variables: Configuring. (line 92)
* eof: Files. (line 93)
* eof <1>: Arrays. (line 339)
* eol: Files. (line 93)
* eol <1>: Arrays. (line 339)
* EPS: label. (line 78)
-* EPS <1>: Options. (line 149)
+* EPS <1>: Options. (line 156)
* erase: Drawing in interactive mode.
(line 11)
* erase <1>: Data types. (line 256)
@@ -9111,12 +9153,12 @@ Index
* extension: Paths and guides. (line 246)
* extension <1>: MetaPost. (line 10)
* external: embed. (line 11)
-* extrude: three. (line 475)
+* extrude: three. (line 501)
* F: Mathematical functions.
(line 48)
* fabs: Mathematical functions.
(line 6)
-* face: three. (line 588)
+* face: three. (line 614)
* factorial: Mathematical functions.
(line 39)
* Fedora: UNIX binary distributions.
@@ -9146,7 +9188,7 @@ Index
* firstcut: Paths and guides. (line 262)
* fit: Frames and pictures.
(line 113)
-* fit3: three. (line 251)
+* fit3: three. (line 277)
* fixedscaling: Frames and pictures.
(line 81)
* floor: Mathematical functions.
@@ -9162,12 +9204,12 @@ Index
* fontsize: Pens. (line 192)
* for: Programming. (line 26)
* format: Data types. (line 289)
-* format <1>: Options. (line 149)
+* format <1>: Options. (line 156)
* forum: Help. (line 6)
* frame: Frames and pictures.
(line 7)
* from: Import. (line 16)
-* FrontView: three. (line 367)
+* FrontView: three. (line 393)
* function declarations: Functions. (line 79)
* Function shading: fill. (line 99)
* function shading: fill. (line 99)
@@ -9186,8 +9228,8 @@ Index
* getstring: Files. (line 118)
* gettriple: Files. (line 118)
* git: Git. (line 6)
-* glOptions: three. (line 192)
-* glOptions <1>: Options. (line 135)
+* glOptions: three. (line 221)
+* glOptions <1>: Options. (line 142)
* GNU Scientific Library: Mathematical functions.
(line 48)
* gouraudshade: fill. (line 62)
@@ -9203,12 +9245,12 @@ Index
* grid: Pens. (line 269)
* grid <1>: graph. (line 747)
* grid3: grid3. (line 6)
-* gs: Configuring. (line 6)
+* gs: Configuring. (line 20)
* GSL: Compiling from UNIX source.
(line 63)
* gsl: Mathematical functions.
(line 48)
-* gsOptions: Options. (line 135)
+* gsOptions: Options. (line 142)
* GUI: GUI. (line 6)
* GUI installation: GUI installation. (line 6)
* GUI usage: GUI usage. (line 6)
@@ -9225,34 +9267,38 @@ Index
* hex <1>: Pens. (line 64)
* hexadecimal: Data types. (line 305)
* hexadecimal <1>: Pens. (line 62)
-* hidden surface removal: three. (line 588)
+* hidden surface removal: three. (line 614)
* histogram: Mathematical functions.
(line 39)
* history: Files. (line 143)
* history <1>: Interactive mode. (line 54)
* historylines: Interactive mode. (line 57)
* HookHead: draw. (line 26)
-* HookHead3: three. (line 547)
+* HookHead3: three. (line 573)
* Horizontal: flowchart. (line 77)
-* hyperrefOptions: Options. (line 135)
+* HTML5: three. (line 192)
+* htmlviewer: Configuring. (line 20)
+* htmlviewer <1>: Configuring. (line 43)
+* htmlviewerOptions: Options. (line 142)
+* hyperrefOptions: Options. (line 142)
* hypot: Mathematical functions.
(line 6)
* I: Mathematical functions.
(line 48)
-* iconify: three. (line 192)
+* iconify: three. (line 221)
* identity: Transforms. (line 24)
* identity <1>: Mathematical functions.
(line 6)
* identity <2>: Arrays. (line 296)
-* identity4: three. (line 419)
+* identity4: three. (line 445)
* if: Programming. (line 26)
* IgnoreAspect: Frames and pictures.
(line 63)
* image: palette. (line 33)
* image <1>: palette. (line 58)
-* ImageMagick: Configuring. (line 64)
+* ImageMagick: Configuring. (line 72)
* ImageMagick <1>: animation. (line 6)
-* ImageMagick <2>: Options. (line 149)
+* ImageMagick <2>: Options. (line 156)
* images: palette. (line 6)
* implicit casts: Casts. (line 6)
* implicit linear solver: MetaPost. (line 10)
@@ -9280,7 +9326,7 @@ Index
* inside: Paths and guides. (line 294)
* inside <1>: Paths and guides. (line 299)
* inside <2>: Paths and guides. (line 305)
-* insphere: three. (line 510)
+* insphere: three. (line 536)
* inst: Debugger. (line 35)
* installation: Installation. (line 6)
* int: Data types. (line 30)
@@ -9300,23 +9346,23 @@ Index
* interpolate: interpolate. (line 6)
* intersect: Paths and guides. (line 195)
* intersect <1>: math. (line 13)
-* intersect <2>: three. (line 481)
+* intersect <2>: three. (line 507)
* intersectionpoint: Paths and guides. (line 238)
* intersectionpoint <1>: math. (line 17)
-* intersectionpoint <2>: three. (line 481)
+* intersectionpoint <2>: three. (line 507)
* intersectionpoints: Paths and guides. (line 242)
-* intersectionpoints <1>: three. (line 481)
-* intersectionpoints <2>: three. (line 494)
+* intersectionpoints <1>: three. (line 507)
+* intersectionpoints <2>: three. (line 520)
* intersections: Paths and guides. (line 206)
* intersections <1>: Paths and guides. (line 213)
-* intersections <2>: three. (line 481)
-* intersections <3>: three. (line 487)
+* intersections <2>: three. (line 507)
+* intersections <3>: three. (line 513)
* InTicks: graph3. (line 35)
* intMax: Data types. (line 30)
* intMin: Data types. (line 30)
* inverse: Transforms. (line 16)
* inverse <1>: Arrays. (line 302)
-* invert: three. (line 409)
+* invert: three. (line 435)
* invisible: Pens. (line 43)
* isnan: Data types. (line 35)
* i_scaled: Mathematical functions.
@@ -9348,7 +9394,7 @@ Index
* label <1>: label. (line 6)
* Label <1>: label. (line 14)
* Label <2>: graph. (line 330)
-* label <2>: three. (line 445)
+* label <2>: three. (line 471)
* labelpath: labelpath. (line 6)
* labelpath3: labelpath3. (line 6)
* labelx: graph. (line 330)
@@ -9357,7 +9403,7 @@ Index
(line 104)
* lastcut: Paths and guides. (line 266)
* lasy-mode: Editing modes. (line 6)
-* latex: Options. (line 149)
+* latex: Options. (line 156)
* LaTeX fonts: Pens. (line 206)
* LaTeX usage: LaTeX usage. (line 6)
* latexmk: LaTeX usage. (line 30)
@@ -9372,7 +9418,7 @@ Index
* LeftSide: label. (line 60)
* LeftTicks: graph. (line 160)
* LeftTicks <1>: graph. (line 233)
-* LeftView: three. (line 367)
+* LeftView: three. (line 393)
* legend: Drawing commands. (line 31)
* legend <1>: draw. (line 64)
* legend <2>: graph. (line 425)
@@ -9384,12 +9430,11 @@ Index
* length <3>: Paths and guides. (line 76)
* length <4>: Paths and guides. (line 373)
* length <5>: Arrays. (line 39)
-* length <6>: three. (line 481)
-* letter: Configuring. (line 58)
+* length <6>: three. (line 507)
+* letter: Configuring. (line 66)
* lexorder: math. (line 67)
* lexorder <1>: math. (line 70)
-* libgs: Configuring. (line 64)
-* libgs <1>: Options. (line 154)
+* libgs: Options. (line 161)
* libm routines: Mathematical functions.
(line 6)
* libsigsegv: Functions. (line 100)
@@ -9421,19 +9466,19 @@ Index
* longdashed: Pens. (line 102)
* longitude: Data types. (line 168)
* loop: Programming. (line 26)
-* lualatex: Options. (line 149)
-* luatex: Options. (line 149)
+* lualatex: Options. (line 156)
+* luatex: Options. (line 156)
* MacOS X binary distributions: MacOS X binary distributions.
(line 6)
* makepen: Pens. (line 322)
* map: Arrays. (line 131)
* Margin: draw. (line 42)
* Margin <1>: draw. (line 42)
-* Margin3: three. (line 563)
-* Margin3 <1>: three. (line 563)
+* Margin3: three. (line 589)
+* Margin3 <1>: three. (line 589)
* Margins: draw. (line 42)
-* margins: three. (line 244)
-* Margins3: three. (line 563)
+* margins: three. (line 270)
+* Margins3: three. (line 589)
* mark: graph. (line 481)
* markangle: markers. (line 35)
* marker: graph. (line 481)
@@ -9449,12 +9494,12 @@ Index
(line 7)
* max <2>: Arrays. (line 221)
* max <3>: Arrays. (line 231)
-* max <4>: three. (line 481)
+* max <4>: three. (line 507)
* maxbound: Data types. (line 134)
* maxbound <1>: Data types. (line 204)
-* maxtile: three. (line 192)
+* maxtile: three. (line 221)
* maxtimes: Paths and guides. (line 233)
-* maxviewport: three. (line 192)
+* maxviewport: three. (line 221)
* MetaPost: MetaPost. (line 6)
* MetaPost ... : Bezier curves. (line 70)
* MetaPost cutafter: Paths and guides. (line 267)
@@ -9463,9 +9508,9 @@ Index
* MetaPost whatever: MetaPost. (line 10)
* Microsoft Windows: Microsoft Windows. (line 6)
* MidArcArrow: draw. (line 26)
-* MidArcArrow3: three. (line 547)
+* MidArcArrow3: three. (line 573)
* MidArrow: draw. (line 26)
-* MidArrow3: three. (line 547)
+* MidArrow3: three. (line 573)
* MidPoint: label. (line 55)
* midpoint: Paths and guides. (line 180)
* min: Paths and guides. (line 275)
@@ -9473,7 +9518,7 @@ Index
(line 7)
* min <2>: Arrays. (line 216)
* min <3>: Arrays. (line 226)
-* min <4>: three. (line 481)
+* min <4>: three. (line 507)
* minbound: Data types. (line 131)
* minbound <1>: Data types. (line 201)
* minipage: label. (line 116)
@@ -9482,6 +9527,7 @@ Index
* miterlimit: Pens. (line 159)
* mktemp: Files. (line 44)
* mm: Figure size. (line 18)
+* mobile browser: three. (line 192)
* mode: Files. (line 76)
* mode <1>: Files. (line 89)
* monotonic: graph. (line 36)
@@ -9490,7 +9536,7 @@ Index
* mouse wheel: GUI usage. (line 6)
* Move: Pens. (line 359)
* MoveQuiet: Pens. (line 365)
-* multisample: three. (line 142)
+* multisample: three. (line 144)
* N: Labels. (line 18)
* name: Files. (line 89)
* named arguments: Named arguments. (line 6)
@@ -9513,12 +9559,12 @@ Index
* NoFill <1>: Frames and pictures.
(line 154)
* NoMargin: draw. (line 42)
-* NoMargin3: three. (line 563)
+* NoMargin3: three. (line 589)
* None: draw. (line 19)
* None <1>: draw. (line 26)
* none: Files. (line 61)
-* normal: three. (line 467)
-* nosafe: Options. (line 173)
+* normal: three. (line 493)
+* nosafe: Options. (line 180)
* NOT: Arithmetic & logical.
(line 68)
* notaknot: graph. (line 36)
@@ -9530,22 +9576,22 @@ Index
(line 140)
* nullpen <2>: Frames and pictures.
(line 149)
-* NURBS: three. (line 343)
-* O: three. (line 256)
+* NURBS: three. (line 369)
+* O: three. (line 282)
* obj: obj. (line 6)
-* oblique: three. (line 299)
-* obliqueX: three. (line 306)
-* obliqueY: three. (line 312)
-* obliqueZ: three. (line 299)
+* oblique: three. (line 325)
+* obliqueX: three. (line 332)
+* obliqueY: three. (line 338)
+* obliqueZ: three. (line 325)
* ode: ode. (line 6)
* offset: Pens. (line 123)
-* offset <1>: Options. (line 178)
+* offset <1>: Options. (line 185)
* OmitTick: graph. (line 223)
* OmitTickInterval: graph. (line 223)
* OmitTickIntervals: graph. (line 223)
* opacity: Pens. (line 237)
* open: Files. (line 12)
-* OpenGL: three. (line 142)
+* OpenGL: three. (line 144)
* operator: User-defined operators.
(line 6)
* operator +(...string[] a).: Data types. (line 283)
@@ -9562,15 +9608,15 @@ Index
* OR: Arithmetic & logical.
(line 68)
* orient: Data types. (line 108)
-* orient <1>: three. (line 498)
+* orient <1>: three. (line 524)
* orientation: Frames and pictures.
(line 104)
-* orthographic: three. (line 316)
-* outformat: three. (line 142)
+* orthographic: three. (line 342)
+* outformat: three. (line 144)
* outprefix: Frames and pictures.
(line 91)
* output: Files. (line 36)
-* output <1>: Options. (line 149)
+* output <1>: Options. (line 156)
* OutTicks: graph3. (line 35)
* overloading functions: Functions. (line 55)
* overwrite: Pens. (line 344)
@@ -9581,9 +9627,9 @@ Index
* pair: Figure size. (line 6)
* pair <1>: Data types. (line 46)
* pairs: Arrays. (line 236)
-* paperheight: Configuring. (line 58)
-* papertype: Configuring. (line 58)
-* paperwidth: Configuring. (line 58)
+* paperheight: Configuring. (line 66)
+* papertype: Configuring. (line 66)
+* paperwidth: Configuring. (line 66)
* parallelogram: flowchart. (line 47)
* parametric surface: graph3. (line 99)
* parametrized curve: graph. (line 640)
@@ -9600,37 +9646,37 @@ Index
* path[]: Paths. (line 23)
* patterns: Pens. (line 255)
* patterns <1>: patterns. (line 6)
-* PDF: Options. (line 149)
-* pdflatex: Options. (line 149)
-* pdfreloadOptions: Options. (line 135)
-* pdfviewer: Configuring. (line 6)
-* pdfviewerOptions: Options. (line 135)
+* PDF: Options. (line 156)
+* pdflatex: Options. (line 156)
+* pdfreloadOptions: Options. (line 142)
+* pdfviewer: Configuring. (line 20)
+* pdfviewerOptions: Options. (line 142)
* pen: Pens. (line 6)
* PenMargin: draw. (line 42)
-* PenMargin2: three. (line 563)
-* PenMargin3: three. (line 563)
+* PenMargin2: three. (line 589)
+* PenMargin3: three. (line 589)
* PenMargins: draw. (line 42)
-* PenMargins2: three. (line 563)
-* PenMargins3: three. (line 563)
+* PenMargins2: three. (line 589)
+* PenMargins3: three. (line 589)
* periodic: graph. (line 36)
* perl: LaTeX usage. (line 30)
* perpendicular: geometry. (line 6)
-* perspective: three. (line 343)
+* perspective: three. (line 369)
* picture: Frames and pictures.
(line 39)
* picture alignment: Frames and pictures.
(line 228)
* piecewisestraight: Paths and guides. (line 92)
-* pixel: three. (line 570)
+* pixel: three. (line 596)
* Pl: Mathematical functions.
(line 48)
* plain: plain. (line 6)
* planar: three. (line 88)
-* plane: three. (line 282)
-* planeproject: three. (line 464)
+* plane: three. (line 308)
+* planeproject: three. (line 490)
* point: Paths and guides. (line 95)
* point <1>: Paths and guides. (line 379)
-* point <2>: three. (line 481)
+* point <2>: three. (line 507)
* polar: Data types. (line 148)
* polargraph: graph. (line 88)
* polygon: graph. (line 481)
@@ -9638,7 +9684,7 @@ Index
* Portrait: Frames and pictures.
(line 104)
* postcontrol: Paths and guides. (line 146)
-* postcontrol <1>: three. (line 481)
+* postcontrol <1>: three. (line 507)
* postfix operators: Self & prefix operators.
(line 19)
* postscript: Frames and pictures.
@@ -9647,18 +9693,18 @@ Index
* PostScript subpath: Paths. (line 23)
* pow10: Mathematical functions.
(line 6)
-* prc: three. (line 213)
+* prc: three. (line 239)
* precision: Files. (line 93)
* precontrol: Paths and guides. (line 139)
-* precontrol <1>: three. (line 481)
+* precontrol <1>: three. (line 507)
* prefix operators: Self & prefix operators.
(line 6)
* private: Structures. (line 6)
* programming: Programming. (line 6)
* pstoedit: PostScript to Asymptote.
(line 6)
-* psviewer: Configuring. (line 6)
-* psviewerOptions: Options. (line 135)
+* psviewer: Configuring. (line 20)
+* psviewerOptions: Options. (line 142)
* pt: Figure size. (line 18)
* public: Structures. (line 6)
* push: Arrays. (line 39)
@@ -9666,7 +9712,7 @@ Index
* quadraticroots: Arrays. (line 305)
* quadraticroots <1>: Arrays. (line 310)
* quarticroots: math. (line 22)
-* quick reference: Description. (line 81)
+* quick reference: Description. (line 84)
* quit: Drawing in interactive mode.
(line 11)
* quit <1>: Interactive mode. (line 54)
@@ -9682,7 +9728,7 @@ Index
* radians: Mathematical functions.
(line 17)
* radius: Paths and guides. (line 135)
-* radius <1>: three. (line 481)
+* radius <1>: three. (line 507)
* Rainbow: palette. (line 12)
* rand: Mathematical functions.
(line 39)
@@ -9700,7 +9746,7 @@ Index
* realmult: Data types. (line 100)
* rectangle: flowchart. (line 34)
* recursion: Functions. (line 100)
-* reference: Description. (line 81)
+* reference: Description. (line 84)
* reflect: Transforms. (line 42)
* Relative: label. (line 50)
* Relative <1>: label. (line 60)
@@ -9710,8 +9756,8 @@ Index
(line 6)
* rename: Files. (line 152)
* render: three. (line 46)
-* render <1>: three. (line 142)
-* render <2>: Options. (line 149)
+* render <1>: three. (line 144)
+* render <2>: Options. (line 156)
* replace: Data types. (line 269)
* resetdefaultpen: Pens. (line 371)
* rest arguments: Rest arguments. (line 6)
@@ -9723,7 +9769,7 @@ Index
* reverse <1>: Paths and guides. (line 183)
* reverse <2>: Paths and guides. (line 382)
* reverse <3>: Arrays. (line 136)
-* reverse <4>: three. (line 481)
+* reverse <4>: three. (line 507)
* rewind: Files. (line 93)
* rfind: Data types. (line 246)
* rgb: Pens. (line 30)
@@ -9735,9 +9781,9 @@ Index
* RightSide: label. (line 60)
* RightTicks: graph. (line 160)
* RightTicks <1>: graph. (line 233)
-* RightView: three. (line 367)
+* RightView: three. (line 393)
* Rotate: label. (line 36)
-* rotate: three. (line 435)
+* rotate: three. (line 461)
* Rotate(pair z): label. (line 39)
* round: Mathematical functions.
(line 26)
@@ -9750,7 +9796,7 @@ Index
* runtime imports: Import. (line 97)
* Russian: unicode. (line 7)
* S: Labels. (line 18)
-* safe: Options. (line 173)
+* safe: Options. (line 180)
* save: Frames and pictures.
(line 285)
* saveline: Files. (line 135)
@@ -9760,8 +9806,8 @@ Index
* scale <2>: Transforms. (line 36)
* scale <3>: graph. (line 691)
* Scale <1>: graph. (line 708)
-* scale <4>: three. (line 434)
-* scale3: three. (line 432)
+* scale <4>: three. (line 460)
+* scale3: three. (line 458)
* scaled graph: graph. (line 671)
* scientific graph: graph. (line 388)
* scroll: Files. (line 109)
@@ -9781,8 +9827,8 @@ Index
* self operators: Self & prefix operators.
(line 6)
* sequence: Arrays. (line 118)
-* settings: Configuring. (line 21)
-* settings <1>: Options. (line 120)
+* settings: Configuring. (line 20)
+* settings <1>: Options. (line 127)
* sgn: Mathematical functions.
(line 26)
* shading: fill. (line 32)
@@ -9790,11 +9836,11 @@ Index
* shift: Transforms. (line 26)
* shift <1>: Transforms. (line 28)
* shift <2>: Transforms. (line 46)
-* shift <3>: three. (line 424)
+* shift <3>: three. (line 450)
* shiftless: Transforms. (line 46)
* shipout: Frames and pictures.
(line 91)
-* showtarget: three. (line 316)
+* showtarget: three. (line 342)
* Si: Mathematical functions.
(line 48)
* signedint: Files. (line 76)
@@ -9814,9 +9860,9 @@ Index
* singlereal <1>: Files. (line 89)
* sinh: Mathematical functions.
(line 6)
-* SixViews: three. (line 382)
-* SixViewsFR: three. (line 382)
-* SixViewsUS: three. (line 382)
+* SixViews: three. (line 408)
+* SixViewsFR: three. (line 408)
+* SixViewsUS: three. (line 408)
* size: Figure size. (line 6)
* size <1>: Paths and guides. (line 81)
* size <2>: Paths and guides. (line 370)
@@ -9824,9 +9870,9 @@ Index
(line 48)
* size <4>: Frames and pictures.
(line 74)
-* size <5>: three. (line 481)
-* size <6>: Options. (line 149)
-* size3: three. (line 241)
+* size <5>: three. (line 507)
+* size <6>: Options. (line 156)
+* size3: three. (line 267)
* Slant: label. (line 42)
* slant: Transforms. (line 38)
* sleep: Data types. (line 375)
@@ -9867,7 +9913,7 @@ Index
* stop: Debugger. (line 10)
* straight: Paths and guides. (line 88)
* Straight: graph. (line 30)
-* straight <1>: three. (line 481)
+* straight <1>: three. (line 507)
* strftime: Data types. (line 320)
* strftime <1>: Data types. (line 345)
* string: Data types. (line 207)
@@ -9879,7 +9925,7 @@ Index
* struct: Structures. (line 6)
* structures: Structures. (line 6)
* subpath: Paths and guides. (line 186)
-* subpath <1>: three. (line 481)
+* subpath <1>: three. (line 507)
* subpictures: Frames and pictures.
(line 113)
* substr: Data types. (line 261)
@@ -9891,9 +9937,9 @@ Index
* surface <1>: three. (line 88)
* surface <2>: three. (line 102)
* surface <3>: graph3. (line 99)
-* SVG: Options. (line 154)
+* SVG: Options. (line 161)
* system: Data types. (line 353)
-* system <1>: Options. (line 173)
+* system <1>: Options. (line 180)
* syzygy: syzygy. (line 6)
* tab: Files. (line 61)
* tab completion: Drawing in interactive mode.
@@ -9904,7 +9950,7 @@ Index
(line 20)
* tanh: Mathematical functions.
(line 6)
-* target: three. (line 316)
+* target: three. (line 342)
* tell: Files. (line 93)
* tension: Bezier curves. (line 56)
* tension <1>: three. (line 6)
@@ -9914,13 +9960,13 @@ Index
* tessellation: three. (line 114)
* tex: Frames and pictures.
(line 302)
-* tex <1>: Options. (line 149)
+* tex <1>: Options. (line 156)
* TeX fonts: Pens. (line 215)
* TeX string: Data types. (line 207)
-* texcommand: Configuring. (line 64)
+* texcommand: Configuring. (line 72)
* TeXHead: draw. (line 26)
-* TeXHead3: three. (line 547)
-* texpath: Configuring. (line 64)
+* TeXHead3: three. (line 573)
+* texpath: Configuring. (line 72)
* texpath <1>: label. (line 113)
* texpreamble: Frames and pictures.
(line 311)
@@ -9929,13 +9975,13 @@ Index
* textbook graph: graph. (line 360)
* tgz: UNIX binary distributions.
(line 6)
-* thick: three. (line 125)
-* thin: three. (line 125)
+* thick: three. (line 126)
+* thin: three. (line 126)
* this: Structures. (line 6)
* three: three. (line 6)
-* ThreeViews: three. (line 382)
-* ThreeViewsFR: three. (line 382)
-* ThreeViewsUS: three. (line 382)
+* ThreeViews: three. (line 408)
+* ThreeViewsFR: three. (line 408)
+* ThreeViewsUS: three. (line 408)
* tick: graph. (line 330)
* ticks: graph. (line 160)
* Ticks: graph. (line 160)
@@ -9950,12 +9996,12 @@ Index
* times: Paths and guides. (line 220)
* times <1>: Paths and guides. (line 224)
* Top: graph. (line 135)
-* TopView: three. (line 367)
+* TopView: three. (line 393)
* trace: Debugger. (line 50)
* trailingzero: graph. (line 175)
* transform: Transforms. (line 6)
-* transform <1>: three. (line 456)
-* transform3: three. (line 419)
+* transform <1>: three. (line 482)
+* transform3: three. (line 445)
* transparency: Pens. (line 237)
* transpose: Arrays. (line 203)
* transpose <1>: Arrays. (line 206)
@@ -9969,8 +10015,8 @@ Index
(line 48)
* triple: Data types. (line 137)
* TrueMargin: draw. (line 42)
-* TrueMargin3: three. (line 563)
-* tube: three. (line 125)
+* TrueMargin3: three. (line 589)
+* tube: three. (line 126)
* tube <1>: tube. (line 6)
* tutorial: Tutorial. (line 6)
* type1cm: Pens. (line 192)
@@ -9991,10 +10037,10 @@ Index
* unit: Data types. (line 83)
* unit <1>: Data types. (line 173)
* unitbox: Paths. (line 44)
-* unitbox <1>: three. (line 288)
+* unitbox <1>: three. (line 314)
* unitcircle: Paths. (line 17)
* unitcircle <1>: Paths. (line 17)
-* unitcircle <2>: three. (line 256)
+* unitcircle <2>: three. (line 282)
* unitrand: Mathematical functions.
(line 39)
* unitsize: Figure size. (line 39)
@@ -10004,7 +10050,7 @@ Index
(line 6)
* unpacking: Rest arguments. (line 39)
* unravel: Import. (line 29)
-* up: three. (line 316)
+* up: three. (line 342)
* update: Files. (line 36)
* UpsideDown: Frames and pictures.
(line 104)
@@ -10031,14 +10077,15 @@ Index
* vertex-dependent colors: three. (line 79)
* Vertical: flowchart. (line 77)
* viewportheight: LaTeX usage. (line 50)
-* viewportmargin: three. (line 244)
-* viewportsize: three. (line 244)
+* viewportmargin: three. (line 270)
+* viewportsize: three. (line 270)
* viewportwidth: LaTeX usage. (line 50)
-* views: three. (line 213)
+* views: three. (line 239)
* vim: Editing modes. (line 32)
* virtual functions: Structures. (line 181)
* void: Data types. (line 10)
* W: Labels. (line 18)
+* WebGL: three. (line 192)
* whatever: Paths and guides. (line 246)
* Wheel: palette. (line 22)
* wheel mouse: GUI. (line 6)
@@ -10049,11 +10096,11 @@ Index
* word: Arrays. (line 349)
* write: Files. (line 53)
* write <1>: Arrays. (line 388)
-* X: three. (line 256)
+* X: three. (line 282)
* xasy: GUI. (line 6)
* xaxis3: graph3. (line 7)
* xdr: Files. (line 76)
-* xelatex: Options. (line 149)
+* xelatex: Options. (line 156)
* XEquals: graph. (line 265)
* xequals: graph. (line 278)
* xlimits: graph. (line 640)
@@ -10062,10 +10109,10 @@ Index
* xpart: Data types. (line 94)
* xpart <1>: Data types. (line 184)
* xscale: Transforms. (line 30)
-* xscale3: three. (line 426)
+* xscale3: three. (line 452)
* xtick: graph. (line 330)
-* XY: three. (line 441)
-* XY <1>: three. (line 456)
+* XY: three. (line 467)
+* XY <1>: three. (line 482)
* XYEquals: graph3. (line 21)
* XYZero: graph3. (line 21)
* XZEquals: graph3. (line 21)
@@ -10075,7 +10122,7 @@ Index
(line 6)
* Y <1>: Mathematical functions.
(line 48)
-* Y <2>: three. (line 256)
+* Y <2>: three. (line 282)
* yaxis3: graph3. (line 7)
* YEquals: graph. (line 128)
* yequals: graph. (line 278)
@@ -10083,14 +10130,14 @@ Index
* ypart: Data types. (line 97)
* ypart <1>: Data types. (line 187)
* yscale: Transforms. (line 32)
-* yscale3: three. (line 428)
+* yscale3: three. (line 454)
* ytick: graph. (line 330)
-* YX: three. (line 456)
-* YZ: three. (line 456)
+* YX: three. (line 482)
+* YZ: three. (line 482)
* YZEquals: graph3. (line 21)
* YZero: graph. (line 123)
* YZZero: graph3. (line 21)
-* Z: three. (line 256)
+* Z: three. (line 282)
* zaxis3: graph3. (line 7)
* zeroTransform: Transforms. (line 44)
* zerowinding: Pens. (line 164)
@@ -10107,159 +10154,159 @@ Index
* zeta: Mathematical functions.
(line 48)
* zpart: Data types. (line 190)
-* zscale3: three. (line 430)
-* ZX: three. (line 456)
-* ZX <1>: three. (line 456)
-* ZY: three. (line 456)
+* zscale3: three. (line 456)
+* ZX: three. (line 482)
+* ZX <1>: three. (line 482)
+* ZY: three. (line 482)

Tag Table:
Node: Top570
-Node: Description7279
-Node: Installation11100
-Node: UNIX binary distributions12144
-Node: MacOS X binary distributions13274
-Node: Microsoft Windows13828
-Node: Configuring15032
-Node: Search paths19178
-Node: Compiling from UNIX source20017
-Node: Editing modes23077
-Node: Git25498
-Node: Uninstall25898
-Node: Tutorial26244
-Node: Drawing in batch mode27132
-Node: Drawing in interactive mode28007
-Node: Figure size29039
-Node: Labels30631
-Node: Paths31458
-Ref: unitcircle32073
-Node: Drawing commands33973
-Node: draw35688
-Ref: arrows36870
-Node: fill42383
-Ref: gradient shading43429
-Node: clip47936
-Node: label48523
-Ref: Label49123
-Node: Bezier curves54968
-Node: Programming58865
-Ref: array iteration60618
-Node: Data types60785
-Ref: format71447
-Node: Paths and guides75893
-Ref: circle76147
-Ref: extension85854
-Node: Pens92663
-Ref: fillrule100352
-Ref: basealign101256
-Ref: transparency104090
-Ref: makepen107670
-Ref: overwrite108553
-Node: Transforms109767
-Node: Frames and pictures111599
-Ref: envelope112757
-Ref: size113850
-Ref: unitsize114837
-Ref: shipout115910
-Ref: filltype118261
-Ref: add121433
-Ref: add about122439
-Ref: tex125468
-Node: Files126364
-Ref: cd127351
-Ref: scroll132036
-Node: Variable initializers134954
-Node: Structures137671
-Node: Operators145173
-Node: Arithmetic & logical145487
-Node: Self & prefix operators147858
-Node: User-defined operators148652
-Node: Implicit scaling149565
-Node: Functions150128
-Ref: stack overflow153271
-Node: Default arguments153553
-Node: Named arguments154309
-Node: Rest arguments156879
-Node: Mathematical functions160001
-Node: Arrays164664
-Ref: sort171772
-Ref: tridiagonal174397
-Ref: solve175628
-Node: Slices179767
-Node: Casts183675
-Node: Import185942
-Node: Static191200
-Node: LaTeX usage194093
-Node: Base modules200608
-Node: plain203165
-Node: simplex203839
-Node: math204113
-Node: interpolate206822
-Node: geometry207101
-Node: trembling207695
-Node: stats207964
-Node: patterns208224
-Node: markers208460
-Node: tree210320
-Node: binarytree210505
-Node: drawtree211171
-Node: syzygy211372
-Node: feynman211646
-Node: roundedpath211921
-Node: animation212204
-Ref: animate212625
-Node: embed213742
-Node: slide214697
-Node: MetaPost215038
-Node: unicode215757
-Node: latin1216631
-Node: babel217000
-Node: labelpath217230
-Node: labelpath3218051
-Node: annotate218362
-Node: CAD218832
-Node: graph219143
-Ref: ticks226304
-Ref: pathmarkers240096
-Ref: marker240567
-Ref: markuniform240921
-Ref: errorbars242729
-Ref: automatic scaling247203
-Node: palette258950
-Ref: images259068
-Ref: image263242
-Ref: logimage263762
-Ref: penimage264867
-Ref: penfunctionimage265129
-Node: three265900
-Ref: PostScript3D292907
-Node: obj294645
-Node: graph3294894
-Ref: GaussianSurface300174
-Node: grid3301323
-Node: solids302107
-Node: tube303099
-Node: flowchart305333
-Node: contour309941
-Node: contour3315256
-Node: smoothcontour3315569
-Node: slopefield317290
-Node: ode318779
-Node: Options319036
-Ref: configuration file325418
-Ref: settings325418
-Ref: texengines326661
-Ref: convert326661
-Node: Interactive mode329985
-Ref: history332135
-Node: GUI333441
-Node: GUI installation333992
-Node: GUI usage334721
-Node: PostScript to Asymptote335637
-Node: Help336395
-Node: Debugger338049
-Node: Credits339805
-Node: Index340822
+Node: Description7280
+Node: Installation11190
+Node: UNIX binary distributions12234
+Node: MacOS X binary distributions13364
+Node: Microsoft Windows13918
+Node: Configuring15123
+Node: Search paths19579
+Node: Compiling from UNIX source20418
+Node: Editing modes23478
+Node: Git25899
+Node: Uninstall26299
+Node: Tutorial26645
+Node: Drawing in batch mode27534
+Node: Drawing in interactive mode28409
+Node: Figure size29441
+Node: Labels31033
+Node: Paths31860
+Ref: unitcircle32475
+Node: Drawing commands34375
+Node: draw36090
+Ref: arrows37272
+Node: fill42785
+Ref: gradient shading43831
+Node: clip48338
+Node: label48925
+Ref: Label49525
+Node: Bezier curves55370
+Node: Programming59267
+Ref: array iteration61020
+Node: Data types61187
+Ref: format71849
+Node: Paths and guides76295
+Ref: circle76549
+Ref: extension86256
+Node: Pens93065
+Ref: fillrule100754
+Ref: basealign101658
+Ref: transparency104492
+Ref: makepen108072
+Ref: overwrite108955
+Node: Transforms110169
+Node: Frames and pictures112001
+Ref: envelope113159
+Ref: size114252
+Ref: unitsize115239
+Ref: shipout116312
+Ref: filltype118663
+Ref: add121835
+Ref: add about122841
+Ref: tex125870
+Node: Files126766
+Ref: cd127753
+Ref: scroll132438
+Node: Variable initializers135356
+Node: Structures138073
+Node: Operators145575
+Node: Arithmetic & logical145889
+Node: Self & prefix operators148259
+Node: User-defined operators149053
+Node: Implicit scaling149966
+Node: Functions150529
+Ref: stack overflow153672
+Node: Default arguments153954
+Node: Named arguments154710
+Node: Rest arguments157280
+Node: Mathematical functions160402
+Node: Arrays165065
+Ref: sort172173
+Ref: tridiagonal174798
+Ref: solve176029
+Node: Slices180169
+Node: Casts184077
+Node: Import186344
+Node: Static191602
+Node: LaTeX usage194495
+Node: Base modules201010
+Node: plain203567
+Node: simplex204241
+Node: math204515
+Node: interpolate207224
+Node: geometry207503
+Node: trembling208097
+Node: stats208366
+Node: patterns208626
+Node: markers208862
+Node: tree210722
+Node: binarytree210907
+Node: drawtree211573
+Node: syzygy211774
+Node: feynman212048
+Node: roundedpath212323
+Node: animation212606
+Ref: animate213027
+Node: embed214144
+Node: slide215099
+Node: MetaPost215440
+Node: unicode216159
+Node: latin1217033
+Node: babel217402
+Node: labelpath217632
+Node: labelpath3218453
+Node: annotate218764
+Node: CAD219234
+Node: graph219545
+Ref: ticks226706
+Ref: pathmarkers240498
+Ref: marker240969
+Ref: markuniform241323
+Ref: errorbars243131
+Ref: automatic scaling247605
+Node: palette259352
+Ref: images259470
+Ref: image263644
+Ref: logimage264164
+Ref: penimage265269
+Ref: penfunctionimage265531
+Node: three266302
+Ref: PostScript3D294487
+Node: obj296225
+Node: graph3296474
+Ref: GaussianSurface301754
+Node: grid3302903
+Node: solids303687
+Node: tube304679
+Node: flowchart306913
+Node: contour311521
+Node: contour3316836
+Node: smoothcontour3317149
+Node: slopefield318870
+Node: ode320359
+Node: Options320616
+Ref: configuration file327464
+Ref: settings327464
+Ref: texengines328728
+Ref: convert328728
+Node: Interactive mode332052
+Ref: history334202
+Node: GUI335508
+Node: GUI installation336059
+Node: GUI usage336789
+Node: PostScript to Asymptote337705
+Node: Help338463
+Node: Debugger340117
+Node: Credits341873
+Node: Index342890

End Tag Table
diff --git a/graphics/asymptote/drawelement.h b/graphics/asymptote/drawelement.h
index cea6baf3c9..4ce7504332 100644
--- a/graphics/asymptote/drawelement.h
+++ b/graphics/asymptote/drawelement.h
@@ -17,16 +17,13 @@
#include "psfile.h"
#include "texfile.h"
#include "prcfile.h"
+#include "jsfile.h"
#include "glrender.h"
#include "arrayop.h"
#include "material.h"
namespace camp {
-//extern double Tx[3]; // x-component of current transform
-//extern double Ty[3]; // y-component of current transform
-extern double* Tz; // z-component of current transform
-
static const double pixel=1.0; // Adaptive rendering constant.
// Return one-sixth of the second derivative of the Bezier curve defined
@@ -36,7 +33,7 @@ inline triple bezierPP(triple a, triple b, triple c) {
}
// Return one-third of the third derivative of the Bezier curve defined by
-// a,b,c,d.
+// a,b,c,d at 0.
inline triple bezierPPP(triple a, triple b, triple c, triple d) {
return d-a+3.0*(b-c);
}
@@ -112,6 +109,62 @@ public:
};
+class bbox2 {
+public:
+ double x,y,X,Y;
+ bbox2(size_t n, const triple *v) {
+ Bounds(v[0]);
+ for(size_t i=1; i < n; ++i)
+ bounds(v[i]);
+ }
+
+ bbox2(const triple& m, const triple& M) {
+ Bounds(m);
+ bounds(triple(m.getx(),m.gety(),M.getz()));
+ bounds(triple(m.getx(),M.gety(),m.getz()));
+ bounds(triple(m.getx(),M.gety(),M.getz()));
+ bounds(triple(M.getx(),m.gety(),m.getz()));
+ bounds(triple(M.getx(),m.gety(),M.getz()));
+ bounds(triple(M.getx(),M.gety(),m.getz()));
+ bounds(M);
+ }
+
+ bbox2(const triple& m, const triple& M, const Billboard& BB) {
+ Bounds(BB.transform(m));
+ bounds(BB.transform(triple(m.getx(),m.gety(),M.getz())));
+ bounds(BB.transform(triple(m.getx(),M.gety(),m.getz())));
+ bounds(BB.transform(triple(m.getx(),M.gety(),M.getz())));
+ bounds(BB.transform(triple(M.getx(),m.gety(),m.getz())));
+ bounds(BB.transform(triple(M.getx(),m.gety(),M.getz())));
+ bounds(BB.transform(triple(M.getx(),M.gety(),m.getz())));
+ bounds(BB.transform(M));
+ }
+
+// Is 2D bounding box formed by projecting 3d points in vector v offscreen?
+ bool offscreen() {
+ double eps=1.0e-2;
+ double min=-1.0-eps;
+ double max=1.0+eps;
+ return X < min || x > max || Y < min || y > max;
+ }
+
+ void Bounds(const triple& v) {
+ pair V=Transform2T(gl::dprojView,v);
+ x=X=V.getx();
+ y=Y=V.gety();
+ }
+
+ void bounds(const triple& v) {
+ pair V=Transform2T(gl::dprojView,v);
+ double a=V.getx();
+ double b=V.gety();
+ if(a < x) x=a;
+ else if(a > X) X=a;
+ if(b < y) y=b;
+ else if(b > Y) Y=b;
+ }
+};
+
typedef mem::vector<box> boxvector;
typedef mem::list<bbox> bboxlist;
@@ -119,26 +172,20 @@ typedef mem::list<bbox> bboxlist;
typedef mem::map<CONST string,unsigned> groupmap;
typedef mem::vector<groupmap> groupsmap;
-#ifdef HAVE_GL
-typedef mem::map<CONST Material,size_t> MaterialMap;
-#endif
-
class drawElement : public gc
{
public:
string KEY;
drawElement(const string& key="") : KEY(key == "" ? processData().KEY : key)
- {}
+ {}
virtual ~drawElement() {}
-
-#ifdef HAVE_GL
- static mem::vector<Material> material;
- static MaterialMap materialMap;
- static size_t materialIndex;
-#endif
+ static mem::vector<triple> center;
+ static size_t centerIndex;
+ static triple lastcenter;
+ static size_t lastcenterIndex;
static pen lastpen;
static const triple zero;
@@ -154,24 +201,24 @@ public:
double fuzz, bool &first) {}
virtual void minratio(const double *t, pair &b, double fuzz, bool &first) {
- ratio(t, b, camp::min, fuzz, first);
+ ratio(t,b,camp::min,fuzz,first);
}
virtual void maxratio(const double *t,pair &b, double fuzz, bool &first) {
- ratio(t, b, camp::max, fuzz, first);
+ ratio(t,b,camp::max,fuzz,first);
}
virtual void ratio(pair &b, double (*m)(double, double), double fuzz,
bool &first) {
- ratio(NULL, b, m, fuzz, first);
+ ratio(NULL,b,m,fuzz,first);
}
virtual void minratio(pair &b, double fuzz, bool &first) {
- minratio(NULL, b, fuzz, first);
+ minratio(NULL,b,fuzz,first);
}
virtual void maxratio(pair &b, double fuzz, bool &first) {
- maxratio(NULL, b, fuzz, first);
+ maxratio(NULL,b,fuzz,first);
}
virtual bool islabel() {return false;}
@@ -217,12 +264,29 @@ public:
return false;
}
+ // Output to a JS file
+ virtual bool write(jsfile *out) {
+ return false;
+ }
+
// Used to compute deviation of a surface from a quadrilateral.
virtual void displacement() {}
// Render with OpenGL
virtual void render(double size2, const triple& Min, const triple& Max,
- double perspective, bool transparent) {}
+ double perspective, bool remesh)
+ {}
+
+ virtual void meshinit() {}
+
+ size_t centerindex(const triple& center) {
+ if(drawElement::center.empty() || center != drawElement::lastcenter) {
+ drawElement::lastcenter=center;
+ drawElement::center.push_back(center);
+ drawElement::lastcenterIndex=drawElement::center.size();
+ }
+ return drawElement::lastcenterIndex;
+ }
// Transform as part of a picture.
virtual drawElement *transformed(const transform&) {
@@ -421,13 +485,18 @@ void registerBuffer(std::vector<T>& buffervector, GLuint bufferIndex) {
glBindBuffer(GL_ARRAY_BUFFER,0);
}
}
+#endif
+#ifdef HAVE_LIBGLM
void setcolors(bool colors,
const prc::RGBAColour& diffuse,
const prc::RGBAColour& emissive,
const prc::RGBAColour& specular, double shininess,
- double metallic, double fresnel0);
+ double metallic, double fresnel0, jsfile *out=NULL);
#endif
+
+
+
}
GC_DECLARE_PTRFREE(camp::box);
diff --git a/graphics/asymptote/drawpath3.cc b/graphics/asymptote/drawpath3.cc
index 55752509ff..8bdd8a35f3 100644
--- a/graphics/asymptote/drawpath3.cc
+++ b/graphics/asymptote/drawpath3.cc
@@ -8,7 +8,7 @@
#include "drawsurface.h"
#include "material.h"
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
@@ -19,13 +19,6 @@ namespace camp {
using vm::array;
using namespace prc;
-#ifdef HAVE_GL
-using gl::modelView;
-
-BezierCurve drawPath3::R;
-Pixel drawPixel::R;
-#endif
-
bool drawPath3::write(prcfile *out, unsigned int *, double, groupsmap&)
{
Int n=g.length();
@@ -57,66 +50,76 @@ bool drawPath3::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-void drawPath3::render(double size2, const triple& b, const triple& B,
- double perspective, bool transparent)
+bool drawPath3::write(jsfile *out)
{
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
Int n=g.length();
- if(n == 0 || invisible || ((color.A < 1.0) ^ transparent))
- return;
-
- const bool billboard=interaction == BILLBOARD &&
- !settings::getSetting<bool>("offscreen");
- triple m,M;
-
- double f,F,s;
- if(perspective) {
- f=Min.getz()*perspective;
- F=Max.getz()*perspective;
- m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz());
- M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz());
- s=max(f,F);
- } else {
- m=b;
- M=B;
- s=1.0;
- }
-
- const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
-
- bbox3 box(m,M);
- box.transform(modelView.Tinv);
- m=box.Min();
- M=box.Max();
+ if(n == 0 || invisible)
+ return true;
- if(!billboard && (Max.getx() < m.getx() || Min.getx() > M.getx() ||
- Max.gety() < m.gety() || Min.gety() > M.gety() ||
- Max.getz() < m.getz() || Min.getz() > M.getz()))
- return;
+ if(billboard) {
+ meshinit();
+ drawElement::centerIndex=centerIndex;
+ } else drawElement::centerIndex=0;
RGBAColour Black(0.0,0.0,0.0,color.A);
- setcolors(false,Black,color,Black,1.0,0.0,0.04);
+ setcolors(false,Black,color,Black,1.0,0.0,0.04,out);
+ for(Int i=0; i < n; ++i) {
+ if(g.straight(i)) {
+ out->addCurve(g.point(i),g.point(i+1),Min,Max);
+ } else
+ out->addCurve(g.point(i),g.postcontrol(i),
+ g.precontrol(i+1),g.point(i+1),Min,Max);
+ }
+#endif
+ return true;
+}
+
+void drawPath3::render(double size2, const triple& b, const triple& B,
+ double perspective, bool remesh)
+{
+#ifdef HAVE_LIBGL
+ Int n=g.length();
+ if(n == 0 || invisible) return;
+
+ bool offscreen;
if(billboard) {
- for(Int i=0; i < n; ++i) {
- triple controls[]={BB.transform(g.point(i)),BB.transform(g.postcontrol(i)),
- BB.transform(g.precontrol(i+1)),
- BB.transform(g.point(i+1))};
- R.queue(controls,straight,size3.length()/size2,m,M);
- }
- } else {
+ drawElement::centerIndex=centerIndex;
BB.init(center);
- for(Int i=0; i < n; ++i) {
- triple controls[]={g.point(i),g.postcontrol(i),g.precontrol(i+1),
- g.point(i+1)};
- R.queue(controls,straight,size3.length()/size2,m,M);
- }
+ offscreen=bbox2(Min,Max,BB).offscreen();
+ } else
+ offscreen=bbox2(Min,Max).offscreen();
+
+ if(offscreen) { // Fully offscreen
+ R.Onscreen=false;
+ R.data.clear();
+ return;
}
- if(BezierCurve::vertexbuffer.size() >= (unsigned) gl::maxvertices) {
- R.draw();
- BezierCurve::clear();
- gl::forceRemesh=true;
+
+ for(Int i=0; i < n; ++i) {
+ triple controls[]={g.point(i),g.postcontrol(i),g.precontrol(i+1),
+ g.point(i+1)};
+ triple *Controls;
+ triple Controls0[4];
+ if(billboard) {
+ Controls=Controls0;
+ for(size_t i=0; i < 4; i++) {
+ Controls[i]=BB.transform(controls[i]);
+ }
+ } else
+ Controls=controls;
+
+ double s=perspective ? Min.getz()*perspective : 1.0; // Move to glrender
+
+ const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
+
+ RGBAColour Black(0.0,0.0,0.0,color.A);
+ setcolors(false,Black,color,Black,1.0,0.0,0.04);
+
+ R.queue(controls,g.straight(i),size3.length()/size2);
}
+
#endif
}
@@ -197,7 +200,7 @@ void drawNurbsPath3::ratio(const double* t, pair &b, double (*m)(double, double)
void drawNurbsPath3::displacement()
{
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
size_t nknots=degree+n+1;
if(Controls == NULL) {
Controls=new(UseGC) GLfloat[(weights ? 4 : 3)*n];
@@ -216,11 +219,10 @@ void drawNurbsPath3::displacement()
}
void drawNurbsPath3::render(double, const triple&, const triple&,
- double, bool transparent)
+ double, bool remesh)
{
-#ifdef HAVE_GL
- if(invisible || ((color.A < 1.0) ^ transparent))
- return;
+#ifdef HAVE_LIBGL
+ if(invisible) return;
// TODO: implement NURBS renderer
#endif
@@ -236,48 +238,35 @@ bool drawPixel::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
+bool drawPixel::write(jsfile *out)
+{
+#ifdef HAVE_LIBGL
+ if(invisible)
+ return true;
+
+ RGBAColour Black(0.0,0.0,0.0,color.A);
+ setcolors(false,color,color,Black,1.0,0.0,0.04,out);
+
+ out->addPixel(v,width,Min,Max);
+#endif
+ return true;
+}
+
void drawPixel::render(double size2, const triple& b, const triple& B,
- double perspective, bool transparent)
+ double perspective, bool remesh)
{
-#ifdef HAVE_GL
- if(invisible || ((color.A < 1.0) ^ transparent)) return;
- triple m,M;
+#ifdef HAVE_LIBGL
+ if(invisible) return;
- double f,F,s;
- if(perspective) {
- f=Min.getz()*perspective;
- F=Max.getz()*perspective;
- m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz());
- M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz());
- s=max(f,F);
- } else {
- m=b;
- M=B;
- s=1.0;
+ if(bbox2(Min,Max).offscreen()) { // Fully offscreen
+ R.data.clear();
+ return;
}
-
- const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
-
- bbox3 box(m,M);
- box.transform(modelView.Tinv);
- m=box.Min();
- M=box.Max();
- if((Max.getx() < m.getx() || Min.getx() > M.getx() ||
- Max.gety() < m.gety() || Min.gety() > M.gety() ||
- Max.getz() < m.getz() || Min.getz() > M.getz()))
- return;
-
RGBAColour Black(0.0,0.0,0.0,color.A);
setcolors(false,color,color,Black,1.0,0.0,0.04);
R.queue(v,width);
-
- if(Pixel::vertexbuffer.size() >= (unsigned) gl::maxvertices) {
- R.draw();
- Pixel::clear();
- gl::forceRemesh=true;
- }
#endif
}
diff --git a/graphics/asymptote/drawpath3.h b/graphics/asymptote/drawpath3.h
index c6515057c9..0df098e84a 100644
--- a/graphics/asymptote/drawpath3.h
+++ b/graphics/asymptote/drawpath3.h
@@ -22,20 +22,31 @@ protected:
bool invisible;
Interaction interaction;
triple Min,Max;
+ bool billboard;
+ size_t centerIndex;
public:
#ifdef HAVE_GL
- static BezierCurve R;
+ BezierCurve R;
#endif
+ void init() {
+ billboard=interaction == BILLBOARD &&
+ !settings::getSetting<bool>("offscreen");
+ centerIndex=0;
+ }
+
drawPath3(path3 g, triple center, const pen& p, Interaction interaction,
const string& key="") :
drawElement(key), g(g), center(center), straight(g.piecewisestraight()),
color(rgba(p)), invisible(p.invisible()), interaction(interaction),
- Min(g.min()), Max(g.max()) {}
+ Min(g.min()), Max(g.max()) {
+ init();
+ }
drawPath3(const double* t, const drawPath3 *s) :
drawElement(s->KEY), g(camp::transformed(t,s->g)), straight(s->straight),
color(s->color), invisible(s->invisible), interaction(s->interaction),
Min(g.min()), Max(g.max()) {
+ init();
center=t*s->center;
}
@@ -68,10 +79,16 @@ public:
} else b=pair(m(b.getx(),z.getx()),m(b.gety(),z.gety()));
}
+ void meshinit() {
+ if(billboard)
+ centerIndex=centerindex(center);
+ }
+
bool write(prcfile *out, unsigned int *, double, groupsmap&);
+ bool write(jsfile *out);
void render(double, const triple&, const triple&, double,
- bool transparent);
+ bool remesh);
drawElement *transformed(const double* t);
};
@@ -87,7 +104,7 @@ protected:
bool invisible;
triple Min,Max;
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
GLfloat *Controls;
GLfloat *Knots;
#endif
@@ -126,7 +143,7 @@ public:
run::copyArrayC(knots,knot,0,NoGC);
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
Controls=NULL;
#endif
}
@@ -138,7 +155,7 @@ public:
for(unsigned int i=0; i < n; ++i)
controls[i]=t*s->controls[i];
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
Controls=NULL;
#endif
}
@@ -156,7 +173,7 @@ public:
bool &first);
void render(double size2, const triple& Min, const triple& Max,
- double perspective, bool transparent);
+ double perspective, bool remesh);
drawElement *transformed(const double* t);
};
@@ -171,7 +188,7 @@ class drawPixel : public drawElement {
triple Min,Max;
public:
#ifdef HAVE_GL
- static Pixel R;
+ Pixel R;
#endif
drawPixel(const triple& v, const pen& p, double width, const string& key="")
: drawElement(key), v(v), p(p), color(rgba(p)), width(width),
@@ -194,9 +211,10 @@ public:
}
void render(double size2, const triple& b, const triple& B,
- double perspective, bool transparent);
+ double perspective, bool remesh);
bool write(prcfile *out, unsigned int *, double, groupsmap&);
+ bool write(jsfile *out);
drawElement *transformed(const double* t);
};
diff --git a/graphics/asymptote/drawsurface.cc b/graphics/asymptote/drawsurface.cc
index 80f7581ee3..7d23ad9308 100644
--- a/graphics/asymptote/drawsurface.cc
+++ b/graphics/asymptote/drawsurface.cc
@@ -12,7 +12,7 @@
#include <iomanip>
#include <fstream>
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
@@ -20,28 +20,19 @@
using namespace prc;
#include "material.h"
-namespace camp {
-
-#ifdef HAVE_GL
-mem::vector<Material> drawElement::material;
-MaterialMap drawElement::materialMap;
-size_t drawElement::materialIndex;
-using gl::modelView;
-//double* Tx=modelView.T; // x-component of current transform
-//double* Ty=modelView.T+4; // y-component of current transform
-double* Tz=modelView.T+8; // z-component of current transform
+namespace camp {
-#endif
+mem::vector<triple> drawElement::center;
+size_t drawElement::centerIndex=0;
+triple drawElement::lastcenter=0;
+size_t drawElement::lastcenterIndex=0;
const triple drawElement::zero;
using vm::array;
-#ifdef HAVE_GL
-BezierCurve drawSurface::C;
-BezierPatch drawBezierPatch::S;
-BezierTriangle drawBezierTriangle::S;
+#ifdef HAVE_LIBGLM
void storecolor(GLfloat *colors, int i, const vm::array &pens, int j)
{
@@ -61,48 +52,38 @@ void storecolor(GLfloat *colors, int i, const RGBAColour& p)
colors[i+3]=p.A;
}
-void clearMaterialBuffer(bool draw)
-{
- if(draw) {
- drawBezierPatch::S.draw();
- drawPath3::R.draw();
- drawPixel::R.draw();
- }
- drawElement::material.clear();
- drawElement::material.reserve(nmaterials);
- drawElement::materialMap.clear();
- drawElement::materialIndex=0;
-}
-
void setcolors(bool colors,
const RGBAColour& diffuse,
const RGBAColour& emissive,
const RGBAColour& specular, double shininess,
- double metallic, double fresnel0)
+ double metallic, double fresnel0, jsfile *out)
{
Material m;
if(colors) {
static glm::vec4 Black(0.0,0.0,0.0,diffuse.A);
m=Material(Black,Black,
glm::vec4(specular.R,specular.G,specular.B,specular.A),
- shininess, metallic, fresnel0);
- } else
+ shininess,metallic,fresnel0);
+ } else
m=Material(glm::vec4(diffuse.R,diffuse.G,diffuse.B,diffuse.A),
glm::vec4(emissive.R,emissive.G,emissive.B,emissive.A),
glm::vec4(specular.R,specular.G,specular.B,specular.A),
- shininess, metallic, fresnel0);
+ shininess,metallic,fresnel0);
- MaterialMap::iterator p=drawElement::materialMap.find(m);
- if(p != drawElement::materialMap.end())
- drawElement::materialIndex=p->second;
+ MaterialMap::iterator p=materialMap.find(m);
+ if(p != materialMap.end()) materialIndex=p->second;
else {
- drawElement::materialIndex=drawElement::material.size();
- if(drawElement::materialIndex >= nmaterials)
+ materialIndex=material.size();
+ if(materialIndex >= nmaterials)
nmaterials=min(Maxmaterials,2*nmaterials);
- if(drawElement::materialIndex >= Maxmaterials)
+#ifdef HAVE_LIBGL
+ if(!out && materialIndex >= Maxmaterials)
clearMaterialBuffer(true);
- drawElement::material.push_back(m);
- drawElement::materialMap[m]=drawElement::materialIndex;
+#endif
+ material.push_back(m);
+ materialMap[m]=materialIndex;
+ if(out)
+ out->addMaterial(materialIndex);
}
}
@@ -161,8 +142,8 @@ void drawBezierPatch::bounds(const double* t, bbox3& b)
c0=cz[0];
fuzz=Fuzz*run::norm(cz,16);
- z=bound(cz,min,b.empty ? c0 : min(c0,b.lower),fuzz,maxdepth);
- Z=bound(cz,max,b.empty ? c0 : max(c0,b.upper),fuzz,maxdepth);
+ z=bound(cz,min,b.empty ? c0 : min(c0,b.near),fuzz,maxdepth);
+ Z=bound(cz,max,b.empty ? c0 : max(c0,b.far),fuzz,maxdepth);
}
b.add(x,y,z);
@@ -238,9 +219,10 @@ bool drawBezierPatch::write(prcfile *out, unsigned int *, double, groupsmap&)
if(straight) {
triple vertices[]={controls[0],controls[12],controls[3],controls[15]};
- if(colors)
- out->addQuad(vertices,colors);
- else
+ if(colors) {
+ prc::RGBAColour Colors[]={colors[0],colors[1],colors[3],colors[2]};
+ out->addQuad(vertices,Colors);
+ } else
out->addRectangle(vertices,m);
} else
out->addPatch(controls,m);
@@ -248,84 +230,89 @@ bool drawBezierPatch::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-void drawBezierPatch::render(double size2, const triple& b, const triple& B,
- double perspective, bool transparent)
+bool drawBezierPatch::write(jsfile *out)
{
-#ifdef HAVE_GL
- if(invisible ||
- ((colors ? colors[0].A+colors[1].A+colors[2].A+colors[3].A < 4.0 :
- diffuse.A < 1.0) ^ transparent)) return;
-
- const bool billboard=interaction == BILLBOARD &&
- !settings::getSetting<bool>("offscreen");
- triple m,M;
-
- double f,F,s;
- if(perspective) {
- f=Min.getz()*perspective;
- F=Max.getz()*perspective;
- m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz());
- M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz());
- s=max(f,F);
- } else {
- m=b;
- M=B;
- s=1.0;
- }
+#ifdef HAVE_LIBGLM
+ if(invisible)
+ return true;
+
+ if(billboard) {
+ meshinit();
+ drawElement::centerIndex=centerIndex;
+ } else drawElement::centerIndex=0;
- const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
+ setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+
+ if(straight) {
+ triple Controls[]={controls[0],controls[12],controls[15],controls[3]};
+ out->addPatch(Controls,4,Min,Max,colors);
+ } else
+ out->addPatch(controls,16,Min,Max,colors);
+
+#endif
+ return true;
+}
- bbox3 box(m,M);
- box.transform(modelView.Tinv);
- m=box.Min();
- M=box.Max();
+void drawBezierPatch::render(double size2, const triple& b, const triple& B,
+ double perspective, bool remesh)
+{
+#ifdef HAVE_LIBGL
+ if(invisible) return;
+ transparent=colors ? colors[0].A+colors[1].A+colors[2].A+colors[3].A < 4.0 :
+ diffuse.A < 1.0;
- if(!billboard && (Max.getx() < m.getx() || Min.getx() > M.getx() ||
- Max.gety() < m.gety() || Min.gety() > M.gety() ||
- Max.getz() < m.getz() || Min.getz() > M.getz()))
+ bool offscreen;
+ if(billboard) {
+ drawElement::centerIndex=centerIndex;
+ BB.init(center);
+ offscreen=bbox2(Min,Max,BB).offscreen();
+ } else
+ offscreen=bbox2(Min,Max).offscreen();
+
+ if(offscreen) { // Fully offscreen
+ S.Onscreen=false;
+ S.data.clear();
return;
+ }
+
+ triple *Controls;
+ triple Controls0[16];
+ if(billboard) {
+ Controls=Controls0;
+ for(size_t i=0; i < 16; i++) {
+ Controls[i]=BB.transform(controls[i]);
+ }
+ } else {
+ Controls=controls;
+ if(!remesh && S.Onscreen) { // Fully onscreen; no need to re-render
+ S.append();
+ return;
+ }
+ }
+
+ double s=perspective ? Min.getz()*perspective : 1.0; // Move to glrender
+
+ const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0);
- if(billboard) BB.init(center);
-
GLfloat c[16];
if(colors)
for(size_t i=0; i < 4; ++i)
storecolor(c,4*i,colors[i]);
- triple *Controls;
- triple Controls0[16];
- if(billboard) {
- Controls=Controls0;
- for(size_t i=0; i < 16; i++)
- Controls[i]=BB.transform(controls[i]);
- } else
- Controls=controls;
-
if(gl::outlinemode) {
triple edge0[]={Controls[0],Controls[4],Controls[8],Controls[12]};
- C.queue(edge0,straight,size3.length()/size2,m,M);
+ C.queue(edge0,straight,size3.length()/size2);
triple edge1[]={Controls[12],Controls[13],Controls[14],Controls[15]};
- C.queue(edge1,straight,size3.length()/size2,m,M);
+ C.queue(edge1,straight,size3.length()/size2);
triple edge2[]={Controls[15],Controls[11],Controls[7],Controls[3]};
- C.queue(edge2,straight,size3.length()/size2,m,M);
+ C.queue(edge2,straight,size3.length()/size2);
triple edge3[]={Controls[3],Controls[2],Controls[1],Controls[0]};
- C.queue(edge3,straight,size3.length()/size2,m,M);
- C.draw();
+ C.queue(edge3,straight,size3.length()/size2);
} else {
- S.queue(Controls,straight,size3.length()/size2,m,M,transparent,
+ S.queue(Controls,straight,size3.length()/size2,transparent,
colors ? c : NULL);
- if(BezierPatch::nvertices >= gl::maxvertices) {
- S.drawMaterials();
- BezierPatch::clear();
- gl::forceRemesh=true;
- }
- if(BezierPatch::Nvertices >= gl::maxvertices) {
- S.drawColors();
- BezierPatch::Clear();
- gl::forceRemesh=true;
- }
}
#endif
}
@@ -386,8 +373,8 @@ void drawBezierTriangle::bounds(const double* t, bbox3& b)
c0=cz[0];
fuzz=Fuzz*run::norm(cz,10);
- z=boundtri(cz,min,b.empty ? c0 : min(c0,b.lower),fuzz,maxdepth);
- Z=boundtri(cz,max,b.empty ? c0 : max(c0,b.upper),fuzz,maxdepth);
+ z=boundtri(cz,min,b.empty ? c0 : min(c0,b.near),fuzz,maxdepth);
+ Z=boundtri(cz,max,b.empty ? c0 : max(c0,b.far),fuzz,maxdepth);
}
b.add(x,y,z);
@@ -474,72 +461,87 @@ bool drawBezierTriangle::write(prcfile *out, unsigned int *, double,
return true;
}
-void drawBezierTriangle::render(double size2, const triple& b, const triple& B,
- double perspective, bool transparent)
+bool drawBezierTriangle::write(jsfile *out)
{
-#ifdef HAVE_GL
- if(invisible ||
- ((colors ? colors[0].A+colors[1].A+colors[2].A < 3.0 :
- diffuse.A < 1.0) ^ transparent)) return;
-
- const bool billboard=interaction == BILLBOARD &&
- !settings::getSetting<bool>("offscreen");
- triple m,M;
-
- double f,F,s;
- if(perspective) {
- f=Min.getz()*perspective;
- F=Max.getz()*perspective;
- m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz());
- M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz());
- s=max(f,F);
- } else {
- m=b;
- M=B;
- s=1.0;
- }
-
- const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
-
- bbox3 box(m,M);
- box.transform(modelView.Tinv);
- m=box.Min();
- M=box.Max();
+#ifdef HAVE_LIBGLM
+ if(invisible)
+ return true;
- if(!billboard && (Max.getx() < m.getx() || Min.getx() > M.getx() ||
- Max.gety() < m.gety() || Min.gety() > M.gety() ||
- Max.getz() < m.getz() || Min.getz() > M.getz()))
- return;
+ if(billboard) {
+ meshinit();
+ drawElement::centerIndex=centerIndex;
+ } else drawElement::centerIndex=0;
+
+ setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+
+ if(straight) {
+ triple Controls[]={controls[0],controls[6],controls[9]};
+ out->addPatch(Controls,3,Min,Max,colors);
+ } else
+ out->addPatch(controls,10,Min,Max,colors);
+
+#endif
+ return true;
+}
- setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0);
+void drawBezierTriangle::render(double size2, const triple& b, const triple& B,
+ double perspective, bool remesh)
+{
+#ifdef HAVE_LIBGL
+ if(invisible) return;
+ transparent=colors ? colors[0].A+colors[1].A+colors[2].A < 3.0 :
+ diffuse.A < 1.0;
- if(billboard) BB.init(center);
+ bool offscreen;
+ if(billboard) {
+ drawElement::centerIndex=centerIndex;
+ BB.init(center);
+ offscreen=bbox2(Min,Max,BB).offscreen();
+ } else
+ offscreen=bbox2(Min,Max).offscreen();
- GLfloat v[12];
- if(colors)
- for(size_t i=0; i < 3; ++i)
- storecolor(v,4*i,colors[i]);
-
+ if(offscreen) { // Fully offscreen
+ S.Onscreen=false;
+ S.data.clear();
+ return;
+ }
+
triple *Controls;
triple Controls0[10];
if(billboard) {
Controls=Controls0;
- for(size_t i=0; i < 10; i++)
- Controls[i]=BB.transform(controls[i]);
- } else
+ for(size_t i=0; i < 10; i++) {
+ Controls[i]=BB.transform(controls[i]);
+ }
+ } else {
Controls=controls;
+ if(!remesh && S.Onscreen) { // Fully onscreen; no need to re-render
+ S.append();
+ return;
+ }
+ }
+
+ double s=perspective ? Min.getz()*perspective : 1.0; // Move to glrender
+
+ const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
+
+ setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0);
+ GLfloat c[12];
+ if(colors)
+ for(size_t i=0; i < 3; ++i)
+ storecolor(c,4*i,colors[i]);
+
if(gl::outlinemode) {
triple edge0[]={Controls[0],Controls[1],Controls[3],Controls[6]};
- C.queue(edge0,straight,size3.length()/size2,m,M);
+ C.queue(edge0,straight,size3.length()/size2);
triple edge1[]={Controls[6],Controls[7],Controls[8],Controls[9]};
- C.queue(edge1,straight,size3.length()/size2,m,M);
+ C.queue(edge1,straight,size3.length()/size2);
triple edge2[]={Controls[9],Controls[5],Controls[2],Controls[0]};
- C.queue(edge2,straight,size3.length()/size2,m,M);
- C.draw();
+ C.queue(edge2,straight,size3.length()/size2);
} else
- S.queue(Controls,straight,size3.length()/size2,m,M,transparent,
- colors ? v : NULL);
+ S.queue(Controls,straight,size3.length()/size2,transparent,
+ colors ? c : NULL);
#endif
}
@@ -626,7 +628,7 @@ void drawNurbs::ratio(const double *t, pair &b, double (*m)(double, double),
void drawNurbs::displacement()
{
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
size_t n=nu*nv;
size_t nuknots=udegree+nu+1;
size_t nvknots=vdegree+nv+1;
@@ -651,37 +653,10 @@ void drawNurbs::displacement()
#endif
}
-void drawNurbs::render(double size2, const triple& Min, const triple& Max,
- double perspective, bool transparent)
+void drawNurbs::render(double size2, const triple& b, const triple& B,
+ double perspective, bool remesh)
{
-#ifdef HAVE_GL
- if(invisible || ((colors ? colors[3]+colors[7]+colors[11]+colors[15] < 4.0
- : diffuse.A < 1.0) ^ transparent)) return;
-
- bbox3 B(this->Min,this->Max);
- B.transform(modelView.T);
-
- triple m=B.Min();
- triple M=B.Max();
-
- if(perspective) {
- double f=m.getz()*perspective;
- double F=M.getz()*perspective;
- if(M.getx() < min(f*Min.getx(),F*Min.getx()) ||
- m.getx() > max(f*Max.getx(),F*Max.getx()) ||
- M.gety() < min(f*Min.gety(),F*Min.gety()) ||
- m.gety() > max(f*Max.gety(),F*Max.gety()) ||
- M.getz() < Min.getz() ||
- m.getz() > Max.getz()) return;
- } else {
- if(M.getx() < Min.getx() || m.getx() > Max.getx() ||
- M.gety() < Min.gety() || m.gety() > Max.gety() ||
- M.getz() < Min.getz() || m.getz() > Max.getz()) return;
- }
-
- setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0);
// TODO: implement NURBS renderer
-#endif
}
void drawSphere::P(triple& t, double x, double y, double z)
@@ -910,41 +885,39 @@ bool drawTriangles::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-void drawTriangles::render(double size2, const triple& Min,
- const triple& Max, double perspective,
- bool transparent)
+bool drawTriangles::write(jsfile *out)
{
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
if(invisible)
- return;
-
- if(invisible || ((diffuse.A < 1.0) ^ transparent)) return;
-
- triple m,M;
-
- bbox3 B(this->Min,this->Max);
- B.transform(modelView.T);
+ return true;
+
+ setcolors(nC,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+
+ out->addTriangles(nP,P,nN,N,nC,C,nI,PI,NI,CI,Min,Max);
+#endif
+ return true;
+}
- m=B.Min();
- M=B.Max();
+void drawTriangles::render(double size2, const triple& b,
+ const triple& B, double perspective,
+ bool remesh)
+{
+#ifdef HAVE_LIBGL
+ if(invisible) return;
+
+ transparent=diffuse.A < 1.0;
- if(perspective) {
- const double f=m.getz()*perspective;
- const double F=M.getz()*perspective;
- if((M.getx() < min(f*Min.getx(),F*Min.getx()) ||
- m.getx() > max(f*Max.getx(),F*Max.getx()) ||
- M.gety() < min(f*Min.gety(),F*Min.gety()) ||
- m.gety() > max(f*Max.gety(),F*Max.gety()) ||
- M.getz() < Min.getz() ||
- m.getz() > Max.getz()))
- return;
- } else {
- if((M.getx() < Min.getx() || m.getx() > Max.getx() ||
- M.gety() < Min.gety() || m.gety() > Max.gety() ||
- M.getz() < Min.getz() || m.getz() > Max.getz()))
- return;
+ if(bbox2(Min,Max).offscreen()) { // Fully offscreen
+ R.Onscreen=false;
+ R.data.clear();
+ return;
}
+ if(!remesh && R.Onscreen) { // Fully onscreen; no need to re-render
+ R.append();
+ return;
+ }
+
setcolors(nC,diffuse,emissive,specular,shininess,metallic,fresnel0);
R.queue(nP,P,nN,N,nC,C,nI,PI,NI,CI,transparent);
#endif
diff --git a/graphics/asymptote/drawsurface.h b/graphics/asymptote/drawsurface.h
index 226de59db7..7a8d0b71aa 100644
--- a/graphics/asymptote/drawsurface.h
+++ b/graphics/asymptote/drawsurface.h
@@ -13,9 +13,13 @@
#include "beziercurve.h"
#include "bezierpatch.h"
+namespace run {
+void inverse(double *a, size_t n);
+}
+
namespace camp {
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
void storecolor(GLfloat *colors, int i, const vm::array &pens, int j);
#endif
@@ -36,13 +40,16 @@ protected:
double PRCshininess;
bool invisible;
Interaction interaction;
+ bool billboard;
+ size_t centerIndex;
triple Min,Max;
bool prc;
public:
#ifdef HAVE_GL
- static BezierCurve C;
+ BezierCurve C;
+ bool transparent;
#endif
string wrongsize() {
@@ -50,13 +57,22 @@ public:
string(" array of triples and array of 4 pens required");
}
+ void init() {
+ billboard=interaction == BILLBOARD &&
+ !settings::getSetting<bool>("offscreen");
+ centerIndex=0;
+ }
+
drawSurface(const vm::array& g, size_t ncontrols, triple center,
bool straight, const vm::array&p, double opacity,
- double shininess, double metallic, double fresnel0, double PRCshininess, const vm::array &pens,
+ double shininess, double metallic, double fresnel0,
+ double PRCshininess, const vm::array &pens,
Interaction interaction, bool prc, const string& key="") :
drawElement(key), ncontrols(ncontrols), center(center), straight(straight),
- opacity(opacity), shininess(shininess), metallic(metallic), fresnel0(fresnel0), PRCshininess(PRCshininess),
- interaction(interaction), prc(prc) {
+ opacity(opacity), shininess(shininess), metallic(metallic),
+ fresnel0(fresnel0), PRCshininess(PRCshininess), interaction(interaction),
+ prc(prc) {
+ init();
if(checkArray(&g) != 4 || checkArray(&p) != 3)
reportError(wrongsize());
@@ -81,7 +97,7 @@ public:
size_t nodes=(ncontrols == 16 ? 4 : 3);
size_t size=checkArray(&pens);
if(size > 0) {
- if(size != nodes) reportError("4 vertex pens required");
+ if(size != nodes) reportError("one vertex pen required per node");
colors=new(UseGC) prc::RGBAColour[nodes];
for(size_t i=0; i < nodes; ++i)
colors[i]=rgba(vm::read<camp::pen>(pens,i));
@@ -96,15 +112,14 @@ public:
PRCshininess(s->PRCshininess), invisible(s->invisible),
interaction(s->interaction), prc(s->prc) {
+ init();
if(s->controls) {
controls=new(UseGC) triple[ncontrols];
for(unsigned int i=0; i < ncontrols; ++i)
controls[i]=t*s->controls[i];
} else controls=NULL;
-#ifdef HAVE_GL
center=t*s->center;
-#endif
}
virtual ~drawSurface() {}
@@ -115,7 +130,7 @@ public:
class drawBezierPatch : public drawSurface {
public:
#ifdef HAVE_GL
- static BezierPatch S;
+ BezierPatch S;
#endif
drawBezierPatch(const vm::array& g, triple center, bool straight,
@@ -124,28 +139,33 @@ public:
double PRCshininess, const vm::array &pens,
Interaction interaction, bool prc) :
drawSurface(g,16,center,straight,p,opacity,
- shininess,metallic,fresnel0,PRCshininess,pens,interaction,prc) {}
+ shininess,metallic,fresnel0,PRCshininess,pens,interaction,prc) {}
drawBezierPatch(const double* t, const drawBezierPatch *s) :
- drawSurface(t,s) {
- }
+ drawSurface(t,s) {}
void bounds(const double* t, bbox3& b);
void ratio(const double* t, pair &b, double (*m)(double, double),
double fuzz, bool &first);
+ void meshinit() {
+ if(billboard)
+ centerIndex=centerindex(center);
+ }
+
bool write(prcfile *out, unsigned int *, double, groupsmap&);
+ bool write(jsfile *out);
- void render(double, const triple& Min, const triple& Max,
- double perspective, bool transparent);
+ void render(double, const triple& b, const triple& B,
+ double perspective, bool remesh);
drawElement *transformed(const double* t);
};
class drawBezierTriangle : public drawSurface {
public:
#ifdef HAVE_GL
- static BezierTriangle S;
+ BezierTriangle S;
#endif
drawBezierTriangle(const vm::array& g, triple center, bool straight,
@@ -157,18 +177,23 @@ public:
PRCshininess,pens,interaction,prc) {}
drawBezierTriangle(const double* t, const drawBezierTriangle *s) :
- drawSurface(t,s) {
- }
+ drawSurface(t,s) {}
void bounds(const double* t, bbox3& b);
void ratio(const double* t, pair &b, double (*m)(double, double),
double fuzz, bool &first);
+ void meshinit() {
+ if(billboard)
+ centerIndex=centerindex(center);
+ }
+
bool write(prcfile *out, unsigned int *, double, groupsmap&);
+ bool write(jsfile *out);
- void render(double, const triple& Min, const triple& Max,
- double perspective, bool transparent);
+ void render(double, const triple& b, const triple& B,
+ double perspective, bool remesh);
drawElement *transformed(const double* t);
};
@@ -192,7 +217,7 @@ protected:
triple Min,Max;
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
GLfloat *colors;
GLfloat *Controls;
GLfloat *uKnots;
@@ -260,7 +285,7 @@ public:
emissive=rgba(vm::read<camp::pen>(p,1));
specular=rgba(vm::read<camp::pen>(p,2));
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
Controls=NULL;
int size=checkArray(&pens);
if(size > 0) {
@@ -287,7 +312,7 @@ public:
for(unsigned int i=0; i < n; ++i)
controls[i]=t*s->controls[i];
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
Controls=NULL;
colors=s->colors;
#endif
@@ -305,8 +330,8 @@ public:
void ratio(const double* t, pair &b, double (*m)(double, double), double,
bool &first);
- void render(double size2, const triple& Min, const triple& Max,
- double perspective, bool transparent);
+ void render(double size2, const triple& b, const triple& B,
+ double perspective, bool remesh);
drawElement *transformed(const double* t);
};
@@ -454,6 +479,7 @@ class drawBaseTriangles : public drawElement {
protected:
#ifdef HAVE_GL
Triangles R;
+ bool transparent;
#endif
size_t nP;
@@ -461,6 +487,7 @@ protected:
size_t nN;
triple* N;
size_t nI;
+ size_t Ni;
uint32_t (*PI)[3];
uint32_t (*NI)[3];
@@ -496,24 +523,29 @@ public:
for(size_t i=0; i < nN; ++i)
N[i]=vm::read<triple>(n,i);
- if(checkArray(&ni) != nI)
- reportError("Index arrays have different lengths");
- NI=new(UseGC) uint32_t[nI][3];
- for(size_t i=0; i < nI; ++i) {
- vm::array *nii=vm::read<vm::array*>(ni,i);
- if(checkArray(nii) != 3) reportError(wrongsize);
- uint32_t *NIi=NI[i];
- for(size_t j=0; j < 3; ++j) {
- size_t index=unsignedcast(vm::read<Int>(nii,j));
- if(index >= nN) reportError(outofrange);
- NIi[j]=index;
+ Ni=checkArray(&ni);
+ if(Ni == 0 && nN == nP)
+ NI=PI;
+ else {
+ if(Ni != nI)
+ reportError("Index arrays have different lengths");
+ NI=new(UseGC) uint32_t[nI][3];
+ for(size_t i=0; i < nI; ++i) {
+ vm::array *nii=vm::read<vm::array*>(ni,i);
+ if(checkArray(nii) != 3) reportError(wrongsize);
+ uint32_t *NIi=NI[i];
+ for(size_t j=0; j < 3; ++j) {
+ size_t index=unsignedcast(vm::read<Int>(nii,j));
+ if(index >= nN) reportError(outofrange);
+ NIi[j]=index;
+ }
}
}
- }
+ } else Ni=0;
}
drawBaseTriangles(const double* t, const drawBaseTriangles *s) :
- drawElement(s->KEY), nP(s->nP), nN(s->nN), nI(s->nI) {
+ drawElement(s->KEY), nP(s->nP), nN(s->nN), nI(s->nI), Ni(s->Ni) {
P=new(UseGC) triple[nP];
for(size_t i=0; i < nP; i++)
P[i]=t*s->P[i];
@@ -528,15 +560,28 @@ public:
if(nN) {
N=new(UseGC) triple[nN];
- for(size_t i=0; i < nN; i++)
- N[i]=transformNormal(t,s->N[i]);
-
- NI=new(UseGC) uint32_t[nI][3];
- for(size_t i=0; i < nI; ++i) {
- uint32_t *NIi=NI[i];
- uint32_t *sNIi=s->NI[i];
- for(size_t j=0; j < 3; ++j)
- NIi[j]=sNIi[j];
+ if(t == NULL) {
+ for(size_t i=0; i < nN; i++)
+ N[i]=s->N[i];
+ } else {
+ double T[]={t[0],t[1],t[2],
+ t[4],t[5],t[6],
+ t[8],t[9],t[10]};
+ run::inverse(T,3);
+ for(size_t i=0; i < nN; i++)
+ N[i]=unit(Transform3(s->N[i],T));
+ }
+
+ if(Ni == 0) {
+ NI=PI;
+ } else {
+ NI=new(UseGC) uint32_t[nI][3];
+ for(size_t i=0; i < nI; ++i) {
+ uint32_t *NIi=NI[i];
+ uint32_t *sNIi=s->NI[i];
+ for(size_t j=0; j < 3; ++j)
+ NIi[j]=sNIi[j];
+ }
}
}
}
@@ -559,6 +604,7 @@ class drawTriangles : public drawBaseTriangles {
size_t nC;
prc::RGBAColour*C;
uint32_t (*CI)[3];
+ size_t Ci;
// Asymptote material data
prc::RGBAColour diffuse;
@@ -597,17 +643,22 @@ public:
size_t nI=checkArray(&vi);
- if(checkArray(&ci) != nI)
- reportError("Index arrays have different lengths");
- CI=new(UseGC) uint32_t[nI][3];
- for(size_t i=0; i < nI; ++i) {
- vm::array *cii=vm::read<vm::array*>(ci,i);
- if(checkArray(cii) != 3) reportError(wrongsize);
- uint32_t *CIi=CI[i];
- for(size_t j=0; j < 3; ++j) {
- size_t index=unsignedcast(vm::read<Int>(cii,j));
- if(index >= nC) reportError(outofrange);
- CIi[j]=index;
+ Ci=checkArray(&ci);
+ if(Ci == 0 && nC == nP)
+ CI=PI;
+ else {
+ if(Ci != nI)
+ reportError("Index arrays have different lengths");
+ CI=new(UseGC) uint32_t[nI][3];
+ for(size_t i=0; i < nI; ++i) {
+ vm::array *cii=vm::read<vm::array*>(ci,i);
+ if(checkArray(cii) != 3) reportError(wrongsize);
+ uint32_t *CIi=CI[i];
+ for(size_t j=0; j < 3; ++j) {
+ size_t index=unsignedcast(vm::read<Int>(cii,j));
+ if(index >= nC) reportError(outofrange);
+ CIi[j]=index;
+ }
}
}
} else {
@@ -620,8 +671,8 @@ public:
drawBaseTriangles(t,s), nC(s->nC),
diffuse(s->diffuse), emissive(s->emissive),
specular(s->specular), opacity(s->opacity), shininess(s->shininess),
- metallic(s->metallic), fresnel0(s->fresnel0), PRCshininess(s->PRCshininess),
- invisible(s->invisible) {
+ metallic(s->metallic), fresnel0(s->fresnel0),
+ PRCshininess(s->PRCshininess), invisible(s->invisible) {
if(nC) {
C=new(UseGC) prc::RGBAColour[nC];
@@ -640,10 +691,11 @@ public:
virtual ~drawTriangles() {}
- void render(double size2, const triple& Min, const triple& Max,
- double perspective, bool transparent);
+ void render(double size2, const triple& b, const triple& B,
+ double perspective, bool remesh);
bool write(prcfile *out, unsigned int *, double, groupsmap&);
+ bool write(jsfile *out);
drawElement *transformed(const double* t) {
return new drawTriangles(t,this);
diff --git a/graphics/asymptote/examples/Klein.asy b/graphics/asymptote/examples/Klein.asy
index 99914d9043..a5e7418fe6 100644
--- a/graphics/asymptote/examples/Klein.asy
+++ b/graphics/asymptote/examples/Klein.asy
@@ -2,8 +2,6 @@ import graph3;
size(469pt);
-viewportmargin=0;
-
currentprojection=perspective(
camera=(25.0851928432063,-30.3337528952473,19.3728775115443),
up=Z,
diff --git a/graphics/asymptote/examples/Sierpinski.asy b/graphics/asymptote/examples/Sierpinski.asy
index c0ff04971d..1b9fb5555b 100644
--- a/graphics/asymptote/examples/Sierpinski.asy
+++ b/graphics/asymptote/examples/Sierpinski.asy
@@ -14,4 +14,4 @@ void Sierpinski(pair A, real s, int q, bool top=true)
}
}
-Sierpinski((0,1),1,9);
+Sierpinski((0,1),1,5);
diff --git a/graphics/asymptote/examples/SierpinskiSponge.asy b/graphics/asymptote/examples/SierpinskiSponge.asy
index c398aa511c..deaf7c1dec 100644
--- a/graphics/asymptote/examples/SierpinskiSponge.asy
+++ b/graphics/asymptote/examples/SierpinskiSponge.asy
@@ -82,18 +82,15 @@ for(int n3=0; n3 < 20; ++n3) {
for(int n2=0; n2 < 20; ++n2) {
surface s1;
for(int n1=0; n1 < 20; ++n1) {
- for(int k=0; k < 6; ++k){
- transform3 T=scale3(u)*shift(M[n1])*scale3(0.5);
+ for(int k=0; k < 6; ++k) {
if(Sponge3[n3][n2][n1][k] > 0) {
- s1.append(T*Squares[k]);
+ s1.append(scale3(u)*shift(M[n1])*scale3(0.5)*Squares[k]);
}
}
}
- transform3 T=scale3(u)*shift(M[n2])*scale3(0.5);
- s2.append(T*s1);
+ s2.append(scale3(u)*shift(M[n2])*scale3(0.5)*s1);
}
- transform3 T=scale3(u)*shift(M[n3])*scale3(0.5);
- s3.append(T*s2);
+ s3.append(scale3(u)*shift(M[n3])*scale3(0.5)*s2);
}
s3.colors(palette(s3.map(abs),Rainbow()));
draw(s3);
diff --git a/graphics/asymptote/examples/logo3.asy b/graphics/asymptote/examples/logo3.asy
index 93b5a331e9..c7947f1c41 100644
--- a/graphics/asymptote/examples/logo3.asy
+++ b/graphics/asymptote/examples/logo3.asy
@@ -1,9 +1,11 @@
import three;
-size(560,320,IgnoreAspect);
+//size(105,50,IgnoreAspect);
+size(560,320,IgnoreAspect); // Fullsize
size3(140,80,15);
currentprojection=perspective(-2,20,10,up=Y);
currentlight=White;
+viewportmargin=(0,10);
real a=-0.4;
real b=0.95;
diff --git a/graphics/asymptote/examples/pdb.asy b/graphics/asymptote/examples/pdb.asy
index 41cd29faaf..43b771fdd0 100644
--- a/graphics/asymptote/examples/pdb.asy
+++ b/graphics/asymptote/examples/pdb.asy
@@ -10,7 +10,7 @@ currentlight=White;
defaultrender.merge=true; // Fast low-quality rendering
//defaultrender.merge=false; // Slow high-quality rendering
bool pixel=false; // Set to true to draw dots as pixels.
-real width=10;
+real width=6;
size(200);
currentprojection=perspective(30,30,15);
@@ -161,4 +161,4 @@ if(!error(input(viewfilename,check=false)))
options="3Dviews="+viewfilename;
shipout(prefix,options=options);
-
+currentpicture.erase();
diff --git a/graphics/asymptote/examples/shellmethod.asy b/graphics/asymptote/examples/shellmethod.asy
index c8e541f2a6..98f88f624f 100644
--- a/graphics/asymptote/examples/shellmethod.asy
+++ b/graphics/asymptote/examples/shellmethod.asy
@@ -2,7 +2,7 @@ import graph3;
import solids;
size(400);
-currentprojection=perspective(0,-1,30,up=Y);
+currentprojection=perspective(2,3,30,up=Y);
currentlight=light(gray(0.75),(0.25,-0.25,1),(0,1,0));
pen color=green;
diff --git a/graphics/asymptote/examples/triangles.asy b/graphics/asymptote/examples/triangles.asy
index fc62c58c12..da1b93d28b 100644
--- a/graphics/asymptote/examples/triangles.asy
+++ b/graphics/asymptote/examples/triangles.asy
@@ -1,12 +1,14 @@
import three;
size(10cm);
+currentlight=Headlamp;
+
triple[] v={O,X,X+Y,Y};
triple[] n={Z,X};
int[][] vi={{0,1,2},{2,3,0}};
-int[][] ni={{0,0,0},{1,1,1}};
+int[][] ni={{1,0,1},{1,1,1}};
// Adobe Reader exhibits a PRC rendering bug for opacities:
pen[] p={red+opacity(0.5),green+opacity(0.5),blue+opacity(0.5),
diff --git a/graphics/asymptote/examples/vertexshading.asy b/graphics/asymptote/examples/vertexshading.asy
index a5555d66f7..fd5e9b2df8 100644
--- a/graphics/asymptote/examples/vertexshading.asy
+++ b/graphics/asymptote/examples/vertexshading.asy
@@ -4,9 +4,12 @@ size(200);
currentprojection=perspective(4,5,5);
+//draw(shift(2Z)*surface(O--X--Y--cycle),blue);
+
draw(surface(unitcircle3,new pen[] {red,green,blue,black}));
draw(surface(shift(Z)*unitsquare3,
- new pen[] {red,green+opacity(0.5),blue,black}));
+ new pen[] {red,green+opacity(0.5),blue,black}),
+ prc() ? nolight : currentlight);
draw(surface(shift(X)*((0,0,0)..controls (1,0,0) and (2,0,0)..(3,0,0)..
controls (2.5,sqrt(3)/2,0) and (2,sqrt(3),0)..
(1.5,3*sqrt(3)/2,0)..
diff --git a/graphics/asymptote/examples/washermethod.asy b/graphics/asymptote/examples/washermethod.asy
index c3177aa111..a61c37e5e5 100644
--- a/graphics/asymptote/examples/washermethod.asy
+++ b/graphics/asymptote/examples/washermethod.asy
@@ -18,7 +18,7 @@ real x2=1.7787;
real x3=1.8043;
path[] p={graph(F,x1,x2,Spline),
- graph(F,0.7,x1,Spline)--graph(F,x2,x3,Spline),
+ graph(F,0.7,x1,Spline)--graph(F,x2,x3,Spline)&cycle,
graph(F,0,0.7,Spline)--graph(F,x3,2,Spline)};
pen[] pn=new pen[] {color1,color2,color1};
diff --git a/graphics/asymptote/fileio.h b/graphics/asymptote/fileio.h
index d5e78cec29..1341d66b2d 100644
--- a/graphics/asymptote/fileio.h
+++ b/graphics/asymptote/fileio.h
@@ -117,7 +117,7 @@ public:
file(const string& name, bool check=true, Mode type=NOMODE, bool binary=false,
bool closed=false) :
name(name), check(check), type(type), linemode(false), csvmode(false),
- singlereal(false), singleint(true), signedint(true),
+ wordmode(false), singlereal(false), singleint(true), signedint(true),
closed(closed), standard(name.empty()),
binary(binary), nullfield(false), whitespace("") {dimension();}
@@ -423,7 +423,8 @@ public:
ifile(name,comment,true,UPDATE,std::ios::in | std::ios::out) {}
Int precision(Int p) {
- return p == 0 ? stream->precision() : stream->precision(p);
+ return p == 0 ? stream->precision(settings::getSetting<Int>("digits")) :
+ stream->precision(p);
}
void flush() {if(fstream) fstream->flush();}
@@ -463,6 +464,7 @@ public:
} else {
name=outpath(name);
stream=fstream=new std::ofstream(name.c_str(),mode | std::ios::trunc);
+ stream->precision(settings::getSetting<Int>("digits"));
index=processData().ofile.add(fstream);
Check();
}
@@ -483,7 +485,8 @@ public:
}
void clear() {stream->clear();}
Int precision(Int p) {
- return p == 0 ? stream->precision() : stream->precision(p);
+ return p == 0 ? stream->precision(settings::getSetting<Int>("digits")) :
+ stream->precision(p);
}
void flush() {stream->flush();}
diff --git a/graphics/asymptote/gl.js b/graphics/asymptote/gl.js
new file mode 120000
index 0000000000..237a568b54
--- /dev/null
+++ b/graphics/asymptote/gl.js
@@ -0,0 +1 @@
+webgl/gl.js \ No newline at end of file
diff --git a/graphics/asymptote/glew.c b/graphics/asymptote/glew.c
index bea419ea8a..4bdea46b60 100644
--- a/graphics/asymptote/glew.c
+++ b/graphics/asymptote/glew.c
@@ -2,6 +2,10 @@
#include "config.h"
#endif
+#ifdef __MSDOS__
+#define _WIN32
+#endif
+
#ifdef HAVE_LIBGL
#include "GL/glew.c"
#endif /* HAVE_LIBGL */
diff --git a/graphics/asymptote/glrender.cc b/graphics/asymptote/glrender.cc
index d864ed34de..d23307c0c9 100644
--- a/graphics/asymptote/glrender.cc
+++ b/graphics/asymptote/glrender.cc
@@ -1,6 +1,6 @@
/*****
* glrender.cc
- * John Bowman and Orest Shardt
+ * John Bowman, Orest Shardt, and Supakorn "Jamie" Rassameemasmuang
* Render 3D Bezier paths and surfaces.
*****/
@@ -13,7 +13,6 @@
#include <cstring>
#include <sys/time.h>
-
#include "common.h"
#include "locate.h"
#include "seconds.h"
@@ -21,6 +20,12 @@
#include "bezierpatch.h"
#include "beziercurve.h"
+#include "picture.h"
+#include "bbox3.h"
+#include "drawimage.h"
+#include "interact.h"
+#include "tr.h"
+
#ifdef HAVE_GL
#ifdef HAVE_LIBGLUT
@@ -36,48 +41,60 @@
#define GLUT_BUILDING_LIB
#endif // HAVE_LIBGLUT
-#include "picture.h"
-#include "arcball.h"
-#include "bbox3.h"
-#include "drawimage.h"
-#include "interact.h"
-#include "tr.h"
-
#ifdef HAVE_LIBGLUT
#ifdef FREEGLUT
#include <GL/freeglut_ext.h>
#endif
#endif
-#include <glm/glm.hpp>
-#include <glm/gtc/matrix_transform.hpp>
-#include <glm/gtc/type_ptr.hpp>
-
#include "shaders.h"
-#include "material.h"
#ifdef HAVE_LIBOPENIMAGEIO
#include <OpenImageIO/imageio.h>
#endif
using settings::locateFile;
+using utils::seconds;
+
+namespace camp {
+Billboard BB;
+
+GLint pixelShader;
+GLint noNormalShader;
+GLint materialShader;
+GLint colorShader;
+GLint transparentShader;
+
+vertexBuffer material0Data;
+vertexBuffer material1Data;
+vertexBuffer materialData;
+vertexBuffer colorData;
+vertexBuffer transparentData;
+vertexBuffer triangleData;
+
+const size_t Nbuffer=10000;
+const size_t nbuffer=1000;
+}
+
+#endif /* HAVE_GL */
+
+#ifdef HAVE_LIBGLM
using camp::Material;
using camp::Maxmaterials;
using camp::Nmaterials;
using camp::nmaterials;
-using utils::seconds;
+using camp::MaterialMap;
namespace camp {
-billboard BB;
-GLint materialShader;
-GLint colorShader;
-GLint noNormalShader;
-GLint pixelShader;
+mem::vector<Material> material;
+MaterialMap materialMap;
+size_t materialIndex;
size_t Maxmaterials;
size_t Nmaterials=1;
size_t nmaterials=48;
}
+
namespace gl {
bool outlinemode=false;
@@ -85,7 +102,7 @@ bool glthread=false;
bool initialize=true;
GLint Maxvertices;
-Int maxvertices;
+size_t maxvertices;
using camp::picture;
using camp::drawRawImage;
@@ -104,27 +121,9 @@ int Fitscreen;
bool queueExport=false;
bool readyAfterExport=false;
-
-#ifdef HAVE_LIBGLUT
-timeval lasttime;
-timeval lastframetime;
-int oldWidth,oldHeight;
-
-bool Xspin,Yspin,Zspin;
-bool Animate;
-bool Step;
bool remesh;
-bool forceRemesh=false;
-bool queueScreen=false;
-
-int x0,y0;
-string Action;
-
-double lastangle;
-Arcball arcball;
-int window;
-#endif
+int Mode;
double Aspect;
bool View;
@@ -132,8 +131,8 @@ int Oldpid;
string Prefix;
const picture* Picture;
string Format;
-int Width,Height;
int fullWidth,fullHeight;
+int Width,Height;
double oWidth,oHeight;
int screenWidth,screenHeight;
int maxWidth;
@@ -141,10 +140,6 @@ int maxHeight;
int maxTileWidth;
int maxTileHeight;
-double T[16];
-
-int Mode;
-
double Angle;
bool orthographic;
double H;
@@ -156,9 +151,12 @@ double Xmin,Xmax;
double Ymin,Ymax;
pair Shift;
+pair Margin;
double X,Y;
+int x0,y0;
double cx,cy;
double Xfactor,Yfactor;
+double ArcballFactor;
static const double pi=acos(-1.0);
static const double degrees=180.0/pi;
@@ -177,107 +175,33 @@ double Zoom;
double Zoom0;
double lastzoom;
+GLint lastshader=-1;
+
using glm::dvec3;
+using glm::dmat3;
+using glm::mat3;
using glm::mat4;
using glm::dmat4;
using glm::value_ptr;
using glm::translate;
+mat3 normMat;
+dmat3 dnormMat=dmat3();
+
mat4 projViewMat;
mat4 viewMat;
-mat4 normMat;
dmat4 dprojMat;
+dmat4 dprojViewMat;
dmat4 dviewMat;
dmat4 drotateMat;
-using utils::statistics;
-statistics S;
+const double *dprojView;
+double BBT[9];
-ModelView modelView;
GLuint ubo;
-#ifdef HAVE_LIBOPENIMAGEIO
-GLuint envMapBuf;
-
-GLuint initHDR() {
- GLuint tex;
- glGenTextures(1, &tex);
-
- auto imagein = OIIO::ImageInput::open(locateFile("res/studio006.hdr").c_str());
- OIIO::ImageSpec const& imspec = imagein->spec();
-
- // uses GL_TEXTURE1 for now.
- glActiveTexture(GL_TEXTURE1);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glBindTexture(GL_TEXTURE_2D, tex);
- std::vector<float> pixels(imspec.width*imspec.height*3);
- imagein->read_image(pixels.data());
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imspec.width, imspec.height, 0,
- GL_RGB, GL_FLOAT, pixels.data());
-
- glGenerateMipmap(GL_TEXTURE_2D);
- imagein->close();
-
- glActiveTexture(GL_TEXTURE0);
- return tex;
-}
-
-#endif
-void updateModelViewData()
-{
- // Like Fortran, OpenGL uses transposed (column-major) format!
- dmat4 MV=glm::transpose(dviewMat);
- dmat4 MVinv=glm::inverse(MV);
-
- normMat=mat4(MVinv);
-
- double* T=value_ptr(MV);
- double* Tinv=value_ptr(MVinv);
-
- for(int j=0; j < 16; ++j) {
- modelView.T[j]=T[j];
- modelView.Tinv[j]=Tinv[j];
- }
-}
-
-
-GLint shaderProg,shaderProgColor;
-
-double *Rotate;
-void *glrenderWrapper(void *a);
-
-#ifdef HAVE_LIBOSMESA
-OSMesaContext ctx;
-unsigned char *osmesa_buffer;
-#endif
-
-#ifdef HAVE_PTHREAD
-pthread_t mainthread;
-
-pthread_cond_t initSignal=PTHREAD_COND_INITIALIZER;
-pthread_mutex_t initLock=PTHREAD_MUTEX_INITIALIZER;
-
-pthread_cond_t readySignal=PTHREAD_COND_INITIALIZER;
-pthread_mutex_t readyLock=PTHREAD_MUTEX_INITIALIZER;
-
-void endwait(pthread_cond_t& signal, pthread_mutex_t& lock)
-{
- pthread_mutex_lock(&lock);
- pthread_cond_signal(&signal);
- pthread_mutex_unlock(&lock);
-}
-void wait(pthread_cond_t& signal, pthread_mutex_t& lock)
-{
- pthread_mutex_lock(&lock);
- pthread_cond_signal(&signal);
- pthread_cond_wait(&signal,&lock);
- pthread_mutex_unlock(&lock);
-}
-#endif
+unsigned int framecount;
template<class T>
inline T min(T a, T b)
@@ -339,18 +263,25 @@ void setDimensions(int Width, int Height, double X, double Y)
}
}
+void updateProjection()
+{
+ dprojViewMat=dprojMat*dviewMat;
+ projViewMat=mat4(dprojViewMat);
+ dprojView=value_ptr(dprojViewMat);
+}
+
void frustum(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top, GLdouble nearVal, GLdouble farVal)
{
dprojMat=glm::frustum(left,right,bottom,top,nearVal,farVal);
- projViewMat=mat4(dprojMat*dviewMat);
+ updateProjection();
}
void ortho(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top, GLdouble nearVal, GLdouble farVal)
{
dprojMat=glm::ortho(left,right,bottom,top,nearVal,farVal);
- projViewMat=mat4(dprojMat*dviewMat);
+ updateProjection();
}
void setProjection()
@@ -358,13 +289,135 @@ void setProjection()
setDimensions(Width,Height,X,Y);
if(orthographic) ortho(xmin,xmax,ymin,ymax,-zmax,-zmin);
else frustum(xmin,xmax,ymin,ymax,-zmax,-zmin);
+}
+
+void updateModelViewData()
+{
+ // Like Fortran, OpenGL uses transposed (column-major) format!
+ dnormMat=dmat3(glm::inverse(dviewMat));
+ double *T=value_ptr(dnormMat);
+ for(size_t i=0; i < 9; ++i)
+ BBT[i]=T[i];
+ normMat=mat3(dnormMat);
+}
+
+bool Xspin,Yspin,Zspin;
+bool Animate;
+bool Step;
+
+#ifdef HAVE_LIBGLUT
+void idle()
+{
+ glutIdleFunc(NULL);
+ Xspin=Yspin=Zspin=Animate=Step=false;
+}
+#endif
+
+void home(bool webgl=false)
+{
+ X=Y=cx=cy=0.0;
+#ifdef HAVE_GL
+#ifdef HAVE_LIBGLUT
+ if(!webgl && !getSetting<bool>("offscreen"))
+ idle();
+#endif
+#endif
+ dviewMat=dmat4(1.0);
+ drotateMat=dmat4(1.0);
+ updateModelViewData();
+
+ remesh=true;
+ lastzoom=Zoom=Zoom0;
+ setDimensions(Width,Height,0,0);
+ framecount=0;
+}
+
+#ifdef HAVE_GL
+
+double T[16];
+
#ifdef HAVE_LIBGLUT
- double arcballRadius=getSetting<double>("arcballradius");
- arcball.set_params(vec2(0.5*Width,0.5*Height),arcballRadius*Zoom);
+timeval lasttime;
+timeval lastframetime;
+int oldWidth,oldHeight;
+
+bool forceRemesh=false;
+
+bool queueScreen=false;
+
+string Action;
+
+double lastangle;
+int window;
#endif
+
+using utils::statistics;
+statistics S;
+
+#ifdef HAVE_LIBOPENIMAGEIO
+GLuint envMapBuf;
+
+GLuint initHDR() {
+ GLuint tex;
+ glGenTextures(1, &tex);
+
+ auto imagein = OIIO::ImageInput::open(locateFile("res/studio006.hdr").c_str());
+ OIIO::ImageSpec const& imspec = imagein->spec();
+
+ // uses GL_TEXTURE1 for now.
+ glActiveTexture(GL_TEXTURE1);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glBindTexture(GL_TEXTURE_2D, tex);
+ std::vector<float> pixels(imspec.width*imspec.height*3);
+ imagein->read_image(pixels.data());
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imspec.width, imspec.height, 0,
+ GL_RGB, GL_FLOAT, pixels.data());
+
+ glGenerateMipmap(GL_TEXTURE_2D);
+ imagein->close();
+
+ glActiveTexture(GL_TEXTURE0);
+ return tex;
}
+#endif
+GLint shaderProg,shaderProgColor;
+
+void *glrenderWrapper(void *a);
+
+#ifdef HAVE_LIBOSMESA
+OSMesaContext ctx;
+unsigned char *osmesa_buffer;
+#endif
+
+#ifdef HAVE_PTHREAD
+pthread_t mainthread;
+
+pthread_cond_t initSignal=PTHREAD_COND_INITIALIZER;
+pthread_mutex_t initLock=PTHREAD_MUTEX_INITIALIZER;
+
+pthread_cond_t readySignal=PTHREAD_COND_INITIALIZER;
+pthread_mutex_t readyLock=PTHREAD_MUTEX_INITIALIZER;
+
+void endwait(pthread_cond_t& signal, pthread_mutex_t& lock)
+{
+ pthread_mutex_lock(&lock);
+ pthread_cond_signal(&signal);
+ pthread_mutex_unlock(&lock);
+}
+void wait(pthread_cond_t& signal, pthread_mutex_t& lock)
+{
+ pthread_mutex_lock(&lock);
+ pthread_cond_signal(&signal);
+ pthread_cond_wait(&signal,&lock);
+ pthread_mutex_unlock(&lock);
+}
+#endif
+
void drawscene(int Width, int Height)
{
#ifdef HAVE_PTHREAD
@@ -384,23 +437,20 @@ void drawscene(int Width, int Height)
double size2=hypot(Width,Height);
- if(remesh) {
- camp::BezierPatch::clear();
- camp::BezierPatch::Clear();
- camp::BezierPatch::tClear();
- camp::BezierCurve::clear();
- camp::Pixel::clear();
+ if(forceRemesh) {
+ remesh=true;
+ forceRemesh=false;
}
- // Render opaque objects
- Picture->render(size2,m,M,perspective,false,remesh);
+ camp::clearBuffers();
+
+ if(remesh)
+ camp::drawElement::center.clear();
- // Enable transparency
- glDepthMask(GL_FALSE);
+ Picture->render(size2,m,M,perspective,remesh);
- // Render transparent objects
- Picture->render(size2,m,M,perspective,true,remesh);
- glDepthMask(GL_TRUE);
+ if(!forceRemesh)
+ remesh=false;
}
// Return x divided by y rounded up to the nearest integer.
@@ -479,38 +529,6 @@ void Export()
#endif
}
-#ifdef HAVE_LIBGLUT
-void idle()
-{
- glutIdleFunc(NULL);
- Xspin=Yspin=Zspin=Animate=Step=false;
-}
-#endif
-
-void home()
-{
- X=Y=cx=cy=0.0;
-#ifdef HAVE_LIBGLUT
- if(!getSetting<bool>("offscreen")) {
- idle();
- arcball.init();
- }
-#endif
- viewMat=mat4(1.0f);
- normMat=mat4(1.0f);
-
- dviewMat=dmat4(1.0);
- drotateMat=dmat4(1.0);
-
- Rotate=value_ptr(drotateMat);
- updateModelViewData();
-
- remesh=true;
- lastzoom=Zoom=Zoom0;
- setDimensions(Width,Height,0,0);
- glClearColor(Background[0],Background[1],Background[2],Background[3]);
-}
-
void nodisplay()
{
}
@@ -567,19 +585,20 @@ void mode()
{
remesh=true;
switch(Mode) {
- case 0: // wireframe -> regular
+ case 0: // regular
outlinemode=false;
nlights=nlights0;
+ lastshader=-1;
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
++Mode;
break;
- case 1: // regular -> outline
+ case 1: // outline
outlinemode=true;
nlights=0;
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
++Mode;
break;
- case 2: // outline -> wireframe
+ case 2: // wireframe
outlinemode=false;
Mode=0;
break;
@@ -736,16 +755,20 @@ void display()
if(maxvertices == 0) maxvertices=Maxvertices;
bool fps=settings::verbose > 2;
- if(fps) seconds();
drawscene(Width,Height);
if(fps) {
- glFinish();
- double s=seconds();
- if(s > 0.0) {
- double rate=1.0/s;
- S.add(rate);
- cout << "FPS=" << rate << "\t" << S.mean() << " +/- " << S.stdev() << endl;
+ if(framecount < 10) // Measure steady-state framerate
+ seconds();
+ else {
+ double s=seconds();
+ if(s > 0.0) {
+ double rate=1.0/s;
+ S.add(rate);
+ cout << "FPS=" << rate << "\t" << S.mean() << " +/- " << S.stdev()
+ << endl;
+ }
}
+ ++framecount;
}
glutSwapBuffers();
@@ -784,12 +807,14 @@ void update()
Animate=getSetting<bool>("autoplay");
glutShowWindow();
if(Zoom != lastzoom) remesh=true;
+
lastzoom=Zoom;
double cz=0.5*(zmin+zmax);
dviewMat=translate(translate(dmat4(1.0),dvec3(cx,cy,cz))*drotateMat,
dvec3(0,0,-cz));
viewMat=mat4(dviewMat);
+
setProjection();
updateModelViewData();
@@ -836,35 +861,31 @@ void reshape(int width, int height)
void shift(int x, int y)
{
- if(x > 0 && y > 0) {
- double Zoominv=1.0/Zoom;
- X += (x-x0)*Zoominv;
- Y += (y0-y)*Zoominv;
- x0=x; y0=y;
- update();
- }
+ double Zoominv=1.0/Zoom;
+ X += (x-x0)*Zoominv;
+ Y += (y0-y)*Zoominv;
+ x0=x; y0=y;
+ update();
}
void pan(int x, int y)
{
- if(x > 0 && y > 0) {
- if(orthographic) {
- double Zoominv=1.0/Zoom;
- X += (x-x0)*Zoominv;
- Y += (y0-y)*Zoominv;
- } else {
- cx += (x-x0)*(xmax-xmin)/Width;
- cy += (y0-y)*(ymax-ymin)/Height;
- }
- x0=x; y0=y;
- update();
+ if(orthographic) {
+ double Zoominv=1.0/Zoom;
+ X += (x-x0)*Zoominv;
+ Y += (y0-y)*Zoominv;
+ } else {
+ cx += (x-x0)*(xmax-xmin)/Width;
+ cy += (y0-y)*(ymax-ymin)/Height;
}
+ x0=x; y0=y;
+ update();
}
void capzoom()
{
static double maxzoom=sqrt(DBL_MAX);
- static double minzoom=1/maxzoom;
+ static double minzoom=1.0/maxzoom;
if(Zoom <= minzoom) Zoom=minzoom;
if(Zoom >= maxzoom) Zoom=maxzoom;
@@ -875,19 +896,17 @@ void capzoom()
void zoom(int x, int y)
{
if(ignorezoom) {ignorezoom=false; y0=y; return;}
- if(x > 0 && y > 0) {
- double zoomFactor=getSetting<double>("zoomfactor");
- if(zoomFactor > 0.0) {
- double zoomStep=getSetting<double>("zoomstep");
- const double limit=log(0.1*DBL_MAX)/log(zoomFactor);
- double s=zoomStep*(y0-y);
- if(fabs(s) < limit) {
- Zoom *= pow(zoomFactor,s);
- capzoom();
- y0=y;
- setProjection();
- glutPostRedisplay();
- }
+ double zoomFactor=getSetting<double>("zoomfactor");
+ if(zoomFactor > 0.0) {
+ double zoomStep=getSetting<double>("zoomstep");
+ const double limit=log(0.1*DBL_MAX)/log(zoomFactor);
+ double stepPower=zoomStep*(y0-y);
+ if(fabs(stepPower) < limit) {
+ Zoom *= pow(zoomFactor,stepPower);
+ capzoom();
+ y0=y;
+ setProjection();
+ glutPostRedisplay();
}
}
}
@@ -906,20 +925,48 @@ void mousewheel(int wheel, int direction, int x, int y)
}
}
+struct arcball {
+ double angle;
+ triple axis;
+
+ arcball(double x0, double y0, double x, double y) {
+ triple v0=norm(x0,y0);
+ triple v1=norm(x,y);
+ double Dot=dot(v0,v1);
+ if(Dot > 1.0) Dot=1.0;
+ else if(Dot < -1.0) Dot=-1.0;
+ angle=acos(Dot);
+ axis=unit(cross(v0,v1));
+ }
+
+ triple norm(double x, double y) {
+ double norm=hypot(x,y);
+ if(norm > 1.0) {
+ double denom=1.0/norm;
+ x *= denom;
+ y *= denom;
+ }
+ return triple(x,y,sqrt(max(1.0-x*x-y*y,0.0)));
+ }
+};
+
+inline double glx(int x) {
+ return 2.0*x/Width-1.0;
+}
+
+inline double gly(int y) {
+ return 1.0-2.0*y/Height;
+}
+
void rotate(int x, int y)
{
- if(x > 0 && y > 0) {
- arcball.mouse_motion(x,Height-y,0,
- Action == "rotateX", // X rotation only
- Action == "rotateY"); // Y rotation only
-
- for(int i=0; i < 4; ++i) {
- const ::vec4& roti=arcball.rot[i];
- int i4=4*i;
- for(int j=0; j < 4; ++j)
- value_ptr(drotateMat)[i4+j]=roti[j];
- }
-
+ if(x != x0 || y != y0) {
+ arcball A(glx(x0),gly(y0),glx(x),gly(y));
+ triple v=A.axis;
+ drotateMat=glm::rotate<double>(2*A.angle/lastzoom*ArcballFactor,
+ glm::dvec3(v.getx(),v.gety(),v.getz()))*
+ drotateMat;
+ x0=x; y0=y;
update();
}
}
@@ -929,24 +976,12 @@ double Degrees(int x, int y)
return atan2(0.5*Height-y-Y,x-0.5*Width-X)*degrees;
}
-void updateArcball()
-{
- Rotate=value_ptr(drotateMat);
- for(int i=0; i < 4; ++i) {
- int i4=4*i;
- ::vec4& roti=arcball.rot[i];
- for(int j=0; j < 4; ++j)
- roti[j]=Rotate[i4+j];
- }
- update();
-}
-
void rotateX(double step)
{
dmat4 tmpRot(1.0);
tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(1,0,0));
drotateMat=tmpRot*drotateMat;
- updateArcball();
+ update();
}
void rotateY(double step)
@@ -954,7 +989,7 @@ void rotateY(double step)
dmat4 tmpRot(1.0);
tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(0,1,0));
drotateMat=tmpRot*drotateMat;
- updateArcball();
+ update();
}
void rotateZ(double step)
@@ -962,16 +997,28 @@ void rotateZ(double step)
dmat4 tmpRot(1.0);
tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(0,0,1));
drotateMat=tmpRot*drotateMat;
- updateArcball();
+ update();
+}
+
+void rotateX(int x, int y)
+{
+ double angle=Degrees(x,y);
+ rotateX(angle-lastangle);
+ lastangle=angle;
+}
+
+void rotateY(int x, int y)
+{
+ double angle=Degrees(x,y);
+ rotateY(angle-lastangle);
+ lastangle=angle;
}
void rotateZ(int x, int y)
{
- if(x > 0 && y > 0) {
- double angle=Degrees(x,y);
- rotateZ(angle-lastangle);
- lastangle=angle;
- }
+ double angle=Degrees(x,y);
+ rotateZ(angle-lastangle);
+ lastangle=angle;
}
#ifndef GLUT_WHEEL_UP
@@ -1061,8 +1108,8 @@ void mouse(int button, int state, int x, int y)
}
if(state == GLUT_DOWN) {
- if(Action == "rotate" || Action == "rotateX" || Action == "rotateY") {
- arcball.mouse_down(x,Height-y);
+ if(Action == "rotate") {
+ x0=x; y0=y;
glutMotionFunc(rotate);
} else if(Action == "shift") {
x0=x; y0=y;
@@ -1073,13 +1120,18 @@ void mouse(int button, int state, int x, int y)
} else if(Action == "zoom" || Action == "zoom/menu") {
y0=y;
glutMotionFunc(zoom);
+ } else if(Action == "rotateX") {
+ lastangle=Degrees(x,y);
+ glutMotionFunc(rotateX);
+ } else if(Action == "rotateY") {
+ lastangle=Degrees(x,y);
+ glutMotionFunc(rotateY);
} else if(Action == "rotateZ") {
lastangle=Degrees(x,y);
glutMotionFunc(rotateZ);
}
} else {
- arcball.mouse_up();
- glutMotionFunc(NULL);
+ glutMotionFunc(NULL);
}
}
@@ -1157,11 +1209,6 @@ void spinz()
}
}
-void write(const char *text, const double *v)
-{
- cout << text << "=(" << v[0] << "," << v[1] << "," << v[2] << ")";
-}
-
void showCamera()
{
projection P=camera();
@@ -1279,6 +1326,8 @@ projection camera(bool user)
double cz=0.5*(zmin+zmax);
+ double *Rotate=value_ptr(drotateMat);
+
if(user) {
for(int i=0; i < 3; ++i) {
double sumCamera=0.0, sumTarget=0.0, sumUp=0.0;
@@ -1313,8 +1362,8 @@ projection camera(bool user)
return projection(orthographic,vCamera,vUp,vTarget,Zoom,
2.0*atan(tan(0.5*Angle)/Zoom)/radians,
- pair(X/Width*lastzoom+Shift.getx(),
- Y/Height*lastzoom+Shift.gety()));
+ pair(X/Width+Shift.getx(),
+ Y/Height+Shift.gety()));
}
void init()
@@ -1335,7 +1384,6 @@ void init()
glutInit(&argc,argv);
screenWidth=glutGet(GLUT_SCREEN_WIDTH);
screenHeight=glutGet(GLUT_SCREEN_HEIGHT);
-
#endif
}
@@ -1378,10 +1426,6 @@ void init_osmesa()
}
#endif // HAVE_LIBOSMESA
}
-
-GLuint vertShader,fragShader;
-GLuint vertShaderCol,fragShaderCol;
-
void initshader()
{
Nlights=max(Nlights,nlights);
@@ -1406,45 +1450,47 @@ void initshader()
std::vector<ShaderfileModePair> shaders;
shaders.push_back(ShaderfileModePair(vs.c_str(),GL_VERTEX_SHADER));
shaders.push_back(ShaderfileModePair(fs.c_str(),GL_FRAGMENT_SHADER));
+ if(orthographic)
+ shaderParams.push_back("ORTHOGRAPHIC");
- camp::noNormalShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
- shaderParams);
-
shaderParams.push_back("WIDTH");
camp::pixelShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
shaderParams);
shaderParams.pop_back();
-
+ camp::noNormalShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
+ shaderParams);
shaderParams.push_back("NORMAL");
camp::materialShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
shaderParams);
-
- shaderParams.push_back("EXPLICIT_COLOR");
+ shaderParams.push_back("COLOR");
camp::colorShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
shaderParams);
+ shaderParams.push_back("TRANSPARENT");
+ camp::transparentShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
+ shaderParams);
}
void deleteshader()
{
- glDeleteProgram(camp::materialShader);
+ glDeleteProgram(camp::transparentShader);
glDeleteProgram(camp::colorShader);
+ glDeleteProgram(camp::materialShader);
+ glDeleteProgram(camp::pixelShader);
glDeleteProgram(camp::noNormalShader);
}
-
+
+#endif /* HAVE_GL */
+
// angle=0 means orthographic.
void glrender(const string& prefix, const picture *pic, const string& format,
double width, double height, double angle, double zoom,
- const triple& m, const triple& M, const pair& shift, double *t,
+ const triple& m, const triple& M, const pair& shift,
+ const pair& margin, double *t,
double *background, size_t nlightsin, triple *lights,
double *diffuse, double *specular, bool view, int oldpid)
{
- remesh=true;
- bool offscreen=getSetting<bool>("offscreen");
Iconify=getSetting<bool>("iconify");
-#ifdef HAVE_PTHREAD
- static bool initializedView=false;
-#endif
width=max(width,1.0);
height=max(height,1.0);
@@ -1453,10 +1499,6 @@ void glrender(const string& prefix, const picture *pic, const string& format,
Prefix=prefix;
Picture=pic;
Format=format;
- for(int i=0; i < 16; ++i)
- T[i]=t[i];
- for(int i=0; i < 4; ++i)
- Background[i]=background[i];
nlights0=nlights=nlightsin;
@@ -1468,6 +1510,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
Zoom0=zoom;
Oldpid=oldpid;
Shift=shift;
+ Margin=margin;
Xmin=m.getx();
Xmax=M.getx();
@@ -1478,7 +1521,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
orthographic=Angle == 0.0;
H=orthographic ? 0.0 : -tan(0.5*Angle)*zmax;
-
+
ignorezoom=false;
Mode=0;
Xfactor=Yfactor=1.0;
@@ -1489,7 +1532,15 @@ void glrender(const string& prefix, const picture *pic, const string& format,
if(maxTileWidth <= 0) maxTileWidth=1024;
if(maxTileHeight <= 0) maxTileHeight=768;
- if(offscreen) {
+ bool webgl=Format == "html";
+
+#ifdef HAVE_GL
+#ifdef HAVE_PTHREAD
+ static bool initializedView=false;
+#endif
+
+ bool offscreen=getSetting<bool>("offscreen");
+ if(offscreen && !webgl) {
screenWidth=maxTileWidth;
screenHeight=maxTileHeight;
@@ -1501,18 +1552,27 @@ void glrender(const string& prefix, const picture *pic, const string& format,
}
if(glinitialize) {
- init();
+ if(!webgl) init();
Fitscreen=1;
}
+#endif
static bool initialized=false;
if(!initialized || !interact::interactive) {
antialias=getSetting<Int>("antialias") > 1;
- double expand=getSetting<double>("render");
- if(expand < 0)
- expand *= (Format.empty() || Format == "eps" || Format == "pdf")
- ? -2.0 : -1.0;
- if(antialias) expand *= 2.0;
+ double expand;
+ if(webgl)
+ expand=1.0;
+ else {
+ expand=getSetting<double>("render");
+ if(expand < 0)
+ expand *= (Format.empty() || Format == "eps" || Format == "pdf") ? -2.0 : -1.0;
+ if(antialias) expand *= 2.0;
+ }
+
+ oWidth=width;
+ oHeight=height;
+ Aspect=width/height;
// Force a hard viewport limit to work around direct rendering bugs.
// Alternatively, one can use -glOptions=-indirect (with a performance
@@ -1522,26 +1582,42 @@ void glrender(const string& prefix, const picture *pic, const string& format,
maxHeight=(int) ceil(maxViewport.gety());
if(maxWidth <= 0) maxWidth=max(maxHeight,2);
if(maxHeight <= 0) maxHeight=max(maxWidth,2);
- if(screenWidth <= 0) screenWidth=maxWidth;
- else screenWidth=min(screenWidth,maxWidth);
- if(screenHeight <= 0) screenHeight=maxHeight;
- else screenHeight=min(screenHeight,maxHeight);
-
- oWidth=width;
- oHeight=height;
- Aspect=width/height;
-
+
fullWidth=(int) ceil(expand*width);
fullHeight=(int) ceil(expand*height);
- Width=min(fullWidth,screenWidth);
- Height=min(fullHeight,screenHeight);
+ if(webgl) {
+ Width=fullWidth;
+ Height=fullHeight;
+ } else {
+ if(screenWidth <= 0) screenWidth=maxWidth;
+ else screenWidth=min(screenWidth,maxWidth);
+ if(screenHeight <= 0) screenHeight=maxHeight;
+ else screenHeight=min(screenHeight,maxHeight);
+
+ Width=min(fullWidth,screenWidth);
+ Height=min(fullHeight,screenHeight);
- if(Width > Height*Aspect)
- Width=min((int) (ceil(Height*Aspect)),screenWidth);
- else
- Height=min((int) (ceil(Width/Aspect)),screenHeight);
+ if(Width > Height*Aspect)
+ Width=min((int) (ceil(Height*Aspect)),screenWidth);
+ else
+ Height=min((int) (ceil(Width/Aspect)),screenHeight);
+ }
+
+ home(webgl);
+ setProjection();
+
+ if(webgl) return;
+
+ ArcballFactor=1+8.0*hypot(Margin.getx(),Margin.gety())/hypot(Width,Height);
+
+#ifdef HAVE_GL
+ for(int i=0; i < 16; ++i)
+ T[i]=t[i];
+ for(int i=0; i < 4; ++i)
+ Background[i]=background[i];
+ remesh=true;
Aspect=((double) Width)/Height;
if(maxTileWidth <= 0) maxTileWidth=screenWidth;
@@ -1553,8 +1629,10 @@ void glrender(const string& prefix, const picture *pic, const string& format,
if(View && settings::verbose > 1)
cout << "Rendering " << stripDir(prefix) << " as "
<< Width << "x" << Height << " image" << endl;
+#endif
}
+#ifdef HAVE_GL
bool havewindow=initialized && glthread && !offscreen;
#ifdef HAVE_LIBGLUT
@@ -1657,7 +1735,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
initshader();
}
- home();
+ glClearColor(Background[0],Background[1],Background[2],Background[3]);
#ifdef HAVE_LIBGLUT
if(!offscreen) {
@@ -1688,7 +1766,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutDisplayFunc(display);
-
+
glutMainLoop();
#endif // HAVE_LIBGLUT
} else {
@@ -1709,10 +1787,16 @@ void glrender(const string& prefix, const picture *pic, const string& format,
quit();
}
}
+
+#endif /* HAVE_GL */
}
} // namespace gl
+#endif
+
+#ifdef HAVE_GL
+
namespace camp {
string getLightIndex(size_t const& index, string const& fieldName) {
@@ -1721,19 +1805,53 @@ string getLightIndex(size_t const& index, string const& fieldName) {
return Strdup(buf.str());
}
+string getCenterIndex(size_t const& index) {
+ ostringstream buf;
+ buf << "Centers[" << index << "]";
+ return Strdup(buf.str());
+}
+
void setUniforms(GLint shader)
{
if(gl::nlights > gl::Nlights || nmaterials > Nmaterials) {
gl::deleteshader();
gl::initshader();
+ gl::lastshader=-1;
}
- glUseProgram(shader);
+ bool normal=shader != pixelShader && shader != noNormalShader;
+
+ if(shader != gl::lastshader) {
+ glUseProgram(shader);
+ gl::lastshader=shader;
- glUniformMatrix4fv(glGetUniformLocation(shader,"projViewMat"),1,GL_FALSE, value_ptr(gl::projViewMat));
- glUniformMatrix4fv(glGetUniformLocation(shader,"viewMat"),1,GL_FALSE, value_ptr(gl::viewMat));
- glUniformMatrix4fv(glGetUniformLocation(shader,"normMat"),1,GL_FALSE, value_ptr(gl::normMat));
+ glUniform1i(glGetUniformLocation(shader,"nlights"),gl::nlights);
+
+ for(size_t i=0; i < gl::nlights; ++i) {
+ triple Lighti=gl::Lights[i];
+ size_t i4=4*i;
+ glUniform3f(glGetUniformLocation(shader,
+ getLightIndex(i,"direction").c_str()),
+ (GLfloat) Lighti.getx(),(GLfloat) Lighti.gety(),
+ (GLfloat) Lighti.getz());
+
+ glUniform3f(glGetUniformLocation(shader,
+ getLightIndex(i,"color").c_str()),
+ (GLfloat) gl::Diffuse[i4],(GLfloat) gl::Diffuse[i4+1],
+ (GLfloat) gl::Diffuse[i4+2]);
+ }
+#if HAVE_LIBOPENIMAGEIO
+ // textures
+ if (settings::getSetting<bool>("envmap")) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindBuffer(GL_TEXTURE_2D, gl::envMapBuf);
+ glUniform1i(glGetUniformLocation(shader, "environmentMap"), 1);
+ glActiveTexture(GL_TEXTURE0);
+ }
+#endif
+ }
+
GLuint binding=0;
GLint blockindex=glGetUniformBlockIndex(shader,"MaterialBuffer");
glUniformBlockBinding(shader,blockindex,binding);
@@ -1741,49 +1859,151 @@ void setUniforms(GLint shader)
glGenBuffers(1,&gl::ubo);
glBindBuffer(GL_UNIFORM_BUFFER,gl::ubo);
- glBufferData(GL_UNIFORM_BUFFER,drawElement::material.size()*sizeof(Material),
- drawElement::material.data(),GL_STATIC_DRAW);
+ glBufferData(GL_UNIFORM_BUFFER,material.size()*sizeof(Material),
+ material.data(),GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER,binding,gl::ubo);
- glUniform1i(glGetUniformLocation(shader,"nlights"),gl::nlights);
-
- for(size_t i=0; i < gl::nlights; ++i) {
- triple Lighti=gl::Lights[i];
- size_t i4=4*i;
- glUniform4f(glGetUniformLocation(shader,
- getLightIndex(i,"direction").c_str()),
- (GLfloat) Lighti.getx(),(GLfloat) Lighti.gety(),
- (GLfloat) Lighti.getz(),0.0);
-
- glUniform4f(glGetUniformLocation(shader,
- getLightIndex(i,"diffuse").c_str()),
- (GLfloat) gl::Diffuse[i4],(GLfloat) gl::Diffuse[i4+1],
- (GLfloat) gl::Diffuse[i4+2],(GLfloat) gl::Diffuse[i4+3]);
-
- glUniform4f(glGetUniformLocation(shader,
- getLightIndex(i,"specular").c_str()),
- (GLfloat) gl::Specular[i4],(GLfloat) gl::Specular[i4+1],
- (GLfloat) gl::Specular[i4+2],(GLfloat) gl::Specular[i4+3]);
- }
-
-#if HAVE_LIBOPENIMAGEIO
- // textures
- if (settings::getSetting<bool>("envmap")) {
- glActiveTexture(GL_TEXTURE1);
- glBindBuffer(GL_TEXTURE_2D, gl::envMapBuf);
- glUniform1i(glGetUniformLocation(shader, "environmentMap"), 1);
- glActiveTexture(GL_TEXTURE0);
- }
-#endif
+ glUniformMatrix4fv(glGetUniformLocation(shader,"projViewMat"),1,GL_FALSE, value_ptr(gl::projViewMat));
+
+ glUniformMatrix4fv(glGetUniformLocation(shader,"viewMat"),1,GL_FALSE, value_ptr(gl::viewMat));
+
+ if(normal)
+ glUniformMatrix3fv(glGetUniformLocation(shader,"normMat"),1,GL_FALSE, value_ptr(gl::normMat));
}
void deleteUniforms()
{
glBindBuffer(GL_UNIFORM_BUFFER,0);
glDeleteBuffers(1,&gl::ubo);
- glUseProgram(0);
}
+void drawBuffer(vertexBuffer& data, GLint shader)
+{
+ if(data.indices.empty()) return;
+
+ bool pixel=shader == pixelShader;
+ bool normal=!pixel && (shader != noNormalShader);
+ bool color=shader == colorShader || shader == transparentShader;
+
+ const size_t size=sizeof(GLfloat);
+ const size_t intsize=sizeof(GLint);
+ const size_t bytestride=color ? sizeof(VertexData) :
+ (normal ? sizeof(vertexData) :
+ (pixel ? sizeof(vertexData0) : sizeof(vertexData1)));
+
+ GLuint vertsBufferIndex;
+ GLuint elemBufferIndex;
+
+ GLuint vao;
+
+ glGenVertexArrays(1,&vao);
+ glBindVertexArray(vao);
+
+ glGenBuffers(1,&vertsBufferIndex);
+ glGenBuffers(1,&elemBufferIndex);
+
+ if(color) registerBuffer(data.Vertices,vertsBufferIndex);
+ else if(normal) registerBuffer(data.vertices,vertsBufferIndex);
+ else if(pixel) registerBuffer(data.vertices0,vertsBufferIndex);
+ else registerBuffer(data.vertices1,vertsBufferIndex);
+
+ registerBuffer(data.indices,elemBufferIndex);
+
+ glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex);
+
+ camp::setUniforms(shader);
+
+ const GLint posAttrib=glGetAttribLocation(shader,"position");
+ const GLint materialAttrib=glGetAttribLocation(shader,"material");
+ GLint normalAttrib,colorAttrib,widthAttrib=0;
+
+ glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,(void *) 0);
+ glEnableVertexAttribArray(posAttrib);
+
+ if(normal) {
+ normalAttrib=glGetAttribLocation(shader,"normal");
+ glVertexAttribPointer(normalAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
+ (void *) (3*size));
+ glEnableVertexAttribArray(normalAttrib);
+ } else if(pixel) {
+ widthAttrib=glGetAttribLocation(shader,"width");
+ glVertexAttribPointer(widthAttrib,1,GL_FLOAT,GL_FALSE,bytestride,
+ (void *) (3*size));
+ glEnableVertexAttribArray(widthAttrib);
+ }
+
+ glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,
+ (void *) ((normal ? 6 : (pixel ? 4 : 3))*size));
+ glEnableVertexAttribArray(materialAttrib);
+
+ if(color) {
+ colorAttrib=glGetAttribLocation(shader,"color");
+ glVertexAttribPointer(colorAttrib,4,GL_UNSIGNED_BYTE,GL_TRUE,bytestride,
+ (void *) (6*size+intsize));
+ glEnableVertexAttribArray(colorAttrib);
+ }
+
+ glFlush(); // Workaround broken MSWindows drivers for Intel GPU
+ glDrawElements(normal ? GL_TRIANGLES : (pixel ? GL_POINTS : GL_LINES),
+ data.indices.size(),GL_UNSIGNED_INT,(void *) 0);
+
+ glDisableVertexAttribArray(posAttrib);
+ if(normal)
+ glDisableVertexAttribArray(normalAttrib);
+ if(pixel)
+ glDisableVertexAttribArray(widthAttrib);
+ glDisableVertexAttribArray(materialAttrib);
+ if(color)
+ glDisableVertexAttribArray(colorAttrib);
+
+ deleteUniforms();
+
+ glBindBuffer(GL_ARRAY_BUFFER,0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+
+ glBindVertexArray(0);
+ glDeleteVertexArrays(1,&vao);
+
+ glDeleteBuffers(1,&vertsBufferIndex);
+ glDeleteBuffers(1,&elemBufferIndex);
}
-#endif
+void drawBuffers()
+{
+ drawBuffer(material0Data,pixelShader);
+ drawBuffer(material1Data,noNormalShader);
+ drawBuffer(materialData,materialShader);
+ drawBuffer(colorData,colorShader);
+ drawBuffer(triangleData,transparentShader);
+ sortTriangles();
+
+ glDepthMask(GL_FALSE); // Enable transparency
+ drawBuffer(transparentData,transparentShader);
+ glDepthMask(GL_TRUE); // Disable transparency
+}
+
+void clearBuffers()
+{
+ material0Data.clear();
+ material1Data.clear();
+ materialData.clear();
+ colorData.clear();
+ triangleData.clear();
+ transparentData.clear();
+}
+
+void clearMaterialBuffer(bool draw)
+{
+ if(draw)
+ drawBuffers();
+ material.clear();
+ material.reserve(nmaterials);
+ materialMap.clear();
+ materialIndex=0;
+}
+
+
+}
+
+#endif /* HAVE_GL */
diff --git a/graphics/asymptote/glrender.h b/graphics/asymptote/glrender.h
index 5354fa59e7..cebc13f355 100644
--- a/graphics/asymptote/glrender.h
+++ b/graphics/asymptote/glrender.h
@@ -9,6 +9,13 @@
#include "common.h"
#include "triple.h"
+#ifdef HAVE_LIBGLM
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#include <glm/gtx/transform.hpp>
+#endif
+
#ifdef HAVE_GL
#include <csignal>
@@ -47,6 +54,14 @@
#endif
#endif
+#else
+typedef float GLfloat;
+#endif
+
+#ifdef HAVE_LIBGLM
+#include "material.h"
+#endif
+
namespace camp {
class picture;
@@ -78,9 +93,22 @@ namespace gl {
extern bool outlinemode;
extern bool wireframeMode;
-extern Int maxvertices;
+extern size_t maxvertices;
extern bool forceRemesh;
-extern GLuint ubo;
+
+extern bool orthographic;
+extern double xmin,xmax;
+extern double ymin,ymax;
+extern double zmin,zmax;
+extern int fullWidth,fullHeight;
+extern double Zoom0;
+extern double Angle;
+extern double Zoom0;
+extern camp::pair Margin;
+
+extern camp::triple *Lights;
+extern size_t nlights;
+extern double *Diffuse;
struct projection
{
@@ -101,80 +129,255 @@ public:
zoom(zoom), angle(angle), viewportshift(viewportshift) {}
};
+#ifdef HAVE_GL
+extern GLuint ubo;
GLuint initHDR();
+void setUniforms(GLint shader);
+void deleteUniforms();
+#endif
+
projection camera(bool user=true);
void glrender(const string& prefix, const camp::picture* pic,
const string& format, double width, double height, double angle,
double zoom, const camp::triple& m, const camp::triple& M,
- const camp::pair& shift, double *t, double *background,
- size_t nlights, camp::triple *lights, double *diffuse,
- double *specular, bool view, int oldpid=0);
+ const camp::pair& shift, const camp::pair& margin, double *t,
+ double *background, size_t nlights, camp::triple *lights,
+ double *diffuse, double *specular, bool view, int oldpid=0);
-struct ModelView {
- double T[16];
- double Tinv[16];
-};
-
-extern ModelView modelView;
+extern const double *dprojView;
void initshader();
void deleteshader();
+extern double BBT[9];
+
}
namespace camp {
-struct billboard
-{
+struct Billboard {
double cx,cy,cz;
- triple u,v,w;
void init(const triple& center) {
cx=center.getx();
cy=center.gety();
cz=center.getz();
- gl::projection P=gl::camera(false);
- w=unit(P.camera-P.target);
- v=unit(perp(P.up,w));
- u=cross(v,w);
}
- triple transform(const triple& V) {
- double x=V.getx()-cx;
- double y=V.gety()-cy;
- double z=V.getz()-cz;
+ triple transform(const triple& v) const {
+ double x=v.getx()-cx;
+ double y=v.gety()-cy;
+ double z=v.getz()-cz;
- return triple(cx+u.getx()*x+v.getx()*y+w.getx()*z,
- cy+u.gety()*x+v.gety()*y+w.gety()*z,
- cz+u.getz()*x+v.getz()*y+w.getz()*z);
+ return triple(x*gl::BBT[0]+y*gl::BBT[3]+z*gl::BBT[6]+cx,
+ x*gl::BBT[1]+y*gl::BBT[4]+z*gl::BBT[7]+cy,
+ x*gl::BBT[2]+y*gl::BBT[5]+z*gl::BBT[8]+cz);
}
-
- void store(GLfloat* C, const triple& V) {
- double x=V.getx()-cx;
- double y=V.gety()-cy;
- double z=V.getz()-cz;
- C[0]=cx+u.getx()*x+v.getx()*y+w.getx()*z;
- C[1]=cy+u.gety()*x+v.gety()*y+w.gety()*z;
- C[2]=cz+u.getz()*x+v.getz()*y+w.getz()*z;
+};
+
+extern Billboard BB;
+
+#ifdef HAVE_LIBGLM
+typedef mem::map<CONST Material,size_t> MaterialMap;
+
+extern mem::vector<Material> material;
+extern MaterialMap materialMap;
+extern size_t materialIndex;
+extern int MaterialIndex;
+#endif
+
+#ifdef HAVE_GL
+
+extern const size_t Nbuffer; // Initial size of 2D dynamic buffers
+extern const size_t nbuffer; // Initial size of 0D & 1D dynamic buffers
+
+class vertexData
+{
+public:
+ GLfloat position[3];
+ GLfloat normal[3];
+ GLint material;
+ vertexData() {};
+ vertexData(const triple& v, const triple& n) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ normal[0]=n.getx();
+ normal[1]=n.gety();
+ normal[2]=n.getz();
+ material=MaterialIndex;
}
};
-extern billboard BB;
+class VertexData
+{
+public:
+ GLfloat position[3];
+ GLfloat normal[3];
+ GLint material;
+ GLubyte color[4];
+ VertexData() {};
+ VertexData(const triple& v, const triple& n) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ normal[0]=n.getx();
+ normal[1]=n.gety();
+ normal[2]=n.getz();
+ material=MaterialIndex;
+ }
+ VertexData(const triple& v, const triple& n, GLfloat *c) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ normal[0]=n.getx();
+ normal[1]=n.gety();
+ normal[2]=n.getz();
+ material=MaterialIndex;
+ color[0]=(int)(bytescale*c[0]);
+ color[1]=(int)(bytescale*c[1]);
+ color[2]=(int)(bytescale*c[2]);
+ color[3]=(int)(bytescale*c[3]);
+ }
+};
+class vertexData1 {
+public:
+ GLfloat position[3];
+ GLint material;
+ vertexData1() {};
+ vertexData1(const triple& v) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ material=MaterialIndex;
+ }
+};
+
+class vertexData0 {
+public:
+ GLfloat position[3];
+ GLfloat width;
+ GLint material;
+ vertexData0() {};
+ vertexData0(const triple& v, double width) : width(width) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ material=MaterialIndex;
+ }
+};
+
+class vertexBuffer {
+public:
+ std::vector<vertexData> vertices;
+ std::vector<VertexData> Vertices;
+ std::vector<vertexData1> vertices1;
+ std::vector<vertexData0> vertices0;
+ std::vector<GLuint> indices;
+ void clear() {
+ vertices.clear();
+ Vertices.clear();
+ vertices1.clear();
+ vertices0.clear();
+ indices.clear();
+ vertices.reserve(Nbuffer);
+ Vertices.reserve(Nbuffer);
+ vertices1.reserve(nbuffer);
+ vertices0.reserve(nbuffer);
+ indices.reserve(Nbuffer);
+ }
+
+// Store the vertex v and its normal vector n.
+ GLuint vertex(const triple &v, const triple& n) {
+ size_t nvertices=vertices.size();
+ vertices.push_back(vertexData(v,n));
+ return nvertices;
+ }
+
+// Store the vertex v and its normal vector n, without an explicit color.
+ GLuint tvertex(const triple &v, const triple& n) {
+ size_t nvertices=Vertices.size();
+ Vertices.push_back(VertexData(v,n));
+ return nvertices;
+ }
+
+// Store the vertex v, its normal vector n, and colors c.
+ GLuint Vertex(const triple &v, const triple& n, GLfloat *c) {
+ size_t nvertices=Vertices.size();
+ Vertices.push_back(VertexData(v,n,c));
+ return nvertices;
+ }
+
+// Store the vertex v.
+ GLuint vertex1(const triple &v) {
+ size_t nvertices=vertices1.size();
+ vertices1.push_back(vertexData1(v));
+ return nvertices;
+ }
+
+// Store the pixel v and its width.
+ GLuint vertex0(const triple &v, double width) {
+ size_t nvertices=vertices0.size();
+ vertices0.push_back(vertexData0(v,width));
+ return nvertices;
+ }
+
+ // append array b onto array a with offset
+ void appendOffset(std::vector<GLuint>& a,
+ const std::vector<GLuint>& b, size_t offset) {
+ size_t n=a.size();
+ size_t m=b.size();
+ a.resize(n+m);
+ for(size_t i=0; i < m; ++i)
+ a[n+i]=b[i]+offset;
+ }
+
+ // append array b onto array a
+ void append(const vertexBuffer& b) {
+ appendOffset(indices,b.indices,vertices.size());
+ vertices.insert(vertices.end(),b.vertices.begin(),b.vertices.end());
+ }
+
+ void Append(const vertexBuffer& b) {
+ appendOffset(indices,b.indices,Vertices.size());
+ Vertices.insert(Vertices.end(),b.Vertices.begin(),b.Vertices.end());
+ }
+
+ void append1(const vertexBuffer& b) {
+ appendOffset(indices,b.indices,vertices1.size());
+ vertices1.insert(vertices1.end(),b.vertices1.begin(),b.vertices1.end());
+ }
+
+ void append0(const vertexBuffer& b) {
+ appendOffset(indices,b.indices,vertices0.size());
+ vertices0.insert(vertices0.end(),b.vertices0.begin(),b.vertices0.end());
+ }
+
+};
+
+extern GLint pixelShader;
+extern GLint noNormalShader;
extern GLint materialShader;
extern GLint colorShader;
-extern GLint noNormalShader;
-extern GLint pixelShader;
+extern GLint transparentShader;
-void setUniforms(GLint shader);
-void deleteUniforms();
+extern vertexBuffer material0Data; // pixels
+extern vertexBuffer material1Data; // material Bezier curves
+extern vertexBuffer materialData; // material Bezier patches & triangles
+extern vertexBuffer colorData; // colored Bezier patches & triangles
+extern vertexBuffer transparentData; // transparent patches & triangles
+extern vertexBuffer triangleData; // opaque indexed triangles
-}
+extern void drawBuffer(vertexBuffer& data, GLint shader);
+extern void drawBuffers();
+extern void clearBuffers();
+extern void clearMaterialBuffer(bool draw=false);
-#else
-typedef float GLfloat;
#endif
+}
+
#endif
diff --git a/graphics/asymptote/jsfile.cc b/graphics/asymptote/jsfile.cc
new file mode 100644
index 0000000000..f838ce14c5
--- /dev/null
+++ b/graphics/asymptote/jsfile.cc
@@ -0,0 +1,218 @@
+#include "jsfile.h"
+
+#include "settings.h"
+#include "glrender.h"
+#include "drawelement.h"
+
+#ifdef HAVE_LIBGLM
+
+using namespace settings;
+
+namespace camp {
+
+void jsfile::copy(string name) {
+ std::ifstream fin(locateFile(name).c_str());
+ string s;
+ while(getline(fin,s))
+ out << s << newl;
+}
+
+void jsfile::open(string name) {
+ out.open(name);
+ out << "<!DOCTYPE html>" << newl << newl;
+
+ bool absolute=getSetting<bool>("absolute");
+ if(!absolute)
+ out << "<!-- Use the following line to include this file within another web page:" << newl
+ << newl
+ << "<object data=\"" << name <<"\" style=\"width:"
+ << gl::fullWidth << ";height:" << gl::fullHeight
+ << ";position:relative;top:0;left:0;\"></object>" << newl << newl
+ << "-->" << newl << newl;
+
+ out.precision(getSetting<Int>("digits"));
+ copy(locateFile(WebGLheader));
+
+ if(getSetting<bool>("offline")) {
+ out << "<script>" << newl;
+ copy(locateFile(AsyGL));
+ out << "</script>" << newl;
+ } else {
+ out << "<script type=\"text/javascript\"" << newl << "src=\""
+ << getSetting<string>("asygl") << "\"></script>" << newl;
+ }
+ out << "<script type=\"text/javascript\">" << newl;
+ out << newl
+ << "canvasWidth=" << gl::fullWidth << ";" << newl
+ << "canvasHeight=" << gl::fullHeight << ";" << newl
+ << "absolute=" << std::boolalpha << absolute << ";" << newl
+ << newl
+ << "b=[" << gl::xmin << "," << gl::ymin << "," << gl::zmin << "];"
+ << newl
+ << "B=[" << gl::xmax << "," << gl::ymax << "," << gl::zmax << "];"
+ << newl
+ << "orthographic=" << gl::orthographic << ";"
+ << newl
+ << "angle=" << gl::Angle << ";"
+ << newl
+ << "Zoom0=" << gl::Zoom0 << ";" << newl
+ << "zoomFactor=" << getSetting<double>("zoomfactor") << ";" << newl
+ << "zoomPinchFactor=" << getSetting<double>("zoomPinchFactor") << ";"
+ << newl
+ << "zoomPinchCap=" << getSetting<double>("zoomPinchCap") << ";" << newl
+ << "zoomStep=" << getSetting<double>("zoomstep") << ";" << newl
+ << "shiftHoldDistance=" << getSetting<double>("shiftHoldDistance") << ";"
+ << newl
+ << "shiftWaitTime=" << getSetting<double>("shiftWaitTime") << ";"
+ << newl
+ << "vibrateTime=" << getSetting<double>("vibrateTime") << ";"
+ << newl
+ << "viewportmargin=" << gl::Margin << ";" << newl << newl
+ << "Lights=[";
+ for(size_t i=0; i < gl::nlights; ++i) {
+ size_t i4=4*i;
+ out << "new Light(" << newl
+ << "direction=" << gl::Lights[i] << "," << newl
+ << "color=[" << gl::Diffuse[i4] << "," << gl::Diffuse[i4+1]
+ << "," << gl::Diffuse[i4+2] << "])," << newl;
+ }
+ out << "];" << newl << newl;
+ size_t nmaterials=material.size();
+ out << "Materials=[";
+ for(size_t i=0; i < nmaterials; ++i)
+ out << "new Material(" << newl
+ << material[i]
+ << ")," << newl;
+ out << "];" << newl << newl;
+}
+
+jsfile::~jsfile() {
+ size_t ncenters=drawElement::center.size();
+ if(ncenters > 0) {
+ out << "Centers=[";
+ for(size_t i=0; i < ncenters; ++i)
+ out << newl << drawElement::center[i] << ",";
+ out << newl << "];" << newl;
+ }
+ copy(locateFile(WebGLfooter));
+}
+
+void jsfile::addColor(const prc::RGBAColour& c)
+{
+ out << "[" << byte(c.R) << "," << byte(c.G) << "," << byte(c.B)
+ << "," << byte(c.A) << "]";
+}
+
+void jsfile::addIndices(const uint32_t *I)
+{
+ out << "[" << I[0] << "," << I[1] << "," << I[2] << "]";
+}
+
+bool distinct(const uint32_t *I, const uint32_t *J)
+{
+ return I[0] != J[0] || I[1] != J[1] || I[2] != J[2];
+}
+
+void jsfile::addPatch(triple const* controls, size_t n,
+ const triple& Min, const triple& Max,
+ const prc::RGBAColour *c)
+{
+ out << "P.push(new BezierPatch([" << newl;
+ size_t last=n-1;
+ for(size_t i=0; i < last; ++i)
+ out << controls[i] << "," << newl;
+ out << controls[last] << newl << "],"
+ << drawElement::centerIndex << "," << materialIndex << ","
+ << Min << "," << Max;
+ if(c) {
+ out << ",[" << newl;
+ for(int i=0; i < 4; ++i) {
+ addColor(c[i]);
+ out << "," << newl;
+ }
+ out << "]";
+ }
+ out << "));" << newl << newl;
+}
+
+void jsfile::addCurve(const triple& z0, const triple& c0,
+ const triple& c1, const triple& z1,
+ const triple& Min, const triple& Max)
+{
+ out << "P.push(new BezierCurve([" << newl;
+ out << z0 << "," << newl
+ << c0 << "," << newl
+ << c1 << "," << newl
+ << z1 << newl << "],"
+ << drawElement::centerIndex << "," << materialIndex << ","
+ << Min << "," << Max << "));" << newl << newl;
+}
+
+void jsfile::addCurve(const triple& z0, const triple& z1,
+ const triple& Min, const triple& Max)
+{
+ out << "P.push(new BezierCurve([" << newl;
+ out << z0 << "," << newl
+ << z1 << newl << "],"
+ << drawElement::centerIndex << "," << materialIndex << ","
+ << Min << "," << Max << "));" << newl << newl;
+}
+
+void jsfile::addPixel(const triple& z0, double width,
+ const triple& Min, const triple& Max)
+{
+ out << "P.push(new Pixel(" << newl;
+ out << z0 << "," << width << "," << newl
+ << materialIndex << "," << Min << "," << Max << "));" << newl << newl;
+}
+
+void jsfile::addMaterial(size_t index)
+{
+ out << "Materials.push(new Material(" << newl
+ << material[index]
+ << "));" << newl << newl;
+}
+
+void jsfile::addTriangles(size_t nP, const triple* P, size_t nN,
+ const triple* N, size_t nC, const prc::RGBAColour* C,
+ size_t nI, const uint32_t (*PI)[3],
+ const uint32_t (*NI)[3], const uint32_t (*CI)[3],
+ const triple& Min, const triple& Max)
+{
+ for(size_t i=0; i < nP; ++i)
+ out << "Positions.push(" << P[i] << ");" << newl;
+
+ for(size_t i=0; i < nN; ++i)
+ out << "Normals.push(" << N[i] << ");" << newl;
+
+ for(size_t i=0; i < nC; ++i) {
+ out << "Colors.push(";
+ addColor(C[i]);
+ out << ");" << newl;
+ }
+
+ for(size_t i=0; i < nI; ++i) {
+ out << "Indices.push([";
+ const uint32_t *PIi=PI[i];
+ const uint32_t *NIi=NI[i];
+ bool keepNI=distinct(NIi,PIi);
+ bool keepCI=nC && distinct(CI[i],PIi);
+ addIndices(PIi);
+ if(keepNI || keepCI) {
+ out << ",";
+ if(keepNI) addIndices(NIi);
+ }
+ if(keepCI) {
+ out << ",";
+ addIndices(CI[i]);
+ }
+ out << "]);" << newl;
+ }
+ out << "P.push(new Triangles("
+ << materialIndex << "," << newl
+ << Min << "," << Max << "));" << newl;
+ out << newl;
+}
+
+}
+#endif
diff --git a/graphics/asymptote/jsfile.h b/graphics/asymptote/jsfile.h
new file mode 100644
index 0000000000..883cb4a70f
--- /dev/null
+++ b/graphics/asymptote/jsfile.h
@@ -0,0 +1,55 @@
+#ifndef JSFILE_H
+#define JSFILE_H
+
+#include <fstream>
+#include <glm/glm.hpp>
+
+#include "common.h"
+#include "triple.h"
+#include "locate.h"
+#include "prcfile.h"
+
+namespace gl {
+extern glm::mat4 projViewMat;
+}
+
+namespace camp {
+
+class jsfile {
+ jsofstream out;
+
+public:
+ jsfile() {}
+ ~jsfile();
+
+ void open(string name);
+ void copy(string name);
+
+ void addColor(const prc::RGBAColour& c);
+ void addIndices(const uint32_t *I);
+
+ void addPatch(const triple* controls, size_t n, const triple& Min,
+ const triple& Max, const prc::RGBAColour *colors);
+
+ void addCurve(const triple& z0, const triple& c0,
+ const triple& c1, const triple& z1,
+ const triple& Min, const triple& Max);
+
+ void addCurve(const triple& z0, const triple& z1,
+ const triple& Min, const triple& Max);
+
+ void addPixel(const triple& z0, double width,
+ const triple& Min, const triple& Max);
+
+ void addMaterial(size_t index);
+
+ void addTriangles(size_t nP, const triple* P, size_t nN, const triple* N,
+ size_t nC, const prc::RGBAColour* C, size_t nI,
+ const uint32_t (*PI)[3], const uint32_t (*NI)[3],
+ const uint32_t (*CI)[3],
+ const triple& Min, const triple& Max);
+};
+
+} //namespace camp
+
+#endif
diff --git a/graphics/asymptote/main.cc b/graphics/asymptote/main.cc
index 486e84ef78..46af145910 100644
--- a/graphics/asymptote/main.cc
+++ b/graphics/asymptote/main.cc
@@ -72,7 +72,7 @@ int sigsegv_handler (void *, int emergency)
{
if(!emergency) return 0; // Really a stack overflow
em.runtime(vm::getPos());
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
if(gl::glthread)
cerr << "Stack overflow or segmentation fault: rerun with -nothreads"
<< endl;
@@ -177,7 +177,7 @@ void *asymain(void *A)
int status;
while(wait(&status) > 0);
}
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
#ifdef HAVE_PTHREAD
if(gl::glthread && !getSetting<bool>("offscreen")) {
pthread_kill(gl::mainthread,SIGURG);
@@ -208,7 +208,7 @@ int main(int argc, char *argv[])
}
Args args(argc,argv);
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
#ifdef __APPLE__
bool usethreads=true;
#else
diff --git a/graphics/asymptote/material.h b/graphics/asymptote/material.h
index 4a07229046..d6a6084ae5 100644
--- a/graphics/asymptote/material.h
+++ b/graphics/asymptote/material.h
@@ -1,6 +1,13 @@
-#ifndef MATERIAL_STRUCT
-#define MATERIAL_STRUCT
-#ifdef HAVE_GL
+#ifndef MATERIAL_H
+#define MATERIAL_H
+
+#ifdef HAVE_LIBGLM
+
+#include <iostream>
+#include <fstream>
+
+#include "common.h"
+#include "triple.h"
#include <glm/glm.hpp>
@@ -21,6 +28,13 @@ inline glm::vec4 GLparameters(GLfloat shininess, GLfloat metallic,
return glm::vec4(shininess,metallic,fresnel0,0.0);
}
+inline ostream& operator << (ostream& out, const glm::vec4& v)
+{
+ out << "[" << v[0] << "," << v[1] << "," << v[2] << "," << v[3]
+ << "]";
+ return out;
+}
+
struct Material {
public:
glm::vec4 diffuse,emissive,specular;
@@ -45,6 +59,7 @@ public:
parameters=m.parameters;
return *this;
}
+
friend bool operator < (const Material& m1, const Material& m2) {
return m1.diffuse < m2.diffuse ||
(m1.diffuse == m2.diffuse &&
@@ -54,13 +69,23 @@ public:
(m1.specular == m2.specular &&
(m1.parameters < m2.parameters))))));
}
+
+ friend ostream& operator << (ostream& out, const Material& m) {
+ out << "diffuse=" << m.diffuse << "," << newl
+ << "emissive=" << m.emissive << "," << newl
+ << "specular=" << m.specular << "," << newl
+ << "shininess=" << m.parameters[0] << "," << newl
+ << "metallic=" << m.parameters[1] << "," << newl
+ << "fresnel0=" << m.parameters[2] << newl;
+ return out;
+ }
+
};
extern size_t Nmaterials; // Number of materials compiled in shader
extern size_t nmaterials; // Current size of materials buffer
extern size_t Maxmaterials; // Maxinum size of materials buffer
-void clearMaterialBuffer(bool draw=false);
-
}
+
#endif
#endif
diff --git a/graphics/asymptote/pair.h b/graphics/asymptote/pair.h
index 4a2ca09d68..c474600326 100644
--- a/graphics/asymptote/pair.h
+++ b/graphics/asymptote/pair.h
@@ -16,12 +16,27 @@
#include <cassert>
#include <cmath>
+#include <iostream>
+#include <fstream>
#include "common.h"
#include "angle.h"
namespace camp {
+class jsofstream : public std::ofstream {
+public:
+ jsofstream() {}
+ jsofstream(const string& name) : std::ofstream(name.c_str()) {}
+ void open(const string& name) {std::ofstream::open(name.c_str());}
+
+ template<class T>
+ jsofstream& operator << (const T& x) {
+ (std::ofstream&)(*this) << x;
+ return *this;
+ }
+};
+
class pair : public gc {
double x;
double y;
@@ -207,6 +222,12 @@ public:
return out;
}
+ friend jsofstream& operator << (jsofstream& out, const pair& z)
+ {
+ out << "[" << z.x << "," << z.y << "]";
+ return out;
+ }
+
friend class box;
};
diff --git a/graphics/asymptote/patches/README b/graphics/asymptote/patches/README
index f7e67aad98..1f1276c383 100644
--- a/graphics/asymptote/patches/README
+++ b/graphics/asymptote/patches/README
@@ -21,3 +21,6 @@ The file fixmem.reg patches the Microsoft Windows registry so that the
cygwin1.dll library can allocate more than 384MB. It is applied
automatically by the Asymptote setup.exe file but may also be applied manually:
regedit /s fixmem.reg
+
+The file gl-matrix-2.4.0-pruned.patch is used to build the required subset of
+the gl-matrix library. \ No newline at end of file
diff --git a/graphics/asymptote/patches/gl-matrix-2.4.0-pruned.patch b/graphics/asymptote/patches/gl-matrix-2.4.0-pruned.patch
new file mode 100644
index 0000000000..20d7b44c01
--- /dev/null
+++ b/graphics/asymptote/patches/gl-matrix-2.4.0-pruned.patch
@@ -0,0 +1,608 @@
+Only in gl-matrix-2.4.0-pruned: LICENSE.js
+diff -r -u gl-matrix-2.4.0/src/gl-matrix/mat3.js gl-matrix-2.4.0-pruned/src/gl-matrix/mat3.js
+--- gl-matrix-2.4.0/src/gl-matrix/mat3.js 2017-07-22 13:02:47.000000000 -0600
++++ gl-matrix-2.4.0-pruned/src/gl-matrix/mat3.js 2019-09-27 15:41:24.534735384 -0600
+@@ -70,7 +70,7 @@
+ * @param {mat3} a matrix to clone
+ * @returns {mat3} a new 3x3 matrix
+ */
+-export function clone(a) {
++function clone(a) {
+ let out = new glMatrix.ARRAY_TYPE(9);
+ out[0] = a[0];
+ out[1] = a[1];
+@@ -91,7 +91,7 @@
+ * @param {mat3} a the source matrix
+ * @returns {mat3} out
+ */
+-export function copy(out, a) {
++function copy(out, a) {
+ out[0] = a[0];
+ out[1] = a[1];
+ out[2] = a[2];
+@@ -118,7 +118,7 @@
+ * @param {Number} m22 Component in column 2, row 2 position (index 8)
+ * @returns {mat3} A new mat3
+ */
+-export function fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
++function fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
+ let out = new glMatrix.ARRAY_TYPE(9);
+ out[0] = m00;
+ out[1] = m01;
+@@ -147,7 +147,7 @@
+ * @param {Number} m22 Component in column 2, row 2 position (index 8)
+ * @returns {mat3} out
+ */
+-export function set(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {
++function set(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {
+ out[0] = m00;
+ out[1] = m01;
+ out[2] = m02;
+@@ -166,7 +166,7 @@
+ * @param {mat3} out the receiving matrix
+ * @returns {mat3} out
+ */
+-export function identity(out) {
++function identity(out) {
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+@@ -186,7 +186,7 @@
+ * @param {mat3} a the source matrix
+ * @returns {mat3} out
+ */
+-export function transpose(out, a) {
++function transpose(out, a) {
+ // If we are transposing ourselves we can skip a few steps but have to cache some values
+ if (out === a) {
+ let a01 = a[1], a02 = a[2], a12 = a[5];
+@@ -254,7 +254,7 @@
+ * @param {mat3} a the source matrix
+ * @returns {mat3} out
+ */
+-export function adjoint(out, a) {
++function adjoint(out, a) {
+ let a00 = a[0], a01 = a[1], a02 = a[2];
+ let a10 = a[3], a11 = a[4], a12 = a[5];
+ let a20 = a[6], a21 = a[7], a22 = a[8];
+@@ -277,7 +277,7 @@
+ * @param {mat3} a the source matrix
+ * @returns {Number} determinant of a
+ */
+-export function determinant(a) {
++function determinant(a) {
+ let a00 = a[0], a01 = a[1], a02 = a[2];
+ let a10 = a[3], a11 = a[4], a12 = a[5];
+ let a20 = a[6], a21 = a[7], a22 = a[8];
+@@ -293,7 +293,7 @@
+ * @param {mat3} b the second operand
+ * @returns {mat3} out
+ */
+-export function multiply(out, a, b) {
++function multiply(out, a, b) {
+ let a00 = a[0], a01 = a[1], a02 = a[2];
+ let a10 = a[3], a11 = a[4], a12 = a[5];
+ let a20 = a[6], a21 = a[7], a22 = a[8];
+@@ -324,7 +324,7 @@
+ * @param {vec2} v vector to translate by
+ * @returns {mat3} out
+ */
+-export function translate(out, a, v) {
++function translate(out, a, v) {
+ let a00 = a[0], a01 = a[1], a02 = a[2],
+ a10 = a[3], a11 = a[4], a12 = a[5],
+ a20 = a[6], a21 = a[7], a22 = a[8],
+@@ -352,7 +352,7 @@
+ * @param {Number} rad the angle to rotate the matrix by
+ * @returns {mat3} out
+ */
+-export function rotate(out, a, rad) {
++function rotate(out, a, rad) {
+ let a00 = a[0], a01 = a[1], a02 = a[2],
+ a10 = a[3], a11 = a[4], a12 = a[5],
+ a20 = a[6], a21 = a[7], a22 = a[8],
+@@ -382,7 +382,7 @@
+ * @param {vec2} v the vec2 to scale the matrix by
+ * @returns {mat3} out
+ **/
+-export function scale(out, a, v) {
++function scale(out, a, v) {
+ let x = v[0], y = v[1];
+
+ out[0] = x * a[0];
+@@ -410,7 +410,7 @@
+ * @param {vec2} v Translation vector
+ * @returns {mat3} out
+ */
+-export function fromTranslation(out, v) {
++function fromTranslation(out, v) {
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+@@ -434,7 +434,7 @@
+ * @param {Number} rad the angle to rotate the matrix by
+ * @returns {mat3} out
+ */
+-export function fromRotation(out, rad) {
++function fromRotation(out, rad) {
+ let s = Math.sin(rad), c = Math.cos(rad);
+
+ out[0] = c;
+@@ -462,7 +462,7 @@
+ * @param {vec2} v Scaling vector
+ * @returns {mat3} out
+ */
+-export function fromScaling(out, v) {
++function fromScaling(out, v) {
+ out[0] = v[0];
+ out[1] = 0;
+ out[2] = 0;
+@@ -484,7 +484,7 @@
+ * @param {mat2d} a the matrix to copy
+ * @returns {mat3} out
+ **/
+-export function fromMat2d(out, a) {
++function fromMat2d(out, a) {
+ out[0] = a[0];
+ out[1] = a[1];
+ out[2] = 0;
+@@ -507,7 +507,7 @@
+ *
+ * @returns {mat3} out
+ */
+-export function fromQuat(out, q) {
++function fromQuat(out, q) {
+ let x = q[0], y = q[1], z = q[2], w = q[3];
+ let x2 = x + x;
+ let y2 = y + y;
+@@ -546,7 +546,7 @@
+ *
+ * @returns {mat3} out
+ */
+-export function normalFromMat4(out, a) {
++function normalFromMat4(out, a) {
+ let a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
+ let a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
+ let a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
+@@ -596,7 +596,7 @@
+ * @param {number} height Height of gl context
+ * @returns {mat3} out
+ */
+-export function projection(out, width, height) {
++function projection(out, width, height) {
+ out[0] = 2 / width;
+ out[1] = 0;
+ out[2] = 0;
+@@ -615,7 +615,7 @@
+ * @param {mat3} a matrix to represent as a string
+ * @returns {String} string representation of the matrix
+ */
+-export function str(a) {
++function str(a) {
+ return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
+ a[3] + ', ' + a[4] + ', ' + a[5] + ', ' +
+ a[6] + ', ' + a[7] + ', ' + a[8] + ')';
+@@ -627,7 +627,7 @@
+ * @param {mat3} a the matrix to calculate Frobenius norm of
+ * @returns {Number} Frobenius norm
+ */
+-export function frob(a) {
++function frob(a) {
+ return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2)))
+ }
+
+@@ -639,7 +639,7 @@
+ * @param {mat3} b the second operand
+ * @returns {mat3} out
+ */
+-export function add(out, a, b) {
++function add(out, a, b) {
+ out[0] = a[0] + b[0];
+ out[1] = a[1] + b[1];
+ out[2] = a[2] + b[2];
+@@ -660,7 +660,7 @@
+ * @param {mat3} b the second operand
+ * @returns {mat3} out
+ */
+-export function subtract(out, a, b) {
++function subtract(out, a, b) {
+ out[0] = a[0] - b[0];
+ out[1] = a[1] - b[1];
+ out[2] = a[2] - b[2];
+@@ -683,7 +683,7 @@
+ * @param {Number} b amount to scale the matrix's elements by
+ * @returns {mat3} out
+ */
+-export function multiplyScalar(out, a, b) {
++function multiplyScalar(out, a, b) {
+ out[0] = a[0] * b;
+ out[1] = a[1] * b;
+ out[2] = a[2] * b;
+@@ -705,7 +705,7 @@
+ * @param {Number} scale the amount to scale b's elements by before adding
+ * @returns {mat3} out
+ */
+-export function multiplyScalarAndAdd(out, a, b, scale) {
++function multiplyScalarAndAdd(out, a, b, scale) {
+ out[0] = a[0] + (b[0] * scale);
+ out[1] = a[1] + (b[1] * scale);
+ out[2] = a[2] + (b[2] * scale);
+@@ -725,7 +725,7 @@
+ * @param {mat3} b The second matrix.
+ * @returns {Boolean} True if the matrices are equal, false otherwise.
+ */
+-export function exactEquals(a, b) {
++function exactEquals(a, b) {
+ return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] &&
+ a[3] === b[3] && a[4] === b[4] && a[5] === b[5] &&
+ a[6] === b[6] && a[7] === b[7] && a[8] === b[8];
+@@ -738,7 +738,7 @@
+ * @param {mat3} b The second matrix.
+ * @returns {Boolean} True if the matrices are equal, false otherwise.
+ */
+-export function equals(a, b) {
++function equals(a, b) {
+ let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7], a8 = a[8];
+ let b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], b8 = b[8];
+ return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) &&
+@@ -756,10 +756,10 @@
+ * Alias for {@link mat3.multiply}
+ * @function
+ */
+-export const mul = multiply;
++const mul = multiply;
+
+ /**
+ * Alias for {@link mat3.subtract}
+ * @function
+ */
+-export const sub = subtract;
++const sub = subtract;
+diff -r -u gl-matrix-2.4.0/src/gl-matrix/mat4.js gl-matrix-2.4.0-pruned/src/gl-matrix/mat4.js
+--- gl-matrix-2.4.0/src/gl-matrix/mat4.js 2017-07-22 13:02:47.000000000 -0600
++++ gl-matrix-2.4.0-pruned/src/gl-matrix/mat4.js 2019-09-27 15:41:24.534735384 -0600
+@@ -57,7 +57,7 @@
+ * @param {mat4} a matrix to clone
+ * @returns {mat4} a new 4x4 matrix
+ */
+-export function clone(a) {
++function clone(a) {
+ let out = new glMatrix.ARRAY_TYPE(16);
+ out[0] = a[0];
+ out[1] = a[1];
+@@ -85,7 +85,7 @@
+ * @param {mat4} a the source matrix
+ * @returns {mat4} out
+ */
+-export function copy(out, a) {
++function copy(out, a) {
+ out[0] = a[0];
+ out[1] = a[1];
+ out[2] = a[2];
+@@ -126,7 +126,7 @@
+ * @param {Number} m33 Component in column 3, row 3 position (index 15)
+ * @returns {mat4} A new mat4
+ */
+-export function fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
++function fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
+ let out = new glMatrix.ARRAY_TYPE(16);
+ out[0] = m00;
+ out[1] = m01;
+@@ -169,7 +169,7 @@
+ * @param {Number} m33 Component in column 3, row 3 position (index 15)
+ * @returns {mat4} out
+ */
+-export function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
++function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
+ out[0] = m00;
+ out[1] = m01;
+ out[2] = m02;
+@@ -223,7 +223,7 @@
+ * @param {mat4} a the source matrix
+ * @returns {mat4} out
+ */
+-export function transpose(out, a) {
++function transpose(out, a) {
+ // If we are transposing ourselves we can skip a few steps but have to cache some values
+ if (out === a) {
+ let a01 = a[1], a02 = a[2], a03 = a[3];
+@@ -325,7 +325,7 @@
+ * @param {mat4} a the source matrix
+ * @returns {mat4} out
+ */
+-export function adjoint(out, a) {
++function adjoint(out, a) {
+ let a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
+ let a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
+ let a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
+@@ -356,7 +356,7 @@
+ * @param {mat4} a the source matrix
+ * @returns {Number} determinant of a
+ */
+-export function determinant(a) {
++function determinant(a) {
+ let a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
+ let a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
+ let a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
+@@ -465,7 +465,7 @@
+ * @param {vec3} v the vec3 to scale the matrix by
+ * @returns {mat4} out
+ **/
+-export function scale(out, a, v) {
++function scale(out, a, v) {
+ let x = v[0], y = v[1], z = v[2];
+
+ out[0] = a[0] * x;
+@@ -558,7 +558,7 @@
+ * @param {Number} rad the angle to rotate the matrix by
+ * @returns {mat4} out
+ */
+-export function rotateX(out, a, rad) {
++function rotateX(out, a, rad) {
+ let s = Math.sin(rad);
+ let c = Math.cos(rad);
+ let a10 = a[4];
+@@ -601,7 +601,7 @@
+ * @param {Number} rad the angle to rotate the matrix by
+ * @returns {mat4} out
+ */
+-export function rotateY(out, a, rad) {
++function rotateY(out, a, rad) {
+ let s = Math.sin(rad);
+ let c = Math.cos(rad);
+ let a00 = a[0];
+@@ -644,7 +644,7 @@
+ * @param {Number} rad the angle to rotate the matrix by
+ * @returns {mat4} out
+ */
+-export function rotateZ(out, a, rad) {
++function rotateZ(out, a, rad) {
+ let s = Math.sin(rad);
+ let c = Math.cos(rad);
+ let a00 = a[0];
+@@ -721,7 +721,7 @@
+ * @param {vec3} v Scaling vector
+ * @returns {mat4} out
+ */
+-export function fromScaling(out, v) {
++function fromScaling(out, v) {
+ out[0] = v[0];
+ out[1] = 0;
+ out[2] = 0;
+@@ -800,7 +800,7 @@
+ * @param {Number} rad the angle to rotate the matrix by
+ * @returns {mat4} out
+ */
+-export function fromXRotation(out, rad) {
++function fromXRotation(out, rad) {
+ let s = Math.sin(rad);
+ let c = Math.cos(rad);
+
+@@ -835,7 +835,7 @@
+ * @param {Number} rad the angle to rotate the matrix by
+ * @returns {mat4} out
+ */
+-export function fromYRotation(out, rad) {
++function fromYRotation(out, rad) {
+ let s = Math.sin(rad);
+ let c = Math.cos(rad);
+
+@@ -870,7 +870,7 @@
+ * @param {Number} rad the angle to rotate the matrix by
+ * @returns {mat4} out
+ */
+-export function fromZRotation(out, rad) {
++function fromZRotation(out, rad) {
+ let s = Math.sin(rad);
+ let c = Math.cos(rad);
+
+@@ -909,7 +909,7 @@
+ * @param {vec3} v Translation vector
+ * @returns {mat4} out
+ */
+-export function fromRotationTranslation(out, q, v) {
++function fromRotationTranslation(out, q, v) {
+ // Quaternion math
+ let x = q[0], y = q[1], z = q[2], w = q[3];
+ let x2 = x + x;
+@@ -955,7 +955,7 @@
+ * @param {mat4} mat Matrix to be decomposed (input)
+ * @return {vec3} out
+ */
+-export function getTranslation(out, mat) {
++function getTranslation(out, mat) {
+ out[0] = mat[12];
+ out[1] = mat[13];
+ out[2] = mat[14];
+@@ -973,7 +973,7 @@
+ * @param {mat4} mat Matrix to be decomposed (input)
+ * @return {vec3} out
+ */
+-export function getScaling(out, mat) {
++function getScaling(out, mat) {
+ let m11 = mat[0];
+ let m12 = mat[1];
+ let m13 = mat[2];
+@@ -1000,7 +1000,7 @@
+ * @param {mat4} mat Matrix to be decomposed (input)
+ * @return {quat} out
+ */
+-export function getRotation(out, mat) {
++function getRotation(out, mat) {
+ // Algorithm taken from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
+ let trace = mat[0] + mat[5] + mat[10];
+ let S = 0;
+@@ -1051,7 +1051,7 @@
+ * @param {vec3} s Scaling vector
+ * @returns {mat4} out
+ */
+-export function fromRotationTranslationScale(out, q, v, s) {
++function fromRotationTranslationScale(out, q, v, s) {
+ // Quaternion math
+ let x = q[0], y = q[1], z = q[2], w = q[3];
+ let x2 = x + x;
+@@ -1111,7 +1111,7 @@
+ * @param {vec3} o The origin vector around which to scale and rotate
+ * @returns {mat4} out
+ */
+-export function fromRotationTranslationScaleOrigin(out, q, v, s, o) {
++function fromRotationTranslationScaleOrigin(out, q, v, s, o) {
+ // Quaternion math
+ let x = q[0], y = q[1], z = q[2], w = q[3];
+ let x2 = x + x;
+@@ -1164,7 +1164,7 @@
+ *
+ * @returns {mat4} out
+ */
+-export function fromQuat(out, q) {
++function fromQuat(out, q) {
+ let x = q[0], y = q[1], z = q[2], w = q[3];
+ let x2 = x + x;
+ let y2 = y + y;
+@@ -1248,7 +1248,7 @@
+ * @param {number} far Far bound of the frustum
+ * @returns {mat4} out
+ */
+-export function perspective(out, fovy, aspect, near, far) {
++function perspective(out, fovy, aspect, near, far) {
+ let f = 1.0 / Math.tan(fovy / 2);
+ let nf = 1 / (near - far);
+ out[0] = f / aspect;
+@@ -1281,7 +1281,7 @@
+ * @param {number} far Far bound of the frustum
+ * @returns {mat4} out
+ */
+-export function perspectiveFromFieldOfView(out, fov, near, far) {
++function perspectiveFromFieldOfView(out, fov, near, far) {
+ let upTan = Math.tan(fov.upDegrees * Math.PI/180.0);
+ let downTan = Math.tan(fov.downDegrees * Math.PI/180.0);
+ let leftTan = Math.tan(fov.leftDegrees * Math.PI/180.0);
+@@ -1352,7 +1352,7 @@
+ * @param {vec3} up vec3 pointing up
+ * @returns {mat4} out
+ */
+-export function lookAt(out, eye, center, up) {
++function lookAt(out, eye, center, up) {
+ let x0, x1, x2, y0, y1, y2, z0, z1, z2, len;
+ let eyex = eye[0];
+ let eyey = eye[1];
+@@ -1439,7 +1439,7 @@
+ * @param {vec3} up vec3 pointing up
+ * @returns {mat4} out
+ */
+-export function targetTo(out, eye, target, up) {
++function targetTo(out, eye, target, up) {
+ let eyex = eye[0],
+ eyey = eye[1],
+ eyez = eye[2],
+@@ -1488,7 +1488,7 @@
+ * @param {mat4} a matrix to represent as a string
+ * @returns {String} string representation of the matrix
+ */
+-export function str(a) {
++function str(a) {
+ return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' +
+ a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' +
+ a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' +
+@@ -1501,7 +1501,7 @@
+ * @param {mat4} a the matrix to calculate Frobenius norm of
+ * @returns {Number} Frobenius norm
+ */
+-export function frob(a) {
++function frob(a) {
+ return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2) ))
+ }
+
+@@ -1513,7 +1513,7 @@
+ * @param {mat4} b the second operand
+ * @returns {mat4} out
+ */
+-export function add(out, a, b) {
++function add(out, a, b) {
+ out[0] = a[0] + b[0];
+ out[1] = a[1] + b[1];
+ out[2] = a[2] + b[2];
+@@ -1541,7 +1541,7 @@
+ * @param {mat4} b the second operand
+ * @returns {mat4} out
+ */
+-export function subtract(out, a, b) {
++function subtract(out, a, b) {
+ out[0] = a[0] - b[0];
+ out[1] = a[1] - b[1];
+ out[2] = a[2] - b[2];
+@@ -1569,7 +1569,7 @@
+ * @param {Number} b amount to scale the matrix's elements by
+ * @returns {mat4} out
+ */
+-export function multiplyScalar(out, a, b) {
++function multiplyScalar(out, a, b) {
+ out[0] = a[0] * b;
+ out[1] = a[1] * b;
+ out[2] = a[2] * b;
+@@ -1598,7 +1598,7 @@
+ * @param {Number} scale the amount to scale b's elements by before adding
+ * @returns {mat4} out
+ */
+-export function multiplyScalarAndAdd(out, a, b, scale) {
++function multiplyScalarAndAdd(out, a, b, scale) {
+ out[0] = a[0] + (b[0] * scale);
+ out[1] = a[1] + (b[1] * scale);
+ out[2] = a[2] + (b[2] * scale);
+@@ -1625,7 +1625,7 @@
+ * @param {mat4} b The second matrix.
+ * @returns {Boolean} True if the matrices are equal, false otherwise.
+ */
+-export function exactEquals(a, b) {
++function exactEquals(a, b) {
+ return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] &&
+ a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] &&
+ a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] &&
+@@ -1639,7 +1639,7 @@
+ * @param {mat4} b The second matrix.
+ * @returns {Boolean} True if the matrices are equal, false otherwise.
+ */
+-export function equals(a, b) {
++function equals(a, b) {
+ let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
+ let a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7];
+ let a8 = a[8], a9 = a[9], a10 = a[10], a11 = a[11];
+@@ -1672,10 +1672,10 @@
+ * Alias for {@link mat4.multiply}
+ * @function
+ */
+-export const mul = multiply;
++const mul = multiply;
+
+ /**
+ * Alias for {@link mat4.subtract}
+ * @function
+ */
+-export const sub = subtract;
++const sub = subtract;
+diff -r -u gl-matrix-2.4.0/src/gl-matrix.js gl-matrix-2.4.0-pruned/src/gl-matrix.js
+--- gl-matrix-2.4.0/src/gl-matrix.js 2017-07-22 13:02:47.000000000 -0600
++++ gl-matrix-2.4.0-pruned/src/gl-matrix.js 2019-09-27 17:04:06.477164503 -0600
+@@ -26,19 +26,9 @@
+ THE SOFTWARE. */
+ // END HEADER
+
+-import * as glMatrix from "./gl-matrix/common";
+-import * as mat2 from "./gl-matrix/mat2";
+-import * as mat2d from "./gl-matrix/mat2d";
+ import * as mat3 from "./gl-matrix/mat3";
+ import * as mat4 from "./gl-matrix/mat4";
+-import * as quat from "./gl-matrix/quat";
+-import * as vec2 from "./gl-matrix/vec2";
+-import * as vec3 from "./gl-matrix/vec3";
+-import * as vec4 from "./gl-matrix/vec4";
+
+ export {
+- glMatrix,
+- mat2, mat2d, mat3, mat4,
+- quat,
+- vec2, vec3, vec4,
+-};
+\ No newline at end of file
++ mat3,mat4
++};
diff --git a/graphics/asymptote/path3.h b/graphics/asymptote/path3.h
index 14ed3dd1ca..35eadbaf8e 100644
--- a/graphics/asymptote/path3.h
+++ b/graphics/asymptote/path3.h
@@ -17,6 +17,10 @@
#include "path.h"
#include "arrayop.h"
+// For CYGWIN
+#undef near
+#undef far
+
namespace camp {
void checkEmpty3(Int n);
@@ -283,13 +287,13 @@ public:
triple mintimes() const {
checkEmpty3(n);
bounds();
- return camp::triple(times.left,times.bottom,times.lower);
+ return camp::triple(times.left,times.bottom,times.near);
}
triple maxtimes() const {
checkEmpty3(n);
bounds();
- return camp::triple(times.right,times.top,times.upper);
+ return camp::triple(times.right,times.top,times.far);
}
template<class T>
diff --git a/graphics/asymptote/pen.h b/graphics/asymptote/pen.h
index 1208f4a60c..d9572eee5c 100644
--- a/graphics/asymptote/pen.h
+++ b/graphics/asymptote/pen.h
@@ -136,14 +136,14 @@ inline bool operator == (const Transparency& a, const Transparency& b) {
extern const char* BlendMode[];
extern const Int nBlendMode;
+const double bytescale=256.0*(1.0-DBL_EPSILON);
+
// Map [0,1] to [0,255]
inline unsigned int byte(double r)
{
if(r < 0.0) r=0.0;
else if(r > 1.0) r=1.0;
- int a=(int)(256.0*r);
- if(a == 256) a=255;
- return a;
+ return (int)(bytescale*r);
}
class pen;
diff --git a/graphics/asymptote/picture.cc b/graphics/asymptote/picture.cc
index c59c28e91b..93e5f6a6eb 100644
--- a/graphics/asymptote/picture.cc
+++ b/graphics/asymptote/picture.cc
@@ -459,17 +459,6 @@ bool picture::texprocess(const string& texname, const string& outname,
cmd.push_back("-o"+outname);
ostringstream buf;
bbox B=svgbbox(b,bboxshift);
- /*
- double height=b.top-b.bottom;
- double threshold=12.0*tex2ps;
- if(height < threshold) {
- double offset=threshold-height;
- b.top += offset;
- b.bottom += offset;
- }
- bbox B=b;
- B.shift(bboxshift+pair(1.99*cm,1.9*cm));
- */
buf << "--bbox="
<< B.left << "bp "
<< B.bottom << "bp "
@@ -746,6 +735,8 @@ bool picture::postprocess(const string& prename, const string& outname,
bool wait, bool view, bool pdftex,
bool epsformat, bool svg)
{
+ if(outputformat == "html")
+ reportError("Use svg instead of html output format for 2D pictures.");
static mem::map<CONST string,int> pids;
int status=0;
bool pdfformat=(settings::pdf(getSetting<string>("tex"))
@@ -1176,23 +1167,16 @@ bool picture::shipout(picture *preamble, const string& Prefix,
// render viewport with width x height pixels.
void picture::render(double size2, const triple& Min, const triple& Max,
- double perspective, bool transparent, bool remesh) const
+ double perspective, bool remesh) const
{
- if(remesh) {
- for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
- assert(*p);
- (*p)->render(size2,Min,Max,perspective,transparent);
- }
+ for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if(remesh) (*p)->meshinit();
+ (*p)->render(size2,Min,Max,perspective,remesh);
}
-#ifdef HAVE_GL
- if(transparent)
- drawBezierPatch::S.drawTransparent();
- else {
- drawBezierPatch::S.drawOpaque();
- drawPath3::R.draw();
- drawPixel::R.draw();
- }
+#ifdef HAVE_LIBGL
+ drawBuffers();
#endif
}
@@ -1207,6 +1191,7 @@ struct Communicate : public gc {
triple m;
triple M;
pair shift;
+ pair margin;
double *t;
double *background;
size_t nlights;
@@ -1220,31 +1205,39 @@ Communicate com;
void glrenderWrapper()
{
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
#ifdef HAVE_PTHREAD
wait(initSignal,initLock);
endwait(initSignal,initLock);
#endif
glrender(com.prefix,com.pic,com.format,com.width,com.height,com.angle,
- com.zoom,com.m,com.M,com.shift,com.t,com.background,com.nlights,
- com.lights,com.diffuse,com.specular,com.view);
+ com.zoom,com.m,com.M,com.shift,com.margin,com.t,com.background,
+ com.nlights,com.lights,com.diffuse,com.specular,com.view);
#endif
}
bool picture::shipout3(const string& prefix, const string& format,
double width, double height, double angle, double zoom,
const triple& m, const triple& M, const pair& shift,
- double *t, double *background, size_t nlights,
- triple *lights, double *diffuse, double *specular, bool view)
+ const pair& margin, double *t, double *background,
+ size_t nlights, triple *lights, double *diffuse,
+ double *specular, bool view)
{
if(getSetting<bool>("interrupt"))
return true;
-#ifndef HAVE_LIBGLUT
- if(!getSetting<bool>("offscreen"))
+ bool webgl=format == "html";
+
+#ifndef HAVE_GL
+ if(!webgl && !getSetting<bool>("offscreen"))
camp::reportError("to support onscreen rendering, please install glut library, run ./configure, and recompile");
#endif
+#ifndef HAVE_LIBGLM
+ if(webgl)
+ camp::reportError("to support WebGL rendering, please install glm header files, run ./configure, and recompile");
+#endif
+
#ifndef HAVE_LIBOSMESA
if(getSetting<bool>("offscreen"))
camp::reportError("to support offscreen rendering; please install OSMesa library, run ./configure --enable-offscreen, and recompile");
@@ -1278,71 +1271,106 @@ bool picture::shipout3(const string& prefix, const string& format,
const string outputformat=format.empty() ?
getSetting<string>("outformat") : format;
-#ifdef HAVE_GL
- bool View=settings::view() && view;
+#ifdef HAVE_LIBGLM
static int oldpid=0;
+ bool View=settings::view() && view;
+#endif
+
+#ifdef HAVE_GL
bool offscreen=getSetting<bool>("offscreen");
#ifdef HAVE_PTHREAD
bool animating=getSetting<bool>("animating");
bool Wait=!interact::interactive || !View || animating;
#endif
-#endif
+#endif
-#if defined(HAVE_LIBGLUT) && defined(HAVE_GL)
- if(glthread && !offscreen) {
+ if(!webgl) {
+#ifdef HAVE_GL
+ if(glthread && !offscreen) {
#ifdef HAVE_PTHREAD
- if(gl::initialize) {
- gl::initialize=false;
- com.prefix=prefix;
- com.pic=pic;
- com.format=outputformat;
- com.width=width;
- com.height=height;
- com.angle=angle;
- com.zoom=zoom;
- com.m=m;
- com.M=M;
- com.shift=shift;
- com.t=t;
- com.background=background;
- com.nlights=nlights;
- com.lights=lights;
- com.diffuse=diffuse;
- com.specular=specular;
- com.view=View;
- if(Wait)
- pthread_mutex_lock(&readyLock);
- wait(initSignal,initLock);
- endwait(initSignal,initLock);
- static bool initialize=true;
- if(initialize) {
+ if(gl::initialize) {
+ gl::initialize=false;
+ com.prefix=prefix;
+ com.pic=pic;
+ com.format=outputformat;
+ com.width=width;
+ com.height=height;
+ com.angle=angle;
+ com.zoom=zoom;
+ com.m=m;
+ com.M=M;
+ com.shift=shift;
+ com.margin=margin;
+ com.t=t;
+ com.background=background;
+ com.nlights=nlights;
+ com.lights=lights;
+ com.diffuse=diffuse;
+ com.specular=specular;
+ com.view=View;
+ if(Wait)
+ pthread_mutex_lock(&readyLock);
wait(initSignal,initLock);
endwait(initSignal,initLock);
- initialize=false;
+ static bool initialize=true;
+ if(initialize) {
+ wait(initSignal,initLock);
+ endwait(initSignal,initLock);
+ initialize=false;
+ }
+ if(Wait) {
+ pthread_cond_wait(&readySignal,&readyLock);
+ pthread_mutex_unlock(&readyLock);
+ }
+ return true;
}
- if(Wait) {
- pthread_cond_wait(&readySignal,&readyLock);
- pthread_mutex_unlock(&readyLock);
+ if(Wait)
+ pthread_mutex_lock(&readyLock);
+#endif
+ } else {
+ int pid=fork();
+ if(pid == -1)
+ camp::reportError("Cannot fork process");
+ if(pid != 0) {
+ oldpid=pid;
+ waitpid(pid,NULL,interact::interactive && View ? WNOHANG : 0);
+ return true;
}
- return true;
}
- if(Wait)
- pthread_mutex_lock(&readyLock);
#endif
- } else {
- int pid=fork();
- if(pid == -1)
- camp::reportError("Cannot fork process");
- if(pid != 0) {
- oldpid=pid;
- waitpid(pid,NULL,interact::interactive && View ? WNOHANG : 0);
- return true;
- }
}
+
+#if HAVE_LIBGLM
+ glrender(prefix,pic,outputformat,width,height,angle,zoom,m,M,shift,margin,t,
+ background,nlights,lights,diffuse,specular,View,oldpid);
+
+ if(webgl) {
+ jsfile js;
+ string name=buildname(prefix,format);
+ js.open(name);
+
+ for(nodelist::iterator p=pic->nodes.begin(); p != pic->nodes.end(); ++p) {
+ assert(*p);
+ (*p)->write(&js);
+ }
+ if(verbose > 0)
+ cout << "Wrote " << name << endl;
+ if(View) {
+ mem::vector<string> cmd;
+ push_command(cmd,getSetting<string>("htmlviewer"));
+#ifdef __MSDOS__
+ cmd.push_back("file://%CD%/"+name);
+#else
+ cmd.push_back(name);
#endif
+ push_split(cmd,getSetting<string>("htmlviewerOptions"));
+ System(cmd,2,false);
+ }
+ return true;
+ }
+#endif
+
#ifdef HAVE_GL
- glrender(prefix,pic,outputformat,width,height,angle,zoom,m,M,shift,t,
- background,nlights,lights,diffuse,specular,View,oldpid);
#ifdef HAVE_PTHREAD
if(glthread && !offscreen && Wait) {
pthread_cond_wait(&readySignal,&readyLock);
@@ -1351,17 +1379,17 @@ bool picture::shipout3(const string& prefix, const string& format,
return true;
#endif
#endif
-
+
return false;
}
-bool picture::shipout3(const string& prefix)
+bool picture::shipout3(const string& prefix, const string format)
{
bounds3();
- bool status = true;
+ bool status;
- string prcname=buildname(prefix,"prc");
- prcfile prc(prcname);
+ string name=buildname(prefix,"prc");
+ prcfile prc(name);
static const double limit=2.5*10.0/INT_MAX;
double compressionlimit=max(length(b3.Max()),length(b3.Min()))*limit;
@@ -1372,12 +1400,11 @@ bool picture::shipout3(const string& prefix)
(*p)->write(&prc,&billboard,compressionlimit,groups);
}
groups.pop_back();
- if(status)
- status=prc.finish();
-
+ status=prc.finish();
+
if(!status) reportError("shipout3 failed");
- if(verbose > 0) cout << "Wrote " << prcname << endl;
+ if(verbose > 0) cout << "Wrote " << name << endl;
return true;
}
diff --git a/graphics/asymptote/picture.h b/graphics/asymptote/picture.h
index 0d571d0a3b..58223caf37 100644
--- a/graphics/asymptote/picture.h
+++ b/graphics/asymptote/picture.h
@@ -87,15 +87,16 @@ public:
const string& format, bool wait=false, bool view=true);
void render(double size2, const triple &Min, const triple& Max,
- double perspective, bool transparent, bool remesh) const;
+ double perspective, bool remesh) const;
bool shipout3(const string& prefix, const string& format,
double width, double height, double angle, double zoom,
- const triple& m, const triple& M, const pair& shift, double *t,
+ const triple& m, const triple& M, const pair& shift,
+ const pair& margin, double *t,
double *background, size_t nlights, triple *lights,
double *diffuse, double *specular, bool view);
- // PRC output
- bool shipout3(const string& prefix);
+ // 3D output
+ bool shipout3(const string& prefix, const string format);
bool reloadPDF(const string& Viewer, const string& outname) const;
diff --git a/graphics/asymptote/pipestream.cc b/graphics/asymptote/pipestream.cc
index c53287c28c..f7f3006c01 100644
--- a/graphics/asymptote/pipestream.cc
+++ b/graphics/asymptote/pipestream.cc
@@ -93,7 +93,7 @@ void iopipestream::eof()
void iopipestream::pipeclose()
{
if(pipeopen) {
-// kill(pid,SIGTERM);
+ kill(pid,SIGHUP);
eof();
close(out[0]);
Running=false;
diff --git a/graphics/asymptote/prcfile.h b/graphics/asymptote/prcfile.h
index a40fb64e16..224a92f8a0 100644
--- a/graphics/asymptote/prcfile.h
+++ b/graphics/asymptote/prcfile.h
@@ -2,6 +2,7 @@
#define PRCFILE_H
#include "memory.h"
+#include "pen.h"
inline double X(const camp::triple &v) {return v.getx();}
inline double Y(const camp::triple &v) {return v.gety();}
diff --git a/graphics/asymptote/quaternion.h b/graphics/asymptote/quaternion.h
deleted file mode 100644
index f58a7445e5..0000000000
--- a/graphics/asymptote/quaternion.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-
- quaternion.h - A quaternion class
-
- GLUI User Interface Toolkit (LGPL)
- Copyright (c) 1998 Paul Rademacher
-
- ---------------------------------------------------------------------
-
- WWW: http://sourceforge.net/projects/glui/
- Forums: http://sourceforge.net/forum/?group_id=92496
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-#ifndef GLUI_QUATERNION_H
-#define GLUI_QUATERNION_H
-
-#include "algebra3.h"
-#include <cstdio>
-
-/* this line defines a new type: pointer to a function which returns a */
-/* float and takes as argument a float */
-typedef float (*V_FCT_PTR)(float);
-
-/****************************************************************
- * Quaternion *
- ****************************************************************/
-
-class quat
-{
- /*protected: */
-public:
-
- vec3 v; /* vector component */
- float s; /* scalar component */
-
- /*public: */
-
- /* Constructors */
-
- quat();
- quat(float x, float y, float z, float w);
- quat(const vec3 &v, float s);
- quat(float s, const vec3 &v);
- quat(const float *d); /* copy from four-element float array */
- quat(const double *f); /* copy from four-element double array */
- quat(const quat &q); /* copy from other quat */
-
- /* Assignment operators */
-
- quat &operator = (const quat &v); /* assignment of a quat */
- quat &operator += (const quat &v); /* incrementation by a quat */
- quat &operator -= (const quat &v); /* decrementation by a quat */
- quat &operator *= (float d); /* multiplication by a constant */
- quat &operator /= (float d); /* division by a constant */
-
- /* special functions */
-
- float length() const; /* length of a quat */
- float length2() const; /* squared length of a quat */
- quat &normalize(); /* normalize a quat */
- quat &apply(V_FCT_PTR fct); /* apply a func. to each component */
- vec3 xform(const vec3 &v ); /* q*v*q-1 */
- mat4 to_mat4() const;
- void set_angle(float f); /* set rot angle (degrees) */
- void scale_angle(float f); /* scale rot angle (degrees) */
- float get_angle() const; /* set rot angle (degrees) */
- vec3 get_axis() const; /* get axis */
-
- void print( FILE *file, const char *name ) const; /* print to a file */
-
- float &operator [] (int i); /* indexing */
- const float &operator [] (int i) const; /* indexing */
-
- void set(float x, float y, float z); /* set quat */
- void set(const vec3 &v, float s); /* set quat */
-
- /* friends */
-
- friend quat operator - (const quat &v); /* -q1 */
- friend quat operator + (const quat &a, const quat &b); /* q1 + q2 */
- friend quat operator - (const quat &a, const quat &b); /* q1 - q2 */
- friend quat operator * (const quat &a, float d); /* q1 * 3.0 */
- friend quat operator * (float d, const quat &a); /* 3.0 * q1 */
- friend quat operator * (const quat &a, const quat &b); /* q1 * q2 */
- friend quat operator / (const quat &a, float d); /* q1 / 3.0 */
- friend int operator == (const quat &a, const quat &b); /* q1 == q2 ? */
- friend int operator != (const quat &a, const quat &b); /* q1 != q2 ? */
- friend void swap(quat &a, quat &b); /* swap q1 &q2 */
- /*friend quat min(const quat &a, const quat &b); -- min(q1, q2) */
- /*friend quat max(const quat &a, const quat &b); -- max(q1, q2) */
- friend quat prod(const quat &a, const quat &b); /* term by term mult*/
-};
-
-/* Utility functions */
-
-quat quat_identity(); /* Returns quaternion identity element */
-quat quat_slerp(const quat &from, const quat &to, float t);
-
-#endif
diff --git a/graphics/asymptote/revision.cc b/graphics/asymptote/revision.cc
index 4f90aa3b17..2d99676d71 100644
--- a/graphics/asymptote/revision.cc
+++ b/graphics/asymptote/revision.cc
@@ -1 +1 @@
-const char *REVISION="2.53";
+const char *REVISION="2.54";
diff --git a/graphics/asymptote/runarray.cc b/graphics/asymptote/runarray.cc
index a0ad0675ed..d750211978 100644
--- a/graphics/asymptote/runarray.cc
+++ b/graphics/asymptote/runarray.cc
@@ -391,8 +391,44 @@ void transpose(double *a, size_t n)
}
// Invert an n x n array in place.
-void inverse(double *a, size_t n)
+void inverse(double *M, size_t n)
{
+ if(n == 2) {
+ real a=M[0];
+ real b=M[1];
+ real c=M[2];
+ real d=M[3];
+ real det=a*d-b*c;
+ if(det == 0.0)
+ error(singular);
+ det=1.0/det;
+ M[0]=d*det;
+ M[1]=-b*det;
+ M[2]=-c*det;
+ M[3]=a*det;
+ return;
+ }
+
+ if(n == 3) {
+ real a=M[0], b=M[1], c=M[2];
+ real d=M[3], e=M[4], f=M[5];
+ real g=M[6], h=M[7], i=M[8];
+
+ real A=e*i-f*h;
+ real B=f*g-d*i;
+ real C=d*h-e*g;
+
+ real det=a*A+b*B+c*C;
+ if(det == 0.0)
+ error(singular);
+ det=1.0/det;
+
+ M[0]=A*det; M[1]=(c*h-b*i)*det; M[2]=(b*f-c*e)*det;
+ M[3]=B*det; M[4]=(a*i-c*g)*det; M[5]=(c*d-a*f)*det;
+ M[6]=C*det; M[7]=(b*g-a*h)*det; M[8]=(a*e-b*d)*det;
+ return;
+ }
+
inverseAllocate(n);
for(size_t i=0; i < n; i++)
@@ -404,7 +440,7 @@ void inverse(double *a, size_t n)
real big=0.0;
// This is the outer loop of the search for a pivot element.
for(size_t j=0; j < n; j++) {
- double *aj=a+n*j;
+ double *aj=M+n*j;
if(pivot[j] != 1) {
for(size_t k=0; k < n; k++) {
if(pivot[k] == 0) {
@@ -424,9 +460,9 @@ void inverse(double *a, size_t n)
++(pivot[col]);
// Interchange rows, if needed, to put the pivot element on the diagonal.
- double *acol=a+n*col;
+ double *acol=M+n*col;
if(row != col) {
- double *arow=a+n*row;
+ double *arow=M+n*row;
for(size_t k=0; k < n; k++) {
real temp=arow[k];
arow[k]=acol[k];
@@ -451,7 +487,7 @@ void inverse(double *a, size_t n)
// Reduce all rows except for the pivoted one.
for(size_t k=0; k < n; k++) {
if(k != col) {
- double *ak=a+n*k;
+ double *ak=M+n*k;
real akcol=ak[col];
ak[col]=0.0;
for(size_t j=0; j < n; j++)
@@ -467,7 +503,7 @@ void inverse(double *a, size_t n)
size_t c=Col[k];
if(r != c) {
for(size_t j=0; j < n; j++) {
- double *aj=a+n*j;
+ double *aj=M+n*j;
real temp=aj[r];
aj[r]=aj[c];
aj[c]=temp;
@@ -597,10 +633,10 @@ void integeroverflow(size_t i)
#endif
namespace run {
// Create an empty array.
-#line 550 "runarray.in"
+#line 586 "runarray.in"
void emptyArray(stack *Stack)
{
-#line 551 "runarray.in"
+#line 587 "runarray.in"
{Stack->push<array*>(new array(0)); return;}
}
@@ -609,11 +645,11 @@ void emptyArray(stack *Stack)
// is popped off the stack, followed by each dimension in reverse order.
// The array itself is technically a one dimensional array of one
// dimension arrays and so on.
-#line 560 "runarray.in"
+#line 596 "runarray.in"
void newDeepArray(stack *Stack)
{
Int depth=vm::pop<Int>(Stack);
-#line 561 "runarray.in"
+#line 597 "runarray.in"
assert(depth > 0);
Int *dims = new Int[depth];
@@ -632,11 +668,11 @@ void newDeepArray(stack *Stack)
// Creates an array with elements already specified. First, the number
// of elements is popped off the stack, followed by each element in
// reverse order.
-#line 580 "runarray.in"
+#line 616 "runarray.in"
void newInitializedArray(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 581 "runarray.in"
+#line 617 "runarray.in"
assert(n >= 0);
array *a = new array(n);
@@ -649,12 +685,12 @@ void newInitializedArray(stack *Stack)
// Similar to newInitializedArray, but after the n elements, append another
// array to it.
-#line 594 "runarray.in"
+#line 630 "runarray.in"
void newAppendedArray(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
array* tail=vm::pop<array*>(Stack);
-#line 595 "runarray.in"
+#line 631 "runarray.in"
assert(n >= 0);
array *a = new array(n);
@@ -671,14 +707,14 @@ void newAppendedArray(stack *Stack)
// typeDepth is the true depth of the array determined at compile-time when the
// operations for the array type are added. This typeDepth argument is
// automatically pushed on the stack and is not visible to the user.
-#line 612 "runarray.in"
+#line 648 "runarray.in"
void copyArrayValue(stack *Stack)
{
Int typeDepth=vm::pop<Int>(Stack);
Int depth=vm::pop<Int>(Stack,Int_MAX);
item value=vm::pop(Stack);
Int n=vm::pop<Int>(Stack);
-#line 613 "runarray.in"
+#line 649 "runarray.in"
if(n < 0) error("cannot create a negative length array");
if(depth < 0) error("cannot copy to a negative depth");
if(depth > typeDepth) depth=typeDepth;
@@ -689,25 +725,25 @@ void copyArrayValue(stack *Stack)
// typeDepth is the true depth of the array determined at compile-time when the
// operations for the array type are added. This typeDepth argument is
// automatically pushed on the stack and is not visible to the user.
-#line 624 "runarray.in"
+#line 660 "runarray.in"
void copyArray(stack *Stack)
{
Int typeDepth=vm::pop<Int>(Stack);
Int depth=vm::pop<Int>(Stack,Int_MAX);
array * a=vm::pop<array *>(Stack);
-#line 625 "runarray.in"
+#line 661 "runarray.in"
if(depth < 0) error("cannot copy to a negative depth");
if(depth > typeDepth) depth=typeDepth;
{Stack->push<array*>(a->copyToDepth(depth)); return;}
}
// Read an element from an array. Checks for initialization & bounds.
-#line 632 "runarray.in"
+#line 668 "runarray.in"
void arrayRead(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 633 "runarray.in"
+#line 669 "runarray.in"
item& i=arrayRead(a,n);
if (i.empty()) {
ostringstream buf;
@@ -718,37 +754,37 @@ void arrayRead(stack *Stack)
}
// Slice a substring from an array.
-#line 644 "runarray.in"
+#line 680 "runarray.in"
void arraySliceRead(stack *Stack)
{
Int right=vm::pop<Int>(Stack);
Int left=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 645 "runarray.in"
+#line 681 "runarray.in"
checkArray(a);
{Stack->push(a->slice(left, right)); return;}
}
// Slice a substring from an array. This implements the cases a[i:] and a[:]
// where the endpoint is not given, and assumed to be the length of the array.
-#line 652 "runarray.in"
+#line 688 "runarray.in"
void arraySliceReadToEnd(stack *Stack)
{
Int left=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 653 "runarray.in"
+#line 689 "runarray.in"
size_t len=checkArray(a);
{Stack->push(a->slice(left, (Int)len)); return;}
}
// Read an element from an array of arrays. Check bounds and initialize
// as necessary.
-#line 660 "runarray.in"
+#line 696 "runarray.in"
void arrayArrayRead(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 661 "runarray.in"
+#line 697 "runarray.in"
item& i=arrayRead(a,n);
if (i.empty()) i=new array(0);
{Stack->push(i); return;}
@@ -756,13 +792,13 @@ void arrayArrayRead(stack *Stack)
// Write an element to an array. Increase size if necessary.
// TODO: Add arrayWriteAndPop
-#line 669 "runarray.in"
+#line 705 "runarray.in"
void arrayWrite(stack *Stack)
{
item value=vm::pop(Stack);
Int n=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 670 "runarray.in"
+#line 706 "runarray.in"
size_t len=checkArray(a);
bool cyclic=a->cyclic();
if(cyclic && len > 0) n=imod(n,len);
@@ -776,27 +812,27 @@ void arrayWrite(stack *Stack)
{Stack->push(value); return;}
}
-#line 684 "runarray.in"
+#line 720 "runarray.in"
void arraySliceWrite(stack *Stack)
{
array * src=vm::pop<array *>(Stack);
Int right=vm::pop<Int>(Stack);
Int left=vm::pop<Int>(Stack);
array * dest=vm::pop<array *>(Stack);
-#line 685 "runarray.in"
+#line 721 "runarray.in"
checkArray(src);
checkArray(dest);
dest->setSlice(left, right, src);
{Stack->push<array*>(src); return;}
}
-#line 692 "runarray.in"
+#line 728 "runarray.in"
void arraySliceWriteToEnd(stack *Stack)
{
array * src=vm::pop<array *>(Stack);
Int left=vm::pop<Int>(Stack);
array * dest=vm::pop<array *>(Stack);
-#line 693 "runarray.in"
+#line 729 "runarray.in"
checkArray(src);
size_t len=checkArray(dest);
dest->setSlice(left, (Int) len, src);
@@ -804,20 +840,20 @@ void arraySliceWriteToEnd(stack *Stack)
}
// Returns the length of an array.
-#line 701 "runarray.in"
+#line 737 "runarray.in"
void arrayLength(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 702 "runarray.in"
+#line 738 "runarray.in"
{Stack->push<Int>((Int) checkArray(a)); return;}
}
// Returns an array of integers representing the keys of the array.
-#line 707 "runarray.in"
+#line 743 "runarray.in"
void arrayKeys(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 708 "runarray.in"
+#line 744 "runarray.in"
size_t size=checkArray(a);
array *keys=new array();
@@ -831,33 +867,33 @@ void arrayKeys(stack *Stack)
}
// Return the cyclic flag for an array.
-#line 722 "runarray.in"
+#line 758 "runarray.in"
void arrayCyclicFlag(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 723 "runarray.in"
+#line 759 "runarray.in"
checkArray(a);
{Stack->push<bool>(a->cyclic()); return;}
}
-#line 728 "runarray.in"
+#line 764 "runarray.in"
void arraySetCyclicFlag(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
bool b=vm::pop<bool>(Stack);
-#line 729 "runarray.in"
+#line 765 "runarray.in"
checkArray(a);
a->cyclic(b);
{Stack->push<bool>(b); return;}
}
// Check to see if an array element is initialized.
-#line 736 "runarray.in"
+#line 772 "runarray.in"
void arrayInitializedHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
Int n=vm::pop<Int>(Stack);
-#line 737 "runarray.in"
+#line 773 "runarray.in"
size_t len=checkArray(a);
bool cyclic=a->cyclic();
if(cyclic && len > 0) n=imod(n,len);
@@ -867,62 +903,62 @@ void arrayInitializedHelper(stack *Stack)
}
// Returns the initialize method for an array.
-#line 747 "runarray.in"
+#line 783 "runarray.in"
void arrayInitialized(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 748 "runarray.in"
+#line 784 "runarray.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayInitializedHelper),a)); return;}
}
// The helper function for the cyclic method that sets the cyclic flag.
-#line 753 "runarray.in"
+#line 789 "runarray.in"
void arrayCyclicHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
bool b=vm::pop<bool>(Stack);
-#line 754 "runarray.in"
+#line 790 "runarray.in"
checkArray(a);
a->cyclic(b);
}
// Set the cyclic flag for an array.
-#line 760 "runarray.in"
+#line 796 "runarray.in"
void arrayCyclic(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 761 "runarray.in"
+#line 797 "runarray.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayCyclicHelper),a)); return;}
}
// The helper function for the push method that does the actual operation.
-#line 766 "runarray.in"
+#line 802 "runarray.in"
void arrayPushHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
item x=vm::pop(Stack);
-#line 767 "runarray.in"
+#line 803 "runarray.in"
checkArray(a);
a->push(x);
{Stack->push(x); return;}
}
// Returns the push method for an array.
-#line 774 "runarray.in"
+#line 810 "runarray.in"
void arrayPush(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 775 "runarray.in"
+#line 811 "runarray.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayPushHelper),a)); return;}
}
// The helper function for the append method that appends b to a.
-#line 780 "runarray.in"
+#line 816 "runarray.in"
void arrayAppendHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
array * b=vm::pop<array *>(Stack);
-#line 781 "runarray.in"
+#line 817 "runarray.in"
checkArray(a);
size_t size=checkArray(b);
for(size_t i=0; i < size; i++)
@@ -930,20 +966,20 @@ void arrayAppendHelper(stack *Stack)
}
// Returns the append method for an array.
-#line 789 "runarray.in"
+#line 825 "runarray.in"
void arrayAppend(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 790 "runarray.in"
+#line 826 "runarray.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayAppendHelper),a)); return;}
}
// The helper function for the pop method.
-#line 795 "runarray.in"
+#line 831 "runarray.in"
void arrayPopHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 796 "runarray.in"
+#line 832 "runarray.in"
size_t asize=checkArray(a);
if(asize == 0)
error("cannot pop element from empty array");
@@ -951,22 +987,22 @@ void arrayPopHelper(stack *Stack)
}
// Returns the pop method for an array.
-#line 804 "runarray.in"
+#line 840 "runarray.in"
void arrayPop(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 805 "runarray.in"
+#line 841 "runarray.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayPopHelper),a)); return;}
}
// The helper function for the insert method.
-#line 810 "runarray.in"
+#line 846 "runarray.in"
void arrayInsertHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
array * x=vm::pop<array *>(Stack);
Int i=vm::pop<Int>(Stack);
-#line 811 "runarray.in"
+#line 847 "runarray.in"
size_t asize=checkArray(a);
checkArray(x);
if(a->cyclic() && asize > 0) i=imod(i,asize);
@@ -976,39 +1012,39 @@ void arrayInsertHelper(stack *Stack)
}
// Returns the insert method for an array.
-#line 821 "runarray.in"
+#line 857 "runarray.in"
void arrayInsert(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 822 "runarray.in"
+#line 858 "runarray.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayInsertHelper),a)); return;}
}
// Returns the delete method for an array.
-#line 827 "runarray.in"
+#line 863 "runarray.in"
void arrayDelete(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 828 "runarray.in"
+#line 864 "runarray.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayDeleteHelper),a)); return;}
}
-#line 832 "runarray.in"
+#line 868 "runarray.in"
void arrayAlias(stack *Stack)
{
array * b=vm::pop<array *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 833 "runarray.in"
+#line 869 "runarray.in"
{Stack->push<bool>(a==b); return;}
}
// Return array formed by indexing array a with elements of integer array b
-#line 838 "runarray.in"
+#line 874 "runarray.in"
void arrayIntArray(stack *Stack)
{
array * b=vm::pop<array *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 839 "runarray.in"
+#line 875 "runarray.in"
size_t asize=checkArray(a);
size_t bsize=checkArray(b);
array *r=new array(bsize);
@@ -1026,13 +1062,13 @@ void arrayIntArray(stack *Stack)
// returns the complement of the integer array a in {0,2,...,n-1},
// so that b[complement(a,b.length)] yields the complement of b[a].
-#line 857 "runarray.in"
+#line 893 "runarray.in"
// Intarray* complement(Intarray *a, Int n);
void gen_runarray32(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
Intarray * a=vm::pop<Intarray *>(Stack);
-#line 858 "runarray.in"
+#line 894 "runarray.in"
size_t asize=checkArray(a);
array *r=new array(0);
bool *keep=new bool[n];
@@ -1049,12 +1085,12 @@ void gen_runarray32(stack *Stack)
}
// Generate the sequence {f(i) : i=0,1,...n-1} given a function f and integer n
-#line 875 "runarray.in"
+#line 911 "runarray.in"
void arraySequence(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
callable * f=vm::pop<callable *>(Stack);
-#line 876 "runarray.in"
+#line 912 "runarray.in"
if(n < 0) n=0;
array *a=new array(n);
for(Int i=0; i < n; ++i) {
@@ -1066,12 +1102,12 @@ void arraySequence(stack *Stack)
}
// Return the array {0,1,...n-1}
-#line 888 "runarray.in"
+#line 924 "runarray.in"
// Intarray* sequence(Int n);
void gen_runarray34(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 889 "runarray.in"
+#line 925 "runarray.in"
if(n < 0) n=0;
array *a=new array(n);
for(Int i=0; i < n; ++i) {
@@ -1081,12 +1117,12 @@ void gen_runarray34(stack *Stack)
}
// Apply a function to each element of an array
-#line 899 "runarray.in"
+#line 935 "runarray.in"
void arrayFunction(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
callable * f=vm::pop<callable *>(Stack);
-#line 900 "runarray.in"
+#line 936 "runarray.in"
size_t size=checkArray(a);
array *b=new array(size);
for(size_t i=0; i < size; ++i) {
@@ -1097,13 +1133,13 @@ void arrayFunction(stack *Stack)
{Stack->push<array*>(b); return;}
}
-#line 911 "runarray.in"
+#line 947 "runarray.in"
void arraySort(stack *Stack)
{
bool stable=vm::pop<bool>(Stack,true);
callable * less=vm::pop<callable *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 912 "runarray.in"
+#line 948 "runarray.in"
array *c=copyArray(a);
compareFunc=less;
FuncStack=Stack;
@@ -1112,13 +1148,13 @@ void arraySort(stack *Stack)
{Stack->push<array*>(c); return;}
}
-#line 921 "runarray.in"
+#line 957 "runarray.in"
void arraySearch(stack *Stack)
{
callable * less=vm::pop<callable *>(Stack);
item key=vm::pop(Stack);
array * a=vm::pop<array *>(Stack);
-#line 922 "runarray.in"
+#line 958 "runarray.in"
size_t size=a->size();
compareFunc=less;
FuncStack=Stack;
@@ -1136,12 +1172,12 @@ void arraySearch(stack *Stack)
{Stack->push<Int>(0); return;}
}
-#line 940 "runarray.in"
+#line 976 "runarray.in"
// bool all(boolarray *a);
void gen_runarray38(stack *Stack)
{
boolarray * a=vm::pop<boolarray *>(Stack);
-#line 941 "runarray.in"
+#line 977 "runarray.in"
size_t size=checkArray(a);
bool c=true;
for(size_t i=0; i < size; i++)
@@ -1149,12 +1185,12 @@ void gen_runarray38(stack *Stack)
{Stack->push<bool>(c); return;}
}
-#line 949 "runarray.in"
+#line 985 "runarray.in"
// boolarray* !(boolarray* a);
void gen_runarray39(stack *Stack)
{
boolarray* a=vm::pop<boolarray*>(Stack);
-#line 950 "runarray.in"
+#line 986 "runarray.in"
size_t size=checkArray(a);
array *c=new array(size);
for(size_t i=0; i < size; i++)
@@ -1162,12 +1198,12 @@ void gen_runarray39(stack *Stack)
{Stack->push<boolarray*>(c); return;}
}
-#line 958 "runarray.in"
+#line 994 "runarray.in"
// Int sum(boolarray *a);
void gen_runarray40(stack *Stack)
{
boolarray * a=vm::pop<boolarray *>(Stack);
-#line 959 "runarray.in"
+#line 995 "runarray.in"
size_t size=checkArray(a);
Int sum=0;
for(size_t i=0; i < size; i++)
@@ -1175,11 +1211,11 @@ void gen_runarray40(stack *Stack)
{Stack->push<Int>(sum); return;}
}
-#line 967 "runarray.in"
+#line 1003 "runarray.in"
void arrayConcat(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 968 "runarray.in"
+#line 1004 "runarray.in"
// a is an array of arrays to be concatenated together.
// The signature is
// T[] concat(... T[][] a);
@@ -1206,11 +1242,11 @@ void arrayConcat(stack *Stack)
{Stack->push<array*>(result); return;}
}
-#line 995 "runarray.in"
+#line 1031 "runarray.in"
void array2Transpose(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 996 "runarray.in"
+#line 1032 "runarray.in"
size_t asize=checkArray(a);
array *c=new array(0);
for(size_t i=0; i < asize; i++) {
@@ -1237,12 +1273,12 @@ void array2Transpose(stack *Stack)
// permutation (021 or 120, etc; original is 012).
// Transpose by sending respective members to the permutated locations:
// return the array obtained by putting a[i][j][k] into position perm{ijk}.
-#line 1023 "runarray.in"
+#line 1059 "runarray.in"
void array3Transpose(stack *Stack)
{
array * perm=vm::pop<array *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 1024 "runarray.in"
+#line 1060 "runarray.in"
const size_t DIM=3;
if(checkArray(perm) != DIM) {
@@ -1326,13 +1362,13 @@ void array3Transpose(stack *Stack)
// Find the index of the nth true value in a boolean array or -1 if not found.
// If n is negative, search backwards.
-#line 1108 "runarray.in"
+#line 1144 "runarray.in"
// Int find(boolarray *a, Int n=1);
void gen_runarray44(stack *Stack)
{
Int n=vm::pop<Int>(Stack,1);
boolarray * a=vm::pop<boolarray *>(Stack);
-#line 1109 "runarray.in"
+#line 1145 "runarray.in"
size_t size=checkArray(a);
Int j=-1;
if(n > 0)
@@ -1349,12 +1385,12 @@ void gen_runarray44(stack *Stack)
}
// Find all indices of true values in a boolean array.
-#line 1126 "runarray.in"
+#line 1162 "runarray.in"
// Intarray* findall(boolarray *a);
void gen_runarray45(stack *Stack)
{
boolarray * a=vm::pop<boolarray *>(Stack);
-#line 1127 "runarray.in"
+#line 1163 "runarray.in"
size_t size=checkArray(a);
array *b=new array(0);
for(size_t i=0; i < size; i++) {
@@ -1367,13 +1403,13 @@ void gen_runarray45(stack *Stack)
// construct vector obtained by replacing those elements of b for which the
// corresponding elements of a are false by the corresponding element of c.
-#line 1140 "runarray.in"
+#line 1176 "runarray.in"
void arrayConditional(stack *Stack)
{
array * c=vm::pop<array *>(Stack);
array * b=vm::pop<array *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 1141 "runarray.in"
+#line 1177 "runarray.in"
size_t size=checkArray(a);
array *r=new array(size);
if(b && c) {
@@ -1397,22 +1433,22 @@ void arrayConditional(stack *Stack)
}
// Return an n x n identity matrix.
-#line 1165 "runarray.in"
+#line 1201 "runarray.in"
// realarray2* identity(Int n);
void gen_runarray47(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 1166 "runarray.in"
+#line 1202 "runarray.in"
{Stack->push<realarray2*>(Identity(n)); return;}
}
// Return the inverse of an n x n matrix a using Gauss-Jordan elimination.
-#line 1171 "runarray.in"
+#line 1207 "runarray.in"
// realarray2* inverse(realarray2 *a);
void gen_runarray48(stack *Stack)
{
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1172 "runarray.in"
+#line 1208 "runarray.in"
size_t n=checkArray(a);
double *A;
copyArray2C(A,a,true,0,NoGC);
@@ -1425,14 +1461,14 @@ void gen_runarray48(stack *Stack)
// Solve the linear equation ax=b by LU decomposition, returning the
// solution x, where a is an n x n matrix and b is an array of length n.
// If no solution exists, return an empty array.
-#line 1185 "runarray.in"
+#line 1221 "runarray.in"
// realarray* solve(realarray2 *a, realarray *b, bool warn=true);
void gen_runarray49(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
realarray * b=vm::pop<realarray *>(Stack);
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1186 "runarray.in"
+#line 1222 "runarray.in"
size_t n=checkArray(a);
if(n == 0) {Stack->push<realarray*>(new array(0)); return;}
@@ -1484,14 +1520,14 @@ void gen_runarray49(stack *Stack)
// Solve the linear equation ax=b by LU decomposition, returning the
// solution x, where a is an n x n matrix and b is an n x m matrix.
// If no solution exists, return an empty array.
-#line 1238 "runarray.in"
+#line 1274 "runarray.in"
// realarray2* solve(realarray2 *a, realarray2 *b, bool warn=true);
void gen_runarray50(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
realarray2 * b=vm::pop<realarray2 *>(Stack);
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1239 "runarray.in"
+#line 1275 "runarray.in"
size_t n=checkArray(a);
if(n == 0) {Stack->push<realarray2*>(new array(0)); return;}
@@ -1553,12 +1589,12 @@ void gen_runarray50(stack *Stack)
}
// Compute the determinant of an n x n matrix.
-#line 1301 "runarray.in"
+#line 1337 "runarray.in"
// real determinant(realarray2 *a);
void gen_runarray51(stack *Stack)
{
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1302 "runarray.in"
+#line 1338 "runarray.in"
real *A;
copyArray2C(A,a);
size_t n=checkArray(a);
@@ -1573,13 +1609,13 @@ void gen_runarray51(stack *Stack)
{Stack->push<real>(det); return;}
}
-#line 1317 "runarray.in"
+#line 1353 "runarray.in"
// realarray* *(realarray2 *a, realarray *b);
void gen_runarray52(stack *Stack)
{
realarray * b=vm::pop<realarray *>(Stack);
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1318 "runarray.in"
+#line 1354 "runarray.in"
size_t n=checkArray(a);
size_t m=checkArray(b);
array *c=new array(n);
@@ -1597,13 +1633,13 @@ void gen_runarray52(stack *Stack)
{Stack->push<realarray*>(c); return;}
}
-#line 1336 "runarray.in"
+#line 1372 "runarray.in"
// realarray* *(realarray *a, realarray2 *b);
void gen_runarray53(stack *Stack)
{
realarray2 * b=vm::pop<realarray2 *>(Stack);
realarray * a=vm::pop<realarray *>(Stack);
-#line 1337 "runarray.in"
+#line 1373 "runarray.in"
size_t n=checkArray(a);
if(n != checkArray(b)) error(incommensurate);
real *A;
@@ -1631,62 +1667,62 @@ void gen_runarray53(stack *Stack)
{Stack->push<realarray*>(c); return;}
}
-#line 1365 "runarray.in"
+#line 1401 "runarray.in"
// Intarray2* *(Intarray2 *a, Intarray2 *b);
void gen_runarray54(stack *Stack)
{
Intarray2 * b=vm::pop<Intarray2 *>(Stack);
Intarray2 * a=vm::pop<Intarray2 *>(Stack);
-#line 1366 "runarray.in"
+#line 1402 "runarray.in"
{Stack->push<Intarray2*>(mult<Int>(a,b)); return;}
}
-#line 1370 "runarray.in"
+#line 1406 "runarray.in"
// realarray2* *(realarray2 *a, realarray2 *b);
void gen_runarray55(stack *Stack)
{
realarray2 * b=vm::pop<realarray2 *>(Stack);
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1371 "runarray.in"
+#line 1407 "runarray.in"
{Stack->push<realarray2*>(mult<real>(a,b)); return;}
}
-#line 1375 "runarray.in"
+#line 1411 "runarray.in"
// pairarray2* *(pairarray2 *a, pairarray2 *b);
void gen_runarray56(stack *Stack)
{
pairarray2 * b=vm::pop<pairarray2 *>(Stack);
pairarray2 * a=vm::pop<pairarray2 *>(Stack);
-#line 1376 "runarray.in"
+#line 1412 "runarray.in"
{Stack->push<pairarray2*>(mult<pair>(a,b)); return;}
}
-#line 1380 "runarray.in"
+#line 1416 "runarray.in"
// triple *(realarray2 *t, triple v);
void gen_runarray57(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
-#line 1381 "runarray.in"
+#line 1417 "runarray.in"
{Stack->push<triple>(*t*v); return;}
}
-#line 1385 "runarray.in"
+#line 1421 "runarray.in"
// realarray2* AtA(realarray2 *a);
void gen_runarray58(stack *Stack)
{
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1386 "runarray.in"
+#line 1422 "runarray.in"
{Stack->push<realarray2*>(AtA<real>(a)); return;}
}
-#line 1390 "runarray.in"
+#line 1426 "runarray.in"
// pair project(triple v, realarray2 *t);
void gen_runarray59(stack *Stack)
{
realarray2 * t=vm::pop<realarray2 *>(Stack);
triple v=vm::pop<triple>(Stack);
-#line 1391 "runarray.in"
+#line 1427 "runarray.in"
size_t n=checkArray(t);
if(n != 4) error(incommensurate);
array *t0=read<array*>(t,0);
@@ -1711,13 +1747,13 @@ void gen_runarray59(stack *Stack)
}
// Compute the dot product of vectors a and b.
-#line 1416 "runarray.in"
+#line 1452 "runarray.in"
// real dot(realarray *a, realarray *b);
void gen_runarray60(stack *Stack)
{
realarray * b=vm::pop<realarray *>(Stack);
realarray * a=vm::pop<realarray *>(Stack);
-#line 1417 "runarray.in"
+#line 1453 "runarray.in"
size_t n=checkArrays(a,b);
real sum=0.0;
for(size_t i=0; i < n; ++i)
@@ -1726,13 +1762,13 @@ void gen_runarray60(stack *Stack)
}
// Compute the complex dot product of vectors a and b.
-#line 1426 "runarray.in"
+#line 1462 "runarray.in"
// pair dot(pairarray *a, pairarray *b);
void gen_runarray61(stack *Stack)
{
pairarray * b=vm::pop<pairarray *>(Stack);
pairarray * a=vm::pop<pairarray *>(Stack);
-#line 1427 "runarray.in"
+#line 1463 "runarray.in"
size_t n=checkArrays(a,b);
pair sum=zero;
for(size_t i=0; i < n; ++i)
@@ -1747,7 +1783,7 @@ void gen_runarray61(stack *Stack)
// [ a[2] b[2] c[2] ]
// [ ... ]
// [ c[n-1] a[n-1] b[n-1] ]
-#line 1442 "runarray.in"
+#line 1478 "runarray.in"
// realarray* tridiagonal(realarray *a, realarray *b, realarray *c, realarray *f);
void gen_runarray62(stack *Stack)
{
@@ -1755,7 +1791,7 @@ void gen_runarray62(stack *Stack)
realarray * c=vm::pop<realarray *>(Stack);
realarray * b=vm::pop<realarray *>(Stack);
realarray * a=vm::pop<realarray *>(Stack);
-#line 1443 "runarray.in"
+#line 1479 "runarray.in"
size_t n=checkArrays(a,b);
checkEqual(n,checkArray(c));
checkEqual(n,checkArray(f));
@@ -1852,7 +1888,7 @@ void gen_runarray62(stack *Stack)
}
// Root solve by Newton-Raphson
-#line 1540 "runarray.in"
+#line 1576 "runarray.in"
// real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x, bool verbose=false);
void gen_runarray63(stack *Stack)
{
@@ -1861,7 +1897,7 @@ void gen_runarray63(stack *Stack)
callableReal * fprime=vm::pop<callableReal *>(Stack);
callableReal * f=vm::pop<callableReal *>(Stack);
Int iterations=vm::pop<Int>(Stack,100);
-#line 1542 "runarray.in"
+#line 1578 "runarray.in"
static const real fuzz=1000.0*DBL_EPSILON;
Int i=0;
size_t oldPrec=0;
@@ -1907,7 +1943,7 @@ void gen_runarray63(stack *Stack)
// Root solve by Newton-Raphson bisection
// cf. routine rtsafe (Press et al., Numerical Recipes, 1991).
-#line 1588 "runarray.in"
+#line 1624 "runarray.in"
// real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x1, real x2, bool verbose=false);
void gen_runarray64(stack *Stack)
{
@@ -1917,7 +1953,7 @@ void gen_runarray64(stack *Stack)
callableReal * fprime=vm::pop<callableReal *>(Stack);
callableReal * f=vm::pop<callableReal *>(Stack);
Int iterations=vm::pop<Int>(Stack,100);
-#line 1590 "runarray.in"
+#line 1626 "runarray.in"
static const real fuzz=1000.0*DBL_EPSILON;
size_t oldPrec=0;
if(verbose)
@@ -2003,7 +2039,7 @@ void gen_runarray64(stack *Stack)
// In this implementation, the binary search is interleaved
// with a modified version of quadratic interpolation.
// This is a C++ port of the Asymptote routine written by Charles Staats III.
-#line 1676 "runarray.in"
+#line 1712 "runarray.in"
// real _findroot(callableReal *f, real a, real b, real tolerance, real fa, real fb);
void gen_runarray65(stack *Stack)
{
@@ -2013,7 +2049,7 @@ void gen_runarray65(stack *Stack)
real b=vm::pop<real>(Stack);
real a=vm::pop<real>(Stack);
callableReal * f=vm::pop<callableReal *>(Stack);
-#line 1678 "runarray.in"
+#line 1714 "runarray.in"
if(fa == 0.0) {Stack->push<real>(a); return;}
if(fb == 0.0) {Stack->push<real>(b); return;}
@@ -2105,7 +2141,7 @@ void gen_runarray65(stack *Stack)
{Stack->push<real>(a-(b-a)/(fb-fa)*fa); return;}
}
-#line 1770 "runarray.in"
+#line 1806 "runarray.in"
// real simpson(callableReal *f, real a, real b, real acc=DBL_EPSILON, real dxmax=0);
void gen_runarray66(stack *Stack)
{
@@ -2114,7 +2150,7 @@ void gen_runarray66(stack *Stack)
real b=vm::pop<real>(Stack);
real a=vm::pop<real>(Stack);
callableReal * f=vm::pop<callableReal *>(Stack);
-#line 1772 "runarray.in"
+#line 1808 "runarray.in"
real integral;
if(dxmax <= 0) dxmax=fabs(b-a);
callable *oldFunc=Func;
@@ -2127,13 +2163,13 @@ void gen_runarray66(stack *Stack)
}
// Compute the fast Fourier transform of a pair array
-#line 1785 "runarray.in"
+#line 1821 "runarray.in"
// pairarray* fft(pairarray *a, Int sign=1);
void gen_runarray67(stack *Stack)
{
Int sign=vm::pop<Int>(Stack,1);
pairarray * a=vm::pop<pairarray *>(Stack);
-#line 1786 "runarray.in"
+#line 1822 "runarray.in"
#ifdef HAVE_LIBFFTW3
unsigned n=(unsigned) checkArray(a);
array *c=new array(n);
@@ -2162,12 +2198,12 @@ void gen_runarray67(stack *Stack)
{Stack->push<pairarray*>(c); return;}
}
-#line 1815 "runarray.in"
+#line 1851 "runarray.in"
// Intarray2* triangulate(pairarray *z);
void gen_runarray68(stack *Stack)
{
pairarray * z=vm::pop<pairarray *>(Stack);
-#line 1816 "runarray.in"
+#line 1852 "runarray.in"
size_t nv=checkArray(z);
// Call robust version of Gilles Dumoulin's port of Paul Bourke's
// triangulation code.
@@ -2201,12 +2237,12 @@ void gen_runarray68(stack *Stack)
{Stack->push<Intarray2*>(t); return;}
}
-#line 1850 "runarray.in"
+#line 1886 "runarray.in"
// real norm(realarray *a);
void gen_runarray69(stack *Stack)
{
realarray * a=vm::pop<realarray *>(Stack);
-#line 1851 "runarray.in"
+#line 1887 "runarray.in"
size_t n=checkArray(a);
real M=0.0;
for(size_t i=0; i < n; ++i) {
@@ -2216,12 +2252,12 @@ void gen_runarray69(stack *Stack)
{Stack->push<real>(M); return;}
}
-#line 1861 "runarray.in"
+#line 1897 "runarray.in"
// real norm(realarray2 *a);
void gen_runarray70(stack *Stack)
{
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1862 "runarray.in"
+#line 1898 "runarray.in"
size_t n=checkArray(a);
real M=0.0;
for(size_t i=0; i < n; ++i) {
@@ -2235,12 +2271,12 @@ void gen_runarray70(stack *Stack)
{Stack->push<real>(M); return;}
}
-#line 1876 "runarray.in"
+#line 1912 "runarray.in"
// real norm(triplearray2 *a);
void gen_runarray71(stack *Stack)
{
triplearray2 * a=vm::pop<triplearray2 *>(Stack);
-#line 1877 "runarray.in"
+#line 1913 "runarray.in"
size_t n=checkArray(a);
real M=0.0;
for(size_t i=0; i < n; ++i) {
@@ -2254,12 +2290,12 @@ void gen_runarray71(stack *Stack)
{Stack->push<real>(sqrt(M)); return;}
}
-#line 1891 "runarray.in"
+#line 1927 "runarray.in"
// real change2(triplearray2 *a);
void gen_runarray72(stack *Stack)
{
triplearray2 * a=vm::pop<triplearray2 *>(Stack);
-#line 1892 "runarray.in"
+#line 1928 "runarray.in"
size_t n=checkArray(a);
if(n == 0) {Stack->push<real>(0.0); return;}
@@ -2280,13 +2316,13 @@ void gen_runarray72(stack *Stack)
{Stack->push<real>(M); return;}
}
-#line 1913 "runarray.in"
+#line 1949 "runarray.in"
// triple minbezier(triplearray2 *P, triple b);
void gen_runarray73(stack *Stack)
{
triple b=vm::pop<triple>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 1914 "runarray.in"
+#line 1950 "runarray.in"
size_t N;
real *A=copyTripleArray2Components(P,N);
bound_double *B=bounddouble(N);
@@ -2297,13 +2333,13 @@ void gen_runarray73(stack *Stack)
{Stack->push<triple>(b); return;}
}
-#line 1925 "runarray.in"
+#line 1961 "runarray.in"
// triple maxbezier(triplearray2 *P, triple b);
void gen_runarray74(stack *Stack)
{
triple b=vm::pop<triple>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 1926 "runarray.in"
+#line 1962 "runarray.in"
size_t N;
real *A=copyTripleArray2Components(P,N);
bound_double *B=bounddouble(N);
@@ -2314,13 +2350,13 @@ void gen_runarray74(stack *Stack)
{Stack->push<triple>(b); return;}
}
-#line 1937 "runarray.in"
+#line 1973 "runarray.in"
// pair minratio(triplearray2 *P, pair b);
void gen_runarray75(stack *Stack)
{
pair b=vm::pop<pair>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 1938 "runarray.in"
+#line 1974 "runarray.in"
size_t N;
triple *A=copyTripleArray2C(P,N);
real fuzz=Fuzz*norm(A,N);
@@ -2331,13 +2367,13 @@ void gen_runarray75(stack *Stack)
{Stack->push<pair>(b); return;}
}
-#line 1949 "runarray.in"
+#line 1985 "runarray.in"
// pair maxratio(triplearray2 *P, pair b);
void gen_runarray76(stack *Stack)
{
pair b=vm::pop<pair>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 1950 "runarray.in"
+#line 1986 "runarray.in"
size_t N;
triple *A=copyTripleArray2C(P,N);
bound_triple *B=boundtriple(N);
@@ -2348,11 +2384,11 @@ void gen_runarray76(stack *Stack)
{Stack->push<pair>(b); return;}
}
-#line 1961 "runarray.in"
+#line 1997 "runarray.in"
// realarray* _projection();
void gen_runarray77(stack *Stack)
{
-#line 1962 "runarray.in"
+#line 1998 "runarray.in"
#ifdef HAVE_GL
array *a=new array(14);
gl::projection P=gl::camera();
@@ -2389,161 +2425,161 @@ namespace trans {
void gen_runarray_venv(venv &ve)
{
-#line 549 "runarray.in"
+#line 585 "runarray.in"
REGISTER_BLTIN(run::emptyArray,"emptyArray");
-#line 555 "runarray.in"
+#line 591 "runarray.in"
REGISTER_BLTIN(run::newDeepArray,"newDeepArray");
-#line 577 "runarray.in"
+#line 613 "runarray.in"
REGISTER_BLTIN(run::newInitializedArray,"newInitializedArray");
-#line 592 "runarray.in"
+#line 628 "runarray.in"
REGISTER_BLTIN(run::newAppendedArray,"newAppendedArray");
-#line 608 "runarray.in"
+#line 644 "runarray.in"
REGISTER_BLTIN(run::copyArrayValue,"copyArrayValue");
-#line 620 "runarray.in"
+#line 656 "runarray.in"
REGISTER_BLTIN(run::copyArray,"copyArray");
-#line 631 "runarray.in"
+#line 667 "runarray.in"
REGISTER_BLTIN(run::arrayRead,"arrayRead");
-#line 643 "runarray.in"
+#line 679 "runarray.in"
REGISTER_BLTIN(run::arraySliceRead,"arraySliceRead");
-#line 650 "runarray.in"
+#line 686 "runarray.in"
REGISTER_BLTIN(run::arraySliceReadToEnd,"arraySliceReadToEnd");
-#line 658 "runarray.in"
+#line 694 "runarray.in"
REGISTER_BLTIN(run::arrayArrayRead,"arrayArrayRead");
-#line 667 "runarray.in"
+#line 703 "runarray.in"
REGISTER_BLTIN(run::arrayWrite,"arrayWrite");
-#line 684 "runarray.in"
+#line 720 "runarray.in"
REGISTER_BLTIN(run::arraySliceWrite,"arraySliceWrite");
-#line 692 "runarray.in"
+#line 728 "runarray.in"
REGISTER_BLTIN(run::arraySliceWriteToEnd,"arraySliceWriteToEnd");
-#line 700 "runarray.in"
+#line 736 "runarray.in"
REGISTER_BLTIN(run::arrayLength,"arrayLength");
-#line 706 "runarray.in"
+#line 742 "runarray.in"
REGISTER_BLTIN(run::arrayKeys,"arrayKeys");
-#line 721 "runarray.in"
+#line 757 "runarray.in"
REGISTER_BLTIN(run::arrayCyclicFlag,"arrayCyclicFlag");
-#line 728 "runarray.in"
+#line 764 "runarray.in"
REGISTER_BLTIN(run::arraySetCyclicFlag,"arraySetCyclicFlag");
-#line 735 "runarray.in"
+#line 771 "runarray.in"
REGISTER_BLTIN(run::arrayInitializedHelper,"arrayInitializedHelper");
-#line 746 "runarray.in"
+#line 782 "runarray.in"
REGISTER_BLTIN(run::arrayInitialized,"arrayInitialized");
-#line 752 "runarray.in"
+#line 788 "runarray.in"
REGISTER_BLTIN(run::arrayCyclicHelper,"arrayCyclicHelper");
-#line 759 "runarray.in"
+#line 795 "runarray.in"
REGISTER_BLTIN(run::arrayCyclic,"arrayCyclic");
-#line 765 "runarray.in"
+#line 801 "runarray.in"
REGISTER_BLTIN(run::arrayPushHelper,"arrayPushHelper");
-#line 773 "runarray.in"
+#line 809 "runarray.in"
REGISTER_BLTIN(run::arrayPush,"arrayPush");
-#line 779 "runarray.in"
+#line 815 "runarray.in"
REGISTER_BLTIN(run::arrayAppendHelper,"arrayAppendHelper");
-#line 788 "runarray.in"
+#line 824 "runarray.in"
REGISTER_BLTIN(run::arrayAppend,"arrayAppend");
-#line 794 "runarray.in"
+#line 830 "runarray.in"
REGISTER_BLTIN(run::arrayPopHelper,"arrayPopHelper");
-#line 803 "runarray.in"
+#line 839 "runarray.in"
REGISTER_BLTIN(run::arrayPop,"arrayPop");
-#line 809 "runarray.in"
+#line 845 "runarray.in"
REGISTER_BLTIN(run::arrayInsertHelper,"arrayInsertHelper");
-#line 820 "runarray.in"
+#line 856 "runarray.in"
REGISTER_BLTIN(run::arrayInsert,"arrayInsert");
-#line 826 "runarray.in"
+#line 862 "runarray.in"
REGISTER_BLTIN(run::arrayDelete,"arrayDelete");
-#line 832 "runarray.in"
+#line 868 "runarray.in"
REGISTER_BLTIN(run::arrayAlias,"arrayAlias");
-#line 837 "runarray.in"
+#line 873 "runarray.in"
REGISTER_BLTIN(run::arrayIntArray,"arrayIntArray");
-#line 855 "runarray.in"
+#line 891 "runarray.in"
addFunc(ve, run::gen_runarray32, IntArray(), SYM(complement), formal(IntArray(), SYM(a), false, false), formal(primInt(), SYM(n), false, false));
-#line 874 "runarray.in"
+#line 910 "runarray.in"
REGISTER_BLTIN(run::arraySequence,"arraySequence");
-#line 887 "runarray.in"
+#line 923 "runarray.in"
addFunc(ve, run::gen_runarray34, IntArray(), SYM(sequence), formal(primInt(), SYM(n), false, false));
-#line 898 "runarray.in"
+#line 934 "runarray.in"
REGISTER_BLTIN(run::arrayFunction,"arrayFunction");
-#line 911 "runarray.in"
+#line 947 "runarray.in"
REGISTER_BLTIN(run::arraySort,"arraySort");
-#line 921 "runarray.in"
+#line 957 "runarray.in"
REGISTER_BLTIN(run::arraySearch,"arraySearch");
-#line 940 "runarray.in"
+#line 976 "runarray.in"
addFunc(ve, run::gen_runarray38, primBoolean(), SYM(all), formal(booleanArray(), SYM(a), false, false));
-#line 949 "runarray.in"
+#line 985 "runarray.in"
addFunc(ve, run::gen_runarray39, booleanArray(), SYM_LOGNOT, formal(booleanArray(), SYM(a), false, false));
-#line 958 "runarray.in"
+#line 994 "runarray.in"
addFunc(ve, run::gen_runarray40, primInt(), SYM(sum), formal(booleanArray(), SYM(a), false, false));
-#line 967 "runarray.in"
+#line 1003 "runarray.in"
REGISTER_BLTIN(run::arrayConcat,"arrayConcat");
-#line 995 "runarray.in"
+#line 1031 "runarray.in"
REGISTER_BLTIN(run::array2Transpose,"array2Transpose");
-#line 1019 "runarray.in"
+#line 1055 "runarray.in"
REGISTER_BLTIN(run::array3Transpose,"array3Transpose");
-#line 1106 "runarray.in"
+#line 1142 "runarray.in"
addFunc(ve, run::gen_runarray44, primInt(), SYM(find), formal(booleanArray(), SYM(a), false, false), formal(primInt(), SYM(n), true, false));
-#line 1125 "runarray.in"
+#line 1161 "runarray.in"
addFunc(ve, run::gen_runarray45, IntArray(), SYM(findall), formal(booleanArray(), SYM(a), false, false));
-#line 1138 "runarray.in"
+#line 1174 "runarray.in"
REGISTER_BLTIN(run::arrayConditional,"arrayConditional");
-#line 1164 "runarray.in"
+#line 1200 "runarray.in"
addFunc(ve, run::gen_runarray47, realArray2(), SYM(identity), formal(primInt(), SYM(n), false, false));
-#line 1170 "runarray.in"
+#line 1206 "runarray.in"
addFunc(ve, run::gen_runarray48, realArray2(), SYM(inverse), formal(realArray2(), SYM(a), false, false));
-#line 1182 "runarray.in"
+#line 1218 "runarray.in"
addFunc(ve, run::gen_runarray49, realArray(), SYM(solve), formal(realArray2(), SYM(a), false, false), formal(realArray(), SYM(b), false, false), formal(primBoolean(), SYM(warn), true, false));
-#line 1235 "runarray.in"
+#line 1271 "runarray.in"
addFunc(ve, run::gen_runarray50, realArray2(), SYM(solve), formal(realArray2(), SYM(a), false, false), formal(realArray2(), SYM(b), false, false), formal(primBoolean(), SYM(warn), true, false));
-#line 1300 "runarray.in"
+#line 1336 "runarray.in"
addFunc(ve, run::gen_runarray51, primReal(), SYM(determinant), formal(realArray2(), SYM(a), false, false));
-#line 1317 "runarray.in"
+#line 1353 "runarray.in"
addFunc(ve, run::gen_runarray52, realArray(), SYM_TIMES, formal(realArray2(), SYM(a), false, false), formal(realArray(), SYM(b), false, false));
-#line 1336 "runarray.in"
+#line 1372 "runarray.in"
addFunc(ve, run::gen_runarray53, realArray(), SYM_TIMES, formal(realArray(), SYM(a), false, false), formal(realArray2(), SYM(b), false, false));
-#line 1365 "runarray.in"
+#line 1401 "runarray.in"
addFunc(ve, run::gen_runarray54, IntArray2(), SYM_TIMES, formal(IntArray2(), SYM(a), false, false), formal(IntArray2(), SYM(b), false, false));
-#line 1370 "runarray.in"
+#line 1406 "runarray.in"
addFunc(ve, run::gen_runarray55, realArray2(), SYM_TIMES, formal(realArray2(), SYM(a), false, false), formal(realArray2(), SYM(b), false, false));
-#line 1375 "runarray.in"
+#line 1411 "runarray.in"
addFunc(ve, run::gen_runarray56, pairArray2(), SYM_TIMES, formal(pairArray2(), SYM(a), false, false), formal(pairArray2(), SYM(b), false, false));
-#line 1380 "runarray.in"
+#line 1416 "runarray.in"
addFunc(ve, run::gen_runarray57, primTriple(), SYM_TIMES, formal(realArray2(), SYM(t), false, false), formal(primTriple(), SYM(v), false, false));
-#line 1385 "runarray.in"
+#line 1421 "runarray.in"
addFunc(ve, run::gen_runarray58, realArray2(), SYM(AtA), formal(realArray2(), SYM(a), false, false));
-#line 1390 "runarray.in"
+#line 1426 "runarray.in"
addFunc(ve, run::gen_runarray59, primPair(), SYM(project), formal(primTriple(), SYM(v), false, false), formal(realArray2(), SYM(t), false, false));
-#line 1415 "runarray.in"
+#line 1451 "runarray.in"
addFunc(ve, run::gen_runarray60, primReal(), SYM(dot), formal(realArray(), SYM(a), false, false), formal(realArray(), SYM(b), false, false));
-#line 1425 "runarray.in"
+#line 1461 "runarray.in"
addFunc(ve, run::gen_runarray61, primPair(), SYM(dot), formal(pairArray(), SYM(a), false, false), formal(pairArray(), SYM(b), false, false));
-#line 1435 "runarray.in"
+#line 1471 "runarray.in"
addFunc(ve, run::gen_runarray62, realArray(), SYM(tridiagonal), formal(realArray(), SYM(a), false, false), formal(realArray(), SYM(b), false, false), formal(realArray(), SYM(c), false, false), formal(realArray(), SYM(f), false, false));
-#line 1539 "runarray.in"
+#line 1575 "runarray.in"
addFunc(ve, run::gen_runarray63, primReal(), SYM(newton), formal(primInt(), SYM(iterations), true, false), formal(realRealFunction(), SYM(f), false, false), formal(realRealFunction(), SYM(fprime), false, false), formal(primReal(), SYM(x), false, false), formal(primBoolean(), SYM(verbose), true, false));
-#line 1586 "runarray.in"
+#line 1622 "runarray.in"
addFunc(ve, run::gen_runarray64, primReal(), SYM(newton), formal(primInt(), SYM(iterations), true, false), formal(realRealFunction(), SYM(f), false, false), formal(realRealFunction(), SYM(fprime), false, false), formal(primReal(), SYM(x1), false, false), formal(primReal(), SYM(x2), false, false), formal(primBoolean(), SYM(verbose), true, false));
-#line 1668 "runarray.in"
+#line 1704 "runarray.in"
addFunc(ve, run::gen_runarray65, primReal(), SYM(_findroot), formal(realRealFunction(), SYM(f), false, false), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(tolerance), false, false), formal(primReal(), SYM(fa), false, false), formal(primReal(), SYM(fb), false, false));
-#line 1770 "runarray.in"
+#line 1806 "runarray.in"
addFunc(ve, run::gen_runarray66, primReal(), SYM(simpson), formal(realRealFunction(), SYM(f), false, false), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(acc), true, false), formal(primReal(), SYM(dxmax), true, false));
-#line 1784 "runarray.in"
+#line 1820 "runarray.in"
addFunc(ve, run::gen_runarray67, pairArray(), SYM(fft), formal(pairArray(), SYM(a), false, false), formal(primInt(), SYM(sign), true, false));
-#line 1815 "runarray.in"
+#line 1851 "runarray.in"
addFunc(ve, run::gen_runarray68, IntArray2(), SYM(triangulate), formal(pairArray(), SYM(z), false, false));
-#line 1850 "runarray.in"
+#line 1886 "runarray.in"
addFunc(ve, run::gen_runarray69, primReal(), SYM(norm), formal(realArray(), SYM(a), false, false));
-#line 1861 "runarray.in"
+#line 1897 "runarray.in"
addFunc(ve, run::gen_runarray70, primReal(), SYM(norm), formal(realArray2(), SYM(a), false, false));
-#line 1876 "runarray.in"
+#line 1912 "runarray.in"
addFunc(ve, run::gen_runarray71, primReal(), SYM(norm), formal(tripleArray2(), SYM(a), false, false));
-#line 1891 "runarray.in"
+#line 1927 "runarray.in"
addFunc(ve, run::gen_runarray72, primReal(), SYM(change2), formal(tripleArray2(), SYM(a), false, false));
-#line 1913 "runarray.in"
+#line 1949 "runarray.in"
addFunc(ve, run::gen_runarray73, primTriple(), SYM(minbezier), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(b), false, false));
-#line 1925 "runarray.in"
+#line 1961 "runarray.in"
addFunc(ve, run::gen_runarray74, primTriple(), SYM(maxbezier), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(b), false, false));
-#line 1937 "runarray.in"
+#line 1973 "runarray.in"
addFunc(ve, run::gen_runarray75, primPair(), SYM(minratio), formal(tripleArray2(), SYM(p), false, false), formal(primPair(), SYM(b), false, false));
-#line 1949 "runarray.in"
+#line 1985 "runarray.in"
addFunc(ve, run::gen_runarray76, primPair(), SYM(maxratio), formal(tripleArray2(), SYM(p), false, false), formal(primPair(), SYM(b), false, false));
-#line 1961 "runarray.in"
+#line 1997 "runarray.in"
addFunc(ve, run::gen_runarray77, realArray(), SYM(_projection));
}
diff --git a/graphics/asymptote/runarray.in b/graphics/asymptote/runarray.in
index 10469aac7a..b68ac0c573 100644
--- a/graphics/asymptote/runarray.in
+++ b/graphics/asymptote/runarray.in
@@ -347,8 +347,44 @@ void transpose(double *a, size_t n)
}
// Invert an n x n array in place.
-void inverse(double *a, size_t n)
+void inverse(double *M, size_t n)
{
+ if(n == 2) {
+ real a=M[0];
+ real b=M[1];
+ real c=M[2];
+ real d=M[3];
+ real det=a*d-b*c;
+ if(det == 0.0)
+ error(singular);
+ det=1.0/det;
+ M[0]=d*det;
+ M[1]=-b*det;
+ M[2]=-c*det;
+ M[3]=a*det;
+ return;
+ }
+
+ if(n == 3) {
+ real a=M[0], b=M[1], c=M[2];
+ real d=M[3], e=M[4], f=M[5];
+ real g=M[6], h=M[7], i=M[8];
+
+ real A=e*i-f*h;
+ real B=f*g-d*i;
+ real C=d*h-e*g;
+
+ real det=a*A+b*B+c*C;
+ if(det == 0.0)
+ error(singular);
+ det=1.0/det;
+
+ M[0]=A*det; M[1]=(c*h-b*i)*det; M[2]=(b*f-c*e)*det;
+ M[3]=B*det; M[4]=(a*i-c*g)*det; M[5]=(c*d-a*f)*det;
+ M[6]=C*det; M[7]=(b*g-a*h)*det; M[8]=(a*e-b*d)*det;
+ return;
+ }
+
inverseAllocate(n);
for(size_t i=0; i < n; i++)
@@ -360,7 +396,7 @@ void inverse(double *a, size_t n)
real big=0.0;
// This is the outer loop of the search for a pivot element.
for(size_t j=0; j < n; j++) {
- double *aj=a+n*j;
+ double *aj=M+n*j;
if(pivot[j] != 1) {
for(size_t k=0; k < n; k++) {
if(pivot[k] == 0) {
@@ -380,9 +416,9 @@ void inverse(double *a, size_t n)
++(pivot[col]);
// Interchange rows, if needed, to put the pivot element on the diagonal.
- double *acol=a+n*col;
+ double *acol=M+n*col;
if(row != col) {
- double *arow=a+n*row;
+ double *arow=M+n*row;
for(size_t k=0; k < n; k++) {
real temp=arow[k];
arow[k]=acol[k];
@@ -407,7 +443,7 @@ void inverse(double *a, size_t n)
// Reduce all rows except for the pivoted one.
for(size_t k=0; k < n; k++) {
if(k != col) {
- double *ak=a+n*k;
+ double *ak=M+n*k;
real akcol=ak[col];
ak[col]=0.0;
for(size_t j=0; j < n; j++)
@@ -423,7 +459,7 @@ void inverse(double *a, size_t n)
size_t c=Col[k];
if(r != c) {
for(size_t j=0; j < n; j++) {
- double *aj=a+n*j;
+ double *aj=M+n*j;
real temp=aj[r];
aj[r]=aj[c];
aj[c]=temp;
diff --git a/graphics/asymptote/runmath.cc b/graphics/asymptote/runmath.cc
index d9686dc80c..73854167c4 100644
--- a/graphics/asymptote/runmath.cc
+++ b/graphics/asymptote/runmath.cc
@@ -185,21 +185,16 @@ unsigned long long bitreverse64(unsigned long long a)
((unsigned long long) BitReverseTable8[(a >> 56)]);
}
-// From Warren, Jr., Henry S. (2013) [2002]. Hacker's Delight (2 ed.).
-// Addison Wesley - Pearson Education, Inc. pp. 81-96.
-Int popcount(Int a)
+// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+#define T unsignedInt
+Int popcount(T a)
{
- const uint64_t m1 = 0x5555555555555555; //binary: 0101...
- const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
- const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
- const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
-
-// This algorithm uses 12 arithmetic operations, one of which is a multiply.
- a -= (a >> 1) & m1; //put count of each 2 bits into those 2 bits
- a=(a & m2)+((a >> 2) & m2); //put count of each 4 bits into those 4 bits
- a=(a+(a >> 4)) & m4; //put count of each 8 bits into those 8 bits
- return (a * h01) >> 56; //returns left 8 bits of a+(a << 8)+(a << 16)+(a << 24)+...
+ a=a-((a >> 1) & (T)~(T)0/3);
+ a=(a & (T)~(T)0/15*3)+((a >> 2) & (T)~(T)0/15*3);
+ a=(a+(a >> 4)) & (T)~(T)0/255*15;
+return (T)(a*((T)~(T)0/255)) >> (sizeof(T)-1)*CHAR_BIT;
}
+#undef T
// Return the factorial of a non-negative integer using a lookup table.
Int factorial(Int n)
@@ -251,233 +246,233 @@ void Srand(Int seed)
#endif
namespace run {
-#line 195 "runmath.in"
+#line 190 "runmath.in"
// real ^(real x, Int y);
void gen_runmath0(stack *Stack)
{
Int y=vm::pop<Int>(Stack);
real x=vm::pop<real>(Stack);
-#line 196 "runmath.in"
+#line 191 "runmath.in"
{Stack->push<real>(pow(x,y)); return;}
}
-#line 200 "runmath.in"
+#line 195 "runmath.in"
// pair ^(pair z, Int y);
void gen_runmath1(stack *Stack)
{
Int y=vm::pop<Int>(Stack);
pair z=vm::pop<pair>(Stack);
-#line 201 "runmath.in"
+#line 196 "runmath.in"
{Stack->push<pair>(pow(z,y)); return;}
}
-#line 205 "runmath.in"
+#line 200 "runmath.in"
// Int quotient(Int x, Int y);
void gen_runmath2(stack *Stack)
{
Int y=vm::pop<Int>(Stack);
Int x=vm::pop<Int>(Stack);
-#line 206 "runmath.in"
+#line 201 "runmath.in"
{Stack->push<Int>(quotient<Int>()(x,y)); return;}
}
-#line 210 "runmath.in"
+#line 205 "runmath.in"
// Int abs(Int x);
void gen_runmath3(stack *Stack)
{
Int x=vm::pop<Int>(Stack);
-#line 211 "runmath.in"
+#line 206 "runmath.in"
{Stack->push<Int>(Abs(x)); return;}
}
-#line 215 "runmath.in"
+#line 210 "runmath.in"
// Int sgn(real x);
void gen_runmath4(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 216 "runmath.in"
+#line 211 "runmath.in"
{Stack->push<Int>(sgn(x)); return;}
}
-#line 220 "runmath.in"
+#line 215 "runmath.in"
// Int rand();
void gen_runmath5(stack *Stack)
{
-#line 221 "runmath.in"
+#line 216 "runmath.in"
if(initializeRandom)
Srand(1);
{Stack->push<Int>(random()); return;}
}
-#line 227 "runmath.in"
+#line 222 "runmath.in"
// void srand(Int seed);
void gen_runmath6(stack *Stack)
{
Int seed=vm::pop<Int>(Stack);
-#line 228 "runmath.in"
+#line 223 "runmath.in"
Srand(seed);
}
// a random number uniformly distributed in the interval [0,1]
-#line 233 "runmath.in"
+#line 228 "runmath.in"
// real unitrand();
void gen_runmath7(stack *Stack)
{
-#line 234 "runmath.in"
+#line 229 "runmath.in"
{Stack->push<real>(((real) random())/RANDOM_MAX); return;}
}
-#line 238 "runmath.in"
+#line 233 "runmath.in"
// Int ceil(real x);
void gen_runmath8(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 239 "runmath.in"
+#line 234 "runmath.in"
{Stack->push<Int>(Intcast(ceil(x))); return;}
}
-#line 243 "runmath.in"
+#line 238 "runmath.in"
// Int floor(real x);
void gen_runmath9(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 244 "runmath.in"
+#line 239 "runmath.in"
{Stack->push<Int>(Intcast(floor(x))); return;}
}
-#line 248 "runmath.in"
+#line 243 "runmath.in"
// Int round(real x);
void gen_runmath10(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 249 "runmath.in"
+#line 244 "runmath.in"
if(validInt(x)) {Stack->push<Int>(Round(x)); return;}
integeroverflow(0);
}
-#line 254 "runmath.in"
+#line 249 "runmath.in"
// Int Ceil(real x);
void gen_runmath11(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 255 "runmath.in"
+#line 250 "runmath.in"
{Stack->push<Int>(Ceil(x)); return;}
}
-#line 259 "runmath.in"
+#line 254 "runmath.in"
// Int Floor(real x);
void gen_runmath12(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 260 "runmath.in"
+#line 255 "runmath.in"
{Stack->push<Int>(Floor(x)); return;}
}
-#line 264 "runmath.in"
+#line 259 "runmath.in"
// Int Round(real x);
void gen_runmath13(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 265 "runmath.in"
+#line 260 "runmath.in"
{Stack->push<Int>(Round(Intcap(x))); return;}
}
-#line 269 "runmath.in"
+#line 264 "runmath.in"
// real fmod(real x, real y);
void gen_runmath14(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 270 "runmath.in"
+#line 265 "runmath.in"
if (y == 0.0) dividebyzero();
{Stack->push<real>(fmod(x,y)); return;}
}
-#line 275 "runmath.in"
+#line 270 "runmath.in"
// real atan2(real y, real x);
void gen_runmath15(stack *Stack)
{
real x=vm::pop<real>(Stack);
real y=vm::pop<real>(Stack);
-#line 276 "runmath.in"
+#line 271 "runmath.in"
{Stack->push<real>(atan2(y,x)); return;}
}
-#line 280 "runmath.in"
+#line 275 "runmath.in"
// real hypot(real x, real y);
void gen_runmath16(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 281 "runmath.in"
+#line 276 "runmath.in"
{Stack->push<real>(hypot(x,y)); return;}
}
-#line 285 "runmath.in"
+#line 280 "runmath.in"
// real remainder(real x, real y);
void gen_runmath17(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 286 "runmath.in"
+#line 281 "runmath.in"
{Stack->push<real>(remainder(x,y)); return;}
}
-#line 290 "runmath.in"
+#line 285 "runmath.in"
// real Jn(Int n, real x);
void gen_runmath18(stack *Stack)
{
real x=vm::pop<real>(Stack);
Int n=vm::pop<Int>(Stack);
-#line 291 "runmath.in"
+#line 286 "runmath.in"
{Stack->push<real>(jn(n,x)); return;}
}
-#line 295 "runmath.in"
+#line 290 "runmath.in"
// real Yn(Int n, real x);
void gen_runmath19(stack *Stack)
{
real x=vm::pop<real>(Stack);
Int n=vm::pop<Int>(Stack);
-#line 296 "runmath.in"
+#line 291 "runmath.in"
{Stack->push<real>(yn(n,x)); return;}
}
-#line 300 "runmath.in"
+#line 295 "runmath.in"
// real erf(real x);
void gen_runmath20(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 301 "runmath.in"
+#line 296 "runmath.in"
{Stack->push<real>(erf(x)); return;}
}
-#line 305 "runmath.in"
+#line 300 "runmath.in"
// real erfc(real x);
void gen_runmath21(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 306 "runmath.in"
+#line 301 "runmath.in"
{Stack->push<real>(erfc(x)); return;}
}
-#line 310 "runmath.in"
+#line 305 "runmath.in"
// Int factorial(Int n);
void gen_runmath22(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 311 "runmath.in"
+#line 306 "runmath.in"
if(n < 0) error(invalidargument);
{Stack->push<Int>(factorial(n)); return;}
}
-#line 315 "runmath.in"
+#line 310 "runmath.in"
// Int choose(Int n, Int k);
void gen_runmath23(stack *Stack)
{
Int k=vm::pop<Int>(Stack);
Int n=vm::pop<Int>(Stack);
-#line 316 "runmath.in"
+#line 311 "runmath.in"
if(n < 0 || k < 0 || k > n) error(invalidargument);
Int f=1;
Int r=n-k;
@@ -488,12 +483,12 @@ void gen_runmath23(stack *Stack)
{Stack->push<Int>(f); return;}
}
-#line 326 "runmath.in"
+#line 321 "runmath.in"
// real gamma(real x);
void gen_runmath24(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 327 "runmath.in"
+#line 322 "runmath.in"
#ifdef HAVE_TGAMMA
{Stack->push<real>(tgamma(x)); return;}
#else
@@ -502,14 +497,14 @@ void gen_runmath24(stack *Stack)
#endif
}
-#line 336 "runmath.in"
+#line 331 "runmath.in"
// realarray* quadraticroots(real a, real b, real c);
void gen_runmath25(stack *Stack)
{
real c=vm::pop<real>(Stack);
real b=vm::pop<real>(Stack);
real a=vm::pop<real>(Stack);
-#line 337 "runmath.in"
+#line 332 "runmath.in"
quadraticroots q(a,b,c);
array *roots=new array(q.roots);
if(q.roots >= 1) (*roots)[0]=q.t1;
@@ -517,14 +512,14 @@ void gen_runmath25(stack *Stack)
{Stack->push<realarray*>(roots); return;}
}
-#line 345 "runmath.in"
+#line 340 "runmath.in"
// pairarray* quadraticroots(explicit pair a, explicit pair b, explicit pair c);
void gen_runmath26(stack *Stack)
{
pair c=vm::pop<pair>(Stack);
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 346 "runmath.in"
+#line 341 "runmath.in"
Quadraticroots q(a,b,c);
array *roots=new array(q.roots);
if(q.roots >= 1) (*roots)[0]=q.z1;
@@ -532,7 +527,7 @@ void gen_runmath26(stack *Stack)
{Stack->push<pairarray*>(roots); return;}
}
-#line 354 "runmath.in"
+#line 349 "runmath.in"
// realarray* cubicroots(real a, real b, real c, real d);
void gen_runmath27(stack *Stack)
{
@@ -540,7 +535,7 @@ void gen_runmath27(stack *Stack)
real c=vm::pop<real>(Stack);
real b=vm::pop<real>(Stack);
real a=vm::pop<real>(Stack);
-#line 355 "runmath.in"
+#line 350 "runmath.in"
cubicroots q(a,b,c,d);
array *roots=new array(q.roots);
if(q.roots >= 1) (*roots)[0]=q.t1;
@@ -551,98 +546,98 @@ void gen_runmath27(stack *Stack)
// Logical operations
-#line 366 "runmath.in"
+#line 361 "runmath.in"
// bool !(bool b);
void gen_runmath28(stack *Stack)
{
bool b=vm::pop<bool>(Stack);
-#line 367 "runmath.in"
+#line 362 "runmath.in"
{Stack->push<bool>(!b); return;}
}
-#line 372 "runmath.in"
+#line 367 "runmath.in"
void boolMemEq(stack *Stack)
{
frame * b=vm::pop<frame *>(Stack);
frame * a=vm::pop<frame *>(Stack);
-#line 373 "runmath.in"
+#line 368 "runmath.in"
{Stack->push<bool>(a == b); return;}
}
-#line 377 "runmath.in"
+#line 372 "runmath.in"
void boolMemNeq(stack *Stack)
{
frame * b=vm::pop<frame *>(Stack);
frame * a=vm::pop<frame *>(Stack);
-#line 378 "runmath.in"
+#line 373 "runmath.in"
{Stack->push<bool>(a != b); return;}
}
-#line 382 "runmath.in"
+#line 377 "runmath.in"
void boolFuncEq(stack *Stack)
{
callable * b=vm::pop<callable *>(Stack);
callable * a=vm::pop<callable *>(Stack);
-#line 383 "runmath.in"
+#line 378 "runmath.in"
{Stack->push<bool>(a->compare(b)); return;}
}
-#line 387 "runmath.in"
+#line 382 "runmath.in"
void boolFuncNeq(stack *Stack)
{
callable * b=vm::pop<callable *>(Stack);
callable * a=vm::pop<callable *>(Stack);
-#line 388 "runmath.in"
+#line 383 "runmath.in"
{Stack->push<bool>(!(a->compare(b))); return;}
}
// Bit operations
-#line 394 "runmath.in"
+#line 389 "runmath.in"
// Int AND(Int a, Int b);
void gen_runmath33(stack *Stack)
{
Int b=vm::pop<Int>(Stack);
Int a=vm::pop<Int>(Stack);
-#line 395 "runmath.in"
+#line 390 "runmath.in"
{Stack->push<Int>(a & b); return;}
}
-#line 400 "runmath.in"
+#line 395 "runmath.in"
// Int OR(Int a, Int b);
void gen_runmath34(stack *Stack)
{
Int b=vm::pop<Int>(Stack);
Int a=vm::pop<Int>(Stack);
-#line 401 "runmath.in"
+#line 396 "runmath.in"
{Stack->push<Int>(a | b); return;}
}
-#line 405 "runmath.in"
+#line 400 "runmath.in"
// Int XOR(Int a, Int b);
void gen_runmath35(stack *Stack)
{
Int b=vm::pop<Int>(Stack);
Int a=vm::pop<Int>(Stack);
-#line 406 "runmath.in"
+#line 401 "runmath.in"
{Stack->push<Int>(a ^ b); return;}
}
-#line 410 "runmath.in"
+#line 405 "runmath.in"
// Int NOT(Int a);
void gen_runmath36(stack *Stack)
{
Int a=vm::pop<Int>(Stack);
-#line 411 "runmath.in"
+#line 406 "runmath.in"
{Stack->push<Int>(~a); return;}
}
-#line 415 "runmath.in"
+#line 410 "runmath.in"
// Int CLZ(Int a);
void gen_runmath37(stack *Stack)
{
Int a=vm::pop<Int>(Stack);
-#line 416 "runmath.in"
+#line 411 "runmath.in"
if((unsigned long long) a > 0xFFFFFFFF)
{Stack->push<Int>(CLZ((uint32_t) ((unsigned long long) a >> 32))); return;}
else {
@@ -652,32 +647,32 @@ void gen_runmath37(stack *Stack)
}
}
-#line 426 "runmath.in"
+#line 421 "runmath.in"
// Int popcount(Int a);
void gen_runmath38(stack *Stack)
{
Int a=vm::pop<Int>(Stack);
-#line 427 "runmath.in"
+#line 422 "runmath.in"
{Stack->push<Int>(popcount(a)); return;}
}
-#line 431 "runmath.in"
+#line 426 "runmath.in"
// Int CTZ(Int a);
void gen_runmath39(stack *Stack)
{
Int a=vm::pop<Int>(Stack);
-#line 432 "runmath.in"
+#line 427 "runmath.in"
{Stack->push<Int>(popcount((a&-a)-1)); return;}
}
// bitreverse a within a word of length bits.
-#line 437 "runmath.in"
+#line 432 "runmath.in"
// Int bitreverse(Int a, Int bits);
void gen_runmath40(stack *Stack)
{
Int bits=vm::pop<Int>(Stack);
Int a=vm::pop<Int>(Stack);
-#line 438 "runmath.in"
+#line 433 "runmath.in"
typedef unsigned long long Bitreverse(unsigned long long a);
static Bitreverse *B[]={bitreverse8,bitreverse16,bitreverse24,bitreverse32,
bitreverse40,bitreverse48,bitreverse56,bitreverse64};
@@ -698,87 +693,87 @@ namespace trans {
void gen_runmath_venv(venv &ve)
{
-#line 195 "runmath.in"
+#line 190 "runmath.in"
addFunc(ve, run::gen_runmath0, primReal(), SYM_CARET, formal(primReal(), SYM(x), false, false), formal(primInt(), SYM(y), false, false));
-#line 200 "runmath.in"
+#line 195 "runmath.in"
addFunc(ve, run::gen_runmath1, primPair(), SYM_CARET, formal(primPair(), SYM(z), false, false), formal(primInt(), SYM(y), false, false));
-#line 205 "runmath.in"
+#line 200 "runmath.in"
addFunc(ve, run::gen_runmath2, primInt(), SYM(quotient), formal(primInt(), SYM(x), false, false), formal(primInt(), SYM(y), false, false));
-#line 210 "runmath.in"
+#line 205 "runmath.in"
addFunc(ve, run::gen_runmath3, primInt(), SYM(abs), formal(primInt(), SYM(x), false, false));
-#line 215 "runmath.in"
+#line 210 "runmath.in"
addFunc(ve, run::gen_runmath4, primInt(), SYM(sgn), formal(primReal(), SYM(x), false, false));
-#line 220 "runmath.in"
+#line 215 "runmath.in"
addFunc(ve, run::gen_runmath5, primInt(), SYM(rand));
-#line 227 "runmath.in"
+#line 222 "runmath.in"
addFunc(ve, run::gen_runmath6, primVoid(), SYM(srand), formal(primInt(), SYM(seed), false, false));
-#line 232 "runmath.in"
+#line 227 "runmath.in"
addFunc(ve, run::gen_runmath7, primReal(), SYM(unitrand));
-#line 238 "runmath.in"
+#line 233 "runmath.in"
addFunc(ve, run::gen_runmath8, primInt(), SYM(ceil), formal(primReal(), SYM(x), false, false));
-#line 243 "runmath.in"
+#line 238 "runmath.in"
addFunc(ve, run::gen_runmath9, primInt(), SYM(floor), formal(primReal(), SYM(x), false, false));
-#line 248 "runmath.in"
+#line 243 "runmath.in"
addFunc(ve, run::gen_runmath10, primInt(), SYM(round), formal(primReal(), SYM(x), false, false));
-#line 254 "runmath.in"
+#line 249 "runmath.in"
addFunc(ve, run::gen_runmath11, primInt(), SYM(Ceil), formal(primReal(), SYM(x), false, false));
-#line 259 "runmath.in"
+#line 254 "runmath.in"
addFunc(ve, run::gen_runmath12, primInt(), SYM(Floor), formal(primReal(), SYM(x), false, false));
-#line 264 "runmath.in"
+#line 259 "runmath.in"
addFunc(ve, run::gen_runmath13, primInt(), SYM(Round), formal(primReal(), SYM(x), false, false));
-#line 269 "runmath.in"
+#line 264 "runmath.in"
addFunc(ve, run::gen_runmath14, primReal(), SYM(fmod), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 275 "runmath.in"
+#line 270 "runmath.in"
addFunc(ve, run::gen_runmath15, primReal(), SYM(atan2), formal(primReal(), SYM(y), false, false), formal(primReal(), SYM(x), false, false));
-#line 280 "runmath.in"
+#line 275 "runmath.in"
addFunc(ve, run::gen_runmath16, primReal(), SYM(hypot), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 285 "runmath.in"
+#line 280 "runmath.in"
addFunc(ve, run::gen_runmath17, primReal(), SYM(remainder), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 290 "runmath.in"
+#line 285 "runmath.in"
addFunc(ve, run::gen_runmath18, primReal(), SYM(Jn), formal(primInt(), SYM(n), false, false), formal(primReal(), SYM(x), false, false));
-#line 295 "runmath.in"
+#line 290 "runmath.in"
addFunc(ve, run::gen_runmath19, primReal(), SYM(Yn), formal(primInt(), SYM(n), false, false), formal(primReal(), SYM(x), false, false));
-#line 300 "runmath.in"
+#line 295 "runmath.in"
addFunc(ve, run::gen_runmath20, primReal(), SYM(erf), formal(primReal(), SYM(x), false, false));
-#line 305 "runmath.in"
+#line 300 "runmath.in"
addFunc(ve, run::gen_runmath21, primReal(), SYM(erfc), formal(primReal(), SYM(x), false, false));
-#line 310 "runmath.in"
+#line 305 "runmath.in"
addFunc(ve, run::gen_runmath22, primInt(), SYM(factorial), formal(primInt(), SYM(n), false, false));
-#line 315 "runmath.in"
+#line 310 "runmath.in"
addFunc(ve, run::gen_runmath23, primInt(), SYM(choose), formal(primInt(), SYM(n), false, false), formal(primInt(), SYM(k), false, false));
-#line 326 "runmath.in"
+#line 321 "runmath.in"
addFunc(ve, run::gen_runmath24, primReal(), SYM(gamma), formal(primReal(), SYM(x), false, false));
-#line 336 "runmath.in"
+#line 331 "runmath.in"
addFunc(ve, run::gen_runmath25, realArray(), SYM(quadraticroots), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(c), false, false));
-#line 345 "runmath.in"
+#line 340 "runmath.in"
addFunc(ve, run::gen_runmath26, pairArray(), SYM(quadraticroots), formal(primPair(), SYM(a), false, true), formal(primPair(), SYM(b), false, true), formal(primPair(), SYM(c), false, true));
-#line 354 "runmath.in"
+#line 349 "runmath.in"
addFunc(ve, run::gen_runmath27, realArray(), SYM(cubicroots), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(c), false, false), formal(primReal(), SYM(d), false, false));
-#line 364 "runmath.in"
+#line 359 "runmath.in"
addFunc(ve, run::gen_runmath28, primBoolean(), SYM_LOGNOT, formal(primBoolean(), SYM(b), false, false));
-#line 372 "runmath.in"
+#line 367 "runmath.in"
REGISTER_BLTIN(run::boolMemEq,"boolMemEq");
-#line 377 "runmath.in"
+#line 372 "runmath.in"
REGISTER_BLTIN(run::boolMemNeq,"boolMemNeq");
-#line 382 "runmath.in"
+#line 377 "runmath.in"
REGISTER_BLTIN(run::boolFuncEq,"boolFuncEq");
-#line 387 "runmath.in"
+#line 382 "runmath.in"
REGISTER_BLTIN(run::boolFuncNeq,"boolFuncNeq");
-#line 392 "runmath.in"
+#line 387 "runmath.in"
addFunc(ve, run::gen_runmath33, primInt(), SYM(AND), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
-#line 400 "runmath.in"
+#line 395 "runmath.in"
addFunc(ve, run::gen_runmath34, primInt(), SYM(OR), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
-#line 405 "runmath.in"
+#line 400 "runmath.in"
addFunc(ve, run::gen_runmath35, primInt(), SYM(XOR), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
-#line 410 "runmath.in"
+#line 405 "runmath.in"
addFunc(ve, run::gen_runmath36, primInt(), SYM(NOT), formal(primInt(), SYM(a), false, false));
-#line 415 "runmath.in"
+#line 410 "runmath.in"
addFunc(ve, run::gen_runmath37, primInt(), SYM(CLZ), formal(primInt(), SYM(a), false, false));
-#line 426 "runmath.in"
+#line 421 "runmath.in"
addFunc(ve, run::gen_runmath38, primInt(), SYM(popcount), formal(primInt(), SYM(a), false, false));
-#line 431 "runmath.in"
+#line 426 "runmath.in"
addFunc(ve, run::gen_runmath39, primInt(), SYM(CTZ), formal(primInt(), SYM(a), false, false));
-#line 436 "runmath.in"
+#line 431 "runmath.in"
addFunc(ve, run::gen_runmath40, primInt(), SYM(bitreverse), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(bits), false, false));
}
diff --git a/graphics/asymptote/runmath.in b/graphics/asymptote/runmath.in
index fa9dbf3e69..c1068ce217 100644
--- a/graphics/asymptote/runmath.in
+++ b/graphics/asymptote/runmath.in
@@ -132,21 +132,16 @@ unsigned long long bitreverse64(unsigned long long a)
((unsigned long long) BitReverseTable8[(a >> 56)]);
}
-// From Warren, Jr., Henry S. (2013) [2002]. Hacker's Delight (2 ed.).
-// Addison Wesley - Pearson Education, Inc. pp. 81-96.
-Int popcount(Int a)
-{
- const uint64_t m1 = 0x5555555555555555; //binary: 0101...
- const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
- const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
- const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
-
-// This algorithm uses 12 arithmetic operations, one of which is a multiply.
- a -= (a >> 1) & m1; //put count of each 2 bits into those 2 bits
- a=(a & m2)+((a >> 2) & m2); //put count of each 4 bits into those 4 bits
- a=(a+(a >> 4)) & m4; //put count of each 8 bits into those 8 bits
- return (a * h01) >> 56; //returns left 8 bits of a+(a << 8)+(a << 16)+(a << 24)+...
+// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+#define T unsignedInt
+Int popcount(T a)
+{
+ a=a-((a >> 1) & (T)~(T)0/3);
+ a=(a & (T)~(T)0/15*3)+((a >> 2) & (T)~(T)0/15*3);
+ a=(a+(a >> 4)) & (T)~(T)0/255*15;
+return (T)(a*((T)~(T)0/255)) >> (sizeof(T)-1)*CHAR_BIT;
}
+#undef T
// Return the factorial of a non-negative integer using a lookup table.
Int factorial(Int n)
diff --git a/graphics/asymptote/runpicture.cc b/graphics/asymptote/runpicture.cc
index d800347ffd..32e5037ab0 100644
--- a/graphics/asymptote/runpicture.cc
+++ b/graphics/asymptote/runpicture.cc
@@ -156,6 +156,8 @@ array *nop(array *a)
triple Zero;
+string defaultformat3="prc";
+
// Autogenerated routines:
@@ -165,71 +167,71 @@ triple Zero;
#endif
namespace run {
-#line 126 "runpicture.in"
+#line 128 "runpicture.in"
void newPicture(stack *Stack)
{
-#line 127 "runpicture.in"
+#line 129 "runpicture.in"
{Stack->push<picture*>(new picture()); return;}
}
-#line 131 "runpicture.in"
+#line 133 "runpicture.in"
// bool empty(picture *f);
void gen_runpicture1(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 132 "runpicture.in"
+#line 134 "runpicture.in"
{Stack->push<bool>(f->null()); return;}
}
-#line 136 "runpicture.in"
+#line 138 "runpicture.in"
// void erase(picture *f);
void gen_runpicture2(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 137 "runpicture.in"
+#line 139 "runpicture.in"
f->nodes.clear();
}
-#line 141 "runpicture.in"
+#line 143 "runpicture.in"
// pair min(picture *f);
void gen_runpicture3(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 142 "runpicture.in"
+#line 144 "runpicture.in"
{Stack->push<pair>(f->bounds().Min()); return;}
}
-#line 146 "runpicture.in"
+#line 148 "runpicture.in"
// pair max(picture *f);
void gen_runpicture4(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 147 "runpicture.in"
+#line 149 "runpicture.in"
{Stack->push<pair>(f->bounds().Max()); return;}
}
-#line 151 "runpicture.in"
+#line 153 "runpicture.in"
// pair size(picture *f);
void gen_runpicture5(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 152 "runpicture.in"
+#line 154 "runpicture.in"
bbox b=f->bounds();
{Stack->push<pair>(b.Max()-b.Min()); return;}
}
-#line 157 "runpicture.in"
+#line 159 "runpicture.in"
// void _draw(picture *f, path g, pen p);
void gen_runpicture6(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
path g=vm::pop<path>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 158 "runpicture.in"
+#line 160 "runpicture.in"
f->append(new drawPath(g,p));
}
-#line 162 "runpicture.in"
+#line 164 "runpicture.in"
// void fill(picture *f, patharray *g, pen p=CURRENTPEN, bool copy=true);
void gen_runpicture7(stack *Stack)
{
@@ -237,12 +239,12 @@ void gen_runpicture7(stack *Stack)
pen p=vm::pop<pen>(Stack,CURRENTPEN);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 163 "runpicture.in"
+#line 165 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
f->append(new drawFill(*copyarray(g),false,p));
}
-#line 168 "runpicture.in"
+#line 170 "runpicture.in"
// void latticeshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray2 *p, transform t=identity, bool copy=true);
void gen_runpicture8(stack *Stack)
{
@@ -253,13 +255,13 @@ void gen_runpicture8(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 171 "runpicture.in"
+#line 173 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p),
t));
}
-#line 177 "runpicture.in"
+#line 179 "runpicture.in"
// void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a, bool extenda=true, pen penb, pair b, bool extendb=true, bool copy=true);
void gen_runpicture9(stack *Stack)
{
@@ -273,13 +275,13 @@ void gen_runpicture9(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 180 "runpicture.in"
+#line 182 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,extenda,penb,b,
extendb));
}
-#line 186 "runpicture.in"
+#line 188 "runpicture.in"
// void radialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a, real ra, bool extenda=true, pen penb, pair b, real rb, bool extendb=true, bool copy=true);
void gen_runpicture10(stack *Stack)
{
@@ -295,13 +297,13 @@ void gen_runpicture10(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 189 "runpicture.in"
+#line 191 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,extenda,
penb,b,rb,extendb));
}
-#line 195 "runpicture.in"
+#line 197 "runpicture.in"
// void gouraudshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray *p, pairarray *z, Intarray *edges, bool copy=true);
void gen_runpicture11(stack *Stack)
{
@@ -313,7 +315,7 @@ void gen_runpicture11(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 198 "runpicture.in"
+#line 200 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
checkArrays(p,z);
checkArrays(z,edges);
@@ -321,7 +323,7 @@ void gen_runpicture11(stack *Stack)
*copyarray(z),*copyarray(edges)));
}
-#line 206 "runpicture.in"
+#line 208 "runpicture.in"
// void gouraudshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray *p, Intarray *edges, bool copy=true);
void gen_runpicture12(stack *Stack)
{
@@ -332,7 +334,7 @@ void gen_runpicture12(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 209 "runpicture.in"
+#line 211 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
size_t n=checkArrays(p,edges);
size_t m=checkArray(g);
@@ -353,7 +355,7 @@ void gen_runpicture12(stack *Stack)
*z,*copyarray(edges)));
}
-#line 230 "runpicture.in"
+#line 232 "runpicture.in"
// void tensorshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray2 *p, patharray *b=NULL, pairarray2 *z=emptyarray, bool copy=true);
void gen_runpicture13(stack *Stack)
{
@@ -365,7 +367,7 @@ void gen_runpicture13(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 233 "runpicture.in"
+#line 235 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
if(b == NULL) b=g;
@@ -377,7 +379,7 @@ void gen_runpicture13(stack *Stack)
*copyarray(b),*copyarray2(z)));
}
-#line 245 "runpicture.in"
+#line 247 "runpicture.in"
// void functionshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, string shader=emptystring, bool copy=true);
void gen_runpicture14(stack *Stack)
{
@@ -387,14 +389,14 @@ void gen_runpicture14(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 248 "runpicture.in"
+#line 250 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
f->append(new drawFunctionShade(*copyarray(g),stroke,fillrule,shader));
}
// Clip a picture to a superpath using the given fill rule.
// Subsequent additions to the picture will not be affected by the clipping.
-#line 255 "runpicture.in"
+#line 257 "runpicture.in"
// void clip(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, bool copy=true);
void gen_runpicture15(stack *Stack)
{
@@ -403,13 +405,13 @@ void gen_runpicture15(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 257 "runpicture.in"
+#line 259 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
drawClipBegin *begin=new drawClipBegin(*copyarray(g),stroke,fillrule,true);
f->enclose(begin,new drawClipEnd(true,begin));
}
-#line 263 "runpicture.in"
+#line 265 "runpicture.in"
// void beginclip(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, bool copy=true);
void gen_runpicture16(stack *Stack)
{
@@ -418,57 +420,57 @@ void gen_runpicture16(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 265 "runpicture.in"
+#line 267 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
f->append(new drawClipBegin(*copyarray(g),stroke,fillrule,false));
}
-#line 270 "runpicture.in"
+#line 272 "runpicture.in"
// void endclip(picture *f);
void gen_runpicture17(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 271 "runpicture.in"
+#line 273 "runpicture.in"
f->append(new drawClipEnd(false));
}
-#line 275 "runpicture.in"
+#line 277 "runpicture.in"
// void gsave(picture *f);
void gen_runpicture18(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 276 "runpicture.in"
+#line 278 "runpicture.in"
f->append(new drawGsave());
}
-#line 280 "runpicture.in"
+#line 282 "runpicture.in"
// void grestore(picture *f);
void gen_runpicture19(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 281 "runpicture.in"
+#line 283 "runpicture.in"
f->append(new drawGrestore());
}
-#line 285 "runpicture.in"
+#line 287 "runpicture.in"
// void begingroup(picture *f);
void gen_runpicture20(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 286 "runpicture.in"
+#line 288 "runpicture.in"
f->append(new drawBegin());
}
-#line 290 "runpicture.in"
+#line 292 "runpicture.in"
// void endgroup(picture *f);
void gen_runpicture21(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 291 "runpicture.in"
+#line 293 "runpicture.in"
f->append(new drawEnd());
}
-#line 295 "runpicture.in"
+#line 297 "runpicture.in"
// void _begingroup3(picture *f, string name, real compression, real granularity, bool closed, bool tessellate, bool dobreak, bool nobreak, triple center, Int interaction);
void gen_runpicture22(stack *Stack)
{
@@ -482,62 +484,62 @@ void gen_runpicture22(stack *Stack)
real compression=vm::pop<real>(Stack);
string name=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 298 "runpicture.in"
+#line 300 "runpicture.in"
f->append(new drawBegin3(name,compression,granularity,
closed,tessellate,dobreak,nobreak,
center,(Interaction) intcast(interaction)));
}
-#line 304 "runpicture.in"
+#line 306 "runpicture.in"
// void endgroup3(picture *f);
void gen_runpicture23(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 305 "runpicture.in"
+#line 307 "runpicture.in"
f->append(new drawEnd3());
}
-#line 309 "runpicture.in"
+#line 311 "runpicture.in"
// void add(picture *dest, picture *src);
void gen_runpicture24(stack *Stack)
{
picture * src=vm::pop<picture *>(Stack);
picture * dest=vm::pop<picture *>(Stack);
-#line 310 "runpicture.in"
+#line 312 "runpicture.in"
dest->add(*src);
}
-#line 314 "runpicture.in"
+#line 316 "runpicture.in"
// void prepend(picture *dest, picture *src);
void gen_runpicture25(stack *Stack)
{
picture * src=vm::pop<picture *>(Stack);
picture * dest=vm::pop<picture *>(Stack);
-#line 315 "runpicture.in"
+#line 317 "runpicture.in"
dest->prepend(*src);
}
-#line 319 "runpicture.in"
+#line 321 "runpicture.in"
// void postscript(picture *f, string s);
void gen_runpicture26(stack *Stack)
{
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 320 "runpicture.in"
+#line 322 "runpicture.in"
f->append(new drawVerbatim(PostScript,s));
}
-#line 324 "runpicture.in"
+#line 326 "runpicture.in"
// void tex(picture *f, string s);
void gen_runpicture27(stack *Stack)
{
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 325 "runpicture.in"
+#line 327 "runpicture.in"
f->append(new drawVerbatim(TeX,s));
}
-#line 329 "runpicture.in"
+#line 331 "runpicture.in"
// void postscript(picture *f, string s, pair min, pair max);
void gen_runpicture28(stack *Stack)
{
@@ -545,11 +547,11 @@ void gen_runpicture28(stack *Stack)
pair min=vm::pop<pair>(Stack);
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 330 "runpicture.in"
+#line 332 "runpicture.in"
f->append(new drawVerbatim(PostScript,s,min,max));
}
-#line 334 "runpicture.in"
+#line 336 "runpicture.in"
// void tex(picture *f, string s, pair min, pair max);
void gen_runpicture29(stack *Stack)
{
@@ -557,33 +559,33 @@ void gen_runpicture29(stack *Stack)
pair min=vm::pop<pair>(Stack);
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 335 "runpicture.in"
+#line 337 "runpicture.in"
f->append(new drawVerbatim(TeX,s,min,max));
}
-#line 339 "runpicture.in"
+#line 341 "runpicture.in"
// void texpreamble(string s);
void gen_runpicture30(stack *Stack)
{
string s=vm::pop<string>(Stack);
-#line 340 "runpicture.in"
+#line 342 "runpicture.in"
string t=s+"\n";
processDataStruct &pd=processData();
pd.TeXpipepreamble.push_back(t);
pd.TeXpreamble.push_back(t);
}
-#line 347 "runpicture.in"
+#line 349 "runpicture.in"
// void deletepreamble();
void gen_runpicture31(stack *)
{
-#line 348 "runpicture.in"
+#line 350 "runpicture.in"
if(getSetting<bool>("inlinetex")) {
unlink(buildname(outname(),"pre").c_str());
}
}
-#line 354 "runpicture.in"
+#line 356 "runpicture.in"
// void _labelpath(picture *f, string s, string size, path g, string justify, pair offset, pen p);
void gen_runpicture32(stack *Stack)
{
@@ -594,40 +596,40 @@ void gen_runpicture32(stack *Stack)
string size=vm::pop<string>(Stack);
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 356 "runpicture.in"
+#line 358 "runpicture.in"
f->append(new drawLabelPath(s,size,g,justify,offset,p));
}
-#line 360 "runpicture.in"
+#line 362 "runpicture.in"
// void texreset();
void gen_runpicture33(stack *)
{
-#line 361 "runpicture.in"
+#line 363 "runpicture.in"
processDataStruct &pd=processData();
pd.TeXpipepreamble.clear();
pd.TeXpreamble.clear();
pd.tex.pipeclose();
}
-#line 368 "runpicture.in"
+#line 370 "runpicture.in"
// void layer(picture *f);
void gen_runpicture34(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 369 "runpicture.in"
+#line 371 "runpicture.in"
f->append(new drawLayer());
}
-#line 373 "runpicture.in"
+#line 375 "runpicture.in"
// void newpage(picture *f);
void gen_runpicture35(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 374 "runpicture.in"
+#line 376 "runpicture.in"
f->append(new drawNewPage());
}
-#line 378 "runpicture.in"
+#line 380 "runpicture.in"
// void _image(picture *f, realarray2 *data, pair initial, pair final, penarray *palette=NULL, transform t=identity, bool copy=true, bool antialias=false);
void gen_runpicture36(stack *Stack)
{
@@ -639,14 +641,14 @@ void gen_runpicture36(stack *Stack)
pair initial=vm::pop<pair>(Stack);
realarray2 * data=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 381 "runpicture.in"
+#line 383 "runpicture.in"
array *(*copyarray)(array *a)=copy ? copyArray : nop;
array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
f->append(new drawPaletteImage(*copyarray2(data),*copyarray(palette),
t*matrix(initial,final),antialias));
}
-#line 388 "runpicture.in"
+#line 390 "runpicture.in"
// void _image(picture *f, penarray2 *data, pair initial, pair final, transform t=identity, bool copy=true, bool antialias=false);
void gen_runpicture37(stack *Stack)
{
@@ -657,13 +659,13 @@ void gen_runpicture37(stack *Stack)
pair initial=vm::pop<pair>(Stack);
penarray2 * data=vm::pop<penarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 390 "runpicture.in"
+#line 392 "runpicture.in"
array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
f->append(new drawNoPaletteImage(*copyarray2(data),t*matrix(initial,final),
antialias));
}
-#line 396 "runpicture.in"
+#line 398 "runpicture.in"
// void _image(picture *f, callablePen *F, Int width, Int height, pair initial, pair final, transform t=identity, bool antialias=false);
void gen_runpicture38(stack *Stack)
{
@@ -675,36 +677,36 @@ void gen_runpicture38(stack *Stack)
Int width=vm::pop<Int>(Stack);
callablePen * F=vm::pop<callablePen *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 398 "runpicture.in"
+#line 400 "runpicture.in"
f->append(new drawFunctionImage(Stack,F,width,height,
t*matrix(initial,final),antialias));
}
-#line 403 "runpicture.in"
+#line 405 "runpicture.in"
// string nativeformat();
void gen_runpicture39(stack *Stack)
{
-#line 404 "runpicture.in"
+#line 406 "runpicture.in"
{Stack->push<string>(nativeformat()); return;}
}
-#line 408 "runpicture.in"
+#line 410 "runpicture.in"
// bool latex();
void gen_runpicture40(stack *Stack)
{
-#line 409 "runpicture.in"
+#line 411 "runpicture.in"
{Stack->push<bool>(latex(getSetting<string>("tex"))); return;}
}
-#line 413 "runpicture.in"
+#line 415 "runpicture.in"
// bool pdf();
void gen_runpicture41(stack *Stack)
{
-#line 414 "runpicture.in"
+#line 416 "runpicture.in"
{Stack->push<bool>(pdf(getSetting<string>("tex"))); return;}
}
-#line 418 "runpicture.in"
+#line 420 "runpicture.in"
// void _shipout(string prefix=emptystring, picture *f, picture *preamble=NULL, string format=emptystring, bool wait=false, bool view=true, transform T=identity);
void gen_runpicture42(stack *Stack)
{
@@ -715,7 +717,7 @@ void gen_runpicture42(stack *Stack)
picture * preamble=vm::pop<picture *>(Stack,NULL);
picture * f=vm::pop<picture *>(Stack);
string prefix=vm::pop<string>(Stack,emptystring);
-#line 421 "runpicture.in"
+#line 423 "runpicture.in"
if(prefix.empty()) prefix=outname();
picture *result=new picture;
@@ -761,8 +763,8 @@ void gen_runpicture42(stack *Stack)
result->shipout(preamble,prefix,format,wait,view);
}
-#line 467 "runpicture.in"
-// void shipout3(string prefix, picture *f, string format=emptystring, real width, real height, real angle, real zoom, triple m, triple M, pair shift, realarray2 *t, realarray *background, triplearray *lights, realarray2 *diffuse, realarray2 *specular, bool view=true);
+#line 469 "runpicture.in"
+// void shipout3(string prefix, picture *f, string format=emptystring, real width, real height, real angle, real zoom, triple m, triple M, pair shift, pair margin, realarray2 *t, realarray *background, triplearray *lights, realarray2 *diffuse, realarray2 *specular, bool view=true);
void gen_runpicture43(stack *Stack)
{
bool view=vm::pop<bool>(Stack,true);
@@ -771,6 +773,7 @@ void gen_runpicture43(stack *Stack)
triplearray * lights=vm::pop<triplearray *>(Stack);
realarray * background=vm::pop<realarray *>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
+ pair margin=vm::pop<pair>(Stack);
pair shift=vm::pop<pair>(Stack);
triple M=vm::pop<triple>(Stack);
triple m=vm::pop<triple>(Stack);
@@ -781,7 +784,7 @@ void gen_runpicture43(stack *Stack)
string format=vm::pop<string>(Stack,emptystring);
picture * f=vm::pop<picture *>(Stack);
string prefix=vm::pop<string>(Stack);
-#line 472 "runpicture.in"
+#line 474 "runpicture.in"
size_t n=checkArrays(lights,diffuse);
checkEqual(n,checkArray(specular));
@@ -794,30 +797,31 @@ void gen_runpicture43(stack *Stack)
copyArray2C(Diffuse,diffuse,false,4,UseGC);
copyArray2C(Specular,specular,false,4,UseGC);
- f->shipout3(prefix,format,width,height,angle,zoom,m,M,shift,T,Background,n,
- Lights,Diffuse,Specular,view);
+ f->shipout3(prefix,format,width,height,angle,zoom,m,M,shift,margin,T,
+ Background,n,Lights,Diffuse,Specular,view);
delete[] Background;
delete[] T;
}
-#line 492 "runpicture.in"
-// void shipout3(string prefix, picture *f);
+#line 494 "runpicture.in"
+// void shipout3(string prefix, picture *f, string format=defaultformat3);
void gen_runpicture44(stack *Stack)
{
+ string format=vm::pop<string>(Stack,defaultformat3);
picture * f=vm::pop<picture *>(Stack);
string prefix=vm::pop<string>(Stack);
-#line 493 "runpicture.in"
- f->shipout3(prefix);
+#line 495 "runpicture.in"
+ f->shipout3(prefix,format);
}
-#line 497 "runpicture.in"
+#line 499 "runpicture.in"
// void xmap(string key, transform t=identity);
void gen_runpicture45(stack *Stack)
{
transform t=vm::pop<transform>(Stack,identity);
string key=vm::pop<string>(Stack);
-#line 498 "runpicture.in"
+#line 500 "runpicture.in"
xmap_t &xmap=processData().xmap;
xmap_t::iterator p=xmap.find(key);
if(p != xmap.end())
@@ -829,14 +833,14 @@ void gen_runpicture45(stack *Stack)
}
}
-#line 510 "runpicture.in"
+#line 512 "runpicture.in"
// void deconstruct(picture *f, picture *preamble=NULL, transform T=identity);
void gen_runpicture46(stack *Stack)
{
transform T=vm::pop<transform>(Stack,identity);
picture * preamble=vm::pop<picture *>(Stack,NULL);
picture * f=vm::pop<picture *>(Stack);
-#line 511 "runpicture.in"
+#line 513 "runpicture.in"
unsigned level=0;
string prefix=outname();
@@ -931,7 +935,7 @@ void gen_runpicture46(stack *Stack)
// Three-dimensional picture and surface operations
// Bezier curve
-#line 606 "runpicture.in"
+#line 608 "runpicture.in"
// void _draw(picture *f, path3 g, triple center=Zero, pen p, Int interaction=0);
void gen_runpicture47(stack *Stack)
{
@@ -940,13 +944,13 @@ void gen_runpicture47(stack *Stack)
triple center=vm::pop<triple>(Stack,Zero);
path3 g=vm::pop<path3>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 607 "runpicture.in"
+#line 609 "runpicture.in"
if(g.size() > 0)
f->append(new drawPath3(g,center,p,(Interaction) intcast(interaction)));
}
// Bezier patch
-#line 613 "runpicture.in"
+#line 615 "runpicture.in"
// void draw(picture *f, triplearray2 *P, triple center, bool straight, penarray *p, real opacity, real shininess, real metallic, real fresnel0, real PRCshininess, penarray *colors, Int interaction, bool prc=true);
void gen_runpicture48(stack *Stack)
{
@@ -963,14 +967,14 @@ void gen_runpicture48(stack *Stack)
triple center=vm::pop<triple>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 616 "runpicture.in"
+#line 618 "runpicture.in"
f->append(new drawBezierPatch(*P,center,straight,*p,opacity,shininess,
metallic,fresnel0,PRCshininess,*colors,
(Interaction) intcast(interaction),prc));
}
// Bezier triangle
-#line 623 "runpicture.in"
+#line 625 "runpicture.in"
// void drawbeziertriangle(picture *f, triplearray2 *P, triple center, bool straight, penarray *p, real opacity, real shininess, real metallic, real fresnel0, real PRCshininess, penarray *colors, Int interaction, bool prc=true);
void gen_runpicture49(stack *Stack)
{
@@ -987,14 +991,14 @@ void gen_runpicture49(stack *Stack)
triple center=vm::pop<triple>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 627 "runpicture.in"
+#line 629 "runpicture.in"
f->append(new drawBezierTriangle(*P,center,straight,*p,opacity,shininess,
metallic,fresnel0,PRCshininess,*colors,
(Interaction) intcast(interaction),prc));
}
// General NURBS curve
-#line 634 "runpicture.in"
+#line 636 "runpicture.in"
// void draw(picture *f, triplearray *P, realarray *knot, realarray *weights=emptyarray, pen p);
void gen_runpicture50(stack *Stack)
{
@@ -1003,12 +1007,12 @@ void gen_runpicture50(stack *Stack)
realarray * knot=vm::pop<realarray *>(Stack);
triplearray * P=vm::pop<triplearray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 636 "runpicture.in"
+#line 638 "runpicture.in"
f->append(new drawNurbsPath3(*P,knot,weights,p));
}
// General NURBS surface
-#line 641 "runpicture.in"
+#line 643 "runpicture.in"
// void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot, realarray2 *weights=emptyarray, penarray *p, real opacity, real shininess,real metallic, real fresnel0, real PRCshininess, penarray *colors);
void gen_runpicture51(stack *Stack)
{
@@ -1024,13 +1028,13 @@ void gen_runpicture51(stack *Stack)
realarray * uknot=vm::pop<realarray *>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 645 "runpicture.in"
+#line 647 "runpicture.in"
f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess, metallic, fresnel0,
PRCshininess,*colors));
}
// PRC unit sphere
-#line 651 "runpicture.in"
+#line 653 "runpicture.in"
// void drawPRCsphere(picture *f, realarray2 *t, bool half=false, penarray *p, real opacity, real shininess, Int type);
void gen_runpicture52(stack *Stack)
{
@@ -1041,12 +1045,12 @@ void gen_runpicture52(stack *Stack)
bool half=vm::pop<bool>(Stack,false);
realarray2 * t=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 653 "runpicture.in"
+#line 655 "runpicture.in"
f->append(new drawSphere(*t,half,*p,opacity,shininess,intcast(type)));
}
// PRC unit cylinder
-#line 658 "runpicture.in"
+#line 660 "runpicture.in"
// void drawPRCcylinder(picture *f, realarray2 *t, penarray *p, real opacity, real shininess);
void gen_runpicture53(stack *Stack)
{
@@ -1055,12 +1059,12 @@ void gen_runpicture53(stack *Stack)
penarray * p=vm::pop<penarray *>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 660 "runpicture.in"
+#line 662 "runpicture.in"
f->append(new drawCylinder(*t,*p,opacity,shininess));
}
// PRC unit disk
-#line 665 "runpicture.in"
+#line 667 "runpicture.in"
// void drawPRCdisk(picture *f, realarray2 *t, penarray *p, real opacity, real shininess);
void gen_runpicture54(stack *Stack)
{
@@ -1069,12 +1073,12 @@ void gen_runpicture54(stack *Stack)
penarray * p=vm::pop<penarray *>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 667 "runpicture.in"
+#line 669 "runpicture.in"
f->append(new drawDisk(*t,*p,opacity,shininess));
}
// General PRC tube
-#line 672 "runpicture.in"
+#line 674 "runpicture.in"
// void drawPRCtube(picture *f, path3 center, path3 g, penarray *p, real opacity, real shininess);
void gen_runpicture55(stack *Stack)
{
@@ -1084,12 +1088,12 @@ void gen_runpicture55(stack *Stack)
path3 g=vm::pop<path3>(Stack);
path3 center=vm::pop<path3>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 674 "runpicture.in"
+#line 676 "runpicture.in"
f->append(new drawTube(center,g,*p,opacity,shininess));
}
// Draw pixel
-#line 679 "runpicture.in"
+#line 681 "runpicture.in"
// void drawpixel(picture *f, triple v, pen p, real width=1.0);
void gen_runpicture56(stack *Stack)
{
@@ -1097,12 +1101,12 @@ void gen_runpicture56(stack *Stack)
pen p=vm::pop<pen>(Stack);
triple v=vm::pop<triple>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 680 "runpicture.in"
+#line 682 "runpicture.in"
f->append(new drawPixel(v,p,width));
}
// Draw triangles
-#line 685 "runpicture.in"
+#line 687 "runpicture.in"
// void draw(picture *f, triplearray *v, Intarray2 *vi, triplearray *n, Intarray2 *ni, penarray *p, real opacity, real shininess, real metallic, real fresnel0, real PRCshininess, penarray *c=emptyarray, Intarray2 *ci=emptyarray);
void gen_runpicture57(stack *Stack)
{
@@ -1119,63 +1123,63 @@ void gen_runpicture57(stack *Stack)
Intarray2 * vi=vm::pop<Intarray2 *>(Stack);
triplearray * v=vm::pop<triplearray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 690 "runpicture.in"
+#line 692 "runpicture.in"
f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,fresnel0,PRCshininess,
*c,*ci));
}
-#line 695 "runpicture.in"
+#line 697 "runpicture.in"
// triple min3(picture *f);
void gen_runpicture58(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 696 "runpicture.in"
+#line 698 "runpicture.in"
{Stack->push<triple>(f->bounds3().Min()); return;}
}
-#line 700 "runpicture.in"
+#line 702 "runpicture.in"
// triple max3(picture *f);
void gen_runpicture59(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 701 "runpicture.in"
+#line 703 "runpicture.in"
{Stack->push<triple>(f->bounds3().Max()); return;}
}
-#line 705 "runpicture.in"
+#line 707 "runpicture.in"
// triple size3(picture *f);
void gen_runpicture60(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 706 "runpicture.in"
+#line 708 "runpicture.in"
bbox3 b=f->bounds3();
{Stack->push<triple>(b.Max()-b.Min()); return;}
}
-#line 711 "runpicture.in"
+#line 713 "runpicture.in"
// pair minratio(picture *f);
void gen_runpicture61(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 712 "runpicture.in"
+#line 714 "runpicture.in"
{Stack->push<pair>(f->ratio(::min)); return;}
}
-#line 716 "runpicture.in"
+#line 718 "runpicture.in"
// pair maxratio(picture *f);
void gen_runpicture62(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 717 "runpicture.in"
+#line 719 "runpicture.in"
{Stack->push<pair>(f->ratio(::max)); return;}
}
-#line 721 "runpicture.in"
+#line 723 "runpicture.in"
// bool is3D(picture *f);
void gen_runpicture63(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 722 "runpicture.in"
+#line 724 "runpicture.in"
{Stack->push<bool>(f->have3D()); return;}
}
@@ -1185,133 +1189,133 @@ namespace trans {
void gen_runpicture_venv(venv &ve)
{
-#line 126 "runpicture.in"
+#line 128 "runpicture.in"
REGISTER_BLTIN(run::newPicture,"newPicture");
-#line 131 "runpicture.in"
+#line 133 "runpicture.in"
addFunc(ve, run::gen_runpicture1, primBoolean(), SYM(empty), formal(primPicture(), SYM(f), false, false));
-#line 136 "runpicture.in"
+#line 138 "runpicture.in"
addFunc(ve, run::gen_runpicture2, primVoid(), SYM(erase), formal(primPicture(), SYM(f), false, false));
-#line 141 "runpicture.in"
+#line 143 "runpicture.in"
addFunc(ve, run::gen_runpicture3, primPair(), SYM(min), formal(primPicture(), SYM(f), false, false));
-#line 146 "runpicture.in"
+#line 148 "runpicture.in"
addFunc(ve, run::gen_runpicture4, primPair(), SYM(max), formal(primPicture(), SYM(f), false, false));
-#line 151 "runpicture.in"
+#line 153 "runpicture.in"
addFunc(ve, run::gen_runpicture5, primPair(), SYM(size), formal(primPicture(), SYM(f), false, false));
-#line 157 "runpicture.in"
+#line 159 "runpicture.in"
addFunc(ve, run::gen_runpicture6, primVoid(), SYM(_draw), formal(primPicture(), SYM(f), false, false), formal(primPath(), SYM(g), false, false), formal(primPen(), SYM(p), false, false));
-#line 162 "runpicture.in"
+#line 164 "runpicture.in"
addFunc(ve, run::gen_runpicture7, primVoid(), SYM(fill), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primPen(), SYM(p), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 168 "runpicture.in"
+#line 170 "runpicture.in"
addFunc(ve, run::gen_runpicture8, primVoid(), SYM(latticeshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray2() , SYM(p), false, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 177 "runpicture.in"
+#line 179 "runpicture.in"
addFunc(ve, run::gen_runpicture9, primVoid(), SYM(axialshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(pena), false, false), formal(primPair(), SYM(a), false, false), formal(primBoolean(), SYM(extenda), true, false), formal(primPen(), SYM(penb), false, false), formal(primPair(), SYM(b), false, false), formal(primBoolean(), SYM(extendb), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 186 "runpicture.in"
+#line 188 "runpicture.in"
addFunc(ve, run::gen_runpicture10, primVoid(), SYM(radialshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(pena), false, false), formal(primPair(), SYM(a), false, false), formal(primReal(), SYM(ra), false, false), formal(primBoolean(), SYM(extenda), true, false), formal(primPen(), SYM(penb), false, false), formal(primPair(), SYM(b), false, false), formal(primReal(), SYM(rb), false, false), formal(primBoolean(), SYM(extendb), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 195 "runpicture.in"
+#line 197 "runpicture.in"
addFunc(ve, run::gen_runpicture11, primVoid(), SYM(gouraudshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray() , SYM(p), false, false), formal(pairArray(), SYM(z), false, false), formal(IntArray(), SYM(edges), false, false), formal(primBoolean(), SYM(copy), true, false));
-#line 206 "runpicture.in"
+#line 208 "runpicture.in"
addFunc(ve, run::gen_runpicture12, primVoid(), SYM(gouraudshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray() , SYM(p), false, false), formal(IntArray(), SYM(edges), false, false), formal(primBoolean(), SYM(copy), true, false));
-#line 230 "runpicture.in"
+#line 232 "runpicture.in"
addFunc(ve, run::gen_runpicture13, primVoid(), SYM(tensorshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray2() , SYM(p), false, false), formal(pathArray() , SYM(b), true, false), formal(pairArray2(), SYM(z), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 245 "runpicture.in"
+#line 247 "runpicture.in"
addFunc(ve, run::gen_runpicture14, primVoid(), SYM(functionshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(primString() , SYM(shader), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 253 "runpicture.in"
+#line 255 "runpicture.in"
addFunc(ve, run::gen_runpicture15, primVoid(), SYM(clip), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 263 "runpicture.in"
+#line 265 "runpicture.in"
addFunc(ve, run::gen_runpicture16, primVoid(), SYM(beginclip), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 270 "runpicture.in"
+#line 272 "runpicture.in"
addFunc(ve, run::gen_runpicture17, primVoid(), SYM(endclip), formal(primPicture(), SYM(f), false, false));
-#line 275 "runpicture.in"
+#line 277 "runpicture.in"
addFunc(ve, run::gen_runpicture18, primVoid(), SYM(gsave), formal(primPicture(), SYM(f), false, false));
-#line 280 "runpicture.in"
+#line 282 "runpicture.in"
addFunc(ve, run::gen_runpicture19, primVoid(), SYM(grestore), formal(primPicture(), SYM(f), false, false));
-#line 285 "runpicture.in"
+#line 287 "runpicture.in"
addFunc(ve, run::gen_runpicture20, primVoid(), SYM(begingroup), formal(primPicture(), SYM(f), false, false));
-#line 290 "runpicture.in"
+#line 292 "runpicture.in"
addFunc(ve, run::gen_runpicture21, primVoid(), SYM(endgroup), formal(primPicture(), SYM(f), false, false));
-#line 295 "runpicture.in"
+#line 297 "runpicture.in"
addFunc(ve, run::gen_runpicture22, primVoid(), SYM(_begingroup3), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(name), false, false), formal(primReal(), SYM(compression), false, false), formal(primReal(), SYM(granularity), false, false), formal(primBoolean(), SYM(closed), false, false), formal(primBoolean(), SYM(tessellate), false, false), formal(primBoolean(), SYM(dobreak), false, false), formal(primBoolean(), SYM(nobreak), false, false), formal(primTriple(), SYM(center), false, false), formal(primInt(), SYM(interaction), false, false));
-#line 304 "runpicture.in"
+#line 306 "runpicture.in"
addFunc(ve, run::gen_runpicture23, primVoid(), SYM(endgroup3), formal(primPicture(), SYM(f), false, false));
-#line 309 "runpicture.in"
+#line 311 "runpicture.in"
addFunc(ve, run::gen_runpicture24, primVoid(), SYM(add), formal(primPicture(), SYM(dest), false, false), formal(primPicture(), SYM(src), false, false));
-#line 314 "runpicture.in"
+#line 316 "runpicture.in"
addFunc(ve, run::gen_runpicture25, primVoid(), SYM(prepend), formal(primPicture(), SYM(dest), false, false), formal(primPicture(), SYM(src), false, false));
-#line 319 "runpicture.in"
+#line 321 "runpicture.in"
addFunc(ve, run::gen_runpicture26, primVoid(), SYM(postscript), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false));
-#line 324 "runpicture.in"
+#line 326 "runpicture.in"
addFunc(ve, run::gen_runpicture27, primVoid(), SYM(tex), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false));
-#line 329 "runpicture.in"
+#line 331 "runpicture.in"
addFunc(ve, run::gen_runpicture28, primVoid(), SYM(postscript), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false), formal(primPair(), SYM(min), false, false), formal(primPair(), SYM(max), false, false));
-#line 334 "runpicture.in"
+#line 336 "runpicture.in"
addFunc(ve, run::gen_runpicture29, primVoid(), SYM(tex), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false), formal(primPair(), SYM(min), false, false), formal(primPair(), SYM(max), false, false));
-#line 339 "runpicture.in"
+#line 341 "runpicture.in"
addFunc(ve, run::gen_runpicture30, primVoid(), SYM(texpreamble), formal(primString() , SYM(s), false, false));
-#line 347 "runpicture.in"
+#line 349 "runpicture.in"
addFunc(ve, run::gen_runpicture31, primVoid(), SYM(deletepreamble));
-#line 354 "runpicture.in"
+#line 356 "runpicture.in"
addFunc(ve, run::gen_runpicture32, primVoid(), SYM(_labelpath), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false), formal(primString() , SYM(size), false, false), formal(primPath(), SYM(g), false, false), formal(primString() , SYM(justify), false, false), formal(primPair(), SYM(offset), false, false), formal(primPen(), SYM(p), false, false));
-#line 360 "runpicture.in"
+#line 362 "runpicture.in"
addFunc(ve, run::gen_runpicture33, primVoid(), SYM(texreset));
-#line 368 "runpicture.in"
+#line 370 "runpicture.in"
addFunc(ve, run::gen_runpicture34, primVoid(), SYM(layer), formal(primPicture(), SYM(f), false, false));
-#line 373 "runpicture.in"
+#line 375 "runpicture.in"
addFunc(ve, run::gen_runpicture35, primVoid(), SYM(newpage), formal(primPicture(), SYM(f), false, false));
-#line 378 "runpicture.in"
+#line 380 "runpicture.in"
addFunc(ve, run::gen_runpicture36, primVoid(), SYM(_image), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(data), false, false), formal(primPair(), SYM(initial), false, false), formal(primPair(), SYM(final), false, false), formal(penArray() , SYM(palette), true, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(copy), true, false), formal(primBoolean(), SYM(antialias), true, false));
-#line 388 "runpicture.in"
+#line 390 "runpicture.in"
addFunc(ve, run::gen_runpicture37, primVoid(), SYM(_image), formal(primPicture(), SYM(f), false, false), formal(penArray2() , SYM(data), false, false), formal(primPair(), SYM(initial), false, false), formal(primPair(), SYM(final), false, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(copy), true, false), formal(primBoolean(), SYM(antialias), true, false));
-#line 396 "runpicture.in"
+#line 398 "runpicture.in"
addFunc(ve, run::gen_runpicture38, primVoid(), SYM(_image), formal(primPicture(), SYM(f), false, false), formal(penFunction(), SYM(f), false, false), formal(primInt(), SYM(width), false, false), formal(primInt(), SYM(height), false, false), formal(primPair(), SYM(initial), false, false), formal(primPair(), SYM(final), false, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(antialias), true, false));
-#line 403 "runpicture.in"
+#line 405 "runpicture.in"
addFunc(ve, run::gen_runpicture39, primString() , SYM(nativeformat));
-#line 408 "runpicture.in"
+#line 410 "runpicture.in"
addFunc(ve, run::gen_runpicture40, primBoolean(), SYM(latex));
-#line 413 "runpicture.in"
+#line 415 "runpicture.in"
addFunc(ve, run::gen_runpicture41, primBoolean(), SYM(pdf));
-#line 418 "runpicture.in"
+#line 420 "runpicture.in"
addFunc(ve, run::gen_runpicture42, primVoid(), SYM(_shipout), formal(primString() , SYM(prefix), true, false), formal(primPicture(), SYM(f), false, false), formal(primPicture(), SYM(preamble), true, false), formal(primString() , SYM(format), true, false), formal(primBoolean(), SYM(wait), true, false), formal(primBoolean(), SYM(view), true, false), formal(primTransform(), SYM(t), true, false));
-#line 467 "runpicture.in"
- addFunc(ve, run::gen_runpicture43, primVoid(), SYM(shipout3), formal(primString() , SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(format), true, false), formal(primReal(), SYM(width), false, false), formal(primReal(), SYM(height), false, false), formal(primReal(), SYM(angle), false, false), formal(primReal(), SYM(zoom), false, false), formal(primTriple(), SYM(m), false, false), formal(primTriple(), SYM(m), false, false), formal(primPair(), SYM(shift), false, false), formal(realArray2(), SYM(t), false, false), formal(realArray(), SYM(background), false, false), formal(tripleArray(), SYM(lights), false, false), formal(realArray2(), SYM(diffuse), false, false), formal(realArray2(), SYM(specular), false, false), formal(primBoolean(), SYM(view), true, false));
-#line 492 "runpicture.in"
- addFunc(ve, run::gen_runpicture44, primVoid(), SYM(shipout3), formal(primString() , SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false));
-#line 497 "runpicture.in"
+#line 469 "runpicture.in"
+ addFunc(ve, run::gen_runpicture43, primVoid(), SYM(shipout3), formal(primString() , SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(format), true, false), formal(primReal(), SYM(width), false, false), formal(primReal(), SYM(height), false, false), formal(primReal(), SYM(angle), false, false), formal(primReal(), SYM(zoom), false, false), formal(primTriple(), SYM(m), false, false), formal(primTriple(), SYM(m), false, false), formal(primPair(), SYM(shift), false, false), formal(primPair(), SYM(margin), false, false), formal(realArray2(), SYM(t), false, false), formal(realArray(), SYM(background), false, false), formal(tripleArray(), SYM(lights), false, false), formal(realArray2(), SYM(diffuse), false, false), formal(realArray2(), SYM(specular), false, false), formal(primBoolean(), SYM(view), true, false));
+#line 494 "runpicture.in"
+ addFunc(ve, run::gen_runpicture44, primVoid(), SYM(shipout3), formal(primString() , SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(format), true, false));
+#line 499 "runpicture.in"
addFunc(ve, run::gen_runpicture45, primVoid(), SYM(xmap), formal(primString() , SYM(key), false, false), formal(primTransform(), SYM(t), true, false));
-#line 510 "runpicture.in"
+#line 512 "runpicture.in"
addFunc(ve, run::gen_runpicture46, primVoid(), SYM(deconstruct), formal(primPicture(), SYM(f), false, false), formal(primPicture(), SYM(preamble), true, false), formal(primTransform(), SYM(t), true, false));
-#line 602 "runpicture.in"
+#line 604 "runpicture.in"
addFunc(ve, run::gen_runpicture47, primVoid(), SYM(_draw), formal(primPicture(), SYM(f), false, false), formal(primPath3(), SYM(g), false, false), formal(primTriple(), SYM(center), true, false), formal(primPen(), SYM(p), false, false), formal(primInt(), SYM(interaction), true, false));
-#line 612 "runpicture.in"
+#line 614 "runpicture.in"
addFunc(ve, run::gen_runpicture48, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray() , SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primBoolean(), SYM(prc), true, false));
-#line 622 "runpicture.in"
+#line 624 "runpicture.in"
addFunc(ve, run::gen_runpicture49, primVoid(), SYM(drawbeziertriangle), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray() , SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primBoolean(), SYM(prc), true, false));
-#line 633 "runpicture.in"
+#line 635 "runpicture.in"
addFunc(ve, run::gen_runpicture50, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(p), false, false), formal(realArray(), SYM(knot), false, false), formal(realArray(), SYM(weights), true, false), formal(primPen(), SYM(p), false, false));
-#line 640 "runpicture.in"
+#line 642 "runpicture.in"
addFunc(ve, run::gen_runpicture51, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(realArray(), SYM(uknot), false, false), formal(realArray(), SYM(vknot), false, false), formal(realArray2(), SYM(weights), true, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray() , SYM(colors), false, false));
-#line 650 "runpicture.in"
+#line 652 "runpicture.in"
addFunc(ve, run::gen_runpicture52, primVoid(), SYM(drawPRCsphere), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(primBoolean(), SYM(half), true, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primInt(), SYM(type), false, false));
-#line 657 "runpicture.in"
+#line 659 "runpicture.in"
addFunc(ve, run::gen_runpicture53, primVoid(), SYM(drawPRCcylinder), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false));
-#line 664 "runpicture.in"
+#line 666 "runpicture.in"
addFunc(ve, run::gen_runpicture54, primVoid(), SYM(drawPRCdisk), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false));
-#line 671 "runpicture.in"
+#line 673 "runpicture.in"
addFunc(ve, run::gen_runpicture55, primVoid(), SYM(drawPRCtube), formal(primPicture(), SYM(f), false, false), formal(primPath3(), SYM(center), false, false), formal(primPath3(), SYM(g), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false));
-#line 678 "runpicture.in"
+#line 680 "runpicture.in"
addFunc(ve, run::gen_runpicture56, primVoid(), SYM(drawpixel), formal(primPicture(), SYM(f), false, false), formal(primTriple(), SYM(v), false, false), formal(primPen(), SYM(p), false, false), formal(primReal(), SYM(width), true, false));
-#line 684 "runpicture.in"
+#line 686 "runpicture.in"
addFunc(ve, run::gen_runpicture57, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(v), false, false), formal(IntArray2(), SYM(vi), false, false), formal(tripleArray(), SYM(n), false, false), formal(IntArray2(), SYM(ni), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray() , SYM(c), true, false), formal(IntArray2(), SYM(ci), true, false));
-#line 695 "runpicture.in"
+#line 697 "runpicture.in"
addFunc(ve, run::gen_runpicture58, primTriple(), SYM(min3), formal(primPicture(), SYM(f), false, false));
-#line 700 "runpicture.in"
+#line 702 "runpicture.in"
addFunc(ve, run::gen_runpicture59, primTriple(), SYM(max3), formal(primPicture(), SYM(f), false, false));
-#line 705 "runpicture.in"
+#line 707 "runpicture.in"
addFunc(ve, run::gen_runpicture60, primTriple(), SYM(size3), formal(primPicture(), SYM(f), false, false));
-#line 711 "runpicture.in"
+#line 713 "runpicture.in"
addFunc(ve, run::gen_runpicture61, primPair(), SYM(minratio), formal(primPicture(), SYM(f), false, false));
-#line 716 "runpicture.in"
+#line 718 "runpicture.in"
addFunc(ve, run::gen_runpicture62, primPair(), SYM(maxratio), formal(primPicture(), SYM(f), false, false));
-#line 721 "runpicture.in"
+#line 723 "runpicture.in"
addFunc(ve, run::gen_runpicture63, primBoolean(), SYM(is3D), formal(primPicture(), SYM(f), false, false));
}
diff --git a/graphics/asymptote/runpicture.in b/graphics/asymptote/runpicture.in
index f6c0d75c07..bb2a5649a5 100644
--- a/graphics/asymptote/runpicture.in
+++ b/graphics/asymptote/runpicture.in
@@ -120,6 +120,8 @@ array *nop(array *a)
triple Zero;
+string defaultformat3="prc";
+
// Autogenerated routines:
@@ -466,7 +468,7 @@ void _shipout(string prefix=emptystring, picture *f, picture *preamble=NULL,
void shipout3(string prefix, picture *f, string format=emptystring,
real width, real height, real angle, real zoom,
- triple m, triple M, pair shift, realarray2 *t,
+ triple m, triple M, pair shift, pair margin, realarray2 *t,
realarray *background, triplearray *lights, realarray2 *diffuse,
realarray2 *specular, bool view=true)
{
@@ -482,16 +484,16 @@ void shipout3(string prefix, picture *f, string format=emptystring,
copyArray2C(Diffuse,diffuse,false,4,UseGC);
copyArray2C(Specular,specular,false,4,UseGC);
- f->shipout3(prefix,format,width,height,angle,zoom,m,M,shift,T,Background,n,
- Lights,Diffuse,Specular,view);
+ f->shipout3(prefix,format,width,height,angle,zoom,m,M,shift,margin,T,
+ Background,n,Lights,Diffuse,Specular,view);
delete[] Background;
delete[] T;
}
-void shipout3(string prefix, picture *f)
+void shipout3(string prefix, picture *f, string format=defaultformat3)
{
- f->shipout3(prefix);
+ f->shipout3(prefix,format);
}
void xmap(string key, transform t=identity)
diff --git a/graphics/asymptote/settings.cc b/graphics/asymptote/settings.cc
index c0478379cd..d3330a9677 100644
--- a/graphics/asymptote/settings.cc
+++ b/graphics/asymptote/settings.cc
@@ -74,7 +74,7 @@ namespace settings {
using camp::pair;
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
const bool havegl=true;
#else
const bool havegl=false;
@@ -84,6 +84,8 @@ mode_t mask;
string systemDir=ASYMPTOTE_SYSDIR;
string defaultEPSdriver="eps2write";
+string defaultAsyGL="https://vectorgraphics.github.io/asymptote/base/webgl/asygl-"+
+ AsyGLVersion+".js";
#ifndef __MSDOS__
@@ -94,9 +96,11 @@ const char pathSeparator=':';
#ifdef __APPLE__
string defaultPSViewer="open";
string defaultPDFViewer="open";
+string defaultHTMLViewer="open";
#else
string defaultPSViewer="gv";
string defaultPDFViewer="acroread";
+string defaultHTMLViewer="google-chrome";
#endif
string defaultGhostscript="gs";
string defaultGhostscriptLibrary="";
@@ -115,6 +119,7 @@ const char pathSeparator=';';
string defaultPSViewer="cmd";
//string defaultPDFViewer="AcroRd32.exe";
string defaultPDFViewer="cmd";
+string defaultHTMLViewer="cmd";
string defaultGhostscript;
string defaultGhostscriptLibrary;
//string defaultDisplay="imdisplay";
@@ -1132,6 +1137,11 @@ void initSettings() {
"Initial 3D rendering screen position"));
addOption(new pairSetting("maxviewport", 0, "pair",
"Maximum viewport size",pair(2048,2048)));
+ addOption(new pairSetting("viewportmargin", 0, "pair",
+ "Horizontal and vertical 3D viewport margin",
+ pair(0.5,0.5)));
+ addOption(new boolSetting("absolute", 0,
+ "Use absolute WebGL dimensions", false));
addOption(new pairSetting("maxtile", 0, "pair",
"Maximum rendering tile size",pair(1024,768)));
addOption(new boolSetting("iconify", 0,
@@ -1261,6 +1271,8 @@ void initSettings() {
addOption(new boolSetting("autorotate", 0,
"Enable automatic PDF page rotation",
false));
+ addOption(new boolSetting("offline", 0,
+ "Produce offline html files",false));
addOption(new boolSetting("pdfreload", 0,
"Automatically reload document in pdfviewer",
false));
@@ -1277,19 +1289,30 @@ void initSettings() {
addOption(new IntSetting("maxvertices", 0, "n", "Maximum number of vertices to queue", 0));
addOption(new realSetting("zoomfactor", 0, "factor", "Zoom step factor",
1.05));
+ addOption(new realSetting("zoomPinchFactor", 0, "n",
+ "WebGL zoom pinch sensitivity", 10));
+ addOption(new realSetting("zoomPinchCap", 0, "limit",
+ "WebGL maximum zoom pinch", 100));
addOption(new realSetting("zoomstep", 0, "step", "Mouse motion zoom step",
0.1));
+ addOption(new realSetting("shiftHoldDistance", 0, "n",
+ "WebGL touch screen distance limit for shift mode",
+ 20));
+ addOption(new realSetting("shiftWaitTime", 0, "ms",
+ "WebGL touch screen shift mode delay",
+ 200));
+ addOption(new realSetting("vibrateTime", 0, "ms",
+ "WebGL shift mode vibrate duration",
+ 25));
addOption(new realSetting("spinstep", 0, "deg/s", "Spin speed",
60.0));
addOption(new realSetting("framerate", 0, "frames/s", "Animation speed",
30.0));
addOption(new realSetting("framedelay", 0, "ms",
"Additional frame delay", 0.0));
- addOption(new realSetting("arcballradius", 0, "pixels",
- "Arcball radius", 750.0));
addOption(new realSetting("resizestep", 0, "step", "Resize step", 1.2));
- addOption(new IntSetting("doubleclick", 0, "ms",
- "Emulated double-click timeout", 200));
+ addOption(new IntSetting("digits", 0, "n",
+ "Default output file precision", 6));
addOption(new realSetting("paperwidth", 0, "bp", ""));
addOption(new realSetting("paperheight", 0, "bp", ""));
@@ -1298,6 +1321,7 @@ void initSettings() {
addOption(new stringSetting("dvisvgmOptions", 0, "string", ""));
addOption(new stringSetting("convertOptions", 0, "string", ""));
addOption(new stringSetting("gsOptions", 0, "string", ""));
+ addOption(new stringSetting("htmlviewerOptions", 0, "string", ""));
addOption(new stringSetting("psviewerOptions", 0, "string", ""));
addOption(new stringSetting("pdfviewerOptions", 0, "string", ""));
addOption(new stringSetting("pdfreloadOptions", 0, "string", ""));
@@ -1306,11 +1330,13 @@ void initSettings() {
"","setpagesize=false,unicode,pdfborder=0 0 0"));
addOption(new envSetting("config","config."+suffix));
+ addOption(new envSetting("htmlviewer", defaultHTMLViewer));
addOption(new envSetting("pdfviewer", defaultPDFViewer));
addOption(new envSetting("psviewer", defaultPSViewer));
addOption(new envSetting("gs", defaultGhostscript));
addOption(new envSetting("libgs", defaultGhostscriptLibrary));
addOption(new envSetting("epsdriver", defaultEPSdriver));
+ addOption(new envSetting("asygl", defaultAsyGL));
addOption(new envSetting("texpath", ""));
addOption(new envSetting("texcommand", ""));
addOption(new envSetting("dvips", "dvips"));
diff --git a/graphics/asymptote/settings.h b/graphics/asymptote/settings.h
index 83db0a30a5..7b46ccd449 100644
--- a/graphics/asymptote/settings.h
+++ b/graphics/asymptote/settings.h
@@ -120,8 +120,13 @@ const double cm=inches/2.54;
const double tex2ps=72.0/72.27;
const double ps2tex=1.0/tex2ps;
+const string AsyGLVersion="1.00";
+const string AsyGL="webgl/asygl-"+ AsyGLVersion+".js";
+const string WebGLheader="webgl/WebGLheader.html";
+const string WebGLfooter="webgl/WebGLfooter.html";
}
+
extern const char *REVISION;
#endif
diff --git a/graphics/asymptote/shaders.cc b/graphics/asymptote/shaders.cc
index 1067068772..fa9239a360 100644
--- a/graphics/asymptote/shaders.cc
+++ b/graphics/asymptote/shaders.cc
@@ -3,7 +3,7 @@
#include "common.h"
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
#include <fstream>
#include <sstream>
@@ -14,7 +14,7 @@
#include "shaders.h"
GLuint compileAndLinkShader(std::vector<ShaderfileModePair> const& shaders,
- size_t NLights, size_t NMaterials,
+ size_t Nlights, size_t NMaterials,
std::vector<std::string> const& defineflags)
{
GLuint mainShader = glCreateProgram();
@@ -23,7 +23,7 @@ GLuint compileAndLinkShader(std::vector<ShaderfileModePair> const& shaders,
size_t n=shaders.size();
for(size_t i=0; i < n; ++i) {
GLint newshader=createShaderFile(shaders[i].first,shaders[i].second,
- NLights,NMaterials,defineflags);
+ Nlights,NMaterials,defineflags);
glAttachShader(mainShader,newshader);
compiledShaders.push_back(newshader);
}
@@ -86,8 +86,6 @@ GLuint createShaderFile(std::string file, int shaderType, size_t Nlights,
shaderSrc << "#version " << GLSL_VERSION << "\r\n";
shaderSrc << "#extension GL_ARB_uniform_buffer_object : enable"
<< "\r\n";
- shaderSrc << "#extension GL_ARB_shading_language_packing : enable"
- << "\r\n";
size_t n=defineflags.size();
for(size_t i=0; i < n; ++i) {
diff --git a/graphics/asymptote/shaders.h b/graphics/asymptote/shaders.h
index f92b7010ab..56b4560d6a 100644
--- a/graphics/asymptote/shaders.h
+++ b/graphics/asymptote/shaders.h
@@ -21,9 +21,8 @@
typedef std::pair<std::string, int> ShaderfileModePair;
GLuint compileAndLinkShader(
- std::vector<ShaderfileModePair> const& shaders,
- size_t NLights, size_t NMaterials,
- std::vector<std::string> const& defineflags);
+ std::vector<ShaderfileModePair> const& shaders, size_t NLights,
+ size_t NMaterials, std::vector<std::string> const& defineflags);
GLuint createShaders(GLchar const *src, int shaderType,
std::string const& filename);
diff --git a/graphics/asymptote/tr.cc b/graphics/asymptote/tr.cc
index c62301cc43..be2beaf764 100644
--- a/graphics/asymptote/tr.cc
+++ b/graphics/asymptote/tr.cc
@@ -44,7 +44,7 @@
#include "common.h"
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGL
#include <assert.h>
#include <math.h>
@@ -53,11 +53,6 @@
#ifdef WIN32
#include <windows.h>
#endif
-#ifdef __APPLE__
-#include <OpenGL/gl.h>
-#else
-#include <GL/gl.h>
-#endif
#include "tr.h"
#define DEFAULT_TILE_WIDTH 256
diff --git a/graphics/asymptote/tr.h b/graphics/asymptote/tr.h
index 72d1bef0e0..5485c44859 100644
--- a/graphics/asymptote/tr.h
+++ b/graphics/asymptote/tr.h
@@ -74,6 +74,7 @@
#ifdef __APPLE__
+#define GL_SILENCE_DEPRECATION
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
diff --git a/graphics/asymptote/triple.h b/graphics/asymptote/triple.h
index de6767a29f..af42e28583 100644
--- a/graphics/asymptote/triple.h
+++ b/graphics/asymptote/triple.h
@@ -11,6 +11,7 @@
#include <cassert>
#include <iostream>
+#include <fstream>
#include <cmath>
#include <cstring>
@@ -18,11 +19,6 @@
#include "angle.h"
#include "pair.h"
-namespace run {
-void transpose(double *a, size_t n);
-void inverse(double *a, size_t n);
-}
-
namespace camp {
typedef double Triple[3];
@@ -55,36 +51,66 @@ public:
double getz() const { return z; }
// transform by row-major matrix
- friend triple operator* (const double* t, const triple& v)
- {
+ friend triple operator* (const double* t, const triple& v) {
if(t == NULL)
return v;
double f=t[12]*v.x+t[13]*v.y+t[14]*v.z+t[15];
- if(f == 0.0)
- reportError("division by 0 in transform of a triple");
+ if(f != 0.0) {
+ f=1.0/f;
+
+ return triple((t[0]*v.x+t[1]*v.y+t[2]*v.z+t[3])*f,
+ (t[4]*v.x+t[5]*v.y+t[6]*v.z+t[7])*f,
+ (t[8]*v.x+t[9]*v.y+t[10]*v.z+t[11])*f);
+ }
+ reportError("division by 0 in transform of a triple");
+ return 0.0;
+ }
+
+ friend triple operator* (const triple& v, const double* t) {
+ if(t == NULL)
+ return v;
+ double f=t[3]*v.x+t[7]*v.y+t[11]*v.z+t[15];
+ if(f != 0.0) {
+ f=1.0/f;
+ return triple((v.x*t[0]+v.y*t[4]+v.z*t[8]+t[12])*f,
+ (v.x*t[1]+v.y*t[5]+v.z*t[9]+t[13])*f,
+ (v.x*t[2]+v.y*t[6]+v.z*t[10]+t[14])*f);
+ }
+ reportError("division by 0 in transform of a triple");
+ return 0.0;
+ }
+
+ friend triple Transform3(const triple& v, const double* t) {
+ return triple((t[0]*v.x+t[1]*v.y+t[2]*v.z),
+ (t[3]*v.x+t[4]*v.y+t[5]*v.z),
+ (t[6]*v.x+t[7]*v.y+t[8]*v.z));
+ }
+
+ friend triple Transform3(const double* t, const triple& v) {
+ return triple(v.x*t[0]+v.y*t[3]+v.z*t[6],
+ v.x*t[1]+v.y*t[4]+v.z*t[7],
+ v.x*t[2]+v.y*t[5]+v.z*t[8]);
+ }
+
+ // return x and y components of v*t.
+ friend pair Transform2T(const double* t, const triple& v)
+ {
+ double f=t[3]*v.x+t[7]*v.y+t[11]*v.z+t[15];
f=1.0/f;
-
- return triple((t[0]*v.x+t[1]*v.y+t[2]*v.z+t[3])*f,
- (t[4]*v.x+t[5]*v.y+t[6]*v.z+t[7])*f,
- (t[8]*v.x+t[9]*v.y+t[10]*v.z+t[11])*f);
+ return pair((t[0]*v.x+t[4]*v.y+t[8]*v.z+t[12])*f,
+ (t[1]*v.x+t[5]*v.y+t[9]*v.z+t[13])*f);
}
- friend triple transformNormal(const double* t, const triple& v)
+ // return z component of v*t.
+ friend double TransformZ(const triple& v, const double* t)
{
- if(t == NULL)
- return v;
-
- double T[16];
- memcpy(T,t,sizeof(double)*16);
- T[3]=T[7]=T[11]=0.0;
- run::inverse(T,4);
- run::transpose(T,4);
- triple V=T*v;
- return unit(V);
+ double f=t[3]*v.x+t[7]*v.y+t[11]*v.z+t[15];
+ f=1.0/f;
+ return (t[2]*v.x+t[6]*v.y+t[10]*v.z+t[14])*f;
}
-
+
friend void transformtriples(const double* t, size_t n, triple* d,
const triple* s)
{
@@ -287,9 +313,15 @@ public:
return s;
}
- friend ostream& operator << (ostream& out, const triple& z)
+ friend ostream& operator << (ostream& out, const triple& v)
{
- out << "(" << z.x << "," << z.y << "," << z.z << ")";
+ out << "(" << v.x << "," << v.y << "," << v.z << ")";
+ return out;
+ }
+
+ friend jsofstream& operator << (jsofstream& out, const triple& v)
+ {
+ out << "[" << v.x << "," << v.y << "," << v.z << "]";
return out;
}
@@ -339,17 +371,6 @@ inline double Straightness(const triple& z0, const triple& c0,
return std::max(abs2(c0-v-z0),abs2(z1-v-c1));
}
-// return the maximum perpendicular distance squared of points c0 and c1
-// from z0--z1.
-inline double Distance1(const triple& z0, const triple& c0,
- const triple& c1, const triple& z1)
-{
- triple Z0=c0-z0;
- triple Q=unit(z1-z0);
- triple Z1=c1-z0;
- return std::max(abs2(Z0-dot(Z0,Q)*Q),abs2(Z1-dot(Z1,Q)*Q));
-}
-
// return the perpendicular distance squared of a point z from the plane
// through u with unit normal n.
inline double Distance2(const triple& z, const triple& u, const triple& n)
diff --git a/graphics/asymptote/util.h b/graphics/asymptote/util.h
index 4414a6de1b..d07c543258 100644
--- a/graphics/asymptote/util.h
+++ b/graphics/asymptote/util.h
@@ -95,7 +95,7 @@ extern "C" double atanh(double x);
extern "C" double cbrt(double x);
extern "C" double erf(double x);
extern "C" double erfc(double x);
-extern "C" double tgamma(double x);
+extern "C" double lgamma(double x);
extern "C" double remainder(double x, double y);
extern "C" double hypot(double x, double y) throw();
extern "C" double jn(Int n, double x);
diff --git a/graphics/asymptote/webgl/WebGLfooter.html b/graphics/asymptote/webgl/WebGLfooter.html
deleted file mode 100644
index 043713cd25..0000000000
--- a/graphics/asymptote/webgl/WebGLfooter.html
+++ /dev/null
@@ -1,17 +0,0 @@
- </script>
-
-</head>
-
-
-<body onload="webGLStart();">
- <script type="text/javascript" id="eventfunc">
- // forceredraw = true;
- function processloop(deltams) {
- // enter arbitrary processing event here
- // if one wants to modify the object per tick.
- }
- </script>
- <canvas id="Asymptote" style="border: none;" width="800" height="800" />
-</body>
-
-</html>
diff --git a/graphics/asymptote/webgl/WebGLheader.html b/graphics/asymptote/webgl/WebGLheader.html
deleted file mode 100644
index 98fa24ec32..0000000000
--- a/graphics/asymptote/webgl/WebGLheader.html
+++ /dev/null
@@ -1,172 +0,0 @@
-<html>
-
-<head>
- <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
-
- <script id="shader-fs" type="x-shader/x-fragment">#version 300 es
- precision mediump float;
-
- in vec4 vColor;
- in vec3 vNormal;
- out vec4 outColor;
-
- flat in int vMaterialIndex;
-
- // can also construct an alternative shader,
- // but would require more work.
- // FIXME: An ad-hoc solution is to use uniforms...
- uniform int useColor;
-
- struct Material {
- vec4 baseColor, emissive, specular;
- float roughness, metallic, f0;
- };
-
- uniform mat4 uMMatrix; // model matrix
- uniform mat4 uPMatrix; // projection matrix
- uniform mat4 uVMatrix; // view matrix
-
- uniform Material objMaterial[100]; // assuming we are doing multiple materials,
-
- // we can upload them one at a time per call.
- // but, we can also make it an array + pass in an index,
- // say uniform Material objMaterial[$nmat];
-
- // or, even use Uniform Buffer Objects...
-
- // type, for now
- #define POINT_LIGHT 1
- #define DIRECTIONAL_LIGHT 2
-
- // for direction, parameter is direction
- // for point light, parameter is position (in homoeg coords?)
- // are these given in world coords, or view coords? - I can do both
- struct Light {
- int type;
- vec3 color;
- float brightness;
- vec4 parameter;
- };
-
- uniform int unLights; // can be replaced by a constant, or even a fixed array in the final release.
- uniform Light objLights[100]; // again, can be set at will by the asy generator.
-
- float NDF_TRG(vec3 halfv, vec3 normal, float roughness) {
- float ndoth=max(dot(normal, halfv), 0.0);
- float alpha2=roughness*roughness;
-
- float denom=pow(ndoth*ndoth*(alpha2-1.0)+1.0, 2.0);
- return alpha2/denom;
- }
-
- float GGX_Geom(vec3 v, vec3 normal, float roughness) {
- float ndotv=max(dot(v, normal), 0.0);
- float ap=pow((1.0+roughness), 2.0);
- float k=ap/8.0;
-
- return ndotv/((ndotv*(1.0-k))+k);
- }
-
- float Geom(vec3 v, vec3 l, vec3 normal, float roughness) {
- return GGX_Geom(v,normal,roughness)*GGX_Geom(l,normal,roughness);
- }
-
- float Fresnel(vec3 h, vec3 v, float f0) {
- float hdotv=max(dot(h,v), 0.0);
- return f0+(1.0-f0)*pow((1.0-hdotv),5.0);
- }
-
- // physical based shading using UE4 model.
- vec3 physBDRF(Material material, vec3 normal, vec3 lightdir, vec3 lookdir) {
- vec3 lambertian=material.baseColor.rgb;
- vec3 h=normalize(lightdir+lookdir);
- float omegain=max(dot(lookdir, normal), 0.0);
- float omegali=max(dot(lightdir, normal), 0.0);
-
- float D=NDF_TRG(h, normal, material.roughness*material.roughness);
- float G=Geom(lookdir, lightdir, normal, material.roughness*material.roughness);
- float F=Fresnel(h, lookdir, material.f0);
-
- float denom=4.0*omegain*omegali;
- if (denom == 0.0) {return vec3(0,0,0); }
-
- float rawrefl=(D*G) / denom;
-
- vec3 dielectric=mix(lambertian, rawrefl*material.specular.rgb, F);
- vec3 metal=rawrefl*material.baseColor.rgb;
-
- return mix(dielectric, metal, material.metallic);
- }
-
- void main(void)
- {
- // change later.
-
- // assuming for now that the headlamp is always on.
- // light dir=+Z, viewDir=+Z,
-
- float normalSign = gl_FrontFacing ? 1.0 : -1.0;
-
- vec3 normal=normalSign*normalize(vNormal);
- vec3 Z=vec3(0,0,1.0);
- vec3 rawCol = vec3(0.0);
-
- Material m=objMaterial[vMaterialIndex];
-
- if (useColor == 1) {
- m.baseColor = vColor;
- }
-
- for (int i=0;i<unLights;++i) {
- Light Li=objLights[i];
- float cosTheta = 0.0;
- float atteunation = 1.0;
- vec3 lightDirection = vec3(0.0);
- if (Li.type == DIRECTIONAL_LIGHT) {
- lightDirection = Li.parameter.xyz;
- cosTheta = max(dot(normal, lightDirection), 0.0);
- }
- vec3 radiance = cosTheta * Li.color * Li.brightness;
- rawCol += physBDRF(m, normal, lightDirection, Z) * radiance;
- }
- outColor=vec4(rawCol,1);
- }
- </script>
-
- <script id="shader-vs" type="x-shader/x-vertex">#version 300 es
- precision mediump float;
- in vec3 aVertexPosition;
- in vec4 aVertexColor;
- in vec3 aVertexNormal;
- in int aVertexMaterialIndex;
-
- uniform mat4 uMMatrix; // model matrix
- uniform mat4 uPMatrix; // projection matrix
- uniform mat4 uVMatrix; // view matrix
-
- out vec4 vColor;
- out vec3 vNormal;
- flat out int vMaterialIndex;
-
- mat4 invdual(mat4 invec) {
- return inverse(transpose(invec));
- }
- void main(void) {
- gl_Position=uPMatrix*uVMatrix*uMMatrix*vec4(aVertexPosition,1.0);
-
- mat4 invdualmat=invdual(uVMatrix*uMMatrix);
- vec4 rawNormal=invdualmat*vec4(aVertexNormal, 0);
-
- vNormal=normalize(rawNormal.xyz);
-
- vColor=aVertexColor;
- vMaterialIndex=aVertexMaterialIndex;
- }
-
- </script>
-
- <script type="text/javascript" src="https://vectorgraphics.github.io/asymptote/webgl/gl-matrix-min-2.3.2.js"></script>
- <script type="text/javascript" src="https://vectorgraphics.github.io/asymptote/webgl/glm-js-min-2.2.2.js"></script>
- <script type="text/javascript" src="https://vectorgraphics.github.io/asymptote/webgl/arcball-min-0.01.js"></script>
- <script type="text/javascript" src="gl.js"></script>
- <script type="text/javascript">
diff --git a/graphics/asymptote/webgl/arcball-0.01.js b/graphics/asymptote/webgl/arcball-0.01.js
deleted file mode 100644
index db6da0f81a..0000000000
--- a/graphics/asymptote/webgl/arcball-0.01.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// double, double => rotation matrix
-// require https://cdn.rawgit.com/humbletim/glm-js/31fd034b/build/glm-js.min.js
-
-
-var arcballLib = {
- arcball: function(oldmouse, newmouse) {
- let oldMouseNew = [0, 0, 0];
- let newMouseNew = [0, 0, 0];
-
- let testNorm = this.twonorm(oldmouse);
- if (testNorm > 1) {
- oldMouseNew[0] = oldmouse[0] / testNorm;
- oldMouseNew[1] = oldmouse[1] / testNorm;
- } else {
- oldMouseNew[0] = oldmouse[0];
- oldMouseNew[1] = oldmouse[1];
- }
-
- let testNorm2 = this.twonorm(newmouse);
- if (testNorm2 > 1) {
- newMouseNew[0] = newmouse[0] / testNorm2;
- newMouseNew[1] = newmouse[1] / testNorm2;
- } else {
- newMouseNew[0] = newmouse[0];
- newMouseNew[1] = newmouse[1];
- }
-
- var z1squared = 1 - (oldMouseNew[1] ** 2) - (oldMouseNew[0] ** 2);
- if (z1squared < 0 && z1squared > -0.00001) {
- z1squared = 0;
- }
-
- var z2squared = 1 - (newMouseNew[1] ** 2) - (newMouseNew[0] ** 2);
- if (z2squared < 0 && z2squared > -0.00001) {
- z2squared = 0;
- }
-
-
- oldMouseNew[2] = Math.sqrt(z1squared);
- newMouseNew[2] = Math.sqrt(z2squared);
-
- if (isNaN(oldMouseNew[2]) || isNaN(newMouseNew[2])) {
-
- alert('Error!');
- }
-
-
- let oldMouseVec = glm.vec3(...oldMouseNew);
- let newMouseVec = glm.vec3(...newMouseNew);
- let axis = glm.normalize(glm.cross(oldMouseVec, newMouseVec));
-
- // console.log(axis[0], axis[1], axis[2]);
-
- let angle = Math.acos(glm.dot(oldMouseVec, newMouseVec));
-
- return [angle, axis]
-
- },
-
- twonorm: function(v) {
- let normSq = 0
- for (let i = 0; i < v.length; i++) {
- normSq += (v[i] ** 2);
- }
- return Math.sqrt(normSq);
- }
-} \ No newline at end of file
diff --git a/graphics/asymptote/webgl/arcball-min-0.01.js b/graphics/asymptote/webgl/arcball-min-0.01.js
deleted file mode 100644
index 9efc72fa4d..0000000000
--- a/graphics/asymptote/webgl/arcball-min-0.01.js
+++ /dev/null
@@ -1 +0,0 @@
-var arcballLib={arcball:function(oldmouse,newmouse){let oldMouseNew=[0,0,0];let newMouseNew=[0,0,0];let testNorm=this.twonorm(oldmouse);if(testNorm>1){oldMouseNew[0]=oldmouse[0]/testNorm;oldMouseNew[1]=oldmouse[1]/testNorm}else{oldMouseNew[0]=oldmouse[0];oldMouseNew[1]=oldmouse[1]}let testNorm2=this.twonorm(newmouse);if(testNorm2>1){newMouseNew[0]=newmouse[0]/testNorm2;newMouseNew[1]=newmouse[1]/testNorm2}else{newMouseNew[0]=newmouse[0];newMouseNew[1]=newmouse[1]}var z1squared=1-oldMouseNew[1]**2-oldMouseNew[0]**2;if(z1squared<0&&z1squared>-1e-5){z1squared=0}var z2squared=1-newMouseNew[1]**2-newMouseNew[0]**2;if(z2squared<0&&z2squared>-1e-5){z2squared=0}oldMouseNew[2]=Math.sqrt(z1squared);newMouseNew[2]=Math.sqrt(z2squared);if(isNaN(oldMouseNew[2])||isNaN(newMouseNew[2])){alert("Error!")}let oldMouseVec=glm.vec3(...oldMouseNew);let newMouseVec=glm.vec3(...newMouseNew);let axis=glm.normalize(glm.cross(oldMouseVec,newMouseVec));let angle=Math.acos(glm.dot(oldMouseVec,newMouseVec));return[angle,axis]},twonorm:function(v){let normSq=0;for(let i=0;i<v.length;i++){normSq+=v[i]**2}return Math.sqrt(normSq)}}; \ No newline at end of file
diff --git a/graphics/asymptote/webgl/arcball.js b/graphics/asymptote/webgl/arcball.js
deleted file mode 100644
index db6da0f81a..0000000000
--- a/graphics/asymptote/webgl/arcball.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// double, double => rotation matrix
-// require https://cdn.rawgit.com/humbletim/glm-js/31fd034b/build/glm-js.min.js
-
-
-var arcballLib = {
- arcball: function(oldmouse, newmouse) {
- let oldMouseNew = [0, 0, 0];
- let newMouseNew = [0, 0, 0];
-
- let testNorm = this.twonorm(oldmouse);
- if (testNorm > 1) {
- oldMouseNew[0] = oldmouse[0] / testNorm;
- oldMouseNew[1] = oldmouse[1] / testNorm;
- } else {
- oldMouseNew[0] = oldmouse[0];
- oldMouseNew[1] = oldmouse[1];
- }
-
- let testNorm2 = this.twonorm(newmouse);
- if (testNorm2 > 1) {
- newMouseNew[0] = newmouse[0] / testNorm2;
- newMouseNew[1] = newmouse[1] / testNorm2;
- } else {
- newMouseNew[0] = newmouse[0];
- newMouseNew[1] = newmouse[1];
- }
-
- var z1squared = 1 - (oldMouseNew[1] ** 2) - (oldMouseNew[0] ** 2);
- if (z1squared < 0 && z1squared > -0.00001) {
- z1squared = 0;
- }
-
- var z2squared = 1 - (newMouseNew[1] ** 2) - (newMouseNew[0] ** 2);
- if (z2squared < 0 && z2squared > -0.00001) {
- z2squared = 0;
- }
-
-
- oldMouseNew[2] = Math.sqrt(z1squared);
- newMouseNew[2] = Math.sqrt(z2squared);
-
- if (isNaN(oldMouseNew[2]) || isNaN(newMouseNew[2])) {
-
- alert('Error!');
- }
-
-
- let oldMouseVec = glm.vec3(...oldMouseNew);
- let newMouseVec = glm.vec3(...newMouseNew);
- let axis = glm.normalize(glm.cross(oldMouseVec, newMouseVec));
-
- // console.log(axis[0], axis[1], axis[2]);
-
- let angle = Math.acos(glm.dot(oldMouseVec, newMouseVec));
-
- return [angle, axis]
-
- },
-
- twonorm: function(v) {
- let normSq = 0
- for (let i = 0; i < v.length; i++) {
- normSq += (v[i] ** 2);
- }
- return Math.sqrt(normSq);
- }
-} \ No newline at end of file
diff --git a/graphics/asymptote/webgl/data.js b/graphics/asymptote/webgl/data.js
deleted file mode 100644
index 915dc35619..0000000000
--- a/graphics/asymptote/webgl/data.js
+++ /dev/null
@@ -1,47 +0,0 @@
-var p = [
- [0, 0, 1.6],
- [1, 1.333333333333333, 0],
- [0, 0.666666666666667, 0],
- [0, 1, 0],
- [0.333333333333333, 0, 0],
- [0.333333333333333, 0.333333333333333, 0],
- [0.333333333333333, 0.666666666666667, 0],
- [0.333333333333333, 1, 0],
- [0.666666666666667, 0, 0],
- [0.666666666666667, 0.333333333333333, 0],
- [0.666666666666667, 0.666666666666667, 0],
- [0.666666666666667, 1, 0],
- [1, 0, 0],
- [1, 0.333333333333333, 0],
- [1, 0.666666666666667, 0],
- [1, 1, 0.1]
- ];
-
- var materialIndex = 0;
-
- var objMaterial = new Material(
- baseColor = [1, 1, 0, 1],
- emissive = [0, 0, 0, 1],
- specular = [1, 1, 1, 1],
- roughness = 0.15,
- metallic = 0,
- f0 = 0.04
- );
-
- // Lighting parameters
- var L = [0.447735768366173, 0.497260947684137, 0.743144825477394];
- var Ambient = [0.1, 0.1, 0.1];
- var Diffuse = [0.8, 0.8, 0.8, 1];
- var Specular = [0.7, 0.7, 0.7, 1];
- var specularfactor = 3;
-
- // Material parameters
- var emissive = [0, 0, 0, 1];
- var ambient = [0, 0, 0, 1];
- var diffuse = [1, 0, 0, 1];
- var specular = [0.75, 0.75, 0.75, 1];
- var shininess = 0.5;
-
- var cameraPos = vec3.fromValues(0, 0, 2);
- var cameraLookAt = vec3.fromValues(0, 0, 0);
- var cameraUp = vec3.fromValues(1, 0, 0);
diff --git a/graphics/asymptote/webgl/gl-0.01.js b/graphics/asymptote/webgl/gl-0.01.js
deleted file mode 100644
index 079b1bb70e..0000000000
--- a/graphics/asymptote/webgl/gl-0.01.js
+++ /dev/null
@@ -1,738 +0,0 @@
-// Contains code from http: //learningwebgl.com/blog/ ? p=28#triangle-vertex-positions
-// modified to produce a subdivision algorithm for rendering Bezier
-// patches with WebGL
-var gl;
-
-function initGL(canvas) {
- try {
- gl=canvas.getContext("experimental-webgl");
- gl.viewportWidth=canvas.width;
- gl.viewportHeight=canvas.height;
- } catch(e) {}
- if(!gl) {
- alert("Could not initialise WebGL, sorry : -(");
- }
-}
-
-function getShader(gl, id) {
- var shaderScript=document.getElementById(id);
- if(!shaderScript) {
- return null;
- }
- var str="";
- var k=shaderScript.firstChild;
- while(k) {
- if(k.nodeType == 3) {
- str += k.textContent;
- }
- k=k.nextSibling;
- }
- var shader;
- if(shaderScript.type == "x-shader/x-fragment") {
- shader=gl.createShader(gl.FRAGMENT_SHADER);
- } else if(shaderScript.type == "x-shader/x-vertex") {
- shader=gl.createShader(gl.VERTEX_SHADER);
- } else {
- return null;
- }
- gl.shaderSource(shader,str);
- gl.compileShader(shader);
- if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)) {
- alert(gl.getShaderInfoLog(shader));
- return null;
- }
- return shader;
-}
-
-var shaderProgram;
-
-function initShaders() {
- var fragmentShader=getShader(gl,"shader-fs");
- var vertexShader=getShader(gl,"shader-vs");
- shaderProgram=gl.createProgram();
- gl.attachShader(shaderProgram,vertexShader);
- gl.attachShader(shaderProgram,fragmentShader);
- gl.linkProgram(shaderProgram);
- if(!gl.getProgramParameter(shaderProgram,gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
- }
- gl.useProgram(shaderProgram);
- shaderProgram.vertexPositionAttribute=gl.getAttribLocation(shaderProgram,"aVertexPosition");
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- shaderProgram.vertexColorAttribute=gl.getAttribLocation(shaderProgram,"aVertexColor");
- gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
- shaderProgram.pMatrixUniform=gl.getUniformLocation(shaderProgram,"uPMatrix");
- shaderProgram.mvMatrixUniform=gl.getUniformLocation(shaderProgram,"uMVMatrix");
-}
-var mvMatrix=mat4.create();
-var pMatrix=mat4.create();
-
-function setMatrixUniforms() {
- gl.uniformMatrix4fv(shaderProgram.pMatrixUniform,false,pMatrix);
- gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform,false,mvMatrix);
-}
-
-var VertexBuffer;
-var ColorBuffer;
-
-var vertices=new Array();
-var colors=new Array();
-var indices=new Array();
-var nvertices=0;
-
-var mvMatrix=mat4.create();
-var translOffset=[0,0,0];
-var zoomFactor=1;
-
-var mvMatrixStack=[] ;
-var pMatrix=mat4.create();
-
-var localRotation=mat4.create();
-
-function mvPushMatrix() {
- var copy=mat4.create();
- mat4.set(mvMatrix,copy);
- mvMatrixStack.push(copy);
-}
-
-function mvPopMatrix() {
- if(mvMatrixStack.length == 0) {
- throw "Invalid popMatrix!";
- }
- mvMatrix=mvMatrixStack.pop();
-}
-
-function degToRad(degrees) {
- return degrees*Math.PI/180;
-}
-
-var redraw=true;
-var mouseDownOrTouchActive=false;
-var lastMouseX=null;
-var lastMouseY=null;
-var touchID=null;
-
-
-var center=[0,0,1];
-var centerInv=[0,0,-1];
-
-var rotationMatLocal=mat4.create();
-var rotationMatrix=mat4.create();
-mat4.identity(rotationMatrix);
-
-function handleMouseDown(event) {
- mouseDownOrTouchActive=true;
- lastMouseX=event.clientX;
- lastMouseY=event.clientY;
-}
-
-function handleTouchStart(evt) {
- evt.preventDefault();
- var touches=evt.targetTouches;
-
- if(touches.length == 1 && !mouseDownOrTouchActive) {
- touchId=touches[0].identifier;
- lastMouseX=touches[0].pageX,
- lastMouseY=touches[0].pageY;
- }
-}
-
-function handleMouseUpOrTouchEnd(event) {
- mouseDownOrTouchActive=false;
-}
-
-function processDrag(newX, newY, pan=false) {
- let lastX=(lastMouseX-400)/400;
- let lastY=(lastMouseY-400)/400;
-
- let rawX=(newX-400)/400;
- let rawY=(newY-400)/400;
-
- if(!pan) {
- let [angle,axis]=arcballLib.arcball([lastX,-lastY],[rawX,-rawY]);
- let tmpMatrix=mat4.create()
- mat4.identity(tmpMatrix)
- mat4.rotate(tmpMatrix,tmpMatrix,angle,[axis[0],axis[1],axis[2]])
- mat4.multiply(rotationMatrix,tmpMatrix,rotationMatrix);
- } else {
- translOffset[0] +=(rawX-lastX);
- translOffset[1] -=(rawY-lastY);
- }
- lastMouseX=newX;
- lastMouseY=newY;
- redraw=true;
-}
-
-function handleKey(key) {
- var keycode=key.key;
- var rotate=true;
- var axis=[0,0,1];
- switch(keycode) {
- case "w":
- axis=[-1,0,0];
- break;
- case "d":
- axis=[0,1,0];
- break;
- case "a":
- axis=[0,-1,0];
- break;
- case "s":
- axis=[1,0,0];
- break;
-
- default:
- rotate=false;
- break;
- }
-
- if(rotate) {
- mat4.rotate(rotationMatrix,rotationMatrix,0.1,axis);
- redraw=true;
- }
-
-}
-
-function handleMouseWheel(event) {
- zoomFactor -= event.deltaY/100;
-
- if(zoomFactor < 0) {
- zoomFactor=0;
- } else if(zoomFactor > 100) {
- zoomFactor=100;
- }
-
- res=zoomFactor*0.001;
- redraw=true;
-}
-
-function handleMouseMove(event) {
- if(!mouseDownOrTouchActive) {
- return;
- }
-
- var newX=event.clientX;
- var newY=event.clientY;
-
- processDrag(newX,newY,event.getModifierState("Alt"));
-}
-
-function handleTouchMove(evt) {
- evt.preventDefault();
- var touches=evt.targetTouches;
-
- if(touches.length == 1 && touchId == touches[0].identifier) {
- var newX=touches[0].pageX;
- var newY=touches[0].pageY;
- processDrag(newX,newY);
- }
-}
-
-// Prepare canvas for drawing
-function sceneSetup() {
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- mat4.perspective(pMatrix,45,gl.viewportWidth/gl.viewportHeight,0.1,100.0);
- mat4.identity(mvMatrix);
-
- mat4.translate(mvMatrix,mvMatrix,centerInv);
- mat4.multiply(mvMatrix,mvMatrix,rotationMatrix);
- mat4.scale(mvMatrix,mvMatrix,[zoomFactor,zoomFactor,zoomFactor]);
- mat4.translate(mvMatrix,mvMatrix,center);
-
- mat4.translate(mvMatrix,mvMatrix,translOffset)
-}
-
-var indexExt;
-
-// Create buffer data for the patch and its subdivisions to be pushed to the graphics card
-//Takes as an argument the array of vertices that define the patch to be drawn
-// Using the vertex position buffer of the above function,draw patch.
-function setBuffer() {
- VertexBuffer=gl.createBuffer();
- VertexBuffer.itemSize=3;
-
- ColorBuffer=gl.createBuffer();
- ColorBuffer.itemSize=4;
-
- indexBuffer=gl.createBuffer();
- indexBuffer.itemSize=1;
-}
-
-function drawBuffer() {
- gl.bindBuffer(gl.ARRAY_BUFFER,VertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
- VertexBuffer.itemSize,gl.FLOAT,false,0,0);
- VertexBuffer.numItems=nvertices;
-
- gl.bindBuffer(gl.ARRAY_BUFFER,ColorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(colors),gl.STATIC_DRAW);
- gl.vertexAttribPointer(shaderProgram.vertexColorAttribute,
- ColorBuffer.itemSize,gl.FLOAT,false,0,0);
- ColorBuffer.numItems=nvertices;
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
- indexExt ? new Uint32Array(indices) : new Uint16Array(indices),
- gl.STATIC_DRAW);
- indexBuffer.numItems=indices.length;
- gl.drawElements(gl.TRIANGLES,indexBuffer.numItems,
- indexExt ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT,0);
- vertices=[];
- colors=[];
- indices=[];
- nvertices=0;
-}
-
-var pixel=1.0; // Adaptive rendering constant.
-var FillFactor=0.1;
-var BezierFactor=0.4;
-//var res=0.0005; // Temporary
-var res=0.001; // Temporary
-var res2=res*res;
-var Epsilon=0.1*res;
-var epsilon=0;
-var Fuzz=1000*Number.EPSILON;
-var Fuzz2=Fuzz*Fuzz;
-
-function Split3(z0, c0, c1, z1) {
- this.m0=new Array(3);
- this.m2=new Array(3);
- this.m3=new Array(3);
- this.m4=new Array(3);
- this.m5=new Array(3);
- for(var i=0; i < 3; ++i) {
- this.m0[i]=0.5*(z0[i]+c0[i]);
- var m1=0.5*(c0[i]+c1[i]);
- this.m2[i]=0.5*(c1[i]+z1[i]);
- this.m3[i]=0.5*(this.m0[i]+m1);
- this.m4[i]=0.5*(m1+this.m2[i]);
- this.m5[i]=0.5*(this.m3[i]+this.m4[i]);
- }
-}
-
-function unit(v) {
- var norm=Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
- norm=(norm != 0) ? 1/norm : 1;
- return [v[0]*norm,v[1]*norm,v[2]*norm];
-}
-
-// Store the vertex v and its color vector c in the buffer.
-function vertex(v,c) {
- vertices.push(v[0]);
- vertices.push(v[1]);
- vertices.push(v[2]);
-
- colors.push(c[0]);
- colors.push(c[1]);
- colors.push(c[2]);
- colors.push(c[3]);
- return nvertices++;
-}
-
-function abs2(v) {
- return v[0]*v[0]+v[1]*v[1]+v[2]*v[2];
-}
-
-function dot(u, v) {
- return u[0]*v[0]+u[1]*v[1]+u[2]*v[2];
-}
-
-function cross(u, v) {
- return [u[1]*v[2]-u[2]*v[1],
- u[2]*v[0]-u[0]*v[2],
- u[0]*v[1]-u[1]*v[0]
- ];
-}
-
-function normal(left3, left2, left1, middle, right1, right2, right3) {
- var u0=right1[0]-middle[0];
- var v0=left1[0]-middle[0];
- var u1=right1[1]-middle[1];
- var v1=left1[1]-middle[1];
- var u2=right1[2]-middle[2];
- var v2=left1[2]-middle[2];
- var n=[
- u1*v2-u2*v1,
- u2*v0-u0*v2,
- u0*v1-u1*v0
- ];
- if(abs2(n) > epsilon)
- return unit(n);
-
- var lp=[v0,v1,v2];
- var rp=[u0,u1,u2];
- var lpp=[middle[0]+left2[0]-2*left1[0],
- middle[1]+left2[1]-2*left1[1],
- middle[2]+left2[2]-2*left1[2]
- ];
- var rpp=[middle[0]+right2[0]-2*right1[0],
- middle[1]+right2[1]-2*right1[1],
- middle[2]+right2[2]-2*right1[2]
- ];
- var a=cross(rpp,lp);
- var b=cross(rp,lpp);
- n=[a[0]+b[0],
- a[1]+b[1],
- a[2]+b[2]
- ];
- if(abs2(n) > epsilon)
- return unit(n);
-
- var lppp=[left3[0]-middle[0]+3*(left1[0]-left2[0]),
- left3[1]-middle[1]+3*(left1[1]-left2[1]),
- left3[2]-middle[2]+3*(left1[2]-left2[2])
- ];
- var rppp=[right3[0]-middle[0]+3*(right1[0]-right2[0]),
- right3[1]-middle[1]+3*(right1[1]-right2[1]),
- right3[2]-middle[2]+3*(right1[2]-right2[2])
- ];
- a=cross(rpp,lpp);
- b=cross(rp,lppp);
- var c=cross(rppp,lp);
- var d=cross(rppp,lpp);
- var e=cross(rpp,lppp);
- var f=cross(rppp,lppp);
- return unit([9*a[0]+3*(b[0]+c[0]+d[0]+e[0])+f[0],
- 9*a[1]+3*(b[1]+c[1]+d[1]+e[1])+f[1],
- 9*a[2]+3*(b[2]+c[2]+d[2]+e[2])+f[2]
- ]);
-}
-
-// return the maximum distance squared of points c0 and c1 from
-// the respective internal control points of z0--z1.
-function Straightness(z0,c0,c1,z1)
-{
- var third=1.0/3.0;
- var v=[third*(z1[0]-z0[0]),third*(z1[1]-z0[1]),third*(z1[2]-z0[2])];
- return Math.max(abs2([c0[0]-v[0]-z0[0],c0[1]-v[1]-z0[1],c0[2]-v[2]-z0[2]]),
- abs2([z1[0]-v[0]-c1[0],z1[1]-v[1]-c1[1],z1[2]-v[2]-c1[2]]));
-}
-
-// return the maximum perpendicular distance squared of points c0 and c1
-// from z0--z1.
-function Distance1(z0, c0, c1, z1) {
- var Z0=[c0[0]-z0[0],c0[1]-z0[1],c0[2]-z0[2]];
- var Q=unit([z1[0]-z0[0],z1[1]-z0[1],z1[2]-z0[2]]);
- var Z1=[c1[0]-z0[0],c1[1]-z0[1],c1[2]-z0[2]];
- var p0=dot(Z0,Q);
- var p1=dot(Z1,Q);
- return Math.max(abs2([Z0[0]-p0*Q[0],Z0[1]-p0*Q[1],Z0[2]-p0*Q[2]]),
- abs2([Z1[0]-p1*Q[0],Z1[1]-p1*Q[1],Z1[2]-p1*Q[2]]));
-}
-
-// return the perpendicular distance squared of a point z from the plane
-// through u with unit normal n.
-function Distance2(z, u, n) {
- var d=dot([z[0]-u[0],z[1]-u[1],z[2]-u[2]],n);
- return d*d;
-}
-
-function Distance(p) {
- var p0=p[0];
- var p3=p[3];
- var p12=p[12];
- var p15=p[15];
-
- // Check the flatness of the quad.
- var d=Distance2(p15,p0,normal(p3,p[2],p[1],p0,p[4],p[8],p12));
-
- // Determine how straight the edges are.
- d=Math.max(d,Straightness(p0,p[1],p[2],p3));
- d=Math.max(d,Straightness(p0,p[4],p[8],p12));
- d=Math.max(d,Straightness(p3,p[7],p[11],p15));
- d=Math.max(d,Straightness(p12,p[13],p[14],p15));
-
- // Determine how straight the interior control curves are.
- d=Math.max(d,Straightness(p[4],p[5],p[6],p[7]));
- d=Math.max(d,Straightness(p[8],p[9],p[10],p[11]));
- d=Math.max(d,Straightness(p[1],p[5],p[9],p[13]));
- return Math.max(d,Straightness(p[2],p[6],p[10],p[14]));
-}
-
-var k=1;
-// Return color associated with unit normal vector n.
-function color(n) {
- var Ldotn=L[0]*n[0]+L[1]*n[1]+L[2]*n[2];
- if(Ldotn < 0) Ldotn=0;
- var p=[emissive[0]+ambient[0]*Ambient[0]+Ldotn*diffuse[0]*Diffuse[0],
- emissive[1]+ambient[1]*Ambient[1]+Ldotn*diffuse[1]*Diffuse[1],
- emissive[2]+ambient[2]*Ambient[2]+Ldotn*diffuse[2]*Diffuse[2]
- ];
- var s=shininess*128;
- var H=unit([L[0],L[1],L[2]+1]);
- var f=Math.pow(H[0]*n[0]+H[1]*n[1]+H[2]*n[2],s);
-
- if(Ldotn > 0) // Phong-Blinn model of specular reflection
- p=[p[0]+f*specular[0]*Specular[0],p[1]+f*specular[1]*Specular[1],
- p[2]+f*specular[2]*Specular[2]
- ];
-
- return [p[0],p[1],p[2],1];
-}
-
-function render(p, I0, I1, I2, I3, P0, P1, P2, P3, flat0, flat1, flat2, flat3,
- C0, C1, C2, C3) {
- if(Distance(p) < res2) { // Patch is flat
- indices.push(I0);
- indices.push(I1);
- indices.push(I2);
-
- indices.push(I0);
- indices.push(I2);
- indices.push(I3);
- return;
- }
-
- var p0=p[0];
- var p3=p[3];
- var p12=p[12];
- var p15=p[15];
-
- var c0=new Split3(p0,p[1],p[2],p3);
- var c1=new Split3(p[4],p[5],p[6],p[7]);
- var c2=new Split3(p[8],p[9],p[10],p[11]);
- var c3=new Split3(p12,p[13],p[14],p15);
- var c4=new Split3(p0,p[4],p[8],p12);
- var c5=new Split3(c0.m0,c1.m0,c2.m0,c3.m0);
- var c6=new Split3(c0.m3,c1.m3,c2.m3,c3.m3);
- var c7=new Split3(c0.m5,c1.m5,c2.m5,c3.m5);
- var c8=new Split3(c0.m4,c1.m4,c2.m4,c3.m4);
- var c9=new Split3(c0.m2,c1.m2,c2.m2,c3.m2);
- var c10=new Split3(p3,p[7],p[11],p15);
-
- var s0=[p0,c0.m0,c0.m3,c0.m5,c4.m0,c5.m0,c6.m0,c7.m0,
- c4.m3,c5.m3,c6.m3,c7.m3,c4.m5,c5.m5,c6.m5,c7.m5
- ];
- var s1=[c4.m5,c5.m5,c6.m5,c7.m5,c4.m4,c5.m4,c6.m4,c7.m4,
- c4.m2,c5.m2,c6.m2,c7.m2,p12,c3.m0,c3.m3,c3.m5
- ];
- var s2=[c7.m5,c8.m5,c9.m5,c10.m5,c7.m4,c8.m4,c9.m4,c10.m4,
- c7.m2,c8.m2,c9.m2,c10.m2,c3.m5,c3.m4,c3.m2,p15
- ];
- var s3=[c0.m5,c0.m4,c0.m2,p3,c7.m0,c8.m0,c9.m0,c10.m0,
- c7.m3,c8.m3,c9.m3,c10.m3,c7.m5,c8.m5,c9.m5,c10.m5
- ];
-
- var m4=s0[15];
-
- var n0=normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]);
- if(n0 == 0.0) {
- n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
- if(n0 == 0.0) n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]);
- }
-
- var n1=normal(s1[12],s1[13],s1[14],s1[15],s1[11],s1[7],s1[3]);
- if(n1 == 0.0) {
- n1=normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]);
- if(n1 == 0.0) n1=normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]);
- }
-
- var n2=normal(s2[15],s2[11],s2[7],s2[3],s2[2],s2[1],s2[0]);
- if(n2 == 0.0) {
- n2=normal(s2[15],s2[11],s2[7],s2[3],s2[4],s2[8],s2[12]);
- if(n2 == 0.0) n2=normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]);
- }
-
- var n3=normal(s3[3],s3[2],s3[1],s3[0],s3[4],s3[8],s3[12]);
- if(n3 == 0.0) {
- n3=normal(s3[3],s3[2],s3[1],s3[0],s3[13],s3[14],s3[15]);
- if(n3 == 0.0) n3=normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]);
- }
-
- var n4=normal(s2[3],s2[2],s2[1],m4,s2[4],s2[8],s2[12]);
-
- var m0,m1,m2,m3;
-
- // A kludge to remove subdivision cracks, only applied the first time
- // an edge is found to be flat before the rest of the subpatch is.
- if(flat0)
- m0=[0.5*(P0[0]+P1[0]),0.5*(P0[1]+P1[1]),0.5*(P0[2]+P1[2])];
- else {
- if((flat0=Distance1(p0,p[4],p[8],p12) < res2)) {
- var u=s0[12];
- var v=s2[3];
- var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]);
- m0=[0.5*(P0[0]+P1[0])+Epsilon*e[0],0.5*(P0[1]+P1[1])+Epsilon*e[1],
- 0.5*(P0[2]+P1[2])+Epsilon*e[2]
- ];
- } else
- m0=s0[12];
- }
-
- if(flat1)
- m1=[0.5*(P1[0]+P2[0]),0.5*(P1[1]+P2[1]),0.5*(P1[2]+P2[2])];
- else {
- if((flat1=Distance1(p12,p[13],p[14],p15) < res2)) {
- var u=s1[15];
- var v=s3[0];
- var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]);
- m1=[0.5*(P1[0]+P2[0])+Epsilon*e[0],0.5*(P1[1]+P2[1])+Epsilon*e[1],
- 0.5*(P1[2]+P2[2])+Epsilon*e[2]
- ];
- } else
- m1=s1[15];
- }
-
- if(flat2)
- m2=[0.5*(P2[0]+P3[0]),0.5*(P2[1]+P3[1]),0.5*(P2[2]+P3[2])];
- else {
- if((flat2=Distance1(p15,p[11],p[7],p3) < res2)) {
- var u=s2[3];
- var v=s0[12];
- var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]);
- m2=[0.5*(P2[0]+P3[0])+Epsilon*e[0],0.5*(P2[1]+P3[1])+Epsilon*e[1],
- 0.5*(P2[2]+P3[2])+Epsilon*e[2]
- ];
- } else
- m2=s2[3];
- }
-
- if(flat3)
- m3=[0.5*(P3[0]+P0[0]),0.5*(P3[1]+P0[1]),0.5*(P3[2]+P0[2])];
- else {
- if((flat3=Distance1(p3,p[2],p[1],p0) < res2)) {
- var u=s3[0];
- var v=s1[15];
- var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]);
- m3=[0.5*(P3[0]+P0[0])+Epsilon*e[0],
- 0.5*(P3[1]+P0[1])+Epsilon*e[1],
- 0.5*(P3[2]+P0[2])+Epsilon*e[2]
- ];
- } else
- m3=s3[0];
- }
-
- // document.write(n0);
- // document.write(" < br > ");
-
- {
- /*
- var c0=new Array(4);
- var c1=new Array(4);
- var c2=new Array(4);
- var c3=new Array(4);
- var c4=new Array(4);
-
- for(var i=0; i < 4; ++i) {
- c0[i]=0.5*(C0[i]+C1[i]);
- c1[i]=0.5*(C1[i]+C2[i]);
- c2[i]=0.5*(C2[i]+C3[i]);
- c3[i]=0.5*(C3[i]+C0[i]);
- c4[i]=0.5*(c0[i]+c2[i]);
- }
- */
-
- var c0=color(n0);
- var c1=color(n1);
- var c2=color(n2);
- var c3=color(n3);
- var c4=color(n4);
-
-
- var i0=vertex(m0,c0);
- var i1=vertex(m1,c1);
- var i2=vertex(m2,c2);
- var i3=vertex(m3,c3);
- var i4=vertex(m4,c4);
-
- render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3,
- C0,c0,c4,c3);
- render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false,
- c0,C1,c1,c4);
- render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false,
- c4,c1,C2,c2);
- render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3,
- c3,c4,c2,C3);
- }
-}
-
-
-function draw(p) {
- var p0=p[0];
- var p3=p[3];
- var p12=p[12];
- var p15=p[15];
-
- epsilon=0;
- for(var i=1; i < 16; ++i)
- epsilon=Math.max(epsilon,
- abs2([p[i][0]-p0[0],p[i][1]-p0[1],p[i][2]-p0[2]]));
- epsilon *= Fuzz2;
-
- var n0=normal(p3,p[2],p[1],p0,p[4],p[8],p12);
- var n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15);
- var n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3);
- var n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0);
-
- var c0=color(n0);
- var c1=color(n1);
- var c2=color(n2);
- var c3=color(n3);
-
- var i0=vertex(p0,c0);
- var i1=vertex(p12,c1);
- var i2=vertex(p15,c2);
- var i3=vertex(p3,c3);
-
- render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false,
- c0,c1,c2,c3);
-
- drawBuffer();
-}
-
-var p=[];
-
-function tick() {
- requestAnimationFrame(tick);
- if(redraw) {
- sceneSetup();
- mat4.translate(mvMatrix,mvMatrix,[-0.5,-0.5,-1.5]);
- setMatrixUniforms();
- for(var i=0; i < p.length; ++i)
- draw(p[i]);
- redraw=false;
- }
-}
-
-function webGLStart() {
- var canvas=document.getElementById("Asymptote");
- initGL(canvas);
- initShaders();
- gl.clearColor(0.0,0.0,0.0,1.0);
- gl.enable(gl.DEPTH_TEST);
-
- indexExt=gl.getExtension("OES_element_index_uint");
-
- gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight);
- setBuffer();
-
- canvas.onmousedown=handleMouseDown;
- document.onmouseup=handleMouseUpOrTouchEnd;
- document.onmousemove=handleMouseMove;
- canvas.onkeydown=handleKey;
- document.onwheel=handleMouseWheel;
-
- canvas.addEventListener("touchstart",handleTouchStart,false);
- canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,false);
- canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,false);
- canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,false);
- canvas.addEventListener("touchmove",handleTouchMove,false);
-
- tick();
-}
-
-
-// Lighting parameters
-var L = [0.447735768366173, 0.497260947684137, 0.743144825477394];
-var Ambient = [0.1, 0.1, 0.1];
-var Diffuse = [0.8, 0.8, 0.8, 1];
-var Specular = [0.7, 0.7, 0.7, 1];
-var specularfactor = 3;
-
-// Material parameters
-var emissive = [0, 0, 0, 1];
-var ambient = [1, 1, 1, 1];
-var diffuse = [0, 1, 0, 1];
-var specular = [0.75, 0.75, 0.75, 1];
-var shininess = 0.5;
diff --git a/graphics/asymptote/webgl/gl-matrix-min-2.3.2.js b/graphics/asymptote/webgl/gl-matrix-min-2.3.2.js
deleted file mode 100644
index 84476b6061..0000000000
--- a/graphics/asymptote/webgl/gl-matrix-min-2.3.2.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @fileoverview gl-matrix - High performance matrix and vector operations
- * @author Brandon Jones
- * @author Colin MacKenzie IV
- * @version 2.3.2
- */
-
-/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE. */
-
-!function(t,a){if("object"==typeof exports&&"object"==typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var n=a();for(var r in n)("object"==typeof exports?exports:t)[r]=n[r]}}(this,function(){return function(t){function a(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,a),o.loaded=!0,o.exports}var n={};return a.m=t,a.c=n,a.p="",a(0)}([function(t,a,n){a.glMatrix=n(1),a.mat2=n(2),a.mat2d=n(3),a.mat3=n(4),a.mat4=n(5),a.quat=n(6),a.vec2=n(9),a.vec3=n(7),a.vec4=n(8)},function(t,a){var n={};n.EPSILON=1e-6,n.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,n.RANDOM=Math.random,n.ENABLE_SIMD=!1,n.SIMD_AVAILABLE=n.ARRAY_TYPE===Float32Array&&"SIMD"in this,n.USE_SIMD=n.ENABLE_SIMD&&n.SIMD_AVAILABLE,n.setMatrixArrayType=function(t){n.ARRAY_TYPE=t};var r=Math.PI/180;n.toRadian=function(t){return t*r},n.equals=function(t,a){return Math.abs(t-a)<=n.EPSILON*Math.max(1,Math.abs(t),Math.abs(a))},t.exports=n},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},o.clone=function(t){var a=new r.ARRAY_TYPE(4);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},o.fromValues=function(t,a,n,o){var u=new r.ARRAY_TYPE(4);return u[0]=t,u[1]=a,u[2]=n,u[3]=o,u},o.set=function(t,a,n,r,o){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t},o.transpose=function(t,a){if(t===a){var n=a[1];t[1]=a[2],t[2]=n}else t[0]=a[0],t[1]=a[2],t[2]=a[1],t[3]=a[3];return t},o.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n*u-o*r;return l?(l=1/l,t[0]=u*l,t[1]=-r*l,t[2]=-o*l,t[3]=n*l,t):null},o.adjoint=function(t,a){var n=a[0];return t[0]=a[3],t[1]=-a[1],t[2]=-a[2],t[3]=n,t},o.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},o.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=n[0],M=n[1],s=n[2],i=n[3];return t[0]=r*e+u*M,t[1]=o*e+l*M,t[2]=r*s+u*i,t[3]=o*s+l*i,t},o.mul=o.multiply,o.rotate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M+u*e,t[1]=o*M+l*e,t[2]=r*-e+u*M,t[3]=o*-e+l*M,t},o.scale=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=n[0],M=n[1];return t[0]=r*e,t[1]=o*e,t[2]=u*M,t[3]=l*M,t},o.fromRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=-n,t[3]=r,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=a[1],t},o.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},o.LDU=function(t,a,n,r){return t[2]=r[2]/r[0],n[0]=r[0],n[1]=r[1],n[3]=r[3]-t[2]*n[1],[t,a,n]},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t},o.sub=o.subtract,o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=a[0],M=a[1],s=a[2],i=a[3];return Math.abs(n-e)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(e))&&Math.abs(o-M)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(M))&&Math.abs(u-s)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(s))&&Math.abs(l-i)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(i))},o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(6);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a[4]=t[4],a[5]=t[5],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},o.fromValues=function(t,a,n,o,u,l){var e=new r.ARRAY_TYPE(6);return e[0]=t,e[1]=a,e[2]=n,e[3]=o,e[4]=u,e[5]=l,e},o.set=function(t,a,n,r,o,u,l){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t[4]=u,t[5]=l,t},o.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=n*u-r*o;return M?(M=1/M,t[0]=u*M,t[1]=-r*M,t[2]=-o*M,t[3]=n*M,t[4]=(o*e-u*l)*M,t[5]=(r*l-n*e)*M,t):null},o.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},o.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=n[0],i=n[1],c=n[2],h=n[3],S=n[4],I=n[5];return t[0]=r*s+u*i,t[1]=o*s+l*i,t[2]=r*c+u*h,t[3]=o*c+l*h,t[4]=r*S+u*I+e,t[5]=o*S+l*I+M,t},o.mul=o.multiply,o.rotate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=Math.sin(n),i=Math.cos(n);return t[0]=r*i+u*s,t[1]=o*i+l*s,t[2]=r*-s+u*i,t[3]=o*-s+l*i,t[4]=e,t[5]=M,t},o.scale=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=n[0],i=n[1];return t[0]=r*s,t[1]=o*s,t[2]=u*i,t[3]=l*i,t[4]=e,t[5]=M,t},o.translate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=n[0],i=n[1];return t[0]=r,t[1]=o,t[2]=u,t[3]=l,t[4]=r*s+u*i+e,t[5]=o*s+l*i+M,t},o.fromRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=-n,t[3]=r,t[4]=0,t[5]=0,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=a[1],t[4]=0,t[5]=0,t},o.fromTranslation=function(t,a){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=a[0],t[5]=a[1],t},o.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t[4]=a[4]+n[4],t[5]=a[5]+n[5],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t[4]=a[4]-n[4],t[5]=a[5]-n[5],t},o.sub=o.subtract,o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t[4]=a[4]*n,t[5]=a[5]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t[4]=a[4]+n[4]*r,t[5]=a[5]+n[5]*r,t},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]&&t[4]===a[4]&&t[5]===a[5]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=t[4],M=t[5],s=a[0],i=a[1],c=a[2],h=a[3],S=a[4],I=a[5];return Math.abs(n-s)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(s))&&Math.abs(o-i)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(i))&&Math.abs(u-c)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(c))&&Math.abs(l-h)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(h))&&Math.abs(e-S)<=r.EPSILON*Math.max(1,Math.abs(e),Math.abs(S))&&Math.abs(M-I)<=r.EPSILON*Math.max(1,Math.abs(M),Math.abs(I))},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.fromMat4=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[4],t[4]=a[5],t[5]=a[6],t[6]=a[8],t[7]=a[9],t[8]=a[10],t},o.clone=function(t){var a=new r.ARRAY_TYPE(9);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a[4]=t[4],a[5]=t[5],a[6]=t[6],a[7]=t[7],a[8]=t[8],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t},o.fromValues=function(t,a,n,o,u,l,e,M,s){var i=new r.ARRAY_TYPE(9);return i[0]=t,i[1]=a,i[2]=n,i[3]=o,i[4]=u,i[5]=l,i[6]=e,i[7]=M,i[8]=s,i},o.set=function(t,a,n,r,o,u,l,e,M,s){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t[4]=u,t[5]=l,t[6]=e,t[7]=M,t[8]=s,t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.transpose=function(t,a){if(t===a){var n=a[1],r=a[2],o=a[5];t[1]=a[3],t[2]=a[6],t[3]=n,t[5]=a[7],t[6]=r,t[7]=o}else t[0]=a[0],t[1]=a[3],t[2]=a[6],t[3]=a[1],t[4]=a[4],t[5]=a[7],t[6]=a[2],t[7]=a[5],t[8]=a[8];return t},o.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=i*l-e*s,h=-i*u+e*M,S=s*u-l*M,I=n*c+r*h+o*S;return I?(I=1/I,t[0]=c*I,t[1]=(-i*r+o*s)*I,t[2]=(e*r-o*l)*I,t[3]=h*I,t[4]=(i*n-o*M)*I,t[5]=(-e*n+o*u)*I,t[6]=S*I,t[7]=(-s*n+r*M)*I,t[8]=(l*n-r*u)*I,t):null},o.adjoint=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8];return t[0]=l*i-e*s,t[1]=o*s-r*i,t[2]=r*e-o*l,t[3]=e*M-u*i,t[4]=n*i-o*M,t[5]=o*u-n*e,t[6]=u*s-l*M,t[7]=r*M-n*s,t[8]=n*l-r*u,t},o.determinant=function(t){var a=t[0],n=t[1],r=t[2],o=t[3],u=t[4],l=t[5],e=t[6],M=t[7],s=t[8];return a*(s*u-l*M)+n*(-s*o+l*e)+r*(M*o-u*e)},o.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=n[0],S=n[1],I=n[2],f=n[3],x=n[4],D=n[5],F=n[6],m=n[7],d=n[8];return t[0]=h*r+S*l+I*s,t[1]=h*o+S*e+I*i,t[2]=h*u+S*M+I*c,t[3]=f*r+x*l+D*s,t[4]=f*o+x*e+D*i,t[5]=f*u+x*M+D*c,t[6]=F*r+m*l+d*s,t[7]=F*o+m*e+d*i,t[8]=F*u+m*M+d*c,t},o.mul=o.multiply,o.translate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=n[0],S=n[1];return t[0]=r,t[1]=o,t[2]=u,t[3]=l,t[4]=e,t[5]=M,t[6]=h*r+S*l+s,t[7]=h*o+S*e+i,t[8]=h*u+S*M+c,t},o.rotate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=Math.sin(n),S=Math.cos(n);return t[0]=S*r+h*l,t[1]=S*o+h*e,t[2]=S*u+h*M,t[3]=S*l-h*r,t[4]=S*e-h*o,t[5]=S*M-h*u,t[6]=s,t[7]=i,t[8]=c,t},o.scale=function(t,a,n){var r=n[0],o=n[1];return t[0]=r*a[0],t[1]=r*a[1],t[2]=r*a[2],t[3]=o*a[3],t[4]=o*a[4],t[5]=o*a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t},o.fromTranslation=function(t,a){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=a[0],t[7]=a[1],t[8]=1,t},o.fromRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=0,t[3]=-n,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=0,t[4]=a[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.fromMat2d=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=0,t[3]=a[2],t[4]=a[3],t[5]=0,t[6]=a[4],t[7]=a[5],t[8]=1,t},o.fromQuat=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n+n,e=r+r,M=o+o,s=n*l,i=r*l,c=r*e,h=o*l,S=o*e,I=o*M,f=u*l,x=u*e,D=u*M;return t[0]=1-c-I,t[3]=i-D,t[6]=h+x,t[1]=i+D,t[4]=1-s-I,t[7]=S-f,t[2]=h-x,t[5]=S+f,t[8]=1-s-c,t},o.normalFromMat4=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=a[9],h=a[10],S=a[11],I=a[12],f=a[13],x=a[14],D=a[15],F=n*e-r*l,m=n*M-o*l,d=n*s-u*l,b=r*M-o*e,v=r*s-u*e,z=o*s-u*M,p=i*f-c*I,w=i*x-h*I,E=i*D-S*I,A=c*x-h*f,P=c*D-S*f,L=h*D-S*x,q=F*L-m*P+d*A+b*E-v*w+z*p;return q?(q=1/q,t[0]=(e*L-M*P+s*A)*q,t[1]=(M*E-l*L-s*w)*q,t[2]=(l*P-e*E+s*p)*q,t[3]=(o*P-r*L-u*A)*q,t[4]=(n*L-o*E+u*w)*q,t[5]=(r*E-n*P-u*p)*q,t[6]=(f*z-x*v+D*b)*q,t[7]=(x*d-I*z-D*m)*q,t[8]=(I*v-f*d+D*F)*q,t):null},o.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t[4]=a[4]+n[4],t[5]=a[5]+n[5],t[6]=a[6]+n[6],t[7]=a[7]+n[7],t[8]=a[8]+n[8],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t[4]=a[4]-n[4],t[5]=a[5]-n[5],t[6]=a[6]-n[6],t[7]=a[7]-n[7],t[8]=a[8]-n[8],t},o.sub=o.subtract,o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t[4]=a[4]*n,t[5]=a[5]*n,t[6]=a[6]*n,t[7]=a[7]*n,t[8]=a[8]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t[4]=a[4]+n[4]*r,t[5]=a[5]+n[5]*r,t[6]=a[6]+n[6]*r,t[7]=a[7]+n[7]*r,t[8]=a[8]+n[8]*r,t},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]&&t[4]===a[4]&&t[5]===a[5]&&t[6]===a[6]&&t[7]===a[7]&&t[8]===a[8]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=t[4],M=t[5],s=t[6],i=t[7],c=t[8],h=a[0],S=a[1],I=a[2],f=a[3],x=a[4],D=a[5],F=t[6],m=a[7],d=a[8];return Math.abs(n-h)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(h))&&Math.abs(o-S)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(S))&&Math.abs(u-I)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(I))&&Math.abs(l-f)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(f))&&Math.abs(e-x)<=r.EPSILON*Math.max(1,Math.abs(e),Math.abs(x))&&Math.abs(M-D)<=r.EPSILON*Math.max(1,Math.abs(M),Math.abs(D))&&Math.abs(s-F)<=r.EPSILON*Math.max(1,Math.abs(s),Math.abs(F))&&Math.abs(i-m)<=r.EPSILON*Math.max(1,Math.abs(i),Math.abs(m))&&Math.abs(c-d)<=r.EPSILON*Math.max(1,Math.abs(c),Math.abs(d))},t.exports=o},function(t,a,n){var r=n(1),o={scalar:{},SIMD:{}};o.create=function(){var t=new r.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.clone=function(t){var a=new r.ARRAY_TYPE(16);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a[4]=t[4],a[5]=t[5],a[6]=t[6],a[7]=t[7],a[8]=t[8],a[9]=t[9],a[10]=t[10],a[11]=t[11],a[12]=t[12],a[13]=t[13],a[14]=t[14],a[15]=t[15],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15],t},o.fromValues=function(t,a,n,o,u,l,e,M,s,i,c,h,S,I,f,x){var D=new r.ARRAY_TYPE(16);return D[0]=t,D[1]=a,D[2]=n,D[3]=o,D[4]=u,D[5]=l,D[6]=e,D[7]=M,D[8]=s,D[9]=i,D[10]=c,D[11]=h,D[12]=S,D[13]=I,D[14]=f,D[15]=x,D},o.set=function(t,a,n,r,o,u,l,e,M,s,i,c,h,S,I,f,x){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t[4]=u,t[5]=l,t[6]=e,t[7]=M,t[8]=s,t[9]=i,t[10]=c,t[11]=h,t[12]=S,t[13]=I,t[14]=f,t[15]=x,t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.scalar.transpose=function(t,a){if(t===a){var n=a[1],r=a[2],o=a[3],u=a[6],l=a[7],e=a[11];t[1]=a[4],t[2]=a[8],t[3]=a[12],t[4]=n,t[6]=a[9],t[7]=a[13],t[8]=r,t[9]=u,t[11]=a[14],t[12]=o,t[13]=l,t[14]=e}else t[0]=a[0],t[1]=a[4],t[2]=a[8],t[3]=a[12],t[4]=a[1],t[5]=a[5],t[6]=a[9],t[7]=a[13],t[8]=a[2],t[9]=a[6],t[10]=a[10],t[11]=a[14],t[12]=a[3],t[13]=a[7],t[14]=a[11],t[15]=a[15];return t},o.SIMD.transpose=function(t,a){var n,r,o,u,l,e,M,s,i,c;return n=SIMD.Float32x4.load(a,0),r=SIMD.Float32x4.load(a,4),o=SIMD.Float32x4.load(a,8),u=SIMD.Float32x4.load(a,12),l=SIMD.Float32x4.shuffle(n,r,0,1,4,5),e=SIMD.Float32x4.shuffle(o,u,0,1,4,5),M=SIMD.Float32x4.shuffle(l,e,0,2,4,6),s=SIMD.Float32x4.shuffle(l,e,1,3,5,7),SIMD.Float32x4.store(t,0,M),SIMD.Float32x4.store(t,4,s),l=SIMD.Float32x4.shuffle(n,r,2,3,6,7),e=SIMD.Float32x4.shuffle(o,u,2,3,6,7),i=SIMD.Float32x4.shuffle(l,e,0,2,4,6),c=SIMD.Float32x4.shuffle(l,e,1,3,5,7),SIMD.Float32x4.store(t,8,i),SIMD.Float32x4.store(t,12,c),t},o.transpose=r.USE_SIMD?o.SIMD.transpose:o.scalar.transpose,o.scalar.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=a[9],h=a[10],S=a[11],I=a[12],f=a[13],x=a[14],D=a[15],F=n*e-r*l,m=n*M-o*l,d=n*s-u*l,b=r*M-o*e,v=r*s-u*e,z=o*s-u*M,p=i*f-c*I,w=i*x-h*I,E=i*D-S*I,A=c*x-h*f,P=c*D-S*f,L=h*D-S*x,q=F*L-m*P+d*A+b*E-v*w+z*p;return q?(q=1/q,t[0]=(e*L-M*P+s*A)*q,t[1]=(o*P-r*L-u*A)*q,t[2]=(f*z-x*v+D*b)*q,t[3]=(h*v-c*z-S*b)*q,t[4]=(M*E-l*L-s*w)*q,t[5]=(n*L-o*E+u*w)*q,t[6]=(x*d-I*z-D*m)*q,t[7]=(i*z-h*d+S*m)*q,t[8]=(l*P-e*E+s*p)*q,t[9]=(r*E-n*P-u*p)*q,t[10]=(I*v-f*d+D*F)*q,t[11]=(c*d-i*v-S*F)*q,t[12]=(e*w-l*A-M*p)*q,t[13]=(n*A-r*w+o*p)*q,t[14]=(f*m-I*b-x*F)*q,t[15]=(i*b-c*m+h*F)*q,t):null},o.SIMD.invert=function(t,a){var n,r,o,u,l,e,M,s,i,c,h=SIMD.Float32x4.load(a,0),S=SIMD.Float32x4.load(a,4),I=SIMD.Float32x4.load(a,8),f=SIMD.Float32x4.load(a,12);return l=SIMD.Float32x4.shuffle(h,S,0,1,4,5),r=SIMD.Float32x4.shuffle(I,f,0,1,4,5),n=SIMD.Float32x4.shuffle(l,r,0,2,4,6),r=SIMD.Float32x4.shuffle(r,l,1,3,5,7),l=SIMD.Float32x4.shuffle(h,S,2,3,6,7),u=SIMD.Float32x4.shuffle(I,f,2,3,6,7),o=SIMD.Float32x4.shuffle(l,u,0,2,4,6),u=SIMD.Float32x4.shuffle(u,l,1,3,5,7),l=SIMD.Float32x4.mul(o,u),l=SIMD.Float32x4.swizzle(l,1,0,3,2),e=SIMD.Float32x4.mul(r,l),M=SIMD.Float32x4.mul(n,l),l=SIMD.Float32x4.swizzle(l,2,3,0,1),e=SIMD.Float32x4.sub(SIMD.Float32x4.mul(r,l),e),M=SIMD.Float32x4.sub(SIMD.Float32x4.mul(n,l),M),M=SIMD.Float32x4.swizzle(M,2,3,0,1),l=SIMD.Float32x4.mul(r,o),l=SIMD.Float32x4.swizzle(l,1,0,3,2),e=SIMD.Float32x4.add(SIMD.Float32x4.mul(u,l),e),i=SIMD.Float32x4.mul(n,l),l=SIMD.Float32x4.swizzle(l,2,3,0,1),e=SIMD.Float32x4.sub(e,SIMD.Float32x4.mul(u,l)),i=SIMD.Float32x4.sub(SIMD.Float32x4.mul(n,l),i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),l=SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(r,2,3,0,1),u),l=SIMD.Float32x4.swizzle(l,1,0,3,2),o=SIMD.Float32x4.swizzle(o,2,3,0,1),e=SIMD.Float32x4.add(SIMD.Float32x4.mul(o,l),e),s=SIMD.Float32x4.mul(n,l),l=SIMD.Float32x4.swizzle(l,2,3,0,1),e=SIMD.Float32x4.sub(e,SIMD.Float32x4.mul(o,l)),s=SIMD.Float32x4.sub(SIMD.Float32x4.mul(n,l),s),s=SIMD.Float32x4.swizzle(s,2,3,0,1),l=SIMD.Float32x4.mul(n,r),l=SIMD.Float32x4.swizzle(l,1,0,3,2),s=SIMD.Float32x4.add(SIMD.Float32x4.mul(u,l),s),i=SIMD.Float32x4.sub(SIMD.Float32x4.mul(o,l),i),l=SIMD.Float32x4.swizzle(l,2,3,0,1),s=SIMD.Float32x4.sub(SIMD.Float32x4.mul(u,l),s),i=SIMD.Float32x4.sub(i,SIMD.Float32x4.mul(o,l)),l=SIMD.Float32x4.mul(n,u),l=SIMD.Float32x4.swizzle(l,1,0,3,2),M=SIMD.Float32x4.sub(M,SIMD.Float32x4.mul(o,l)),s=SIMD.Float32x4.add(SIMD.Float32x4.mul(r,l),s),l=SIMD.Float32x4.swizzle(l,2,3,0,1),M=SIMD.Float32x4.add(SIMD.Float32x4.mul(o,l),M),s=SIMD.Float32x4.sub(s,SIMD.Float32x4.mul(r,l)),l=SIMD.Float32x4.mul(n,o),l=SIMD.Float32x4.swizzle(l,1,0,3,2),M=SIMD.Float32x4.add(SIMD.Float32x4.mul(u,l),M),i=SIMD.Float32x4.sub(i,SIMD.Float32x4.mul(r,l)),l=SIMD.Float32x4.swizzle(l,2,3,0,1),M=SIMD.Float32x4.sub(M,SIMD.Float32x4.mul(u,l)),i=SIMD.Float32x4.add(SIMD.Float32x4.mul(r,l),i),c=SIMD.Float32x4.mul(n,e),c=SIMD.Float32x4.add(SIMD.Float32x4.swizzle(c,2,3,0,1),c),c=SIMD.Float32x4.add(SIMD.Float32x4.swizzle(c,1,0,3,2),c),l=SIMD.Float32x4.reciprocalApproximation(c),c=SIMD.Float32x4.sub(SIMD.Float32x4.add(l,l),SIMD.Float32x4.mul(c,SIMD.Float32x4.mul(l,l))),(c=SIMD.Float32x4.swizzle(c,0,0,0,0))?(SIMD.Float32x4.store(t,0,SIMD.Float32x4.mul(c,e)),SIMD.Float32x4.store(t,4,SIMD.Float32x4.mul(c,M)),SIMD.Float32x4.store(t,8,SIMD.Float32x4.mul(c,s)),SIMD.Float32x4.store(t,12,SIMD.Float32x4.mul(c,i)),t):null},o.invert=r.USE_SIMD?o.SIMD.invert:o.scalar.invert,o.scalar.adjoint=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=a[9],h=a[10],S=a[11],I=a[12],f=a[13],x=a[14],D=a[15];return t[0]=e*(h*D-S*x)-c*(M*D-s*x)+f*(M*S-s*h),t[1]=-(r*(h*D-S*x)-c*(o*D-u*x)+f*(o*S-u*h)),t[2]=r*(M*D-s*x)-e*(o*D-u*x)+f*(o*s-u*M),t[3]=-(r*(M*S-s*h)-e*(o*S-u*h)+c*(o*s-u*M)),t[4]=-(l*(h*D-S*x)-i*(M*D-s*x)+I*(M*S-s*h)),t[5]=n*(h*D-S*x)-i*(o*D-u*x)+I*(o*S-u*h),t[6]=-(n*(M*D-s*x)-l*(o*D-u*x)+I*(o*s-u*M)),t[7]=n*(M*S-s*h)-l*(o*S-u*h)+i*(o*s-u*M),t[8]=l*(c*D-S*f)-i*(e*D-s*f)+I*(e*S-s*c),t[9]=-(n*(c*D-S*f)-i*(r*D-u*f)+I*(r*S-u*c)),t[10]=n*(e*D-s*f)-l*(r*D-u*f)+I*(r*s-u*e),t[11]=-(n*(e*S-s*c)-l*(r*S-u*c)+i*(r*s-u*e)),t[12]=-(l*(c*x-h*f)-i*(e*x-M*f)+I*(e*h-M*c)),t[13]=n*(c*x-h*f)-i*(r*x-o*f)+I*(r*h-o*c),t[14]=-(n*(e*x-M*f)-l*(r*x-o*f)+I*(r*M-o*e)),t[15]=n*(e*h-M*c)-l*(r*h-o*c)+i*(r*M-o*e),t},o.SIMD.adjoint=function(t,a){var n,r,o,u,l,e,M,s,i,c,h,S,I,n=SIMD.Float32x4.load(a,0),r=SIMD.Float32x4.load(a,4),o=SIMD.Float32x4.load(a,8),u=SIMD.Float32x4.load(a,12);return i=SIMD.Float32x4.shuffle(n,r,0,1,4,5),e=SIMD.Float32x4.shuffle(o,u,0,1,4,5),l=SIMD.Float32x4.shuffle(i,e,0,2,4,6),e=SIMD.Float32x4.shuffle(e,i,1,3,5,7),i=SIMD.Float32x4.shuffle(n,r,2,3,6,7),s=SIMD.Float32x4.shuffle(o,u,2,3,6,7),M=SIMD.Float32x4.shuffle(i,s,0,2,4,6),s=SIMD.Float32x4.shuffle(s,i,1,3,5,7),i=SIMD.Float32x4.mul(M,s),i=SIMD.Float32x4.swizzle(i,1,0,3,2),c=SIMD.Float32x4.mul(e,i),h=SIMD.Float32x4.mul(l,i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),c=SIMD.Float32x4.sub(SIMD.Float32x4.mul(e,i),c),h=SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,i),h),h=SIMD.Float32x4.swizzle(h,2,3,0,1),i=SIMD.Float32x4.mul(e,M),i=SIMD.Float32x4.swizzle(i,1,0,3,2),c=SIMD.Float32x4.add(SIMD.Float32x4.mul(s,i),c),I=SIMD.Float32x4.mul(l,i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),c=SIMD.Float32x4.sub(c,SIMD.Float32x4.mul(s,i)),I=SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,i),I),I=SIMD.Float32x4.swizzle(I,2,3,0,1),i=SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,2,3,0,1),s),i=SIMD.Float32x4.swizzle(i,1,0,3,2),M=SIMD.Float32x4.swizzle(M,2,3,0,1),c=SIMD.Float32x4.add(SIMD.Float32x4.mul(M,i),c),S=SIMD.Float32x4.mul(l,i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),c=SIMD.Float32x4.sub(c,SIMD.Float32x4.mul(M,i)),S=SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,i),S),S=SIMD.Float32x4.swizzle(S,2,3,0,1),i=SIMD.Float32x4.mul(l,e),i=SIMD.Float32x4.swizzle(i,1,0,3,2),S=SIMD.Float32x4.add(SIMD.Float32x4.mul(s,i),S),I=SIMD.Float32x4.sub(SIMD.Float32x4.mul(M,i),I),i=SIMD.Float32x4.swizzle(i,2,3,0,1),S=SIMD.Float32x4.sub(SIMD.Float32x4.mul(s,i),S),I=SIMD.Float32x4.sub(I,SIMD.Float32x4.mul(M,i)),i=SIMD.Float32x4.mul(l,s),i=SIMD.Float32x4.swizzle(i,1,0,3,2),h=SIMD.Float32x4.sub(h,SIMD.Float32x4.mul(M,i)),S=SIMD.Float32x4.add(SIMD.Float32x4.mul(e,i),S),i=SIMD.Float32x4.swizzle(i,2,3,0,1),h=SIMD.Float32x4.add(SIMD.Float32x4.mul(M,i),h),S=SIMD.Float32x4.sub(S,SIMD.Float32x4.mul(e,i)),i=SIMD.Float32x4.mul(l,M),i=SIMD.Float32x4.swizzle(i,1,0,3,2),h=SIMD.Float32x4.add(SIMD.Float32x4.mul(s,i),h),I=SIMD.Float32x4.sub(I,SIMD.Float32x4.mul(e,i)),i=SIMD.Float32x4.swizzle(i,2,3,0,1),h=SIMD.Float32x4.sub(h,SIMD.Float32x4.mul(s,i)),I=SIMD.Float32x4.add(SIMD.Float32x4.mul(e,i),I),SIMD.Float32x4.store(t,0,c),SIMD.Float32x4.store(t,4,h),SIMD.Float32x4.store(t,8,S),SIMD.Float32x4.store(t,12,I),t},o.adjoint=r.USE_SIMD?o.SIMD.adjoint:o.scalar.adjoint,o.determinant=function(t){var a=t[0],n=t[1],r=t[2],o=t[3],u=t[4],l=t[5],e=t[6],M=t[7],s=t[8],i=t[9],c=t[10],h=t[11],S=t[12],I=t[13],f=t[14],x=t[15],D=a*l-n*u,F=a*e-r*u,m=a*M-o*u,d=n*e-r*l,b=n*M-o*l,v=r*M-o*e,z=s*I-i*S,p=s*f-c*S,w=s*x-h*S,E=i*f-c*I,A=i*x-h*I,P=c*x-h*f;return D*P-F*A+m*E+d*w-b*p+v*z},o.SIMD.multiply=function(t,a,n){var r=SIMD.Float32x4.load(a,0),o=SIMD.Float32x4.load(a,4),u=SIMD.Float32x4.load(a,8),l=SIMD.Float32x4.load(a,12),e=SIMD.Float32x4.load(n,0),M=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,3,3,3,3),l))));SIMD.Float32x4.store(t,0,M);var s=SIMD.Float32x4.load(n,4),i=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,3,3,3,3),l))));SIMD.Float32x4.store(t,4,i);var c=SIMD.Float32x4.load(n,8),h=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,3,3,3,3),l))));SIMD.Float32x4.store(t,8,h);var S=SIMD.Float32x4.load(n,12),I=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,3,3,3,3),l))));return SIMD.Float32x4.store(t,12,I),t},o.scalar.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=a[9],S=a[10],I=a[11],f=a[12],x=a[13],D=a[14],F=a[15],m=n[0],d=n[1],b=n[2],v=n[3];return t[0]=m*r+d*e+b*c+v*f,t[1]=m*o+d*M+b*h+v*x,t[2]=m*u+d*s+b*S+v*D,t[3]=m*l+d*i+b*I+v*F,m=n[4],d=n[5],b=n[6],v=n[7],t[4]=m*r+d*e+b*c+v*f,t[5]=m*o+d*M+b*h+v*x,t[6]=m*u+d*s+b*S+v*D,t[7]=m*l+d*i+b*I+v*F,m=n[8],d=n[9],b=n[10],v=n[11],t[8]=m*r+d*e+b*c+v*f,t[9]=m*o+d*M+b*h+v*x,t[10]=m*u+d*s+b*S+v*D,t[11]=m*l+d*i+b*I+v*F,m=n[12],d=n[13],b=n[14],v=n[15],t[12]=m*r+d*e+b*c+v*f,t[13]=m*o+d*M+b*h+v*x,t[14]=m*u+d*s+b*S+v*D,t[15]=m*l+d*i+b*I+v*F,t},o.multiply=r.USE_SIMD?o.SIMD.multiply:o.scalar.multiply,o.mul=o.multiply,o.scalar.translate=function(t,a,n){var r,o,u,l,e,M,s,i,c,h,S,I,f=n[0],x=n[1],D=n[2];return a===t?(t[12]=a[0]*f+a[4]*x+a[8]*D+a[12],t[13]=a[1]*f+a[5]*x+a[9]*D+a[13],t[14]=a[2]*f+a[6]*x+a[10]*D+a[14],t[15]=a[3]*f+a[7]*x+a[11]*D+a[15]):(r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=a[9],S=a[10],I=a[11],t[0]=r,t[1]=o,t[2]=u,t[3]=l,t[4]=e,t[5]=M,t[6]=s,t[7]=i,t[8]=c,t[9]=h,t[10]=S,t[11]=I,t[12]=r*f+e*x+c*D+a[12],t[13]=o*f+M*x+h*D+a[13],t[14]=u*f+s*x+S*D+a[14],t[15]=l*f+i*x+I*D+a[15]),t},o.SIMD.translate=function(t,a,n){var r=SIMD.Float32x4.load(a,0),o=SIMD.Float32x4.load(a,4),u=SIMD.Float32x4.load(a,8),l=SIMD.Float32x4.load(a,12),e=SIMD.Float32x4(n[0],n[1],n[2],0);a!==t&&(t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11]),r=SIMD.Float32x4.mul(r,SIMD.Float32x4.swizzle(e,0,0,0,0)),o=SIMD.Float32x4.mul(o,SIMD.Float32x4.swizzle(e,1,1,1,1)),u=SIMD.Float32x4.mul(u,SIMD.Float32x4.swizzle(e,2,2,2,2));var M=SIMD.Float32x4.add(r,SIMD.Float32x4.add(o,SIMD.Float32x4.add(u,l)));return SIMD.Float32x4.store(t,12,M),t},o.translate=r.USE_SIMD?o.SIMD.translate:o.scalar.translate,o.scalar.scale=function(t,a,n){var r=n[0],o=n[1],u=n[2];return t[0]=a[0]*r,t[1]=a[1]*r,t[2]=a[2]*r,t[3]=a[3]*r,t[4]=a[4]*o,t[5]=a[5]*o,t[6]=a[6]*o,t[7]=a[7]*o,t[8]=a[8]*u,t[9]=a[9]*u,t[10]=a[10]*u,t[11]=a[11]*u,t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15],t},o.SIMD.scale=function(t,a,n){var r,o,u,l=SIMD.Float32x4(n[0],n[1],n[2],0);return r=SIMD.Float32x4.load(a,0),SIMD.Float32x4.store(t,0,SIMD.Float32x4.mul(r,SIMD.Float32x4.swizzle(l,0,0,0,0))),o=SIMD.Float32x4.load(a,4),SIMD.Float32x4.store(t,4,SIMD.Float32x4.mul(o,SIMD.Float32x4.swizzle(l,1,1,1,1))),u=SIMD.Float32x4.load(a,8),SIMD.Float32x4.store(t,8,SIMD.Float32x4.mul(u,SIMD.Float32x4.swizzle(l,2,2,2,2))),t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15],t},o.scale=r.USE_SIMD?o.SIMD.scale:o.scalar.scale,o.rotate=function(t,a,n,o){var u,l,e,M,s,i,c,h,S,I,f,x,D,F,m,d,b,v,z,p,w,E,A,P,L=o[0],q=o[1],R=o[2],N=Math.sqrt(L*L+q*q+R*R);return Math.abs(N)<r.EPSILON?null:(N=1/N,L*=N,q*=N,R*=N,u=Math.sin(n),l=Math.cos(n),e=1-l,M=a[0],s=a[1],i=a[2],c=a[3],h=a[4],S=a[5],I=a[6],f=a[7],x=a[8],D=a[9],F=a[10],m=a[11],d=L*L*e+l,b=q*L*e+R*u,v=R*L*e-q*u,z=L*q*e-R*u,p=q*q*e+l,w=R*q*e+L*u,E=L*R*e+q*u,A=q*R*e-L*u,P=R*R*e+l,t[0]=M*d+h*b+x*v,t[1]=s*d+S*b+D*v,t[2]=i*d+I*b+F*v,t[3]=c*d+f*b+m*v,t[4]=M*z+h*p+x*w,t[5]=s*z+S*p+D*w,t[6]=i*z+I*p+F*w,t[7]=c*z+f*p+m*w,t[8]=M*E+h*A+x*P,t[9]=s*E+S*A+D*P,t[10]=i*E+I*A+F*P,t[11]=c*E+f*A+m*P,a!==t&&(t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t)},o.scalar.rotateX=function(t,a,n){var r=Math.sin(n),o=Math.cos(n),u=a[4],l=a[5],e=a[6],M=a[7],s=a[8],i=a[9],c=a[10],h=a[11];return a!==t&&(t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t[4]=u*o+s*r,t[5]=l*o+i*r,t[6]=e*o+c*r,t[7]=M*o+h*r,t[8]=s*o-u*r,t[9]=i*o-l*r,t[10]=c*o-e*r,t[11]=h*o-M*r,t},o.SIMD.rotateX=function(t,a,n){var r=SIMD.Float32x4.splat(Math.sin(n)),o=SIMD.Float32x4.splat(Math.cos(n));a!==t&&(t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]);var u=SIMD.Float32x4.load(a,4),l=SIMD.Float32x4.load(a,8);return SIMD.Float32x4.store(t,4,SIMD.Float32x4.add(SIMD.Float32x4.mul(u,o),SIMD.Float32x4.mul(l,r))),SIMD.Float32x4.store(t,8,SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,o),SIMD.Float32x4.mul(u,r))),t},o.rotateX=r.USE_SIMD?o.SIMD.rotateX:o.scalar.rotateX,o.scalar.rotateY=function(t,a,n){var r=Math.sin(n),o=Math.cos(n),u=a[0],l=a[1],e=a[2],M=a[3],s=a[8],i=a[9],c=a[10],h=a[11];return a!==t&&(t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t[0]=u*o-s*r,t[1]=l*o-i*r,t[2]=e*o-c*r,t[3]=M*o-h*r,t[8]=u*r+s*o,t[9]=l*r+i*o,t[10]=e*r+c*o,t[11]=M*r+h*o,t},o.SIMD.rotateY=function(t,a,n){var r=SIMD.Float32x4.splat(Math.sin(n)),o=SIMD.Float32x4.splat(Math.cos(n));a!==t&&(t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]);var u=SIMD.Float32x4.load(a,0),l=SIMD.Float32x4.load(a,8);return SIMD.Float32x4.store(t,0,SIMD.Float32x4.sub(SIMD.Float32x4.mul(u,o),SIMD.Float32x4.mul(l,r))),SIMD.Float32x4.store(t,8,SIMD.Float32x4.add(SIMD.Float32x4.mul(u,r),SIMD.Float32x4.mul(l,o))),t},o.rotateY=r.USE_SIMD?o.SIMD.rotateY:o.scalar.rotateY,o.scalar.rotateZ=function(t,a,n){var r=Math.sin(n),o=Math.cos(n),u=a[0],l=a[1],e=a[2],M=a[3],s=a[4],i=a[5],c=a[6],h=a[7];return a!==t&&(t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t[0]=u*o+s*r,t[1]=l*o+i*r,t[2]=e*o+c*r,t[3]=M*o+h*r,t[4]=s*o-u*r,t[5]=i*o-l*r,t[6]=c*o-e*r,t[7]=h*o-M*r,t},o.SIMD.rotateZ=function(t,a,n){var r=SIMD.Float32x4.splat(Math.sin(n)),o=SIMD.Float32x4.splat(Math.cos(n));a!==t&&(t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]);var u=SIMD.Float32x4.load(a,0),l=SIMD.Float32x4.load(a,4);return SIMD.Float32x4.store(t,0,SIMD.Float32x4.add(SIMD.Float32x4.mul(u,o),SIMD.Float32x4.mul(l,r))),SIMD.Float32x4.store(t,4,SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,o),SIMD.Float32x4.mul(u,r))),t},o.rotateZ=r.USE_SIMD?o.SIMD.rotateZ:o.scalar.rotateZ,o.fromTranslation=function(t,a){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=a[0],t[13]=a[1],t[14]=a[2],t[15]=1,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=a[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromRotation=function(t,a,n){var o,u,l,e=n[0],M=n[1],s=n[2],i=Math.sqrt(e*e+M*M+s*s);return Math.abs(i)<r.EPSILON?null:(i=1/i,e*=i,M*=i,s*=i,o=Math.sin(a),u=Math.cos(a),l=1-u,t[0]=e*e*l+u,t[1]=M*e*l+s*o,t[2]=s*e*l-M*o,t[3]=0,t[4]=e*M*l-s*o,t[5]=M*M*l+u,t[6]=s*M*l+e*o,t[7]=0,t[8]=e*s*l+M*o,t[9]=M*s*l-e*o,t[10]=s*s*l+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},o.fromXRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=r,t[6]=n,t[7]=0,t[8]=0,t[9]=-n,t[10]=r,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromYRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=0,t[2]=-n,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=n,t[9]=0,t[10]=r,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromZRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=0,t[3]=0,t[4]=-n,t[5]=r,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromRotationTranslation=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=r+r,M=o+o,s=u+u,i=r*e,c=r*M,h=r*s,S=o*M,I=o*s,f=u*s,x=l*e,D=l*M,F=l*s;return t[0]=1-(S+f),t[1]=c+F,t[2]=h-D,t[3]=0,t[4]=c-F,t[5]=1-(i+f),t[6]=I+x,t[7]=0,t[8]=h+D,t[9]=I-x,t[10]=1-(i+S),t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},o.getTranslation=function(t,a){return t[0]=a[12],t[1]=a[13],t[2]=a[14],t},o.getRotation=function(t,a){var n=a[0]+a[5]+a[10],r=0;return n>0?(r=2*Math.sqrt(n+1),t[3]=.25*r,t[0]=(a[6]-a[9])/r,t[1]=(a[8]-a[2])/r,t[2]=(a[1]-a[4])/r):a[0]>a[5]&a[0]>a[10]?(r=2*Math.sqrt(1+a[0]-a[5]-a[10]),t[3]=(a[6]-a[9])/r,t[0]=.25*r,t[1]=(a[1]+a[4])/r,t[2]=(a[8]+a[2])/r):a[5]>a[10]?(r=2*Math.sqrt(1+a[5]-a[0]-a[10]),t[3]=(a[8]-a[2])/r,t[0]=(a[1]+a[4])/r,t[1]=.25*r,t[2]=(a[6]+a[9])/r):(r=2*Math.sqrt(1+a[10]-a[0]-a[5]),t[3]=(a[1]-a[4])/r,t[0]=(a[8]+a[2])/r,t[1]=(a[6]+a[9])/r,t[2]=.25*r),t},o.fromRotationTranslationScale=function(t,a,n,r){var o=a[0],u=a[1],l=a[2],e=a[3],M=o+o,s=u+u,i=l+l,c=o*M,h=o*s,S=o*i,I=u*s,f=u*i,x=l*i,D=e*M,F=e*s,m=e*i,d=r[0],b=r[1],v=r[2];return t[0]=(1-(I+x))*d,t[1]=(h+m)*d,t[2]=(S-F)*d,t[3]=0,t[4]=(h-m)*b,t[5]=(1-(c+x))*b,t[6]=(f+D)*b,t[7]=0,t[8]=(S+F)*v,t[9]=(f-D)*v,t[10]=(1-(c+I))*v,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},o.fromRotationTranslationScaleOrigin=function(t,a,n,r,o){
-var u=a[0],l=a[1],e=a[2],M=a[3],s=u+u,i=l+l,c=e+e,h=u*s,S=u*i,I=u*c,f=l*i,x=l*c,D=e*c,F=M*s,m=M*i,d=M*c,b=r[0],v=r[1],z=r[2],p=o[0],w=o[1],E=o[2];return t[0]=(1-(f+D))*b,t[1]=(S+d)*b,t[2]=(I-m)*b,t[3]=0,t[4]=(S-d)*v,t[5]=(1-(h+D))*v,t[6]=(x+F)*v,t[7]=0,t[8]=(I+m)*z,t[9]=(x-F)*z,t[10]=(1-(h+f))*z,t[11]=0,t[12]=n[0]+p-(t[0]*p+t[4]*w+t[8]*E),t[13]=n[1]+w-(t[1]*p+t[5]*w+t[9]*E),t[14]=n[2]+E-(t[2]*p+t[6]*w+t[10]*E),t[15]=1,t},o.fromQuat=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n+n,e=r+r,M=o+o,s=n*l,i=r*l,c=r*e,h=o*l,S=o*e,I=o*M,f=u*l,x=u*e,D=u*M;return t[0]=1-c-I,t[1]=i+D,t[2]=h-x,t[3]=0,t[4]=i-D,t[5]=1-s-I,t[6]=S+f,t[7]=0,t[8]=h+x,t[9]=S-f,t[10]=1-s-c,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.frustum=function(t,a,n,r,o,u,l){var e=1/(n-a),M=1/(o-r),s=1/(u-l);return t[0]=2*u*e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*M,t[6]=0,t[7]=0,t[8]=(n+a)*e,t[9]=(o+r)*M,t[10]=(l+u)*s,t[11]=-1,t[12]=0,t[13]=0,t[14]=l*u*2*s,t[15]=0,t},o.perspective=function(t,a,n,r,o){var u=1/Math.tan(a/2),l=1/(r-o);return t[0]=u/n,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(o+r)*l,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*o*r*l,t[15]=0,t},o.perspectiveFromFieldOfView=function(t,a,n,r){var o=Math.tan(a.upDegrees*Math.PI/180),u=Math.tan(a.downDegrees*Math.PI/180),l=Math.tan(a.leftDegrees*Math.PI/180),e=Math.tan(a.rightDegrees*Math.PI/180),M=2/(l+e),s=2/(o+u);return t[0]=M,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=s,t[6]=0,t[7]=0,t[8]=-((l-e)*M*.5),t[9]=(o-u)*s*.5,t[10]=r/(n-r),t[11]=-1,t[12]=0,t[13]=0,t[14]=r*n/(n-r),t[15]=0,t},o.ortho=function(t,a,n,r,o,u,l){var e=1/(a-n),M=1/(r-o),s=1/(u-l);return t[0]=-2*e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*M,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*s,t[11]=0,t[12]=(a+n)*e,t[13]=(o+r)*M,t[14]=(l+u)*s,t[15]=1,t},o.lookAt=function(t,a,n,u){var l,e,M,s,i,c,h,S,I,f,x=a[0],D=a[1],F=a[2],m=u[0],d=u[1],b=u[2],v=n[0],z=n[1],p=n[2];return Math.abs(x-v)<r.EPSILON&&Math.abs(D-z)<r.EPSILON&&Math.abs(F-p)<r.EPSILON?o.identity(t):(h=x-v,S=D-z,I=F-p,f=1/Math.sqrt(h*h+S*S+I*I),h*=f,S*=f,I*=f,l=d*I-b*S,e=b*h-m*I,M=m*S-d*h,f=Math.sqrt(l*l+e*e+M*M),f?(f=1/f,l*=f,e*=f,M*=f):(l=0,e=0,M=0),s=S*M-I*e,i=I*l-h*M,c=h*e-S*l,f=Math.sqrt(s*s+i*i+c*c),f?(f=1/f,s*=f,i*=f,c*=f):(s=0,i=0,c=0),t[0]=l,t[1]=s,t[2]=h,t[3]=0,t[4]=e,t[5]=i,t[6]=S,t[7]=0,t[8]=M,t[9]=c,t[10]=I,t[11]=0,t[12]=-(l*x+e*D+M*F),t[13]=-(s*x+i*D+c*F),t[14]=-(h*x+S*D+I*F),t[15]=1,t)},o.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t[4]=a[4]+n[4],t[5]=a[5]+n[5],t[6]=a[6]+n[6],t[7]=a[7]+n[7],t[8]=a[8]+n[8],t[9]=a[9]+n[9],t[10]=a[10]+n[10],t[11]=a[11]+n[11],t[12]=a[12]+n[12],t[13]=a[13]+n[13],t[14]=a[14]+n[14],t[15]=a[15]+n[15],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t[4]=a[4]-n[4],t[5]=a[5]-n[5],t[6]=a[6]-n[6],t[7]=a[7]-n[7],t[8]=a[8]-n[8],t[9]=a[9]-n[9],t[10]=a[10]-n[10],t[11]=a[11]-n[11],t[12]=a[12]-n[12],t[13]=a[13]-n[13],t[14]=a[14]-n[14],t[15]=a[15]-n[15],t},o.sub=o.subtract,o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t[4]=a[4]*n,t[5]=a[5]*n,t[6]=a[6]*n,t[7]=a[7]*n,t[8]=a[8]*n,t[9]=a[9]*n,t[10]=a[10]*n,t[11]=a[11]*n,t[12]=a[12]*n,t[13]=a[13]*n,t[14]=a[14]*n,t[15]=a[15]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t[4]=a[4]+n[4]*r,t[5]=a[5]+n[5]*r,t[6]=a[6]+n[6]*r,t[7]=a[7]+n[7]*r,t[8]=a[8]+n[8]*r,t[9]=a[9]+n[9]*r,t[10]=a[10]+n[10]*r,t[11]=a[11]+n[11]*r,t[12]=a[12]+n[12]*r,t[13]=a[13]+n[13]*r,t[14]=a[14]+n[14]*r,t[15]=a[15]+n[15]*r,t},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]&&t[4]===a[4]&&t[5]===a[5]&&t[6]===a[6]&&t[7]===a[7]&&t[8]===a[8]&&t[9]===a[9]&&t[10]===a[10]&&t[11]===a[11]&&t[12]===a[12]&&t[13]===a[13]&&t[14]===a[14]&&t[15]===a[15]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=t[4],M=t[5],s=t[6],i=t[7],c=t[8],h=t[9],S=t[10],I=t[11],f=t[12],x=t[13],D=t[14],F=t[15],m=a[0],d=a[1],b=a[2],v=a[3],z=a[4],p=a[5],w=a[6],E=a[7],A=a[8],P=a[9],L=a[10],q=a[11],R=a[12],N=a[13],O=a[14],Y=a[15];return Math.abs(n-m)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(m))&&Math.abs(o-d)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(d))&&Math.abs(u-b)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(b))&&Math.abs(l-v)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(v))&&Math.abs(e-z)<=r.EPSILON*Math.max(1,Math.abs(e),Math.abs(z))&&Math.abs(M-p)<=r.EPSILON*Math.max(1,Math.abs(M),Math.abs(p))&&Math.abs(s-w)<=r.EPSILON*Math.max(1,Math.abs(s),Math.abs(w))&&Math.abs(i-E)<=r.EPSILON*Math.max(1,Math.abs(i),Math.abs(E))&&Math.abs(c-A)<=r.EPSILON*Math.max(1,Math.abs(c),Math.abs(A))&&Math.abs(h-P)<=r.EPSILON*Math.max(1,Math.abs(h),Math.abs(P))&&Math.abs(S-L)<=r.EPSILON*Math.max(1,Math.abs(S),Math.abs(L))&&Math.abs(I-q)<=r.EPSILON*Math.max(1,Math.abs(I),Math.abs(q))&&Math.abs(f-R)<=r.EPSILON*Math.max(1,Math.abs(f),Math.abs(R))&&Math.abs(x-N)<=r.EPSILON*Math.max(1,Math.abs(x),Math.abs(N))&&Math.abs(D-O)<=r.EPSILON*Math.max(1,Math.abs(D),Math.abs(O))&&Math.abs(F-Y)<=r.EPSILON*Math.max(1,Math.abs(F),Math.abs(Y))},t.exports=o},function(t,a,n){var r=n(1),o=n(4),u=n(7),l=n(8),e={};e.create=function(){var t=new r.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},e.rotationTo=function(){var t=u.create(),a=u.fromValues(1,0,0),n=u.fromValues(0,1,0);return function(r,o,l){var M=u.dot(o,l);return M<-.999999?(u.cross(t,a,o),u.length(t)<1e-6&&u.cross(t,n,o),u.normalize(t,t),e.setAxisAngle(r,t,Math.PI),r):M>.999999?(r[0]=0,r[1]=0,r[2]=0,r[3]=1,r):(u.cross(t,o,l),r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=1+M,e.normalize(r,r))}}(),e.setAxes=function(){var t=o.create();return function(a,n,r,o){return t[0]=r[0],t[3]=r[1],t[6]=r[2],t[1]=o[0],t[4]=o[1],t[7]=o[2],t[2]=-n[0],t[5]=-n[1],t[8]=-n[2],e.normalize(a,e.fromMat3(a,t))}}(),e.clone=l.clone,e.fromValues=l.fromValues,e.copy=l.copy,e.set=l.set,e.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},e.setAxisAngle=function(t,a,n){n=.5*n;var r=Math.sin(n);return t[0]=r*a[0],t[1]=r*a[1],t[2]=r*a[2],t[3]=Math.cos(n),t},e.getAxisAngle=function(t,a){var n=2*Math.acos(a[3]),r=Math.sin(n/2);return 0!=r?(t[0]=a[0]/r,t[1]=a[1]/r,t[2]=a[2]/r):(t[0]=1,t[1]=0,t[2]=0),n},e.add=l.add,e.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=n[0],M=n[1],s=n[2],i=n[3];return t[0]=r*i+l*e+o*s-u*M,t[1]=o*i+l*M+u*e-r*s,t[2]=u*i+l*s+r*M-o*e,t[3]=l*i-r*e-o*M-u*s,t},e.mul=e.multiply,e.scale=l.scale,e.rotateX=function(t,a,n){n*=.5;var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M+l*e,t[1]=o*M+u*e,t[2]=u*M-o*e,t[3]=l*M-r*e,t},e.rotateY=function(t,a,n){n*=.5;var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M-u*e,t[1]=o*M+l*e,t[2]=u*M+r*e,t[3]=l*M-o*e,t},e.rotateZ=function(t,a,n){n*=.5;var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M+o*e,t[1]=o*M-r*e,t[2]=u*M+l*e,t[3]=l*M-u*e,t},e.calculateW=function(t,a){var n=a[0],r=a[1],o=a[2];return t[0]=n,t[1]=r,t[2]=o,t[3]=Math.sqrt(Math.abs(1-n*n-r*r-o*o)),t},e.dot=l.dot,e.lerp=l.lerp,e.slerp=function(t,a,n,r){var o,u,l,e,M,s=a[0],i=a[1],c=a[2],h=a[3],S=n[0],I=n[1],f=n[2],x=n[3];return u=s*S+i*I+c*f+h*x,u<0&&(u=-u,S=-S,I=-I,f=-f,x=-x),1-u>1e-6?(o=Math.acos(u),l=Math.sin(o),e=Math.sin((1-r)*o)/l,M=Math.sin(r*o)/l):(e=1-r,M=r),t[0]=e*s+M*S,t[1]=e*i+M*I,t[2]=e*c+M*f,t[3]=e*h+M*x,t},e.sqlerp=function(){var t=e.create(),a=e.create();return function(n,r,o,u,l,M){return e.slerp(t,r,l,M),e.slerp(a,o,u,M),e.slerp(n,t,a,2*M*(1-M)),n}}(),e.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n*n+r*r+o*o+u*u,e=l?1/l:0;return t[0]=-n*e,t[1]=-r*e,t[2]=-o*e,t[3]=u*e,t},e.conjugate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t[2]=-a[2],t[3]=a[3],t},e.length=l.length,e.len=e.length,e.squaredLength=l.squaredLength,e.sqrLen=e.squaredLength,e.normalize=l.normalize,e.fromMat3=function(t,a){var n,r=a[0]+a[4]+a[8];if(r>0)n=Math.sqrt(r+1),t[3]=.5*n,n=.5/n,t[0]=(a[5]-a[7])*n,t[1]=(a[6]-a[2])*n,t[2]=(a[1]-a[3])*n;else{var o=0;a[4]>a[0]&&(o=1),a[8]>a[3*o+o]&&(o=2);var u=(o+1)%3,l=(o+2)%3;n=Math.sqrt(a[3*o+o]-a[3*u+u]-a[3*l+l]+1),t[o]=.5*n,n=.5/n,t[3]=(a[3*u+l]-a[3*l+u])*n,t[u]=(a[3*u+o]+a[3*o+u])*n,t[l]=(a[3*l+o]+a[3*o+l])*n}return t},e.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.exactEquals=l.exactEquals,e.equals=l.equals,t.exports=e},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(3);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a},o.fromValues=function(t,a,n){var o=new r.ARRAY_TYPE(3);return o[0]=t,o[1]=a,o[2]=n,o},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t},o.set=function(t,a,n,r){return t[0]=a,t[1]=n,t[2]=r,t},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t},o.sub=o.subtract,o.multiply=function(t,a,n){return t[0]=a[0]*n[0],t[1]=a[1]*n[1],t[2]=a[2]*n[2],t},o.mul=o.multiply,o.divide=function(t,a,n){return t[0]=a[0]/n[0],t[1]=a[1]/n[1],t[2]=a[2]/n[2],t},o.div=o.divide,o.ceil=function(t,a){return t[0]=Math.ceil(a[0]),t[1]=Math.ceil(a[1]),t[2]=Math.ceil(a[2]),t},o.floor=function(t,a){return t[0]=Math.floor(a[0]),t[1]=Math.floor(a[1]),t[2]=Math.floor(a[2]),t},o.min=function(t,a,n){return t[0]=Math.min(a[0],n[0]),t[1]=Math.min(a[1],n[1]),t[2]=Math.min(a[2],n[2]),t},o.max=function(t,a,n){return t[0]=Math.max(a[0],n[0]),t[1]=Math.max(a[1],n[1]),t[2]=Math.max(a[2],n[2]),t},o.round=function(t,a){return t[0]=Math.round(a[0]),t[1]=Math.round(a[1]),t[2]=Math.round(a[2]),t},o.scale=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t},o.scaleAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t},o.distance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2];return Math.sqrt(n*n+r*r+o*o)},o.dist=o.distance,o.squaredDistance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2];return n*n+r*r+o*o},o.sqrDist=o.squaredDistance,o.length=function(t){var a=t[0],n=t[1],r=t[2];return Math.sqrt(a*a+n*n+r*r)},o.len=o.length,o.squaredLength=function(t){var a=t[0],n=t[1],r=t[2];return a*a+n*n+r*r},o.sqrLen=o.squaredLength,o.negate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t[2]=-a[2],t},o.inverse=function(t,a){return t[0]=1/a[0],t[1]=1/a[1],t[2]=1/a[2],t},o.normalize=function(t,a){var n=a[0],r=a[1],o=a[2],u=n*n+r*r+o*o;return u>0&&(u=1/Math.sqrt(u),t[0]=a[0]*u,t[1]=a[1]*u,t[2]=a[2]*u),t},o.dot=function(t,a){return t[0]*a[0]+t[1]*a[1]+t[2]*a[2]},o.cross=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[0],e=n[1],M=n[2];return t[0]=o*M-u*e,t[1]=u*l-r*M,t[2]=r*e-o*l,t},o.lerp=function(t,a,n,r){var o=a[0],u=a[1],l=a[2];return t[0]=o+r*(n[0]-o),t[1]=u+r*(n[1]-u),t[2]=l+r*(n[2]-l),t},o.hermite=function(t,a,n,r,o,u){var l=u*u,e=l*(2*u-3)+1,M=l*(u-2)+u,s=l*(u-1),i=l*(3-2*u);return t[0]=a[0]*e+n[0]*M+r[0]*s+o[0]*i,t[1]=a[1]*e+n[1]*M+r[1]*s+o[1]*i,t[2]=a[2]*e+n[2]*M+r[2]*s+o[2]*i,t},o.bezier=function(t,a,n,r,o,u){var l=1-u,e=l*l,M=u*u,s=e*l,i=3*u*e,c=3*M*l,h=M*u;return t[0]=a[0]*s+n[0]*i+r[0]*c+o[0]*h,t[1]=a[1]*s+n[1]*i+r[1]*c+o[1]*h,t[2]=a[2]*s+n[2]*i+r[2]*c+o[2]*h,t},o.random=function(t,a){a=a||1;var n=2*r.RANDOM()*Math.PI,o=2*r.RANDOM()-1,u=Math.sqrt(1-o*o)*a;return t[0]=Math.cos(n)*u,t[1]=Math.sin(n)*u,t[2]=o*a,t},o.transformMat4=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[3]*r+n[7]*o+n[11]*u+n[15];return l=l||1,t[0]=(n[0]*r+n[4]*o+n[8]*u+n[12])/l,t[1]=(n[1]*r+n[5]*o+n[9]*u+n[13])/l,t[2]=(n[2]*r+n[6]*o+n[10]*u+n[14])/l,t},o.transformMat3=function(t,a,n){var r=a[0],o=a[1],u=a[2];return t[0]=r*n[0]+o*n[3]+u*n[6],t[1]=r*n[1]+o*n[4]+u*n[7],t[2]=r*n[2]+o*n[5]+u*n[8],t},o.transformQuat=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[0],e=n[1],M=n[2],s=n[3],i=s*r+e*u-M*o,c=s*o+M*r-l*u,h=s*u+l*o-e*r,S=-l*r-e*o-M*u;return t[0]=i*s+S*-l+c*-M-h*-e,t[1]=c*s+S*-e+h*-l-i*-M,t[2]=h*s+S*-M+i*-e-c*-l,t},o.rotateX=function(t,a,n,r){var o=[],u=[];return o[0]=a[0]-n[0],o[1]=a[1]-n[1],o[2]=a[2]-n[2],u[0]=o[0],u[1]=o[1]*Math.cos(r)-o[2]*Math.sin(r),u[2]=o[1]*Math.sin(r)+o[2]*Math.cos(r),t[0]=u[0]+n[0],t[1]=u[1]+n[1],t[2]=u[2]+n[2],t},o.rotateY=function(t,a,n,r){var o=[],u=[];return o[0]=a[0]-n[0],o[1]=a[1]-n[1],o[2]=a[2]-n[2],u[0]=o[2]*Math.sin(r)+o[0]*Math.cos(r),u[1]=o[1],u[2]=o[2]*Math.cos(r)-o[0]*Math.sin(r),t[0]=u[0]+n[0],t[1]=u[1]+n[1],t[2]=u[2]+n[2],t},o.rotateZ=function(t,a,n,r){var o=[],u=[];return o[0]=a[0]-n[0],o[1]=a[1]-n[1],o[2]=a[2]-n[2],u[0]=o[0]*Math.cos(r)-o[1]*Math.sin(r),u[1]=o[0]*Math.sin(r)+o[1]*Math.cos(r),u[2]=o[2],t[0]=u[0]+n[0],t[1]=u[1]+n[1],t[2]=u[2]+n[2],t},o.forEach=function(){var t=o.create();return function(a,n,r,o,u,l){var e,M;for(n||(n=3),r||(r=0),M=o?Math.min(o*n+r,a.length):a.length,e=r;e<M;e+=n)t[0]=a[e],t[1]=a[e+1],t[2]=a[e+2],u(t,t,l),a[e]=t[0],a[e+1]=t[1],a[e+2]=t[2];return a}}(),o.angle=function(t,a){var n=o.fromValues(t[0],t[1],t[2]),r=o.fromValues(a[0],a[1],a[2]);o.normalize(n,n),o.normalize(r,r);var u=o.dot(n,r);return u>1?0:Math.acos(u)},o.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=a[0],e=a[1],M=a[2];return Math.abs(n-l)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(l))&&Math.abs(o-e)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(e))&&Math.abs(u-M)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(M))},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(4);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a},o.fromValues=function(t,a,n,o){var u=new r.ARRAY_TYPE(4);return u[0]=t,u[1]=a,u[2]=n,u[3]=o,u},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t},o.set=function(t,a,n,r,o){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t},o.sub=o.subtract,o.multiply=function(t,a,n){return t[0]=a[0]*n[0],t[1]=a[1]*n[1],t[2]=a[2]*n[2],t[3]=a[3]*n[3],t},o.mul=o.multiply,o.divide=function(t,a,n){return t[0]=a[0]/n[0],t[1]=a[1]/n[1],t[2]=a[2]/n[2],t[3]=a[3]/n[3],t},o.div=o.divide,o.ceil=function(t,a){return t[0]=Math.ceil(a[0]),t[1]=Math.ceil(a[1]),t[2]=Math.ceil(a[2]),t[3]=Math.ceil(a[3]),t},o.floor=function(t,a){return t[0]=Math.floor(a[0]),t[1]=Math.floor(a[1]),t[2]=Math.floor(a[2]),t[3]=Math.floor(a[3]),t},o.min=function(t,a,n){return t[0]=Math.min(a[0],n[0]),t[1]=Math.min(a[1],n[1]),t[2]=Math.min(a[2],n[2]),t[3]=Math.min(a[3],n[3]),t},o.max=function(t,a,n){return t[0]=Math.max(a[0],n[0]),t[1]=Math.max(a[1],n[1]),t[2]=Math.max(a[2],n[2]),t[3]=Math.max(a[3],n[3]),t},o.round=function(t,a){return t[0]=Math.round(a[0]),t[1]=Math.round(a[1]),t[2]=Math.round(a[2]),t[3]=Math.round(a[3]),t},o.scale=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t},o.scaleAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t},o.distance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2],u=a[3]-t[3];return Math.sqrt(n*n+r*r+o*o+u*u)},o.dist=o.distance,o.squaredDistance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2],u=a[3]-t[3];return n*n+r*r+o*o+u*u},o.sqrDist=o.squaredDistance,o.length=function(t){var a=t[0],n=t[1],r=t[2],o=t[3];return Math.sqrt(a*a+n*n+r*r+o*o)},o.len=o.length,o.squaredLength=function(t){var a=t[0],n=t[1],r=t[2],o=t[3];return a*a+n*n+r*r+o*o},o.sqrLen=o.squaredLength,o.negate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t[2]=-a[2],t[3]=-a[3],t},o.inverse=function(t,a){return t[0]=1/a[0],t[1]=1/a[1],t[2]=1/a[2],t[3]=1/a[3],t},o.normalize=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n*n+r*r+o*o+u*u;return l>0&&(l=1/Math.sqrt(l),t[0]=n*l,t[1]=r*l,t[2]=o*l,t[3]=u*l),t},o.dot=function(t,a){return t[0]*a[0]+t[1]*a[1]+t[2]*a[2]+t[3]*a[3]},o.lerp=function(t,a,n,r){var o=a[0],u=a[1],l=a[2],e=a[3];return t[0]=o+r*(n[0]-o),t[1]=u+r*(n[1]-u),t[2]=l+r*(n[2]-l),t[3]=e+r*(n[3]-e),t},o.random=function(t,a){return a=a||1,t[0]=r.RANDOM(),t[1]=r.RANDOM(),t[2]=r.RANDOM(),t[3]=r.RANDOM(),o.normalize(t,t),o.scale(t,t,a),t},o.transformMat4=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3];return t[0]=n[0]*r+n[4]*o+n[8]*u+n[12]*l,t[1]=n[1]*r+n[5]*o+n[9]*u+n[13]*l,t[2]=n[2]*r+n[6]*o+n[10]*u+n[14]*l,t[3]=n[3]*r+n[7]*o+n[11]*u+n[15]*l,t},o.transformQuat=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[0],e=n[1],M=n[2],s=n[3],i=s*r+e*u-M*o,c=s*o+M*r-l*u,h=s*u+l*o-e*r,S=-l*r-e*o-M*u;return t[0]=i*s+S*-l+c*-M-h*-e,t[1]=c*s+S*-e+h*-l-i*-M,t[2]=h*s+S*-M+i*-e-c*-l,t[3]=a[3],t},o.forEach=function(){var t=o.create();return function(a,n,r,o,u,l){var e,M;for(n||(n=4),r||(r=0),M=o?Math.min(o*n+r,a.length):a.length,e=r;e<M;e+=n)t[0]=a[e],t[1]=a[e+1],t[2]=a[e+2],t[3]=a[e+3],u(t,t,l),a[e]=t[0],a[e+1]=t[1],a[e+2]=t[2],a[e+3]=t[3];return a}}(),o.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=a[0],M=a[1],s=a[2],i=a[3];return Math.abs(n-e)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(e))&&Math.abs(o-M)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(M))&&Math.abs(u-s)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(s))&&Math.abs(l-i)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(i))},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(2);return a[0]=t[0],a[1]=t[1],a},o.fromValues=function(t,a){var n=new r.ARRAY_TYPE(2);return n[0]=t,n[1]=a,n},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t},o.set=function(t,a,n){return t[0]=a,t[1]=n,t},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t},o.sub=o.subtract,o.multiply=function(t,a,n){return t[0]=a[0]*n[0],t[1]=a[1]*n[1],t},o.mul=o.multiply,o.divide=function(t,a,n){return t[0]=a[0]/n[0],t[1]=a[1]/n[1],t},o.div=o.divide,o.ceil=function(t,a){return t[0]=Math.ceil(a[0]),t[1]=Math.ceil(a[1]),t},o.floor=function(t,a){return t[0]=Math.floor(a[0]),t[1]=Math.floor(a[1]),t},o.min=function(t,a,n){return t[0]=Math.min(a[0],n[0]),t[1]=Math.min(a[1],n[1]),t},o.max=function(t,a,n){return t[0]=Math.max(a[0],n[0]),t[1]=Math.max(a[1],n[1]),t},o.round=function(t,a){return t[0]=Math.round(a[0]),t[1]=Math.round(a[1]),t},o.scale=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t},o.scaleAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t},o.distance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1];return Math.sqrt(n*n+r*r)},o.dist=o.distance,o.squaredDistance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1];return n*n+r*r},o.sqrDist=o.squaredDistance,o.length=function(t){var a=t[0],n=t[1];return Math.sqrt(a*a+n*n)},o.len=o.length,o.squaredLength=function(t){var a=t[0],n=t[1];return a*a+n*n},o.sqrLen=o.squaredLength,o.negate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t},o.inverse=function(t,a){return t[0]=1/a[0],t[1]=1/a[1],t},o.normalize=function(t,a){var n=a[0],r=a[1],o=n*n+r*r;return o>0&&(o=1/Math.sqrt(o),t[0]=a[0]*o,t[1]=a[1]*o),t},o.dot=function(t,a){return t[0]*a[0]+t[1]*a[1]},o.cross=function(t,a,n){var r=a[0]*n[1]-a[1]*n[0];return t[0]=t[1]=0,t[2]=r,t},o.lerp=function(t,a,n,r){var o=a[0],u=a[1];return t[0]=o+r*(n[0]-o),t[1]=u+r*(n[1]-u),t},o.random=function(t,a){a=a||1;var n=2*r.RANDOM()*Math.PI;return t[0]=Math.cos(n)*a,t[1]=Math.sin(n)*a,t},o.transformMat2=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[2]*o,t[1]=n[1]*r+n[3]*o,t},o.transformMat2d=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[2]*o+n[4],t[1]=n[1]*r+n[3]*o+n[5],t},o.transformMat3=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[3]*o+n[6],t[1]=n[1]*r+n[4]*o+n[7],t},o.transformMat4=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[4]*o+n[12],t[1]=n[1]*r+n[5]*o+n[13],t},o.forEach=function(){var t=o.create();return function(a,n,r,o,u,l){var e,M;for(n||(n=2),r||(r=0),M=o?Math.min(o*n+r,a.length):a.length,e=r;e<M;e+=n)t[0]=a[e],t[1]=a[e+1],u(t,t,l),a[e]=t[0],a[e+1]=t[1];return a}}(),o.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]},o.equals=function(t,a){var n=t[0],o=t[1],u=a[0],l=a[1];return Math.abs(n-u)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(u))&&Math.abs(o-l)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(l))},t.exports=o}])}); \ No newline at end of file
diff --git a/graphics/asymptote/webgl/gl.js b/graphics/asymptote/webgl/gl.js
index ab2f5fa799..f3bdf5505f 100644
--- a/graphics/asymptote/webgl/gl.js
+++ b/graphics/asymptote/webgl/gl.js
@@ -1,922 +1,2140 @@
-// Contains code from http: //learningwebgl.com/blog/ ? p=28#triangle-vertex-positions
-// modified to produce a subdivision algorithm for rendering Bezier
-// patches with WebGL
-
-var gl;
+/*@license
+ gl.js: Render Bezier patches via subdivision with WebGL.
+ Copyright 2019: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
+ University of Alberta
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+let gl;
+
+let canvas;
+let canvasWidth,canvasHeight;
+let halfCanvasWidth,halfCanvasHeight;
+
+let pixel=0.75; // Adaptive rendering constant.
+let BezierFactor=0.4;
+let FillFactor=0.1;
+let Zoom;
+let Zoom0;
+
+let maxViewportWidth=window.innerWidth;
+let maxViewportHeight=window.innerHeight;
+let viewportmargin=0;
+
+const windowTrim=10;
+let resizeStep=1.2;
+let zoomFactor;
+let zoomPinchFactor;
+let zoomPinchCap;
+let zoomStep;
+
+let shiftHoldDistance;
+let shiftWaitTime;
+let vibrateTime;
+
+let lastzoom;
+let H; // maximum camera view half-height
+
+let Fuzz2=1000*Number.EPSILON;
+let Fuzz4=Fuzz2*Fuzz2;
+let third=1/3;
+
+let P=[]; // Array of Bezier patches, triangles, curves, and pixels
+let Materials=[]; // Array of materials
+let Lights=[]; // Array of lights
+let Centers=[]; // Array of billboard centers
+
+// Don't account for device pixels when embedding in another html document
+let absolute=false;
+
+let rotMat=mat4.create();
+let projMat=mat4.create(); // projection matrix
+let viewMat=mat4.create(); // view matrix
+
+let projViewMat=mat4.create(); // projection view matrix
+let normMat=mat3.create();
+let viewMat3=mat3.create(); // 3x3 view matrix
+let rotMats=mat4.create();
+let cjMatInv=mat4.create();
+let translMat=mat4.create();
+
+let zmin,zmax;
+let center={x:0,y:0,z:0};
+let size2;
+let ArcballFactor;
+let b,B; // Scene min,max bounding box corners
+let shift={
+ x:0,y:0
+};
+
+let viewParam = {
+ xmin:0,xmax:0,
+ ymin:0,ymax:0,
+ zmin:0,zmax:0
+};
+
+let positionBuffer;
+let materialBuffer;
+let colorBuffer;
+let indexBuffer;
+
+let redraw=true;
+let remesh=true;
+let mouseDownOrTouchActive=false;
+let lastMouseX=null;
+let lastMouseY=null;
+let touchID=null;
+
+// Indexed triangles:
+let Positions=[];
+let Normals=[];
+let Colors=[];
+let Indices=[];
class Material {
- constructor(baseColor, emissive, specular, roughness, metallic, f0) {
- this.baseColor = baseColor;
- this.emissive = emissive;
- this.specular = specular;
- this.roughness = roughness;
- this.metallic = metallic;
- this.f0 = f0;
+ constructor(diffuse,emissive,specular,shininess,metallic,fresnel0) {
+ this.diffuse=diffuse;
+ this.emissive=emissive;
+ this.specular=specular;
+ this.shininess=shininess;
+ this.metallic=metallic;
+ this.fresnel0=fresnel0;
+ }
+
+ setUniform(program,stringLoc,index=null) {
+ let getLoc;
+ if (index === null)
+ getLoc =
+ param => gl.getUniformLocation(program,stringLoc+"."+param);
+ else
+ getLoc =
+ param => gl.getUniformLocation(program,stringLoc+"["+index+"]."+param);
+
+ gl.uniform4fv(getLoc("diffuse"),new Float32Array(this.diffuse));
+ gl.uniform4fv(getLoc("emissive"),new Float32Array(this.emissive));
+ gl.uniform4fv(getLoc("specular"),new Float32Array(this.specular));
+
+ gl.uniform1f(getLoc("shininess"),this.shininess);
+ gl.uniform1f(getLoc("metallic"),this.metallic);
+ gl.uniform1f(getLoc("fresnel0"),this.fresnel0);
+ }
+}
+
+let enumPointLight=1;
+let enumDirectionalLight=2;
+
+class Light {
+ constructor(direction,color) {
+ this.direction=direction;
+ this.color=color;
+ }
+
+ setUniform(program,stringLoc,index) {
+ let getLoc=
+ param => gl.getUniformLocation(program,stringLoc+"["+index+"]."+param);
+
+ gl.uniform3fv(getLoc("direction"),new Float32Array(this.direction));
+ gl.uniform3fv(getLoc("color"),new Float32Array(this.color));
+ }
+}
+
+function initGL() {
+ try {
+ gl=canvas.getContext("webgl",{alpha:false}); // Don't composite background
+ } catch(e) {}
+ if (!gl)
+ alert("Could not initialize WebGL");
+}
+
+function getShader(gl,id,options=[]) {
+ let shaderScript=document.getElementById(id);
+ if(!shaderScript)
+ return null;
+
+ let str=`#version 100
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+ precision highp float;
+#else
+ precision mediump float;
+#endif
+ const int nLights=${Lights.length};
+ const int nMaterials=${Materials.length};\n`
+
+ if(orthographic)
+ str += `#define ORTHOGRAPHIC\n`;
+
+ options.forEach(s => str += `#define `+s+`\n`);
+
+ let k=shaderScript.firstChild;
+ while(k) {
+ if(k.nodeType == 3)
+ str += k.textContent;
+ k=k.nextSibling;
+ }
+ let shader;
+ if(shaderScript.type == "x-shader/x-fragment")
+ shader = gl.createShader(gl.FRAGMENT_SHADER);
+ else if (shaderScript.type == "x-shader/x-vertex")
+ shader = gl.createShader(gl.VERTEX_SHADER);
+ else
+ return null;
+
+ gl.shaderSource(shader,str);
+ gl.compileShader(shader);
+ if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)) {
+ alert(gl.getShaderInfoLog(shader));
+ return null;
+ }
+ return shader;
+}
+
+
+function drawBuffer(data,shader,indices=data.indices)
+{
+ if(data.indices.length == 0) return;
+ let pixel=shader == pixelShader;
+ let normal=!pixel && (shader != noNormalShader);
+
+ setUniforms(shader);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(data.vertices),
+ gl.STATIC_DRAW);
+ gl.vertexAttribPointer(shader.vertexPositionAttribute,
+ 3,gl.FLOAT,false,normal ? 24 : (pixel ? 16 : 12),0);
+ if(normal)
+ gl.vertexAttribPointer(shader.vertexNormalAttribute,
+ 3,gl.FLOAT,false,24,12);
+ else if(pixel)
+ gl.vertexAttribPointer(shader.vertexWidthAttribute,
+ 1,gl.FLOAT,false,16,12);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER,materialBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER,new Int16Array(data.materials),
+ gl.STATIC_DRAW);
+ gl.vertexAttribPointer(shader.vertexMaterialAttribute,
+ 1,gl.SHORT,false,2,0);
+
+ if(shader == colorShader || shader == transparentShader) {
+ gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER,new Uint8Array(data.colors),
+ gl.STATIC_DRAW);
+ gl.vertexAttribPointer(shader.vertexColorAttribute,
+ 4,gl.UNSIGNED_BYTE,true,0,0);
+ }
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
+ indexExt ? new Uint32Array(indices) :
+ new Uint16Array(indices),gl.STATIC_DRAW);
+
+ gl.drawElements(normal ? gl.TRIANGLES : (pixel ? gl.POINTS : gl.LINES),
+ indices.length,
+ indexExt ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT,0);
+}
+
+class vertexBuffer {
+ constructor() {
+ this.clear();
+ }
+ clear() {
+ this.vertices=[];
+ this.materials=[];
+ this.colors=[];
+ this.indices=[];
+ this.nvertices=0;
+ }
+
+ // material vertex
+ vertex(v,n) {
+ this.vertices.push(v[0]);
+ this.vertices.push(v[1]);
+ this.vertices.push(v[2]);
+ this.vertices.push(n[0]);
+ this.vertices.push(n[1]);
+ this.vertices.push(n[2]);
+ this.materials.push(materialIndex);
+ return this.nvertices++;
+ }
+
+ // colored vertex
+ Vertex(v,n,c=[0,0,0,0]) {
+ this.vertices.push(v[0]);
+ this.vertices.push(v[1]);
+ this.vertices.push(v[2]);
+ this.vertices.push(n[0]);
+ this.vertices.push(n[1]);
+ this.vertices.push(n[2]);
+ this.materials.push(materialIndex);
+ this.colors.push(c[0]);
+ this.colors.push(c[1]);
+ this.colors.push(c[2]);
+ this.colors.push(c[3]);
+ return this.nvertices++;
+ }
+
+ // material vertex without normal
+ vertex1(v) {
+ this.vertices.push(v[0]);
+ this.vertices.push(v[1]);
+ this.vertices.push(v[2]);
+ this.materials.push(materialIndex);
+ return this.nvertices++;
+ }
+
+ // material vertex with width and without normal
+ vertex0(v,width) {
+ this.vertices.push(v[0]);
+ this.vertices.push(v[1]);
+ this.vertices.push(v[2]);
+ this.vertices.push(width);
+ this.materials.push(materialIndex);
+ return this.nvertices++;
+ }
+
+ // indexed colored vertex
+ iVertex(i,v,n,c=[0,0,0,0]) {
+ let i6=6*i;
+ this.vertices[i6]=v[0];
+ this.vertices[i6+1]=v[1];
+ this.vertices[i6+2]=v[2];
+ this.vertices[i6+3]=n[0];
+ this.vertices[i6+4]=n[1];
+ this.vertices[i6+5]=n[2];
+ this.materials[i]=materialIndex;
+ let i4=4*i;
+ this.colors[i4]=c[0];
+ this.colors[i4+1]=c[1];
+ this.colors[i4+2]=c[2];
+ this.colors[i4+3]=c[3];
+ this.indices.push(i);
+ }
+
+ append(data) {
+ append(this.vertices,data.vertices);
+ append(this.materials,data.materials);
+ append(this.colors,data.colors);
+ appendOffset(this.indices,data.indices,this.nvertices);
+ this.nvertices += data.nvertices;
+ }
+}
+
+let material0Data=new vertexBuffer(); // pixels
+let material1Data=new vertexBuffer(); // material Bezier curves
+let materialData=new vertexBuffer(); // material Bezier patches & triangles
+let colorData=new vertexBuffer(); // colored Bezier patches & triangles
+let transparentData=new vertexBuffer(); // transparent patches & triangles
+let triangleData=new vertexBuffer(); // opaque indexed triangles
+
+
+let materialIndex;
+
+// efficiently append array b onto array a
+function append(a,b)
+{
+ let n=a.length;
+ let m=b.length;
+ a.length += m;
+ for(let i=0; i < m; ++i)
+ a[n+i]=b[i];
+}
+
+// efficiently append array b onto array a
+function appendOffset(a,b,o)
+{
+ let n=a.length;
+ let m=b.length;
+ a.length += b.length;
+ for(let i=0; i < m; ++i)
+ a[n+i]=b[i]+o;
+}
+
+class Geometry {
+ constructor() {
+ this.data=new vertexBuffer();
+ this.Onscreen=false;
+ this.m=[];
+ }
+
+ // Is 2D bounding box formed by projecting 3d points in vector v offscreen?
+ offscreen(v) {
+ let m=projViewMat;
+ let v0=v[0];
+ let x=v0[0], y=v0[1], z=v0[2];
+ let f=1/(m[3]*x+m[7]*y+m[11]*z+m[15]);
+ this.x=this.X=(m[0]*x+m[4]*y+m[8]*z+m[12])*f;
+ this.y=this.Y=(m[1]*x+m[5]*y+m[9]*z+m[13])*f;
+ for(let i=1, n=v.length; i < n; ++i) {
+ let vi=v[i];
+ let x=vi[0], y=vi[1], z=vi[2];
+ let f=1/(m[3]*x+m[7]*y+m[11]*z+m[15]);
+ let X=(m[0]*x+m[4]*y+m[8]*z+m[12])*f;
+ let Y=(m[1]*x+m[5]*y+m[9]*z+m[13])*f;
+ if(X < this.x) this.x=X;
+ else if(X > this.X) this.X=X;
+ if(Y < this.y) this.y=Y;
+ else if(Y > this.Y) this.Y=Y;
+ }
+ let eps=1e-2;
+ let min=-1-eps;
+ let max=1+eps;
+ if(this.X < min || this.x > max || this.Y < min || this.y > max) {
+ this.Onscreen=false;
+ return true;
}
+ return false;
+ }
- setUniform(program, stringLoc, index=null) {
- var getLoc;
- if (index===null) {
- getLoc =
- param => gl.getUniformLocation(program, stringLoc + "." + param);
- } else {
- getLoc =
- param => gl.getUniformLocation(program, stringLoc + "[" + index + "]." + param);
- }
+ T(v) {
+ let c0=this.c[0];
+ let c1=this.c[1];
+ let c2=this.c[2];
+ let x=v[0]-c0;
+ let y=v[1]-c1;
+ let z=v[2]-c2;
+ return [x*normMat[0]+y*normMat[3]+z*normMat[6]+c0,
+ x*normMat[1]+y*normMat[4]+z*normMat[7]+c1,
+ x*normMat[2]+y*normMat[5]+z*normMat[8]+c2];
+ }
- gl.uniform4fv(getLoc("baseColor"), new Float32Array(this.baseColor));
- gl.uniform4fv(getLoc("emissive"), new Float32Array(this.emissive));
- gl.uniform4fv(getLoc("specular"), new Float32Array(this.specular));
+ Tcorners(m,M) {
+ return [this.T(m),this.T([m[0],m[1],M[2]]),this.T([m[0],M[1],m[2]]),
+ this.T([m[0],M[1],M[2]]),this.T([M[0],m[1],m[2]]),
+ this.T([M[0],m[1],M[2]]),this.T([M[0],M[1],m[2]]),this.T(M)];
- gl.uniform1f(getLoc("roughness"), this.roughness);
- gl.uniform1f(getLoc("metallic"), this.metallic);
- gl.uniform1f(getLoc("f0"), this.f0);
+ }
+
+ render() {
+ // First check if re-rendering is required
+ let v;
+ if(this.CenterIndex == 0)
+ v=corners(this.Min,this.Max);
+ else {
+ this.c=Centers[this.CenterIndex-1];
+ v=this.Tcorners(this.Min,this.Max);
+ }
+
+ if(this.offscreen(v)) { // Fully offscreen
+ this.data.clear();
+ return;
}
+
+ let p=this.controlpoints;
+ let P;
+
+ if(this.CenterIndex == 0) {
+ if(!remesh && this.Onscreen) {
+ // Fully onscreen; no need to re-render
+ this.append();
+ return;
+ }
+ P=p;
+ } else { // Transform billboard labels
+ let n=p.length;
+ P=Array(n);
+ for(let i=0; i < n; ++i)
+ P[i]=this.T(p[i]);
+ }
+
+ materialIndex=this.MaterialIndex;
+
+ let s=orthographic ? 1 : this.Min[2]/B[2];
+ let res=pixel*Math.hypot(s*(viewParam.xmax-viewParam.xmin),
+ s*(viewParam.ymax-viewParam.ymin))/size2;
+ this.res2=res*res;
+ this.Epsilon=FillFactor*res;
+
+ this.data.clear();
+ this.Onscreen=true;
+ this.process(P);
+ }
}
-var enumPointLight = 1;
-var enumDirectionalLight = 2;
+class BezierPatch extends Geometry {
+ /**
+ * Constructor for Bezier Patch
+ * @param {*} controlpoints array of 16 control points
+ * @param {*} CenterIndex center index of billboard labels (or 0)
+ * @param {*} MaterialIndex material index (>= 0)
+ * @param {*} Min bounding box corner
+ * @param {*} Max bounding box corner
+ * @param {*} colors array of 4 RGBA color arrays
+ */
+ constructor(controlpoints,CenterIndex,MaterialIndex,Min,Max,color) {
+ super();
+ this.controlpoints=controlpoints;
+ this.Min=Min;
+ this.Max=Max;
+ this.color=color;
+ this.CenterIndex=CenterIndex;
+ let n=controlpoints.length;
+ if(color) {
+ let sum=color[0][3]+color[1][3]+color[2][3];
+ this.transparent=(n == 16 || n == 4) ?
+ sum+color[3][3] < 1020 : sum < 765;
+ } else
+ this.transparent=Materials[MaterialIndex].diffuse[3] < 1;
+ if(this.transparent) {
+ this.MaterialIndex=color ? -1-MaterialIndex : 1+MaterialIndex;
+ this.vertex=this.data.Vertex.bind(this.data);
+ } else {
+ this.MaterialIndex=MaterialIndex;
+ this.vertex=this.data.vertex.bind(this.data);
+ }
+ this.L2norm(this.controlpoints);
+ }
-class Light {
- constructor(type, lightColor, brightness, customParam) {
- this.type = type;
- this.lightColor = lightColor;
- this.brightness = brightness;
- this.customParam = customParam;
+// Render a Bezier patch via subdivision.
+ L2norm(p) {
+ let p0=p[0];
+ this.epsilon=0;
+ let n=p.length;
+ for(let i=1; i < n; ++i)
+ this.epsilon=Math.max(this.epsilon,
+ abs2([p[i][0]-p0[0],p[i][1]-p0[1],p[i][2]-p0[2]]));
+ this.epsilon *= Fuzz4;
+ }
+
+ processTriangle(p) {
+ let p0=p[0];
+ let p1=p[1];
+ let p2=p[2];
+ let n=unit(cross([p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]],
+ [p2[0]-p0[0],p2[1]-p0[1],p2[2]-p0[2]]));
+ if(!this.offscreen([p0,p1,p2])) {
+ if(this.color) {
+ this.data.indices.push(this.data.Vertex(p0,n,this.color[0]));
+ this.data.indices.push(this.data.Vertex(p1,n,this.color[1]));
+ this.data.indices.push(this.data.Vertex(p2,n,this.color[2]));
+ } else {
+ this.data.indices.push(this.vertex(p0,n));
+ this.data.indices.push(this.vertex(p1,n));
+ this.data.indices.push(this.vertex(p2,n));
+ }
+ this.append();
}
+ }
- setUniform(program, stringLoc, index) {
- var getLoc =
- param => gl.getUniformLocation(program, stringLoc + "[" + index + "]." + param);
+ processQuad(p) {
+ let p0=p[0];
+ let p1=p[1];
+ let p2=p[2];
+ let p3=p[3];
+ let n1=cross([p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]],
+ [p2[0]-p1[0],p2[1]-p1[1],p2[2]-p1[2]]);
+ let n2=cross([p2[0]-p3[0],p2[1]-p3[1],p2[2]-p3[2]],
+ [p3[0]-p0[0],p3[1]-p0[1],p3[2]-p0[2]]);
+ let n=unit([n1[0]+n2[0],n1[1]+n2[1],n1[2]+n2[2]]);
+ if(!this.offscreen([p0,p1,p2,p3])) {
+ let i0,i1,i2,i3;
+ if(this.color) {
+ i0=this.data.Vertex(p0,n,this.color[0]);
+ i1=this.data.Vertex(p1,n,this.color[1]);
+ i2=this.data.Vertex(p2,n,this.color[2]);
+ i3=this.data.Vertex(p3,n,this.color[3]);
+ } else {
+ i0=this.vertex(p0,n);
+ i1=this.vertex(p1,n);
+ i2=this.vertex(p2,n);
+ i3=this.vertex(p3,n);
+ }
+ this.data.indices.push(i0);
+ this.data.indices.push(i1);
+ this.data.indices.push(i2);
+
+ this.data.indices.push(i0);
+ this.data.indices.push(i2);
+ this.data.indices.push(i3);
+
+ this.append();
+ }
+ }
- gl.uniform1i(getLoc("type"), this.type);
- gl.uniform3fv(getLoc("color"), new Float32Array(this.lightColor));
- gl.uniform1f(getLoc("brightness"), this.brightness);
- gl.uniform4fv(getLoc("parameter"), new Float32Array(this.customParam));
+ process(p) {
+ if(p.length == 10) return this.process3(p);
+ if(p.length == 3) return this.processTriangle(p);
+ if(p.length == 4) return this.processQuad(p);
+
+ let p0=p[0];
+ let p3=p[3];
+ let p12=p[12];
+ let p15=p[15];
+
+ let n0=this.normal(p3,p[2],p[1],p0,p[4],p[8],p12);
+ if(iszero(n0)) {
+ n0=this.normal(p3,p[2],p[1],p0,p[13],p[14],p15);
+ if(iszero(n0)) n0=this.normal(p15,p[11],p[7],p3,p[4],p[8],p12);
}
-}
-function initGL(canvas) {
- try {
- gl = canvas.getContext("webgl2");
- gl.viewportWidth = canvas.width;
- gl.viewportHeight = canvas.height;
- } catch (e) {}
- if (!gl) {
- alert("Could not initialize WebGL");
+ let n1=this.normal(p0,p[4],p[8],p12,p[13],p[14],p15);
+ if(iszero(n1)) {
+ n1=this.normal(p0,p[4],p[8],p12,p[11],p[7],p3);
+ if(iszero(n1)) n1=this.normal(p3,p[2],p[1],p0,p[13],p[14],p15);
}
-}
-function getShader(gl, id) {
- var shaderScript = document.getElementById(id);
- if (!shaderScript) {
- return null;
+ let n2=this.normal(p12,p[13],p[14],p15,p[11],p[7],p3);
+ if(iszero(n2)) {
+ n2=this.normal(p12,p[13],p[14],p15,p[2],p[1],p0);
+ if(iszero(n2)) n2=this.normal(p0,p[4],p[8],p12,p[11],p[7],p3);
}
- var str = "";
- var k = shaderScript.firstChild;
- while (k) {
- if (k.nodeType == 3) {
- str += k.textContent;
- }
- k = k.nextSibling;
+
+ let n3=this.normal(p15,p[11],p[7],p3,p[2],p[1],p0);
+ if(iszero(n3)) {
+ n3=this.normal(p15,p[11],p[7],p3,p[4],p[8],p12);
+ if(iszero(n3)) n3=this.normal(p12,p[13],p[14],p15,p[2],p[1],p0);
}
- var shader;
- if (shaderScript.type == "x-shader/x-fragment") {
- shader = gl.createShader(gl.FRAGMENT_SHADER);
- } else if (shaderScript.type == "x-shader/x-vertex") {
- shader = gl.createShader(gl.VERTEX_SHADER);
+
+ if(this.color) {
+ let c0=this.color[0];
+ let c1=this.color[1];
+ let c2=this.color[2];
+ let c3=this.color[3];
+
+ let i0=this.data.Vertex(p0,n0,c0);
+ let i1=this.data.Vertex(p12,n1,c1);
+ let i2=this.data.Vertex(p15,n2,c2);
+ let i3=this.data.Vertex(p3,n3,c3);
+
+ this.Render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false,
+ c0,c1,c2,c3);
} else {
- return null;
+ let i0=this.vertex(p0,n0);
+ let i1=this.vertex(p12,n1);
+ let i2=this.vertex(p15,n2);
+ let i3=this.vertex(p3,n3);
+
+ this.Render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false);
}
- gl.shaderSource(shader, str);
- gl.compileShader(shader);
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(gl.getShaderInfoLog(shader));
- return null;
+ if(this.data.indices.length > 0) this.append();
+ }
+
+ append() {
+ if(this.transparent)
+ transparentData.append(this.data);
+ else if(this.color)
+ colorData.append(this.data);
+ else
+ materialData.append(this.data);
+ }
+
+ Render(p,I0,I1,I2,I3,P0,P1,P2,P3,flat0,flat1,flat2,flat3,C0,C1,C2,C3) {
+ if(this.Distance(p) < this.res2) { // Bezier patch is flat
+ if(!this.offscreen([P0,P1,P2])) {
+ this.data.indices.push(I0);
+ this.data.indices.push(I1);
+ this.data.indices.push(I2);
+ }
+ if(!this.offscreen([P0,P2,P3])) {
+ this.data.indices.push(I0);
+ this.data.indices.push(I2);
+ this.data.indices.push(I3);
+ }
+ } else {
+ // Approximate bounds by bounding box of control polyhedron.
+ if(this.offscreen(p)) return;
+
+ /* Control points are indexed as follows:
+
+ Coordinate
+ +-----
+ Index
+
+
+ 03 13 23 33
+ +-----+-----+-----+
+ |3 |7 |11 |15
+ | | | |
+ |02 |12 |22 |32
+ +-----+-----+-----+
+ |2 |6 |10 |14
+ | | | |
+ |01 |11 |21 |31
+ +-----+-----+-----+
+ |1 |5 |9 |13
+ | | | |
+ |00 |10 |20 |30
+ +-----+-----+-----+
+ 0 4 8 12
+
+
+ Subdivision:
+ P refers to a corner
+ m refers to a midpoint
+ s refers to a subpatch
+
+ m2
+ +--------+--------+
+ |P3 | P2|
+ | | |
+ | s3 | s2 |
+ | | |
+ | |m4 |
+ m3+--------+--------+m1
+ | | |
+ | | |
+ | s0 | s1 |
+ | | |
+ |P0 | P1|
+ +--------+--------+
+ m0
+ */
+
+ // Subdivide patch:
+
+ let p0=p[0];
+ let p3=p[3];
+ let p12=p[12];
+ let p15=p[15];
+
+ let c0=new Split3(p0,p[1],p[2],p3);
+ let c1=new Split3(p[4],p[5],p[6],p[7]);
+ let c2=new Split3(p[8],p[9],p[10],p[11]);
+ let c3=new Split3(p12,p[13],p[14],p15);
+
+ let c4=new Split3(p0,p[4],p[8],p12);
+ let c5=new Split3(c0.m0,c1.m0,c2.m0,c3.m0);
+ let c6=new Split3(c0.m3,c1.m3,c2.m3,c3.m3);
+ let c7=new Split3(c0.m5,c1.m5,c2.m5,c3.m5);
+ let c8=new Split3(c0.m4,c1.m4,c2.m4,c3.m4);
+ let c9=new Split3(c0.m2,c1.m2,c2.m2,c3.m2);
+ let c10=new Split3(p3,p[7],p[11],p15);
+
+ let s0=[p0,c0.m0,c0.m3,c0.m5,c4.m0,c5.m0,c6.m0,c7.m0,
+ c4.m3,c5.m3,c6.m3,c7.m3,c4.m5,c5.m5,c6.m5,c7.m5];
+ let s1=[c4.m5,c5.m5,c6.m5,c7.m5,c4.m4,c5.m4,c6.m4,c7.m4,
+ c4.m2,c5.m2,c6.m2,c7.m2,p12,c3.m0,c3.m3,c3.m5];
+ let s2=[c7.m5,c8.m5,c9.m5,c10.m5,c7.m4,c8.m4,c9.m4,c10.m4,
+ c7.m2,c8.m2,c9.m2,c10.m2,c3.m5,c3.m4,c3.m2,p15];
+ let s3=[c0.m5,c0.m4,c0.m2,p3,c7.m0,c8.m0,c9.m0,c10.m0,
+ c7.m3,c8.m3,c9.m3,c10.m3,c7.m5,c8.m5,c9.m5,c10.m5];
+
+ let m4=s0[15];
+
+ let n0=this.normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]);
+ if(iszero(n0)) {
+ n0=this.normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
+ if(iszero(n0))
+ n0=this.normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]);
+ }
+
+ let n1=this.normal(s1[12],s1[13],s1[14],s1[15],s1[11],s1[7],s1[3]);
+ if(iszero(n1)) {
+ n1=this.normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]);
+ if(iszero(n1))
+ n1=this.normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]);
+ }
+
+ let n2=this.normal(s2[15],s2[11],s2[7],s2[3],s2[2],s2[1],s2[0]);
+ if(iszero(n2)) {
+ n2=this.normal(s2[15],s2[11],s2[7],s2[3],s2[4],s2[8],s2[12]);
+ if(iszero(n2))
+ n2=this.normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]);
+ }
+
+ let n3=this.normal(s3[3],s3[2],s3[1],s3[0],s3[4],s3[8],s3[12]);
+ if(iszero(n3)) {
+ n3=this.normal(s3[3],s3[2],s3[1],s3[0],s3[13],s3[14],s3[15]);
+ if(iszero(n3))
+ n3=this.normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]);
+ }
+
+ let n4=this.normal(s2[3],s2[2],s2[1],m4,s2[4],s2[8],s2[12]);
+
+ let e=this.Epsilon;
+
+ // A kludge to remove subdivision cracks, only applied the first time
+ // an edge is found to be flat before the rest of the subpatch is.
+ let m0=[0.5*(P0[0]+P1[0]),
+ 0.5*(P0[1]+P1[1]),
+ 0.5*(P0[2]+P1[2])];
+ if(!flat0) {
+ if((flat0=Straightness(p0,p[4],p[8],p12) < this.res2)) {
+ let r=unit(this.derivative(s1[0],s1[1],s1[2],s1[3]));
+ m0=[m0[0]-e*r[0],m0[1]-e*r[1],m0[2]-e*r[2]];
+ }
+ else m0=s0[12];
+ }
+
+ let m1=[0.5*(P1[0]+P2[0]),
+ 0.5*(P1[1]+P2[1]),
+ 0.5*(P1[2]+P2[2])];
+ if(!flat1) {
+ if((flat1=Straightness(p12,p[13],p[14],p15) < this.res2)) {
+ let r=unit(this.derivative(s2[12],s2[8],s2[4],s2[0]));
+ m1=[m1[0]-e*r[0],m1[1]-e*r[1],m1[2]-e*r[2]];
+ }
+ else m1=s1[15];
+ }
+
+ let m2=[0.5*(P2[0]+P3[0]),
+ 0.5*(P2[1]+P3[1]),
+ 0.5*(P2[2]+P3[2])];
+ if(!flat2) {
+ if((flat2=Straightness(p15,p[11],p[7],p3) < this.res2)) {
+ let r=unit(this.derivative(s3[15],s2[14],s2[13],s1[12]));
+ m2=[m2[0]-e*r[0],m2[1]-e*r[1],m2[2]-e*r[2]];
+ }
+ else m2=s2[3];
+ }
+
+ let m3=[0.5*(P3[0]+P0[0]),
+ 0.5*(P3[1]+P0[1]),
+ 0.5*(P3[2]+P0[2])];
+ if(!flat3) {
+ if((flat3=Straightness(p0,p[1],p[2],p3) < this.res2)) {
+ let r=unit(this.derivative(s0[3],s0[7],s0[11],s0[15]));
+ m3=[m3[0]-e*r[0],m3[1]-e*r[1],m3[2]-e*r[2]];
+ }
+ else m3=s3[0];
+ }
+
+ if(C0) {
+ let c0=Array(4);
+ let c1=Array(4);
+ let c2=Array(4);
+ let c3=Array(4);
+ let c4=Array(4);
+ for(let i=0; i < 4; ++i) {
+ c0[i]=0.5*(C0[i]+C1[i]);
+ c1[i]=0.5*(C1[i]+C2[i]);
+ c2[i]=0.5*(C2[i]+C3[i]);
+ c3[i]=0.5*(C3[i]+C0[i]);
+ c4[i]=0.5*(c0[i]+c2[i]);
+ }
+
+ let i0=this.data.Vertex(m0,n0,c0);
+ let i1=this.data.Vertex(m1,n1,c1);
+ let i2=this.data.Vertex(m2,n2,c2);
+ let i3=this.data.Vertex(m3,n3,c3);
+ let i4=this.data.Vertex(m4,n4,c4);
+
+ this.Render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3,
+ C0,c0,c4,c3);
+ this.Render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false,
+ c0,C1,c1,c4);
+ this.Render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false,
+ c4,c1,C2,c2);
+ this.Render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3,
+ c3,c4,c2,C3);
+ } else {
+ let i0=this.vertex(m0,n0);
+ let i1=this.vertex(m1,n1);
+ let i2=this.vertex(m2,n2);
+ let i3=this.vertex(m3,n3);
+ let i4=this.vertex(m4,n4);
+
+ this.Render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3);
+ this.Render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false);
+ this.Render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false);
+ this.Render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3);
+ }
}
- return shader;
-}
+ }
-function resetCamera() {
- cameraPos = vec3.fromValues(0, 0, 2);
- cameraLookAt = vec3.fromValues(0, 0, 0);
- cameraUp = vec3.fromValues(1, 0, 0);
- sceneSetup();
- redraw=true;
-}
+// Render a Bezier triangle via subdivision.
+ process3(p) {
+ this.Res2=BezierFactor*BezierFactor*this.res2;
-var shaderProgram;
+ let p0=p[0];
+ let p6=p[6];
+ let p9=p[9];
-function initShaders() {
- var fragmentShader = getShader(gl, "shader-fs");
- var vertexShader = getShader(gl, "shader-vs");
- shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialize shaders");
+ let n0=this.normal(p9,p[5],p[2],p0,p[1],p[3],p6);
+ let n1=this.normal(p0,p[1],p[3],p6,p[7],p[8],p9);
+ let n2=this.normal(p6,p[7],p[8],p9,p[5],p[2],p0);
+
+ if(this.color) {
+ let c0=this.color[0];
+ let c1=this.color[1];
+ let c2=this.color[2];
+
+ let i0=this.data.Vertex(p0,n0,c0);
+ let i1=this.data.Vertex(p6,n1,c1);
+ let i2=this.data.Vertex(p9,n2,c2);
+
+ this.Render3(p,i0,i1,i2,p0,p6,p9,false,false,false,c0,c1,c2);
+
+ } else {
+ let i0=this.vertex(p0,n0);
+ let i1=this.vertex(p6,n1);
+ let i2=this.vertex(p9,n2);
+
+ this.Render3(p,i0,i1,i2,p0,p6,p9,false,false,false);
+ }
+ if(this.data.indices.length > 0) this.append();
+ }
+
+ Render3(p,I0,I1,I2,P0,P1,P2,flat0,flat1,flat2,C0,C1,C2) {
+ if(this.Distance3(p) < this.Res2) { // Bezier triangle is flat
+ if(!this.offscreen([P0,P1,P2])) {
+ this.data.indices.push(I0);
+ this.data.indices.push(I1);
+ this.data.indices.push(I2);
+ }
+ } else {
+ // Approximate bounds by bounding box of control polyhedron.
+ if(this.offscreen(p)) return;
+
+ /* Control points are indexed as follows:
+
+ Coordinate
+ Index
+
+ 030
+ 9
+ /\
+ / \
+ / \
+ / \
+ / \
+ 021 + + 120
+ 5 / \ 8
+ / \
+ / \
+ / \
+ / \
+ 012 + + + 210
+ 2 / 111 \ 7
+ / 4 \
+ / \
+ / \
+ / \
+ /__________________________________\
+ 003 102 201 300
+ 0 1 3 6
+
+
+ Subdivision:
+ P2
+ 030
+ /\
+ / \
+ / \
+ / \
+ / \
+ / up \
+ / \
+ / \
+ p1 /________________\ p0
+ /\ / \
+ / \ / \
+ / \ / \
+ / \ center / \
+ / \ / \
+ / \ / \
+ / left \ / right \
+ / \ / \
+ /________________V_________________\
+ 003 p2 300
+ P0 P1
+ */
+
+ // Subdivide triangle:
+
+ let l003=p[0];
+ let p102=p[1];
+ let p012=p[2];
+ let p201=p[3];
+ let p111=p[4];
+ let p021=p[5];
+ let r300=p[6];
+ let p210=p[7];
+ let p120=p[8];
+ let u030=p[9];
+
+ let u021=[0.5*(u030[0]+p021[0]),
+ 0.5*(u030[1]+p021[1]),
+ 0.5*(u030[2]+p021[2])];
+ let u120=[0.5*(u030[0]+p120[0]),
+ 0.5*(u030[1]+p120[1]),
+ 0.5*(u030[2]+p120[2])];
+
+ let p033=[0.5*(p021[0]+p012[0]),
+ 0.5*(p021[1]+p012[1]),
+ 0.5*(p021[2]+p012[2])];
+ let p231=[0.5*(p120[0]+p111[0]),
+ 0.5*(p120[1]+p111[1]),
+ 0.5*(p120[2]+p111[2])];
+ let p330=[0.5*(p120[0]+p210[0]),
+ 0.5*(p120[1]+p210[1]),
+ 0.5*(p120[2]+p210[2])];
+
+ let p123=[0.5*(p012[0]+p111[0]),
+ 0.5*(p012[1]+p111[1]),
+ 0.5*(p012[2]+p111[2])];
+
+ let l012=[0.5*(p012[0]+l003[0]),
+ 0.5*(p012[1]+l003[1]),
+ 0.5*(p012[2]+l003[2])];
+ let p312=[0.5*(p111[0]+p201[0]),
+ 0.5*(p111[1]+p201[1]),
+ 0.5*(p111[2]+p201[2])];
+ let r210=[0.5*(p210[0]+r300[0]),
+ 0.5*(p210[1]+r300[1]),
+ 0.5*(p210[2]+r300[2])];
+
+ let l102=[0.5*(l003[0]+p102[0]),
+ 0.5*(l003[1]+p102[1]),
+ 0.5*(l003[2]+p102[2])];
+ let p303=[0.5*(p102[0]+p201[0]),
+ 0.5*(p102[1]+p201[1]),
+ 0.5*(p102[2]+p201[2])];
+ let r201=[0.5*(p201[0]+r300[0]),
+ 0.5*(p201[1]+r300[1]),
+ 0.5*(p201[2]+r300[2])];
+
+ let u012=[0.5*(u021[0]+p033[0]),
+ 0.5*(u021[1]+p033[1]),
+ 0.5*(u021[2]+p033[2])];
+ let u210=[0.5*(u120[0]+p330[0]),
+ 0.5*(u120[1]+p330[1]),
+ 0.5*(u120[2]+p330[2])];
+ let l021=[0.5*(p033[0]+l012[0]),
+ 0.5*(p033[1]+l012[1]),
+ 0.5*(p033[2]+l012[2])];
+ let p4xx=[0.5*p231[0]+0.25*(p111[0]+p102[0]),
+ 0.5*p231[1]+0.25*(p111[1]+p102[1]),
+ 0.5*p231[2]+0.25*(p111[2]+p102[2])];
+ let r120=[0.5*(p330[0]+r210[0]),
+ 0.5*(p330[1]+r210[1]),
+ 0.5*(p330[2]+r210[2])];
+ let px4x=[0.5*p123[0]+0.25*(p111[0]+p210[0]),
+ 0.5*p123[1]+0.25*(p111[1]+p210[1]),
+ 0.5*p123[2]+0.25*(p111[2]+p210[2])];
+ let pxx4=[0.25*(p021[0]+p111[0])+0.5*p312[0],
+ 0.25*(p021[1]+p111[1])+0.5*p312[1],
+ 0.25*(p021[2]+p111[2])+0.5*p312[2]];
+ let l201=[0.5*(l102[0]+p303[0]),
+ 0.5*(l102[1]+p303[1]),
+ 0.5*(l102[2]+p303[2])];
+ let r102=[0.5*(p303[0]+r201[0]),
+ 0.5*(p303[1]+r201[1]),
+ 0.5*(p303[2]+r201[2])];
+
+ let l210=[0.5*(px4x[0]+l201[0]),
+ 0.5*(px4x[1]+l201[1]),
+ 0.5*(px4x[2]+l201[2])]; // =c120
+ let r012=[0.5*(px4x[0]+r102[0]),
+ 0.5*(px4x[1]+r102[1]),
+ 0.5*(px4x[2]+r102[2])]; // =c021
+ let l300=[0.5*(l201[0]+r102[0]),
+ 0.5*(l201[1]+r102[1]),
+ 0.5*(l201[2]+r102[2])]; // =r003=c030
+
+ let r021=[0.5*(pxx4[0]+r120[0]),
+ 0.5*(pxx4[1]+r120[1]),
+ 0.5*(pxx4[2]+r120[2])]; // =c012
+ let u201=[0.5*(u210[0]+pxx4[0]),
+ 0.5*(u210[1]+pxx4[1]),
+ 0.5*(u210[2]+pxx4[2])]; // =c102
+ let r030=[0.5*(u210[0]+r120[0]),
+ 0.5*(u210[1]+r120[1]),
+ 0.5*(u210[2]+r120[2])]; // =u300=c003
+
+ let u102=[0.5*(u012[0]+p4xx[0]),
+ 0.5*(u012[1]+p4xx[1]),
+ 0.5*(u012[2]+p4xx[2])]; // =c201
+ let l120=[0.5*(l021[0]+p4xx[0]),
+ 0.5*(l021[1]+p4xx[1]),
+ 0.5*(l021[2]+p4xx[2])]; // =c210
+ let l030=[0.5*(u012[0]+l021[0]),
+ 0.5*(u012[1]+l021[1]),
+ 0.5*(u012[2]+l021[2])]; // =u003=c300
+
+ let l111=[0.5*(p123[0]+l102[0]),
+ 0.5*(p123[1]+l102[1]),
+ 0.5*(p123[2]+l102[2])];
+ let r111=[0.5*(p312[0]+r210[0]),
+ 0.5*(p312[1]+r210[1]),
+ 0.5*(p312[2]+r210[2])];
+ let u111=[0.5*(u021[0]+p231[0]),
+ 0.5*(u021[1]+p231[1]),
+ 0.5*(u021[2]+p231[2])];
+ let c111=[0.25*(p033[0]+p330[0]+p303[0]+p111[0]),
+ 0.25*(p033[1]+p330[1]+p303[1]+p111[1]),
+ 0.25*(p033[2]+p330[2]+p303[2]+p111[2])];
+
+ let l=[l003,l102,l012,l201,l111,l021,l300,l210,l120,l030]; // left
+ let r=[l300,r102,r012,r201,r111,r021,r300,r210,r120,r030]; // right
+ let u=[l030,u102,u012,u201,u111,u021,r030,u210,u120,u030]; // up
+ let c=[r030,u201,r021,u102,c111,r012,l030,l120,l210,l300]; // center
+
+ let n0=this.normal(l300,r012,r021,r030,u201,u102,l030);
+ let n1=this.normal(r030,u201,u102,l030,l120,l210,l300);
+ let n2=this.normal(l030,l120,l210,l300,r012,r021,r030);
+
+ let e=this.Epsilon;
+
+ // A kludge to remove subdivision cracks, only applied the first time
+ // an edge is found to be flat before the rest of the subpatch is.
+
+ let m0=[0.5*(P1[0]+P2[0]),
+ 0.5*(P1[1]+P2[1]),
+ 0.5*(P1[2]+P2[2])];
+ if(!flat0) {
+ if((flat0=Straightness(r300,p210,p120,u030) < this.res2)) {
+ let r=unit(this.sumderivative(c[0],c[2],c[5],c[9],c[1],c[3],c[6]));
+ m0=[m0[0]-e*r[0],m0[1]-e*r[1],m0[2]-e*r[2]];
+ }
+ else m0=r030;
+ }
+
+
+ let m1=[0.5*(P2[0]+P0[0]),
+ 0.5*(P2[1]+P0[1]),
+ 0.5*(P2[2]+P0[2])];
+ if(!flat1) {
+ if((flat1=Straightness(l003,p012,p021,u030) < this.res2)) {
+ let r=unit(this.sumderivative(c[6],c[3],c[1],c[0],c[7],c[8],c[9]));
+ m1=[m1[0]-e*r[0],m1[1]-e*r[1],m1[2]-e*r[2]];
+ }
+ else m1=l030;
+ }
+
+ let m2=[0.5*(P0[0]+P1[0]),
+ 0.5*(P0[1]+P1[1]),
+ 0.5*(P0[2]+P1[2])];
+ if(!flat2) {
+ if((flat2=Straightness(l003,p102,p201,r300) < this.res2)) {
+ let r=unit(this.sumderivative(c[9],c[8],c[7],c[6],c[5],c[2],c[0]));
+ m2=[m2[0]-e*r[0],m2[1]-e*r[1],m2[2]-e*r[2]];
+ }
+ else m2=l300;
+ }
+
+ if(C0) {
+ let c0=Array(4);
+ let c1=Array(4);
+ let c2=Array(4);
+ for(let i=0; i < 4; ++i) {
+ c0[i]=0.5*(C1[i]+C2[i]);
+ c1[i]=0.5*(C2[i]+C0[i]);
+ c2[i]=0.5*(C0[i]+C1[i]);
+ }
+
+ let i0=this.data.Vertex(m0,n0,c0);
+ let i1=this.data.Vertex(m1,n1,c1);
+ let i2=this.data.Vertex(m2,n2,c2);
+
+ this.Render3(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2,C0,c2,c1);
+ this.Render3(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2,c2,C1,c0);
+ this.Render3(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false,c1,c0,C2);
+ this.Render3(c,i0,i1,i2,m0,m1,m2,false,false,false,c0,c1,c2);
+ } else {
+ let i0=this.vertex(m0,n0);
+ let i1=this.vertex(m1,n1);
+ let i2=this.vertex(m2,n2);
+
+ this.Render3(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2);
+ this.Render3(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2);
+ this.Render3(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false);
+ this.Render3(c,i0,i1,i2,m0,m1,m2,false,false,false);
+ }
}
- gl.useProgram(shaderProgram);
+ }
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
- gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
- shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
- gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
+ // Check the flatness of a Bezier patch
+ Distance(p) {
+ let p0=p[0];
+ let p3=p[3];
+ let p12=p[12];
+ let p15=p[15];
- shaderProgram.vertexMaterialIndexAttribute = gl.getAttribLocation(shaderProgram, "aVertexMaterialIndex");
- gl.enableVertexAttribArray(shaderProgram.vertexMaterialIndexAttribute);
+ // Check the flatness of a patch.
+ let d=Distance2(p15,p0,this.normal(p3,p[2],p[1],p0,p[4],p[8],p12));
+
+ // Determine how straight the edges are.
+ d=Math.max(d,Straightness(p0,p[1],p[2],p3));
+ d=Math.max(d,Straightness(p0,p[4],p[8],p12));
+ d=Math.max(d,Straightness(p3,p[7],p[11],p15));
+ d=Math.max(d,Straightness(p12,p[13],p[14],p15));
+ // Determine how straight the interior control curves are.
+ d=Math.max(d,Straightness(p[4],p[5],p[6],p[7]));
+ d=Math.max(d,Straightness(p[8],p[9],p[10],p[11]));
+ d=Math.max(d,Straightness(p[1],p[5],p[9],p[13]));
+ return Math.max(d,Straightness(p[2],p[6],p[10],p[14]));
+ }
- shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
- shaderProgram.mMatrixUniform = gl.getUniformLocation(shaderProgram, "uMMatrix");
- shaderProgram.vMatrixUniform = gl.getUniformLocation(shaderProgram, "uVMatrix");
- shaderProgram.nlightsUniform = gl.getUniformLocation(shaderProgram, "unLights");
- shaderProgram.useColorUniform = gl.getUniformLocation(shaderProgram, "useColor");
+ // Check the flatness of a Bezier triangle
+ Distance3(p) {
+ let p0=p[0];
+ let p4=p[4];
+ let p6=p[6];
+ let p9=p[9];
+
+ // Check how far the internal point is from the centroid of the vertices.
+ let d=abs2([(p0[0]+p6[0]+p9[0])*third-p4[0],
+ (p0[1]+p6[1]+p9[1])*third-p4[1],
+ (p0[2]+p6[2]+p9[2])*third-p4[2]]);
+
+ // Determine how straight the edges are.
+ d=Math.max(d,Straightness(p0,p[1],p[3],p6));
+ d=Math.max(d,Straightness(p0,p[2],p[5],p9));
+ return Math.max(d,Straightness(p6,p[7],p[8],p9));
+ }
+
+ derivative(p0,p1,p2,p3) {
+ let lp=[p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]];
+ if(abs2(lp) > this.epsilon)
+ return lp;
+
+ let lpp=bezierPP(p0,p1,p2);
+ if(abs2(lpp) > this.epsilon)
+ return lpp;
+ return bezierPPP(p0,p1,p2,p3);
+ }
+
+ sumderivative(p0,p1,p2,p3,p4,p5,p6) {
+ let d0=this.derivative(p0,p1,p2,p3);
+ let d1=this.derivative(p0,p4,p5,p6);
+ return [d0[0]+d1[0],d0[1]+d1[1],d0[2]+d1[2]];
+ }
+
+ normal(left3,left2,left1,middle,right1,right2,right3) {
+ let ux=right1[0]-middle[0];
+ let uy=right1[1]-middle[1];
+ let uz=right1[2]-middle[2];
+ let vx=left1[0]-middle[0];
+ let vy=left1[1]-middle[1];
+ let vz=left1[2]-middle[2];
+ let n=[uy*vz-uz*vy,
+ uz*vx-ux*vz,
+ ux*vy-uy*vx];
+ if(abs2(n) > this.epsilon)
+ return unit(n);
+
+ let lp=[vx,vy,vz];
+ let rp=[ux,uy,uz];
+ let lpp=bezierPP(middle,left1,left2);
+ let rpp=bezierPP(middle,right1,right2);
+ let a=cross(rpp,lp);
+ let b=cross(rp,lpp);
+ n=[a[0]+b[0],
+ a[1]+b[1],
+ a[2]+b[2]];
+ if(abs2(n) > this.epsilon)
+ return unit(n);
+
+ let lppp=bezierPPP(middle,left1,left2,left3);
+ let rppp=bezierPPP(middle,right1,right2,right3);
+ a=cross(rpp,lpp);
+ b=cross(rp,lppp);
+ let c=cross(rppp,lp);
+ let d=cross(rppp,lpp);
+ let e=cross(rpp,lppp);
+ let f=cross(rppp,lppp);
+ return unit([9*a[0]+3*(b[0]+c[0]+d[0]+e[0])+f[0],
+ 9*a[1]+3*(b[1]+c[1]+d[1]+e[1])+f[1],
+ 9*a[2]+3*(b[2]+c[2]+d[2]+e[2])+f[2]]);
+ }
}
+class BezierCurve extends Geometry {
+ constructor(controlpoints,CenterIndex,MaterialIndex,Min,Max) {
+ super();
+ this.controlpoints=controlpoints;
+ this.Min=Min;
+ this.Max=Max;
+ this.CenterIndex=CenterIndex;
+ this.MaterialIndex=MaterialIndex;
+ }
-// math aux functions
-function degToRad(degrees) {
- return degrees * Math.PI / 180;
-}
-function unit(v) {
- var norm = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
- norm = (norm != 0) ? 1 / norm : 1;
- return [v[0] * norm, v[1] * norm, v[2] * norm];
-}
+ processLine(p) {
+ let p0=p[0];
+ let p1=p[1];
+ if(!this.offscreen([p0,p1])) {
+ this.data.indices.push(this.data.vertex1(p0));
+ this.data.indices.push(this.data.vertex1(p1));
+ this.append();
+ }
+ }
-function abs2(v) {
-return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
+ process(p) {
+ if(p.length == 2) return this.processLine(p);
+
+ let i0=this.data.vertex1(p[0]);
+ let i3=this.data.vertex1(p[3]);
+
+ this.Render(p,i0,i3);
+ if(this.data.indices.length > 0) this.append();
+ }
+
+ append() {
+ material1Data.append(this.data);
+ }
+
+ Render(p,I0,I1) {
+ let p0=p[0];
+ let p1=p[1];
+ let p2=p[2];
+ let p3=p[3];
+
+ if(Straightness(p0,p1,p2,p3) < this.res2) { // Segment is flat
+ if(!this.offscreen([p0,p3])) {
+ this.data.indices.push(I0);
+ this.data.indices.push(I1);
+ }
+ } else { // Segment is not flat
+ if(this.offscreen(p)) return;
+
+ let m0=[0.5*(p0[0]+p1[0]),0.5*(p0[1]+p1[1]),0.5*(p0[2]+p1[2])];
+ let m1=[0.5*(p1[0]+p2[0]),0.5*(p1[1]+p2[1]),0.5*(p1[2]+p2[2])];
+ let m2=[0.5*(p2[0]+p3[0]),0.5*(p2[1]+p3[1]),0.5*(p2[2]+p3[2])];
+ let m3=[0.5*(m0[0]+m1[0]),0.5*(m0[1]+m1[1]),0.5*(m0[2]+m1[2])];
+ let m4=[0.5*(m1[0]+m2[0]),0.5*(m1[1]+m2[1]),0.5*(m1[2]+m2[2])];
+ let m5=[0.5*(m3[0]+m4[0]),0.5*(m3[1]+m4[1]),0.5*(m3[2]+m4[2])];
+
+ let s0=[p0,m0,m3,m5];
+ let s1=[m5,m4,m2,p3];
+
+ let i0=this.data.vertex1(m5);
+
+ this.Render(s0,I0,i0);
+ this.Render(s1,i0,I1);
+ }
+ }
}
-function dot(u, v) {
-return u[0] * v[0] + u[1] * v[1] + u[2] * v[2];
+class Pixel extends Geometry {
+ constructor(controlpoint,width,MaterialIndex,Min,Max) {
+ super();
+ this.controlpoint=controlpoint;
+ this.width=width;
+ this.CenterIndex=0;
+ this.MaterialIndex=MaterialIndex;
+ this.Min=Min;
+ this.Max=Max;
+ }
+
+ process(p) {
+ this.data.indices.push(this.data.vertex0(this.controlpoint,this.width));
+ this.append();
+ }
+
+ append() {
+ material0Data.append(this.data);
+ }
}
-function cross(u, v) {
-return [u[1] * v[2] - u[2] * v[1],
- u[2] * v[0] - u[0] * v[2],
- u[0] * v[1] - u[1] * v[0]
-];
+class Triangles extends Geometry {
+ constructor(MaterialIndex,Min,Max) {
+ super();
+ this.CenterIndex=0;
+ this.MaterialIndex=MaterialIndex;
+ this.Min=Min;
+ this.Max=Max;
+ this.Positions=Positions;
+ this.Normals=Normals;
+ this.Colors=Colors;
+ this.Indices=Indices;
+ Positions=[];
+ Normals=[];
+ Colors=[];
+ Indices=[];
+ this.transparent=Materials[MaterialIndex].diffuse[3] < 1;
+ }
+
+ process(p) {
+ for(let i=0, n=this.Indices.length; i < n; ++i) {
+ let index=this.Indices[i];
+ let PI=index[0];
+ let P0=this.Positions[PI[0]];
+ let P1=this.Positions[PI[1]];
+ let P2=this.Positions[PI[2]];
+ if(!this.offscreen([P0,P1,P2])) {
+ let NI=index.length > 1 ? index[1] : PI;
+ if(!NI || NI.length == 0) NI=PI;
+ if(this.Colors.length > 0) {
+ let CI=index.length > 2 ? index[2] : PI;
+ if(!CI || CI.length == 0) CI=PI;
+ let C0=this.Colors[CI[0]];
+ let C1=this.Colors[CI[1]];
+ let C2=this.Colors[CI[2]];
+ this.transparent |= C0[3]+C1[3]+C2[3] < 765;
+ materialIndex=-1-this.MaterialIndex;
+ this.data.iVertex(PI[0],P0,this.Normals[NI[0]],C0);
+ this.data.iVertex(PI[1],P1,this.Normals[NI[1]],C1);
+ this.data.iVertex(PI[2],P2,this.Normals[NI[2]],C2);
+ } else {
+ materialIndex=1+this.MaterialIndex;
+ this.data.iVertex(PI[0],P0,this.Normals[NI[0]]);
+ this.data.iVertex(PI[1],P1,this.Normals[NI[1]]);
+ this.data.iVertex(PI[2],P2,this.Normals[NI[2]]);
+ }
+ }
+ }
+ this.data.nvertices=this.Positions.length;
+ if(this.data.indices.length > 0) this.append();
+ }
+
+ append() {
+ if(this.transparent)
+ transparentData.append(this.data);
+ else
+ triangleData.append(this.data);
+ }
}
-// return the perpendicular distance squared of a point z from the plane
-// through u with unit normal n.
-function Distance2(z, u, n) {
- var d = dot([z[0] - u[0], z[1] - u[1], z[2] - u[2]], n);
- return d * d;
+
+function home()
+{
+ mat4.identity(rotMat);
+ initProjection();
+ setProjection();
+ redraw=true;
}
-var vMatrix = mat4.create();
-var mMatrix = mat4.create();
-var pMatrix = mat4.create();
+function initShader(options=[])
+{
+ let fragmentShader=getShader(gl,"fragment",options);
+ let vertexShader=getShader(gl,"vertex",options);
+ let shader=gl.createProgram();
+
+ gl.attachShader(shader,vertexShader);
+ gl.attachShader(shader,fragmentShader);
+ gl.linkProgram(shader);
+ if (!gl.getProgramParameter(shader,gl.LINK_STATUS)) {
+ alert("Could not initialize shaders");
+ }
-var headlamp = new Light(
- type = enumDirectionalLight,
- lightColor = [1, 0.87, 0.745],
- brightness = 1,
- customParam = [0, 0, 1, 0]
-);
+ return shader;
+}
-function setUniforms() {
- gl.uniformMatrix4fv(shaderProgram.vMatrixUniform, false, vMatrix);
- gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
- gl.uniformMatrix4fv(shaderProgram.mMatrixUniform, false, mMatrix);
+class Split3 {
+ constructor(z0,c0,c1,z1) {
+ this.m0=[0.5*(z0[0]+c0[0]),0.5*(z0[1]+c0[1]),0.5*(z0[2]+c0[2])];
+ let m1_0=0.5*(c0[0]+c1[0]);
+ let m1_1=0.5*(c0[1]+c1[1]);
+ let m1_2=0.5*(c0[2]+c1[2]);
+ this.m2=[0.5*(c1[0]+z1[0]),0.5*(c1[1]+z1[1]),0.5*(c1[2]+z1[2])];
+ this.m3=[0.5*(this.m0[0]+m1_0),0.5*(this.m0[1]+m1_1),
+ 0.5*(this.m0[2]+m1_2)];
+ this.m4=[0.5*(m1_0+this.m2[0]),0.5*(m1_1+this.m2[1]),
+ 0.5*(m1_2+this.m2[2])];
+ this.m5=[0.5*(this.m3[0]+this.m4[0]),0.5*(this.m3[1]+this.m4[1]),
+ 0.5*(this.m3[2]+this.m4[2])];
+ }
+}
- objMaterial.setUniform(shaderProgram, "objMaterial", 0);
+function iszero(v)
+{
+ return v[0] == 0 && v[1] == 0 && v[2] == 0;
+}
- // for now, if we simulate headlamp. Can also specify custom lights later on...
- headlamp.setUniform(shaderProgram, "objLights", 0);
- gl.uniform1i(shaderProgram.nlightsUniform, 1);
- gl.uniform1i(shaderProgram.useColorUniform, 0);
+function unit(v)
+{
+ let norm=1/(Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]) || 1);
+ return [v[0]*norm,v[1]*norm,v[2]*norm];
+}
+function abs2(v)
+{
+ return v[0]*v[0]+v[1]*v[1]+v[2]*v[2];
}
-var VertexBuffer;
-var ColorBuffer;
-var NormalBuffer;
+function dot(u,v)
+{
+ return u[0]*v[0]+u[1]*v[1]+u[2]*v[2];
+}
-// base buffer arrays
-var vertices = new Array();
-var colors = new Array();
-var normals = new Array();
-var indices = new Array();
-var materials = new Array();
+function cross(u,v)
+{
+ return [u[1]*v[2]-u[2]*v[1],
+ u[2]*v[0]-u[0]*v[2],
+ u[0]*v[1]-u[1]*v[0]];
+}
-// no. of verts.
-var nvertices = 0;
+// Return one-sixth of the second derivative of the Bezier curve defined
+// by a,b,c,d at 0.
+function bezierPP(a,b,c)
+{
+ return [a[0]+c[0]-2*b[0],
+ a[1]+c[1]-2*b[1],
+ a[2]+c[2]-2*b[2]];
+}
-var mMatrixStack = [];
-var pMatrix = mat4.create();
-var viewMatrix = mat4.create();
-var localRotation = mat4.create();
+// Return one-third of the third derivative of the Bezier curve defined by
+// a,b,c,d at 0.
+function bezierPPP(a,b,c,d)
+{
+ return [d[0]-a[0]+3*(b[0]-c[0]),
+ d[1]-a[1]+3*(b[1]-c[1]),
+ d[2]-a[2]+3*(b[2]-c[2])];
+}
-function mvPushMatrix() {
- var copy = mat4.create();
- mat4.set(mMatrix, copy);
- mMatrixStack.push(copy);
+/**
+ * Return the maximum distance squared of points c0 and c1 from
+ * the respective internal control points of z0--z1.
+*/
+function Straightness(z0,c0,c1,z1)
+{
+ let v=[third*(z1[0]-z0[0]),third*(z1[1]-z0[1]),third*(z1[2]-z0[2])];
+ return Math.max(abs2([c0[0]-v[0]-z0[0],c0[1]-v[1]-z0[1],c0[2]-v[2]-z0[2]]),
+ abs2([z1[0]-v[0]-c1[0],z1[1]-v[1]-c1[1],z1[2]-v[2]-c1[2]]));
}
-function mvPopMatrix() {
- if (mMatrixStack.length == 0) {
- throw "Invalid popMatrix!";
- }
- mMatrix = mMatrixStack.pop();
+/**
+ * Return the perpendicular distance squared of a point z from the plane
+ * through u with unit normal n.
+ */
+function Distance2(z,u,n)
+{
+ let d=dot([z[0]-u[0],z[1]-u[1],z[2]-u[2]],n);
+ return d*d;
}
-var redraw = true;
-var mouseDownOrTouchActive = false;
-var lastMouseX = null;
-var lastMouseY = null;
-var touchID = null;
+// Return the vertices of the box containing 3d points m and M.
+function corners(m,M)
+{
+ return [m,[m[0],m[1],M[2]],[m[0],M[1],m[2]],[m[0],M[1],M[2]],
+ [M[0],m[1],m[2]],[M[0],m[1],M[2]],[M[0],M[1],m[2]],M];
+}
+/**
+ * Perform a change of basis
+ * @param {*} out Out Matrix
+ * @param {*} mat Matrix
+ *
+ * Compute the matrix (translMatrix) * mat * (translMatrix)^{-1}
+ */
+
+function COBTarget(out,mat)
+{
+ mat4.fromTranslation(translMat,[center.x,center.y,center.z])
+ mat4.invert(cjMatInv,translMat);
+ mat4.multiply(out,mat,cjMatInv);
+ mat4.multiply(out,translMat,out);
+}
-var center = [0, 0, 1];
-var centerInv = [0, 0, -1];
+function setUniforms(shader)
+{
+ let pixel=shader == pixelShader;
-var rotationMatLocal = mat4.create();
-var rotationMatrix = mat4.create();
-mat4.identity(rotationMatrix);
+ gl.useProgram(shader);
-function handleMouseDown(event) {
- mouseDownOrTouchActive = true;
- lastMouseX = event.clientX;
- lastMouseY = event.clientY;
-}
+ shader.vertexPositionAttribute=
+ gl.getAttribLocation(shader,"position");
+ gl.enableVertexAttribArray(shader.vertexPositionAttribute);
-function handleTouchStart(evt) {
- evt.preventDefault();
- var touches = evt.targetTouches;
+ if(pixel) {
+ shader.vertexWidthAttribute=
+ gl.getAttribLocation(shader,"width");
+ gl.enableVertexAttribArray(shader.vertexWidthAttribute);
+ }
- if (touches.length == 1 && !mouseDownOrTouchActive) {
- touchId = touches[0].identifier;
- lastMouseX = touches[0].pageX,
- lastMouseY = touches[0].pageY;
+ if(shader != noNormalShader && !pixel) {
+ shader.vertexNormalAttribute=
+ gl.getAttribLocation(shader,"normal");
+ gl.enableVertexAttribArray(shader.vertexNormalAttribute);
}
-}
-function handleMouseUpOrTouchEnd(event) {
- mouseDownOrTouchActive = false;
-}
+ shader.vertexMaterialAttribute=
+ gl.getAttribLocation(shader,"materialIndex");
+ gl.enableVertexAttribArray(shader.vertexMaterialAttribute);
-function processDrag(newX, newY, pan = false) {
- let lastX = (lastMouseX - 400) / 400;
- let lastY = (lastMouseY - 400) / 400;
+ shader.projViewMatUniform=gl.getUniformLocation(shader,"projViewMat");
+ shader.viewMatUniform=gl.getUniformLocation(shader,"viewMat");
+ shader.normMatUniform=gl.getUniformLocation(shader,"normMat");
- let rawX = (newX - 400) / 400;
- let rawY = (newY - 400) / 400;
+ if(shader == colorShader || shader == transparentShader) {
+ shader.vertexColorAttribute=
+ gl.getAttribLocation(shader,"color");
+ gl.enableVertexAttribArray(shader.vertexColorAttribute);
+ }
- let viewmatInv = mat4.create();
- mat4.invert(viewmatInv, vMatrix);
+ for(let i=0; i < Materials.length; ++i)
+ Materials[i].setUniform(shader,"Materials",i);
- let tmpCameraOffset = vec3.create();
- vec3.subtract(tmpCameraOffset, cameraPos, cameraLookAt);
+ for(let i=0; i < Lights.length; ++i)
+ Lights[i].setUniform(shader,"Lights",i);
- if (!pan) {
- let [angle, axis] = arcballLib.arcball([lastX, -lastY], [rawX, -rawY]);
+ gl.uniformMatrix4fv(shader.projViewMatUniform,false,projViewMat);
+ gl.uniformMatrix4fv(shader.viewMatUniform,false,viewMat);
+ gl.uniformMatrix3fv(shader.normMatUniform,false,normMat);
+}
- if (angle == NaN || axis == NaN) {
- console.error("Angle or axis NaN!");
- return;
- }
+function handleMouseDown(event)
+{
+ mouseDownOrTouchActive=true;
+ lastMouseX=event.clientX;
+ lastMouseY=event.clientY;
+}
- let depthVec = vec3.clone(cameraLookAt);
- vec3.transformMat4(depthVec, depthVec, vMatrix);
- //vec3.transformMat4(depthVec, depthVec, pMatrix);
- vec3.add(axis, axis, depthVec);
+let pinch=false;
+let pinchStart;
- // let projMatInv=mat4.create();
- // mat4.invert(projMatInv, pMatrix);
+function pinchDistance(touches)
+{
+ return Math.hypot(
+ touches[0].pageX-touches[1].pageX,
+ touches[0].pageY-touches[1].pageY);
+}
- //vec3.transformMat4(axis,axis,projMatInv);
- vec3.transformMat4(axis, axis, viewmatInv);
- let tmpRotMat = mat4.create();
+let touchStartTime;
- mat4.fromRotation(tmpRotMat, -angle, axis);
+function handleTouchStart(evt)
+{
+ evt.preventDefault();
+ let touches=evt.targetTouches;
+ swipe=rotate=pinch=false;
+ if(zooming) return;
+
+ if(touches.length == 1 && !mouseDownOrTouchActive) {
+ touchStartTime=new Date().getTime();
+ touchId=touches[0].identifier;
+ lastMouseX=touches[0].pageX,
+ lastMouseY=touches[0].pageY;
+ }
+
+ if(touches.length == 2 && !mouseDownOrTouchActive) {
+ touchId=touches[0].identifier;
+ pinchStart=pinchDistance(touches);
+ pinch=true;
+ }
+}
- vec3.transformMat4(tmpCameraOffset, tmpCameraOffset, tmpRotMat);
- vec3.transformMat4(cameraUp, cameraUp, tmpRotMat);
+function handleMouseUpOrTouchEnd(event)
+{
+ mouseDownOrTouchActive=false;
+}
+
+function rotateScene(lastX,lastY,rawX,rawY,factor)
+{
+ if(lastX == rawX && lastY == rawY) return;
+ let [angle,axis]=arcball([lastX,-lastY],[rawX,-rawY]);
- vec3.add(cameraPos, tmpCameraOffset, cameraLookAt);
+ mat4.fromRotation(rotMats,2*factor*ArcballFactor*angle/lastzoom,axis);
+ mat4.multiply(rotMat,rotMats,rotMat);
+}
+function shiftScene(lastX,lastY,rawX,rawY)
+{
+ let zoominv=1/lastzoom;
+ shift.x += (rawX-lastX)*zoominv*halfCanvasWidth;
+ shift.y -= (rawY-lastY)*zoominv*halfCanvasHeight;
+}
+function panScene(lastX,lastY,rawX,rawY)
+{
+ if (orthographic) {
+ shiftScene(lastX,lastY,rawX,rawY);
} else {
- let xTransl = (rawX - lastX);
- let yTransl = (rawY - lastY);
- let normCameraUp = vec3.create();
- vec3.normalize(normCameraUp, cameraUp);
- vec3.scale(normCameraUp, normCameraUp, yTransl);
+ center.x += (rawX-lastX)*(viewParam.xmax-viewParam.xmin);
+ center.y -= (rawY-lastY)*(viewParam.ymax-viewParam.ymin);
+ }
+}
- let normCameraLeft = vec3.create();
- vec3.cross(normCameraLeft, tmpCameraOffset, cameraUp);
- vec3.normalize(normCameraLeft, normCameraLeft);
- vec3.scale(normCameraLeft, normCameraLeft, xTransl);
+function updateViewMatrix()
+{
+ COBTarget(viewMat,rotMat);
+ mat4.translate(viewMat,viewMat,[center.x,center.y,0]);
+ mat3.fromMat4(viewMat3,viewMat);
+ mat3.invert(normMat,viewMat3);
+ mat4.multiply(projViewMat,projMat,viewMat);
+}
+
+function capzoom()
+{
+ let maxzoom=Math.sqrt(Number.MAX_VALUE);
+ let minzoom=1/maxzoom;
+ if(Zoom <= minzoom) Zoom=minzoom;
+ if(Zoom >= maxzoom) Zoom=maxzoom;
+
+ if(Zoom != lastzoom) remesh=true;
+ lastzoom=Zoom;
+}
- let cameraShift = vec3.create();
- vec3.add(cameraShift, normCameraUp, normCameraLeft);
+function zoomImage(diff)
+{
+ let stepPower=zoomStep*halfCanvasHeight*diff;
+ const limit=Math.log(0.1*Number.MAX_VALUE)/Math.log(zoomFactor);
- vec3.add(cameraLookAt, cameraLookAt, cameraShift);
- vec3.add(cameraPos, cameraPos, cameraShift);
+ if(Math.abs(stepPower) < limit) {
+ Zoom *= zoomFactor**stepPower;
+ capzoom();
}
+}
- lastMouseX = newX;
- lastMouseY = newY;
- redraw = true;
+function normMouse(v)
+{
+ let v0=v[0];
+ let v1=v[1];
+ let norm=Math.hypot(v0,v1);
+ if(norm > 1) {
+ denom=1/norm;
+ v0 *= denom;
+ v1 *= denom;
+ }
+ return [v0,v1,Math.sqrt(Math.max(1-v1*v1-v0*v0,0))];
}
-function handleKey(key) {
- var keycode = key.key;
- var rotate = true;
- var axis = [0, 0, 1];
- switch (keycode) {
- case "w":
- axis = [-1, 0, 0];
- break;
- case "d":
- axis = [0, 1, 0];
+function arcball(oldmouse,newmouse)
+{
+ let oldMouse=normMouse(oldmouse);
+ let newMouse=normMouse(newmouse);
+ let Dot=dot(oldMouse,newMouse);
+ if(Dot > 1) Dot=1;
+ else if(Dot < -1) Dot=-1;
+ return [Math.acos(Dot),unit(cross(oldMouse,newMouse))]
+}
+
+/**
+ * Mouse Drag Zoom
+ * @param {*} lastX unused
+ * @param {*} lastY
+ * @param {*} rawX unused
+ * @param {*} rawY
+ */
+function zoomScene(lastX,lastY,rawX,rawY)
+{
+ zoomImage(lastY-rawY);
+}
+
+// mode:
+const DRAGMODE_ROTATE=1;
+const DRAGMODE_SHIFT=2;
+const DRAGMODE_ZOOM=3;
+const DRAGMODE_PAN=4
+function processDrag(newX,newY,mode,factor=1)
+{
+ let dragFunc;
+ switch (mode) {
+ case DRAGMODE_ROTATE:
+ dragFunc=rotateScene;
break;
- case "a":
- axis = [0, -1, 0];
+ case DRAGMODE_SHIFT:
+ dragFunc=shiftScene;
break;
- case "s":
- axis = [1, 0, 0];
+ case DRAGMODE_ZOOM:
+ dragFunc=zoomScene;
break;
- case "h":
- resetCamera();
+ case DRAGMODE_PAN:
+ dragFunc=panScene;
break;
default:
- rotate = false;
+ dragFunc=(_a,_b,_c,_d) => {};
break;
}
- if (rotate) {
- mat4.rotate(rotationMatrix, rotationMatrix, 0.1, axis);
- redraw = true;
- }
-
-}
-
-function handleMouseWheel(event) {
- let zoomFactor = event.deltaY / 50;
-
- // console.log(zoomFactor);
+ let lastX=(lastMouseX-halfCanvasWidth)/halfCanvasWidth;
+ let lastY=(lastMouseY-halfCanvasHeight)/halfCanvasHeight;
+ let rawX=(newX-halfCanvasWidth)/halfCanvasWidth;
+ let rawY=(newY-halfCanvasHeight)/halfCanvasHeight;
- let cameraShift = vec3.create();
- vec3.subtract(cameraShift, cameraPos, cameraLookAt);
+ dragFunc(lastX,lastY,rawX,rawY,factor);
- let cameraDir = vec3.create();
- vec3.normalize(cameraDir, cameraShift);
- vec3.scale(cameraDir, cameraDir, zoomFactor);
+ lastMouseX=newX;
+ lastMouseY=newY;
- let newCameraShift = vec3.create();
- vec3.add(newCameraShift, cameraShift, cameraDir);
-
- // not go beyond the bounds
- if (vec3.length(newCameraShift) < 0.01 && zoomFactor < 0) {
+ setProjection();
+ redraw=true;
+}
- } else if (vec3.length(newCameraShift) > 100 && zoomFactor > 0) {
+function handleKey(event)
+{
+ let keycode=event.key;
+ let axis=[];
+ switch(keycode) {
+ case 'x':
+ axis=[1,0,0];
+ break;
+ case 'y':
+ axis=[0,1,0];
+ break;
+ case 'z':
+ axis=[0,0,1];
+ break;
+ case 'h':
+ home();
+ break;
+ case '+':
+ case '=':
+ case '>':
+ expand();
+ break;
+ case '-':
+ case '_':
+ case '<':
+ shrink();
+ break;
+ default:
+ break;
+ }
- } else if (vec3.dot(newCameraShift, cameraShift) >= 0) {
- cameraShift = vec3.clone(newCameraShift);
+ if(axis.length > 0) {
+ mat4.rotate(rotMat,rotMat,0.1,axis);
+ updateViewMatrix();
+ redraw=true;
}
+}
- vec3.add(cameraPos, cameraShift, cameraLookAt);
+function handleMouseWheel(event)
+{
+ if (event.deltaY < 0) {
+ Zoom *= zoomFactor;
+ } else {
+ Zoom /= zoomFactor;
+ }
+ capzoom();
+ setProjection();
- res = 1 / (vec3.length(cameraShift) + 0.001) * 0.001;
- redraw = true;
+ redraw=true;
}
-function handleMouseMove(event) {
- if (!mouseDownOrTouchActive) {
+function handleMouseMove(event)
+{
+ if(!mouseDownOrTouchActive) {
return;
}
- var newX = event.clientX;
- var newY = event.clientY;
+ let newX=event.clientX;
+ let newY=event.clientY;
+
+ let mode;
+ if(event.getModifierState("Control")) {
+ mode=DRAGMODE_SHIFT;
+ } else if(event.getModifierState("Shift")) {
+ mode=DRAGMODE_ZOOM;
+ } else if(event.getModifierState("Alt")) {
+ mode=DRAGMODE_PAN;
+ } else {
+ mode=DRAGMODE_ROTATE;
+ }
- processDrag(newX, newY, event.getModifierState("Alt"));
+ processDrag(newX,newY,mode);
}
-function handleTouchMove(evt) {
+let zooming=false;
+let swipe=false;
+let rotate=false;
+
+function handleTouchMove(evt)
+{
evt.preventDefault();
- var touches = evt.targetTouches;
+ if(zooming) return;
+ let touches=evt.targetTouches;
+
+ if(!pinch && touches.length == 1 && touchId == touches[0].identifier) {
+ let newX=touches[0].pageX;
+ let newY=touches[0].pageY;
+ let dx=newX-lastMouseX;
+ let dy=newY-lastMouseY;
+ let stationary=dx*dx+dy*dy <= shiftHoldDistance*shiftHoldDistance;
+ if(stationary) {
+ if(!swipe && !rotate &&
+ new Date().getTime()-touchStartTime > shiftWaitTime) {
+ if(navigator.vibrate)
+ window.navigator.vibrate(vibrateTime);
+ swipe=true;
+ }
+ }
+ if(swipe)
+ processDrag(newX,newY,DRAGMODE_SHIFT);
+ else if(!stationary) {
+ rotate=true;
+ let newX=touches[0].pageX;
+ let newY=touches[0].pageY;
+ processDrag(newX,newY,DRAGMODE_ROTATE,0.5);
+ }
+ }
- if (touches.length == 1 && touchId == touches[0].identifier) {
- var newX = touches[0].pageX;
- var newY = touches[0].pageY;
- processDrag(newX, newY);
+ if(pinch && !swipe &&
+ touches.length == 2 && touchId == touches[0].identifier) {
+ let distance=pinchDistance(touches);
+ let diff=distance-pinchStart;
+ zooming=true;
+ diff *= zoomPinchFactor;
+ if(diff > zoomPinchCap) diff=zoomPinchCap;
+ if(diff < -zoomPinchCap) diff=-zoomPinchCap;
+ zoomImage(diff/size2);
+ pinchStart=distance;
+ swipe=rotate=zooming=false;
+ setProjection();
+ redraw=true;
}
}
-// Prepare canvas for drawing
-function sceneSetup() {
- gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- mat4.perspective(pMatrix, 45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);
+let indexExt;
- mat4.lookAt(vMatrix, cameraPos, cameraLookAt, cameraUp);
- mat4.identity(mMatrix);
+// Create buffers for the patch and its subdivisions.
+function setBuffer()
+{
+ positionBuffer=gl.createBuffer();
+ materialBuffer=gl.createBuffer();
+ colorBuffer=gl.createBuffer();
+ indexBuffer=gl.createBuffer();
+ indexExt=gl.getExtension("OES_element_index_uint");
}
-var indexExt;
+let zbuffer=[];
+
+function transformVertices(vertices)
+{
+ let Tz0=viewMat[2];
+ let Tz1=viewMat[6];
+ let Tz2=viewMat[10];
+ zbuffer.length=vertices.length;
+ for(let i=0; i < vertices.length; ++i) {
+ let i6=6*i;
+ zbuffer[i]=Tz0*vertices[i6]+Tz1*vertices[i6+1]+Tz2*vertices[i6+2];
+ }
+}
-// Create buffer data for the patch and its subdivisions to be pushed to the graphics card
-//Takes as an argument the array of vertices that define the patch to be drawn
-// Using the vertex position buffer of the above function,draw patch.
-function setBuffer() {
- VertexBuffer = gl.createBuffer();
- VertexBuffer.itemSize = 3;
+function draw()
+{
+ gl.clearColor(1,1,1,1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- ColorBuffer = gl.createBuffer();
- ColorBuffer.itemSize = 4;
+ material0Data.clear();
+ material1Data.clear();
+ materialData.clear();
+ colorData.clear();
+ triangleData.clear();
+ transparentData.clear();
+
+ P.forEach(function(p) {
+ p.render();
+ });
+
+ drawBuffer(material0Data,pixelShader);
+ drawBuffer(material1Data,noNormalShader);
+ drawBuffer(materialData,materialShader);
+ drawBuffer(colorData,colorShader);
+ drawBuffer(triangleData,transparentShader);
+
+ let indices=transparentData.indices;
+ if(indices.length > 0) {
+ transformVertices(transparentData.vertices);
+
+ let n=indices.length/3;
+ let triangles=Array(n).fill().map((_,i)=>i);
+
+ triangles.sort(function(a,b) {
+ let a3=3*a;
+ Ia=indices[a3];
+ Ib=indices[a3+1];
+ Ic=indices[a3+2];
+
+ let b3=3*b;
+ IA=indices[b3];
+ IB=indices[b3+1];
+ IC=indices[b3+2];
+
+ return zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic] <
+ zbuffer[IA]+zbuffer[IB]+zbuffer[IC] ? -1 : 1;
+ });
+
+ let Indices=Array(indices.length);
+
+ for(let i=0; i < n; ++i) {
+ let i3=3*i;
+ let t=3*triangles[i];
+ Indices[3*i]=indices[t];
+ Indices[3*i+1]=indices[t+1];
+ Indices[3*i+2]=indices[t+2];
+ }
- NormalBuffer = gl.createBuffer();
- NormalBuffer.itemSize = 3;
+ gl.depthMask(false); // Enable transparency
+ drawBuffer(transparentData,transparentShader,Indices);
+ gl.depthMask(true); // Disable transparency
+ }
- MaterialIndexBuffer = gl.createBuffer();
- MaterialIndexBuffer.itemSize = 1;
+ remesh=false;
+}
- indexBuffer = gl.createBuffer();
- indexBuffer.itemSize = 1;
+function tick()
+{
+ requestAnimationFrame(tick);
+ if(redraw) {
+ draw();
+ redraw=false;
+ }
+}
- setUniforms();
- indexExt = gl.getExtension("OES_element_index_uint");
+function setDimensions(width,height,X,Y)
+{
+ let Aspect=width/height;
+ let zoominv=1/lastzoom;
+ let xshift=X/width*lastzoom
+ let yshift=Y/height*lastzoom
+
+ if (orthographic) {
+ let xsize=B[0]-b[0];
+ let ysize=B[1]-b[1];
+ if (xsize < ysize*Aspect) {
+ let r=0.5*ysize*Aspect*zoominv;
+ let X0=2*r*xshift;
+ let Y0=ysize*zoominv*yshift;
+ viewParam.xmin=-r-X0;
+ viewParam.xmax=r-X0;
+ viewParam.ymin=b[1]*zoominv-Y0;
+ viewParam.ymax=B[1]*zoominv-Y0;
+ } else {
+ let r=0.5*xsize/(Aspect*Zoom);
+ let X0=xsize*zoominv*xshift;
+ let Y0=2*r*yshift;
+ viewParam.xmin=b[0]*zoominv-X0;
+ viewParam.xmax=B[0]*zoominv-X0;
+ viewParam.ymin=-r-Y0;
+ viewParam.ymax=r-Y0;
+ }
+ } else {
+ let r=H*zoominv;
+ let rAspect=r*Aspect;
+ let X0=2*rAspect*xshift;
+ let Y0=2*r*yshift;
+ viewParam.xmin=-rAspect-X0;
+ viewParam.xmax=rAspect-X0;
+ viewParam.ymin=-r-Y0;
+ viewParam.ymax=r-Y0;
+ }
}
-function drawBuffer() {
- gl.bindBuffer(gl.ARRAY_BUFFER, VertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
- VertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
- VertexBuffer.numItems = nvertices;
+function setProjection()
+{
+ setDimensions(canvasWidth,canvasHeight,shift.x,shift.y);
+ let f=orthographic ? mat4.ortho : mat4.frustum;
+ f(projMat,viewParam.xmin,viewParam.xmax,
+ viewParam.ymin,viewParam.ymax,
+ -viewParam.zmax,-viewParam.zmin);
+ updateViewMatrix();
+}
- // FIXME: Some kind of a conditional here for colors???
- // along a flag of "useColors or something??? "
- gl.bindBuffer(gl.ARRAY_BUFFER, ColorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
- gl.vertexAttribPointer(shaderProgram.vertexColorAttribute,
- ColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
- ColorBuffer.numItems = nvertices;
+function initProjection()
+{
+ H=-Math.tan(0.5*angle)*B[2];
- gl.bindBuffer(gl.ARRAY_BUFFER, NormalBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
- gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
- NormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
- NormalBuffer.numItems = nvertices;
+ center.x=center.y=0;
+ center.z=0.5*(b[2]+B[2]);
+ lastzoom=Zoom=Zoom0;
- gl.bindBuffer(gl.ARRAY_BUFFER, MaterialIndexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Int32Array(materials), gl.STATIC_DRAW);
- gl.vertexAttribIPointer(shaderProgram.vertexMaterialIndexAttribute,
- MaterialIndexBuffer.itemSize, gl.INT,false,0,0);
- MaterialIndexBuffer.numItems = nvertices;
+ viewParam.zmin=b[2];
+ viewParam.zmax=B[2];
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
- indexExt ? new Uint32Array(indices) : new Uint16Array(indices),
- gl.STATIC_DRAW);
- indexBuffer.numItems = indices.length;
-
- gl.drawElements(gl.TRIANGLES, indexBuffer.numItems,
- indexExt ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT, 0);
- vertices = [];
- colors = [];
- normals = [];
- indices = [];
- materials = [];
- nvertices = 0;
-}
-
-var pixel = 1.0; // Adaptive rendering constant.
-var FillFactor = 0.1;
-var BezierFactor = 0.4;
-//var res=0.0005; // Temporary
-var res = 0.001; // Temporary
-var res2 = res * res;
-var Epsilon = 0.1 * res;
-var epsilon = 0;
-var Fuzz = 1000 * Number.EPSILON;
-var Fuzz2 = Fuzz * Fuzz;
-
-function Split3(z0, c0, c1, z1) {
- this.m0 = new Array(3);
- this.m2 = new Array(3);
- this.m3 = new Array(3);
- this.m4 = new Array(3);
- this.m5 = new Array(3);
- for (var i = 0; i < 3; ++i) {
- this.m0[i] = 0.5 * (z0[i] + c0[i]);
- var m1 = 0.5 * (c0[i] + c1[i]);
- this.m2[i] = 0.5 * (c1[i] + z1[i]);
- this.m3[i] = 0.5 * (this.m0[i] + m1);
- this.m4[i] = 0.5 * (m1 + this.m2[i]);
- this.m5[i] = 0.5 * (this.m3[i] + this.m4[i]);
- }
-}
-
-
-// Store the vertex v and its color vector c in the buffer.
-function vertex(v, c, n) {
- vertices.push(v[0]);
- vertices.push(v[1]);
- vertices.push(v[2]);
-
- colors.push(c[0]);
- colors.push(c[1]);
- colors.push(c[2]);
- colors.push(c[3]);
-
- normals.push(n[0]);
- normals.push(n[1]);
- normals.push(n[2]);
-
- // FIXME: Enable arbitrary materials?
- materials.push(materialIndex);
-
- return nvertices++;
-}
-
-function normal(left3, left2, left1, middle, right1, right2, right3) {
- var u0 = right1[0] - middle[0];
- var v0 = left1[0] - middle[0];
- var u1 = right1[1] - middle[1];
- var v1 = left1[1] - middle[1];
- var u2 = right1[2] - middle[2];
- var v2 = left1[2] - middle[2];
- var n = [
- u1 * v2 - u2 * v1,
- u2 * v0 - u0 * v2,
- u0 * v1 - u1 * v0
- ];
- if (abs2(n) > epsilon)
- return unit(n);
-
- var lp = [v0, v1, v2];
- var rp = [u0, u1, u2];
- var lpp = [middle[0] + left2[0] - 2 * left1[0],
- middle[1] + left2[1] - 2 * left1[1],
- middle[2] + left2[2] - 2 * left1[2]
- ];
- var rpp = [middle[0] + right2[0] - 2 * right1[0],
- middle[1] + right2[1] - 2 * right1[1],
- middle[2] + right2[2] - 2 * right1[2]
- ];
- var a = cross(rpp, lp);
- var b = cross(rp, lpp);
- n = [a[0] + b[0],
- a[1] + b[1],
- a[2] + b[2]
- ];
- if (abs2(n) > epsilon)
- return unit(n);
-
- var lppp = [left3[0] - middle[0] + 3 * (left1[0] - left2[0]),
- left3[1] - middle[1] + 3 * (left1[1] - left2[1]),
- left3[2] - middle[2] + 3 * (left1[2] - left2[2])
- ];
- var rppp = [right3[0] - middle[0] + 3 * (right1[0] - right2[0]),
- right3[1] - middle[1] + 3 * (right1[1] - right2[1]),
- right3[2] - middle[2] + 3 * (right1[2] - right2[2])
- ];
- a = cross(rpp, lpp);
- b = cross(rp, lppp);
- var c = cross(rppp, lp);
- var d = cross(rppp, lpp);
- var e = cross(rpp, lppp);
- var f = cross(rppp, lppp);
- return unit([9 * a[0] + 3 * (b[0] + c[0] + d[0] + e[0]) + f[0],
- 9 * a[1] + 3 * (b[1] + c[1] + d[1] + e[1]) + f[1],
- 9 * a[2] + 3 * (b[2] + c[2] + d[2] + e[2]) + f[2]
- ]);
-}
-
-// return the maximum distance squared of points c0 and c1 from
-// the respective internal control points of z0--z1.
-function Straightness(z0, c0, c1, z1) {
- var third = 1.0 / 3.0;
- var v = [third * (z1[0] - z0[0]), third * (z1[1] - z0[1]), third * (z1[2] - z0[2])];
- return Math.max(abs2([c0[0] - v[0] - z0[0], c0[1] - v[1] - z0[1], c0[2] - v[2] - z0[2]]),
- abs2([z1[0] - v[0] - c1[0], z1[1] - v[1] - c1[1], z1[2] - v[2] - c1[2]]));
-}
-
-// return the maximum perpendicular distance squared of points c0 and c1
-// from z0--z1.
-function Distance1(z0, c0, c1, z1) {
- var Z0 = [c0[0] - z0[0], c0[1] - z0[1], c0[2] - z0[2]];
- var Q = unit([z1[0] - z0[0], z1[1] - z0[1], z1[2] - z0[2]]);
- var Z1 = [c1[0] - z0[0], c1[1] - z0[1], c1[2] - z0[2]];
- var p0 = dot(Z0, Q);
- var p1 = dot(Z1, Q);
- return Math.max(abs2([Z0[0] - p0 * Q[0], Z0[1] - p0 * Q[1], Z0[2] - p0 * Q[2]]),
- abs2([Z1[0] - p1 * Q[0], Z1[1] - p1 * Q[1], Z1[2] - p1 * Q[2]]));
-}
-
-
-function Distance(p) {
- var p0 = p[0];
- var p3 = p[3];
- var p12 = p[12];
- var p15 = p[15];
-
- // Check the flatness of the quad.
- var d = Distance2(p15, p0, normal(p3, p[2], p[1], p0, p[4], p[8], p12));
-
- // Determine how straight the edges are.
- d = Math.max(d, Straightness(p0, p[1], p[2], p3));
- d = Math.max(d, Straightness(p0, p[4], p[8], p12));
- d = Math.max(d, Straightness(p3, p[7], p[11], p15));
- d = Math.max(d, Straightness(p12, p[13], p[14], p15));
-
- // Determine how straight the interior control curves are.
- d = Math.max(d, Straightness(p[4], p[5], p[6], p[7]));
- d = Math.max(d, Straightness(p[8], p[9], p[10], p[11]));
- d = Math.max(d, Straightness(p[1], p[5], p[9], p[13]));
- return Math.max(d, Straightness(p[2], p[6], p[10], p[14]));
-}
-
-var k = 1;
-// Return color associated with unit normal vector n.
-function color(n) {
- var Ldotn = Math.abs(L[0] * n[0] + L[1] * n[1] + L[2] * n[2]);
- var p = [emissive[0] + ambient[0] * Ambient[0] + Ldotn * diffuse[0] * Diffuse[0],
- emissive[1] + ambient[1] * Ambient[1] + Ldotn * diffuse[1] * Diffuse[1],
- emissive[2] + ambient[2] * Ambient[2] + Ldotn * diffuse[2] * Diffuse[2]
- ];
- var s = shininess * 128;
- var H = unit([L[0], L[1], L[2] + 1]);
- var f = Math.pow(H[0] * n[0] + H[1] * n[1] + H[2] * n[2], s);
-
- // Phong-Blinn model of specular reflection
- p = [p[0] + f * specular[0] * Specular[0], p[1] + f * specular[1] * Specular[1],
- p[2] + f * specular[2] * Specular[2]
- ];
-
- return [p[0], p[1], p[2], 1];
-}
-
-function render(p, I0, I1, I2, I3, P0, P1, P2, P3, flat0, flat1, flat2, flat3,
- C0, C1, C2, C3) {
- if (Distance(p) < res2) { // Patch is flat
- indices.push(I0);
- indices.push(I1);
- indices.push(I2);
-
- indices.push(I0);
- indices.push(I2);
- indices.push(I3);
- return;
- }
+ shift.x=shift.y=0;
+}
- var p0 = p[0];
- var p3 = p[3];
- var p12 = p[12];
- var p15 = p[15];
-
- var c0 = new Split3(p0, p[1], p[2], p3);
- var c1 = new Split3(p[4], p[5], p[6], p[7]);
- var c2 = new Split3(p[8], p[9], p[10], p[11]);
- var c3 = new Split3(p12, p[13], p[14], p15);
- var c4 = new Split3(p0, p[4], p[8], p12);
- var c5 = new Split3(c0.m0, c1.m0, c2.m0, c3.m0);
- var c6 = new Split3(c0.m3, c1.m3, c2.m3, c3.m3);
- var c7 = new Split3(c0.m5, c1.m5, c2.m5, c3.m5);
- var c8 = new Split3(c0.m4, c1.m4, c2.m4, c3.m4);
- var c9 = new Split3(c0.m2, c1.m2, c2.m2, c3.m2);
- var c10 = new Split3(p3, p[7], p[11], p15);
-
- var s0 = [p0, c0.m0, c0.m3, c0.m5, c4.m0, c5.m0, c6.m0, c7.m0,
- c4.m3, c5.m3, c6.m3, c7.m3, c4.m5, c5.m5, c6.m5, c7.m5
- ];
- var s1 = [c4.m5, c5.m5, c6.m5, c7.m5, c4.m4, c5.m4, c6.m4, c7.m4,
- c4.m2, c5.m2, c6.m2, c7.m2, p12, c3.m0, c3.m3, c3.m5
- ];
- var s2 = [c7.m5, c8.m5, c9.m5, c10.m5, c7.m4, c8.m4, c9.m4, c10.m4,
- c7.m2, c8.m2, c9.m2, c10.m2, c3.m5, c3.m4, c3.m2, p15
- ];
- var s3 = [c0.m5, c0.m4, c0.m2, p3, c7.m0, c8.m0, c9.m0, c10.m0,
- c7.m3, c8.m3, c9.m3, c10.m3, c7.m5, c8.m5, c9.m5, c10.m5
- ];
-
- var m4 = s0[15];
-
- var n0 = normal(s0[0], s0[4], s0[8], s0[12], s0[13], s0[14], s0[15]);
- if (n0 == 0.0) {
- n0 = normal(s0[0], s0[4], s0[8], s0[12], s0[11], s0[7], s0[3]);
- if (n0 == 0.0) n0 = normal(s0[3], s0[2], s0[1], s0[0], s0[13], s0[14], s0[15]);
- }
-
- var n1 = normal(s1[12], s1[13], s1[14], s1[15], s1[11], s1[7], s1[3]);
- if (n1 == 0.0) {
- n1 = normal(s1[12], s1[13], s1[14], s1[15], s1[2], s1[1], s1[0]);
- if (n1 == 0.0) n1 = normal(s1[0], s1[4], s1[8], s1[12], s1[11], s1[7], s1[3]);
- }
-
- var n2 = normal(s2[15], s2[11], s2[7], s2[3], s2[2], s2[1], s2[0]);
- if (n2 == 0.0) {
- n2 = normal(s2[15], s2[11], s2[7], s2[3], s2[4], s2[8], s2[12]);
- if (n2 == 0.0) n2 = normal(s2[12], s2[13], s2[14], s2[15], s2[2], s2[1], s2[0]);
- }
-
- var n3 = normal(s3[3], s3[2], s3[1], s3[0], s3[4], s3[8], s3[12]);
- if (n3 == 0.0) {
- n3 = normal(s3[3], s3[2], s3[1], s3[0], s3[13], s3[14], s3[15]);
- if (n3 == 0.0) n3 = normal(s3[15], s3[11], s3[7], s3[3], s3[4], s3[8], s3[12]);
- }
-
- var n4 = normal(s2[3], s2[2], s2[1], m4, s2[4], s2[8], s2[12]);
-
- var m0, m1, m2, m3;
-
- // A kludge to remove subdivision cracks, only applied the first time
- // an edge is found to be flat before the rest of the subpatch is.
- if (flat0)
- m0 = [0.5 * (P0[0] + P1[0]), 0.5 * (P0[1] + P1[1]), 0.5 * (P0[2] + P1[2])];
- else {
- if ((flat0 = Distance1(p0, p[4], p[8], p12) < res2)) {
- var u = s0[12];
- var v = s2[3];
- var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]);
- m0 = [0.5 * (P0[0] + P1[0]) + Epsilon * e[0], 0.5 * (P0[1] + P1[1]) + Epsilon * e[1],
- 0.5 * (P0[2] + P1[2]) + Epsilon * e[2]
- ];
- } else
- m0 = s0[12];
- }
-
- if (flat1)
- m1 = [0.5 * (P1[0] + P2[0]), 0.5 * (P1[1] + P2[1]), 0.5 * (P1[2] + P2[2])];
- else {
- if ((flat1 = Distance1(p12, p[13], p[14], p15) < res2)) {
- var u = s1[15];
- var v = s3[0];
- var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]);
- m1 = [0.5 * (P1[0] + P2[0]) + Epsilon * e[0], 0.5 * (P1[1] + P2[1]) + Epsilon * e[1],
- 0.5 * (P1[2] + P2[2]) + Epsilon * e[2]
- ];
- } else
- m1 = s1[15];
- }
-
- if (flat2)
- m2 = [0.5 * (P2[0] + P3[0]), 0.5 * (P2[1] + P3[1]), 0.5 * (P2[2] + P3[2])];
- else {
- if ((flat2 = Distance1(p15, p[11], p[7], p3) < res2)) {
- var u = s2[3];
- var v = s0[12];
- var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]);
- m2 = [0.5 * (P2[0] + P3[0]) + Epsilon * e[0], 0.5 * (P2[1] + P3[1]) + Epsilon * e[1],
- 0.5 * (P2[2] + P3[2]) + Epsilon * e[2]
- ];
- } else
- m2 = s2[3];
- }
-
- if (flat3)
- m3 = [0.5 * (P3[0] + P0[0]), 0.5 * (P3[1] + P0[1]), 0.5 * (P3[2] + P0[2])];
- else {
- if ((flat3 = Distance1(p3, p[2], p[1], p0) < res2)) {
- var u = s3[0];
- var v = s1[15];
- var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]);
- m3 = [0.5 * (P3[0] + P0[0]) + Epsilon * e[0],
- 0.5 * (P3[1] + P0[1]) + Epsilon * e[1],
- 0.5 * (P3[2] + P0[2]) + Epsilon * e[2]
- ];
- } else
- m3 = s3[0];
- }
+function setViewport()
+{
+ gl.viewportWidth=canvasWidth;
+ gl.viewportHeight=canvasHeight;
+ gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight);
+ home();
+}
- // document.write(n0);
- // document.write(" < br > ");
+function setCanvas()
+{
+ canvas.width=canvasWidth;
+ canvas.height=canvasHeight;
+ size2=Math.hypot(canvasWidth,canvasHeight);
+ halfCanvasWidth=0.5*canvasWidth;
+ halfCanvasHeight=0.5*canvasHeight;
+}
- {
- /*
- var c0=new Array(4);
- var c1=new Array(4);
- var c2=new Array(4);
- var c3=new Array(4);
- var c4=new Array(4);
-
- for(var i=0; i < 4; ++i) {
- c0[i]=0.5*(C0[i]+C1[i]);
- c1[i]=0.5*(C1[i]+C2[i]);
- c2[i]=0.5*(C2[i]+C3[i]);
- c3[i]=0.5*(C3[i]+C0[i]);
- c4[i]=0.5*(c0[i]+c2[i]);
- }
- */
+function setsize(w,h)
+{
+ if(w > maxViewportWidth)
+ w=maxViewportWidth;
- var c0 = color(n0);
- var c1 = color(n1);
- var c2 = color(n2);
- var c3 = color(n3);
- var c4 = color(n4);
+ if(h > maxViewportHeight)
+ h=maxViewportHeight;
+ shift.x *= w/canvasWidth;
+ shift.y *= h/canvasHeight;
- var i0 = vertex(m0, c0, n0);
- var i1 = vertex(m1, c1, n1);
- var i2 = vertex(m2, c2, n2);
- var i3 = vertex(m3, c3, n3);
- var i4 = vertex(m4, c4, n4);
+ canvasWidth=w;
+ canvasHeight=h;
+ setCanvas();
+ setViewport();
+}
- render(s0, I0, i0, i4, i3, P0, m0, m4, m3, flat0, false, false, flat3,
- C0, c0, c4, c3);
- render(s1, i0, I1, i1, i4, m0, P1, m1, m4, flat0, flat1, false, false,
- c0, C1, c1, c4);
- render(s2, i4, i1, I2, i2, m4, m1, P2, m2, false, flat1, flat2, false,
- c4, c1, C2, c2);
- render(s3, i3, i4, i2, I3, m3, m4, m2, P3, false, false, flat2, flat3,
- c3, c4, c2, C3);
- }
+function expand()
+{
+ setsize(canvasWidth*resizeStep+0.5,canvasHeight*resizeStep+0.5);
}
-var p;
+function shrink()
+{
+ setsize(Math.max((canvasWidth/resizeStep+0.5),1),
+ Math.max((canvasHeight/resizeStep+0.5),1));
+}
-function draw() {
- sceneSetup();
- // mat4.translate(mMatrix,mMatrix,[-0.5,-0.5,-1.5]);
+let pixelShader,noNormalShader,materialShader,colorShader,transparentShader;
+
+function webGLStart()
+{
+ canvas=document.getElementById("Asymptote");
+
+ if(absolute) {
+ canvasWidth *= window.devicePixelRatio;
+ canvasHeight *= window.devicePixelRatio;
+ } else {
+ if(canvas.width == 0)
+ canvas.width=Math.max(window.innerWidth-windowTrim,windowTrim);
+
+ if(canvas.height == 0)
+ canvas.height=Math.max(window.innerHeight-windowTrim,windowTrim);
+
+ let Aspect=canvasWidth/canvasHeight;
+ if(canvas.width > canvas.height*Aspect)
+ canvas.width=Math.min(canvas.height*Aspect,canvas.width);
+ else
+ canvas.height=Math.min(canvas.width/Aspect,canvas.height);
+
+ if(canvas.width > 0)
+ canvasWidth=canvas.width;
+
+ if(canvas.height > 0)
+ canvasHeight=canvas.height;
- setBuffer();
- var p0 = p[0];
- var p3 = p[3];
- var p12 = p[12];
- var p15 = p[15];
-
- epsilon = 0;
- for (var i = 1; i < 16; ++i)
- epsilon = Math.max(epsilon,
- abs2([p[i][0] - p0[0], p[i][1] - p0[1], p[i][2] - p0[2]]));
- epsilon *= Fuzz2;
-
- var n0 = normal(p3, p[2], p[1], p0, p[4], p[8], p12);
- var n1 = normal(p0, p[4], p[8], p12, p[13], p[14], p15);
- var n2 = normal(p12, p[13], p[14], p15, p[11], p[7], p3);
- var n3 = normal(p15, p[11], p[7], p3, p[2], p[1], p0);
-
- var c0 = color(n0);
- var c1 = color(n1);
- var c2 = color(n2);
- var c3 = color(n3);
-
- var i0 = vertex(p0, c0, n0);
- var i1 = vertex(p12, c1, n1);
- var i2 = vertex(p15, c2, n2);
- var i3 = vertex(p3, c3, n3);
-
- render(p, i0, i1, i2, i3, p0, p12, p15, p3, false, false, false, false,
- c0, c1, c2, c3);
- drawBuffer();
-}
-
-var forceredraw = false;
-var lasttime;
-var newtime;
-
-function tick() {
- requestAnimationFrame(tick);
- lasttime = newtime;
- newtime = performance.now();
- // invariant: every time this loop is called, lasttime stores the
- // last time processloop was called.
- processloop(newtime - lasttime);
- draw();
-}
-function tickNoRedraw() {
- requestAnimationFrame(tickNoRedraw);
- if (redraw) {
- draw();
- redraw = false;
}
-}
-function webGLStart() {
- var canvas = document.getElementById("Asymptote");
- initGL(canvas);
- initShaders();
- gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ setCanvas();
+ ArcballFactor=1+8*Math.hypot(viewportmargin[0],viewportmargin[1])/size2;
+
+ initGL();
+
+ gl.enable(gl.BLEND);
+ gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.DEPTH_TEST);
+ setViewport();
- canvas.onmousedown = handleMouseDown;
- document.onmouseup = handleMouseUpOrTouchEnd;
- document.onmousemove = handleMouseMove;
- canvas.onkeydown = handleKey;
- document.onwheel = handleMouseWheel;
+ noNormalShader=initShader();
+ pixelShader=initShader(["WIDTH"]);
+ materialShader=initShader(["NORMAL"]);
+ colorShader=initShader(["NORMAL","COLOR"]);
+ transparentShader=initShader(["NORMAL","COLOR","TRANSPARENT"]);
- canvas.addEventListener("touchstart", handleTouchStart, false);
- canvas.addEventListener("touchend", handleMouseUpOrTouchEnd, false);
- canvas.addEventListener("touchcancel", handleMouseUpOrTouchEnd, false);
- canvas.addEventListener("touchleave", handleMouseUpOrTouchEnd, false);
- canvas.addEventListener("touchmove", handleTouchMove, false);
+ setBuffer();
+
+ canvas.onmousedown=handleMouseDown;
+ document.onmouseup=handleMouseUpOrTouchEnd;
+ document.onmousemove=handleMouseMove;
+ canvas.onkeydown=handleKey;
+ document.onwheel=handleMouseWheel;
- newtime = performance.now();
+ canvas.addEventListener("touchstart",handleTouchStart,false);
+ canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,false);
+ canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,false);
+ canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,false);
+ canvas.addEventListener("touchmove",handleTouchMove,false);
+ document.addEventListener("keydown",handleKey,false);
- if (forceredraw) {
tick();
- } else {
- tickNoRedraw();
- }
}
diff --git a/graphics/asymptote/webgl/glm-js-min-2.2.2.js b/graphics/asymptote/webgl/glm-js-min-2.2.2.js
deleted file mode 100644
index 3e11d90371..0000000000
--- a/graphics/asymptote/webgl/glm-js-min-2.2.2.js
+++ /dev/null
@@ -1,273 +0,0 @@
-/*! glm-js built 2017-03-20 16:45:23-04:00 | (c) humbletim | http://humbletim.github.io/glm-js */
-(function declare_glmjs_glmatrix(globals, $GLM_log, $GLM_console_log) { var GLM, GLMAT, GLMAT_VERSION, GLMJS_PREFIX, $GLM_console_factory, glm; ArrayBuffer.exists;
-/*
-
- --------------------------------------------------------------------------
- glm-js | (c) humbletim | http://humbletim.github.io/glm-js
- --------------------------------------------------------------------------
-
- The MIT License (MIT)
-
- Copyright (c) 2015-2016 humbletim
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
-
- --------------------------------------------------------------------------
- gl-matrix | (c) Brandon Jones, Colin MacKenzie IV | http://glmatrix.net/
- --------------------------------------------------------------------------
-
- Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-
- 3. This notice may not be removed or altered from any source distribution.
-*/
-GLMAT={};GLMAT_VERSION="2.2.2";
-(function(a){a.VERSION=GLMAT_VERSION;if(!b)var b=1E-6;if(!c)var c="undefined"!==typeof Float32Array?Float32Array:Array;if(!e)var e=Math.random;var d={setMatrixArrayType:function(y){c=y}};"undefined"!==typeof a&&(a.glMatrix=d);var h=Math.PI/180;d.toRadian=function(y){return y*h};d={create:function(){var y=new c(2);y[0]=0;y[1]=0;return y},clone:function(y){var a=new c(2);a[0]=y[0];a[1]=y[1];return a},fromValues:function(y,a){var v=new c(2);v[0]=y;v[1]=a;return v},copy:function(y,a){y[0]=a[0];y[1]=a[1];
-return y},set:function(y,a,v){y[0]=a;y[1]=v;return y},add:function(y,a,v){y[0]=a[0]+v[0];y[1]=a[1]+v[1];return y},subtract:function(y,a,v){y[0]=a[0]-v[0];y[1]=a[1]-v[1];return y}};d.sub=d.subtract;d.multiply=function(y,a,v){y[0]=a[0]*v[0];y[1]=a[1]*v[1];return y};d.mul=d.multiply;d.divide=function(y,a,v){y[0]=a[0]/v[0];y[1]=a[1]/v[1];return y};d.div=d.divide;d.min=function(y,a,v){y[0]=Math.min(a[0],v[0]);y[1]=Math.min(a[1],v[1]);return y};d.max=function(y,a,v){y[0]=Math.max(a[0],v[0]);y[1]=Math.max(a[1],
-v[1]);return y};d.scale=function(y,a,v){y[0]=a[0]*v;y[1]=a[1]*v;return y};d.scaleAndAdd=function(y,a,v,b){y[0]=a[0]+v[0]*b;y[1]=a[1]+v[1]*b;return y};d.distance=function(a,f){var v=f[0]-a[0],b=f[1]-a[1];return Math.sqrt(v*v+b*b)};d.dist=d.distance;d.squaredDistance=function(a,f){var v=f[0]-a[0],b=f[1]-a[1];return v*v+b*b};d.sqrDist=d.squaredDistance;d.length=function(a){var f=a[0];a=a[1];return Math.sqrt(f*f+a*a)};d.len=d.length;d.squaredLength=function(a){var f=a[0];a=a[1];return f*f+a*a};d.sqrLen=
-d.squaredLength;d.negate=function(a,f){a[0]=-f[0];a[1]=-f[1];return a};d.inverse=function(a,f){a[0]=1/f[0];a[1]=1/f[1];return a};d.normalize=function(a,f){var v=f[0],b=f[1],v=v*v+b*b;0<v&&(v=1/Math.sqrt(v),a[0]=f[0]*v,a[1]=f[1]*v);return a};d.dot=function(a,f){return a[0]*f[0]+a[1]*f[1]};d.cross=function(a,f,v){f=f[0]*v[1]-f[1]*v[0];a[0]=a[1]=0;a[2]=f;return a};d.lerp=function(a,f,v,b){var c=f[0];f=f[1];a[0]=c+b*(v[0]-c);a[1]=f+b*(v[1]-f);return a};d.random=function(a,f){f=f||1;var v=2*e()*Math.PI;
-a[0]=Math.cos(v)*f;a[1]=Math.sin(v)*f;return a};d.transformMat2=function(a,f,v){var b=f[0];f=f[1];a[0]=v[0]*b+v[2]*f;a[1]=v[1]*b+v[3]*f;return a};d.transformMat2d=function(a,f,v){var b=f[0];f=f[1];a[0]=v[0]*b+v[2]*f+v[4];a[1]=v[1]*b+v[3]*f+v[5];return a};d.transformMat3=function(a,f,b){var c=f[0];f=f[1];a[0]=b[0]*c+b[3]*f+b[6];a[1]=b[1]*c+b[4]*f+b[7];return a};d.transformMat4=function(a,f,b){var c=f[0];f=f[1];a[0]=b[0]*c+b[4]*f+b[12];a[1]=b[1]*c+b[5]*f+b[13];return a};var j=d.create();d.forEach=function(a,
-f,b,c,d,e){f||(f=2);b||(b=0);for(c=c?Math.min(c*f+b,a.length):a.length;b<c;b+=f)j[0]=a[b],j[1]=a[b+1],d(j,j,e),a[b]=j[0],a[b+1]=j[1];return a};d.str=function(a){return"vec2("+a[0]+", "+a[1]+")"};"undefined"!==typeof a&&(a.vec2=d);var g={create:function(){var a=new c(3);a[0]=0;a[1]=0;a[2]=0;return a},clone:function(a){var f=new c(3);f[0]=a[0];f[1]=a[1];f[2]=a[2];return f},fromValues:function(a,f,b){var P=new c(3);P[0]=a;P[1]=f;P[2]=b;return P},copy:function(a,f){a[0]=f[0];a[1]=f[1];a[2]=f[2];return a},
-set:function(a,f,b,c){a[0]=f;a[1]=b;a[2]=c;return a},add:function(a,f,b){a[0]=f[0]+b[0];a[1]=f[1]+b[1];a[2]=f[2]+b[2];return a},subtract:function(a,f,b){a[0]=f[0]-b[0];a[1]=f[1]-b[1];a[2]=f[2]-b[2];return a}};g.sub=g.subtract;g.multiply=function(a,f,b){a[0]=f[0]*b[0];a[1]=f[1]*b[1];a[2]=f[2]*b[2];return a};g.mul=g.multiply;g.divide=function(a,f,b){a[0]=f[0]/b[0];a[1]=f[1]/b[1];a[2]=f[2]/b[2];return a};g.div=g.divide;g.min=function(a,f,b){a[0]=Math.min(f[0],b[0]);a[1]=Math.min(f[1],b[1]);a[2]=Math.min(f[2],
-b[2]);return a};g.max=function(a,f,b){a[0]=Math.max(f[0],b[0]);a[1]=Math.max(f[1],b[1]);a[2]=Math.max(f[2],b[2]);return a};g.scale=function(a,f,b){a[0]=f[0]*b;a[1]=f[1]*b;a[2]=f[2]*b;return a};g.scaleAndAdd=function(a,f,b,c){a[0]=f[0]+b[0]*c;a[1]=f[1]+b[1]*c;a[2]=f[2]+b[2]*c;return a};g.distance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2];return Math.sqrt(b*b+c*c+d*d)};g.dist=g.distance;g.squaredDistance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2];return b*b+c*c+d*d};g.sqrDist=
-g.squaredDistance;g.length=function(a){var f=a[0],b=a[1];a=a[2];return Math.sqrt(f*f+b*b+a*a)};g.len=g.length;g.squaredLength=function(a){var f=a[0],b=a[1];a=a[2];return f*f+b*b+a*a};g.sqrLen=g.squaredLength;g.negate=function(a,f){a[0]=-f[0];a[1]=-f[1];a[2]=-f[2];return a};g.inverse=function(a,f){a[0]=1/f[0];a[1]=1/f[1];a[2]=1/f[2];return a};g.normalize=function(a,f){var b=f[0],c=f[1],d=f[2],b=b*b+c*c+d*d;0<b&&(b=1/Math.sqrt(b),a[0]=f[0]*b,a[1]=f[1]*b,a[2]=f[2]*b);return a};g.dot=function(a,f){return a[0]*
-f[0]+a[1]*f[1]+a[2]*f[2]};g.cross=function(a,f,b){var c=f[0],d=f[1];f=f[2];var e=b[0],l=b[1];b=b[2];a[0]=d*b-f*l;a[1]=f*e-c*b;a[2]=c*l-d*e;return a};g.lerp=function(a,f,b,c){var d=f[0],e=f[1];f=f[2];a[0]=d+c*(b[0]-d);a[1]=e+c*(b[1]-e);a[2]=f+c*(b[2]-f);return a};g.random=function(a,f){f=f||1;var b=2*e()*Math.PI,c=2*e()-1,d=Math.sqrt(1-c*c)*f;a[0]=Math.cos(b)*d;a[1]=Math.sin(b)*d;a[2]=c*f;return a};g.transformMat4=function(a,f,b){var c=f[0],d=f[1];f=f[2];var e=b[3]*c+b[7]*d+b[11]*f+b[15],e=e||1;a[0]=
-(b[0]*c+b[4]*d+b[8]*f+b[12])/e;a[1]=(b[1]*c+b[5]*d+b[9]*f+b[13])/e;a[2]=(b[2]*c+b[6]*d+b[10]*f+b[14])/e;return a};g.transformMat3=function(a,f,b){var c=f[0],d=f[1];f=f[2];a[0]=c*b[0]+d*b[3]+f*b[6];a[1]=c*b[1]+d*b[4]+f*b[7];a[2]=c*b[2]+d*b[5]+f*b[8];return a};g.transformQuat=function(a,f,b){var c=f[0],d=f[1],e=f[2];f=b[0];var l=b[1],x=b[2];b=b[3];var u=b*c+l*e-x*d,J=b*d+x*c-f*e,g=b*e+f*d-l*c,c=-f*c-l*d-x*e;a[0]=u*b+c*-f+J*-x-g*-l;a[1]=J*b+c*-l+g*-f-u*-x;a[2]=g*b+c*-x+u*-l-J*-f;return a};g.rotateX=
-function(a,f,b,c){var d=[],e=[];d[0]=f[0]-b[0];d[1]=f[1]-b[1];d[2]=f[2]-b[2];e[0]=d[0];e[1]=d[1]*Math.cos(c)-d[2]*Math.sin(c);e[2]=d[1]*Math.sin(c)+d[2]*Math.cos(c);a[0]=e[0]+b[0];a[1]=e[1]+b[1];a[2]=e[2]+b[2];return a};g.rotateY=function(a,f,b,c){var d=[],e=[];d[0]=f[0]-b[0];d[1]=f[1]-b[1];d[2]=f[2]-b[2];e[0]=d[2]*Math.sin(c)+d[0]*Math.cos(c);e[1]=d[1];e[2]=d[2]*Math.cos(c)-d[0]*Math.sin(c);a[0]=e[0]+b[0];a[1]=e[1]+b[1];a[2]=e[2]+b[2];return a};g.rotateZ=function(a,f,b,c){var d=[],e=[];d[0]=f[0]-
-b[0];d[1]=f[1]-b[1];d[2]=f[2]-b[2];e[0]=d[0]*Math.cos(c)-d[1]*Math.sin(c);e[1]=d[0]*Math.sin(c)+d[1]*Math.cos(c);e[2]=d[2];a[0]=e[0]+b[0];a[1]=e[1]+b[1];a[2]=e[2]+b[2];return a};var k=g.create();g.forEach=function(a,f,b,c,d,e){f||(f=3);b||(b=0);for(c=c?Math.min(c*f+b,a.length):a.length;b<c;b+=f)k[0]=a[b],k[1]=a[b+1],k[2]=a[b+2],d(k,k,e),a[b]=k[0],a[b+1]=k[1],a[b+2]=k[2];return a};g.str=function(a){return"vec3("+a[0]+", "+a[1]+", "+a[2]+")"};"undefined"!==typeof a&&(a.vec3=g);var i={create:function(){var a=
-new c(4);a[0]=0;a[1]=0;a[2]=0;a[3]=0;return a},clone:function(a){var f=new c(4);f[0]=a[0];f[1]=a[1];f[2]=a[2];f[3]=a[3];return f},fromValues:function(a,f,b,d){var e=new c(4);e[0]=a;e[1]=f;e[2]=b;e[3]=d;return e},copy:function(a,f){a[0]=f[0];a[1]=f[1];a[2]=f[2];a[3]=f[3];return a},set:function(a,f,b,c,d){a[0]=f;a[1]=b;a[2]=c;a[3]=d;return a},add:function(a,f,b){a[0]=f[0]+b[0];a[1]=f[1]+b[1];a[2]=f[2]+b[2];a[3]=f[3]+b[3];return a},subtract:function(a,f,b){a[0]=f[0]-b[0];a[1]=f[1]-b[1];a[2]=f[2]-b[2];
-a[3]=f[3]-b[3];return a}};i.sub=i.subtract;i.multiply=function(a,f,b){a[0]=f[0]*b[0];a[1]=f[1]*b[1];a[2]=f[2]*b[2];a[3]=f[3]*b[3];return a};i.mul=i.multiply;i.divide=function(a,f,b){a[0]=f[0]/b[0];a[1]=f[1]/b[1];a[2]=f[2]/b[2];a[3]=f[3]/b[3];return a};i.div=i.divide;i.min=function(a,f,b){a[0]=Math.min(f[0],b[0]);a[1]=Math.min(f[1],b[1]);a[2]=Math.min(f[2],b[2]);a[3]=Math.min(f[3],b[3]);return a};i.max=function(a,f,b){a[0]=Math.max(f[0],b[0]);a[1]=Math.max(f[1],b[1]);a[2]=Math.max(f[2],b[2]);a[3]=
-Math.max(f[3],b[3]);return a};i.scale=function(a,f,b){a[0]=f[0]*b;a[1]=f[1]*b;a[2]=f[2]*b;a[3]=f[3]*b;return a};i.scaleAndAdd=function(a,f,b,c){a[0]=f[0]+b[0]*c;a[1]=f[1]+b[1]*c;a[2]=f[2]+b[2]*c;a[3]=f[3]+b[3]*c;return a};i.distance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2],e=f[3]-a[3];return Math.sqrt(b*b+c*c+d*d+e*e)};i.dist=i.distance;i.squaredDistance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2],e=f[3]-a[3];return b*b+c*c+d*d+e*e};i.sqrDist=i.squaredDistance;i.length=function(a){var f=
-a[0],b=a[1],c=a[2];a=a[3];return Math.sqrt(f*f+b*b+c*c+a*a)};i.len=i.length;i.squaredLength=function(a){var f=a[0],b=a[1],c=a[2];a=a[3];return f*f+b*b+c*c+a*a};i.sqrLen=i.squaredLength;i.negate=function(a,f){a[0]=-f[0];a[1]=-f[1];a[2]=-f[2];a[3]=-f[3];return a};i.inverse=function(a,f){a[0]=1/f[0];a[1]=1/f[1];a[2]=1/f[2];a[3]=1/f[3];return a};i.normalize=function(a,f){var b=f[0],c=f[1],d=f[2],e=f[3],b=b*b+c*c+d*d+e*e;0<b&&(b=1/Math.sqrt(b),a[0]=f[0]*b,a[1]=f[1]*b,a[2]=f[2]*b,a[3]=f[3]*b);return a};
-i.dot=function(a,f){return a[0]*f[0]+a[1]*f[1]+a[2]*f[2]+a[3]*f[3]};i.lerp=function(a,f,b,c){var d=f[0],e=f[1],l=f[2];f=f[3];a[0]=d+c*(b[0]-d);a[1]=e+c*(b[1]-e);a[2]=l+c*(b[2]-l);a[3]=f+c*(b[3]-f);return a};i.random=function(a,f){f=f||1;a[0]=e();a[1]=e();a[2]=e();a[3]=e();i.normalize(a,a);i.scale(a,a,f);return a};i.transformMat4=function(a,f,b){var c=f[0],d=f[1],e=f[2];f=f[3];a[0]=b[0]*c+b[4]*d+b[8]*e+b[12]*f;a[1]=b[1]*c+b[5]*d+b[9]*e+b[13]*f;a[2]=b[2]*c+b[6]*d+b[10]*e+b[14]*f;a[3]=b[3]*c+b[7]*d+
-b[11]*e+b[15]*f;return a};i.transformQuat=function(a,b,c){var d=b[0],e=b[1],n=b[2];b=c[0];var l=c[1],x=c[2];c=c[3];var u=c*d+l*n-x*e,J=c*e+x*d-b*n,g=c*n+b*e-l*d,d=-b*d-l*e-x*n;a[0]=u*c+d*-b+J*-x-g*-l;a[1]=J*c+d*-l+g*-b-u*-x;a[2]=g*c+d*-x+u*-l-J*-b;return a};var w=i.create();i.forEach=function(a,b,c,d,e,n){b||(b=4);c||(c=0);for(d=d?Math.min(d*b+c,a.length):a.length;c<d;c+=b)w[0]=a[c],w[1]=a[c+1],w[2]=a[c+2],w[3]=a[c+3],e(w,w,n),a[c]=w[0],a[c+1]=w[1],a[c+2]=w[2],a[c+3]=w[3];return a};i.str=function(a){return"vec4("+
-a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};"undefined"!==typeof a&&(a.vec4=i);d={create:function(){var a=new c(4);a[0]=1;a[1]=0;a[2]=0;a[3]=1;return a},clone:function(a){var b=new c(4);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[3];return a},identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=1;return a},transpose:function(a,b){if(a===b){var c=b[1];a[1]=b[2];a[2]=c}else a[0]=b[0],a[1]=b[2],a[2]=b[1],a[3]=b[3];return a},invert:function(a,b){var c=
-b[0],d=b[1],e=b[2],n=b[3],l=c*n-e*d;if(!l)return null;l=1/l;a[0]=n*l;a[1]=-d*l;a[2]=-e*l;a[3]=c*l;return a},adjoint:function(a,b){var c=b[0];a[0]=b[3];a[1]=-b[1];a[2]=-b[2];a[3]=c;return a},determinant:function(a){return a[0]*a[3]-a[2]*a[1]},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2];b=b[3];var l=c[0],x=c[1],u=c[2];c=c[3];a[0]=d*l+n*x;a[1]=e*l+b*x;a[2]=d*u+n*c;a[3]=e*u+b*c;return a}};d.mul=d.multiply;d.rotate=function(a,b,c){var d=b[0],e=b[1],n=b[2];b=b[3];var l=Math.sin(c);c=Math.cos(c);a[0]=
-d*c+n*l;a[1]=e*c+b*l;a[2]=d*-l+n*c;a[3]=e*-l+b*c;return a};d.scale=function(a,b,c){var d=b[1],e=b[2],n=b[3],l=c[0];c=c[1];a[0]=b[0]*l;a[1]=d*l;a[2]=e*c;a[3]=n*c;return a};d.str=function(a){return"mat2("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};d.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2))};d.LDU=function(a,b,c,d){a[2]=d[2]/d[0];c[0]=d[0];c[1]=d[1];c[3]=d[3]-a[2]*c[1];return[a,b,c]};"undefined"!==typeof a&&(a.mat2=d);d={create:function(){var a=
-new c(6);a[0]=1;a[1]=0;a[2]=0;a[3]=1;a[4]=0;a[5]=0;return a},clone:function(a){var b=new c(6);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[3];a[4]=b[4];a[5]=b[5];return a},identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=1;a[4]=0;a[5]=0;return a},invert:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=c*n-d*e;if(!u)return null;u=1/u;a[0]=n*u;a[1]=-d*u;a[2]=-e*u;a[3]=c*u;a[4]=(e*x-n*l)*u;a[5]=(d*l-c*x)*u;return a},
-determinant:function(a){return a[0]*a[3]-a[1]*a[2]},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4];b=b[5];var u=c[0],g=c[1],h=c[2],K=c[3],j=c[4];c=c[5];a[0]=d*u+n*g;a[1]=e*u+l*g;a[2]=d*h+n*K;a[3]=e*h+l*K;a[4]=d*j+n*c+x;a[5]=e*j+l*c+b;return a}};d.mul=d.multiply;d.rotate=function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4];b=b[5];var u=Math.sin(c);c=Math.cos(c);a[0]=d*c+n*u;a[1]=e*c+l*u;a[2]=d*-u+n*c;a[3]=e*-u+l*c;a[4]=x;a[5]=b;return a};d.scale=function(a,b,c){var d=b[1],e=b[2],
-n=b[3],l=b[4],x=b[5],u=c[0];c=c[1];a[0]=b[0]*u;a[1]=d*u;a[2]=e*c;a[3]=n*c;a[4]=l;a[5]=x;return a};d.translate=function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4];b=b[5];var u=c[0];c=c[1];a[0]=d;a[1]=e;a[2]=n;a[3]=l;a[4]=d*u+n*c+x;a[5]=e*u+l*c+b;return a};d.str=function(a){return"mat2d("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+")"};d.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2)+Math.pow(a[4],2)+Math.pow(a[5],2)+1)};"undefined"!==
-typeof a&&(a.mat2d=d);d={create:function(){var a=new c(9);a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a},fromMat4:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[4];a[4]=b[5];a[5]=b[6];a[6]=b[8];a[7]=b[9];a[8]=b[10];return a},clone:function(a){var b=new c(9);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[3];a[4]=b[4];a[5]=b[5];a[6]=b[6];a[7]=b[7];a[8]=b[8];return a},
-identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a},transpose:function(a,b){if(a===b){var c=b[1],d=b[2],e=b[5];a[1]=b[3];a[2]=b[6];a[3]=c;a[5]=b[7];a[6]=d;a[7]=e}else a[0]=b[0],a[1]=b[3],a[2]=b[6],a[3]=b[1],a[4]=b[4],a[5]=b[7],a[6]=b[2],a[7]=b[5],a[8]=b[8];return a},invert:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=b[6],g=b[7],h=b[8],K=h*l-x*g,j=-h*n+x*u,m=g*n-l*u,i=c*K+d*j+e*m;if(!i)return null;i=1/i;a[0]=K*i;a[1]=(-h*d+e*g)*i;a[2]=(x*
-d-e*l)*i;a[3]=j*i;a[4]=(h*c-e*u)*i;a[5]=(-x*c+e*n)*i;a[6]=m*i;a[7]=(-g*c+d*u)*i;a[8]=(l*c-d*n)*i;return a},adjoint:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=b[6],g=b[7],h=b[8];a[0]=l*h-x*g;a[1]=e*g-d*h;a[2]=d*x-e*l;a[3]=x*u-n*h;a[4]=c*h-e*u;a[5]=e*n-c*x;a[6]=n*g-l*u;a[7]=d*u-c*g;a[8]=c*l-d*n;return a},determinant:function(a){var b=a[3],c=a[4],d=a[5],e=a[6],n=a[7],l=a[8];return a[0]*(l*c-d*n)+a[1]*(-l*b+d*e)+a[2]*(n*b-c*e)},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],
-x=b[4],u=b[5],g=b[6],h=b[7];b=b[8];var j=c[0],m=c[1],i=c[2],k=c[3],q=c[4],t=c[5],s=c[6],r=c[7];c=c[8];a[0]=j*d+m*l+i*g;a[1]=j*e+m*x+i*h;a[2]=j*n+m*u+i*b;a[3]=k*d+q*l+t*g;a[4]=k*e+q*x+t*h;a[5]=k*n+q*u+t*b;a[6]=s*d+r*l+c*g;a[7]=s*e+r*x+c*h;a[8]=s*n+r*u+c*b;return a}};d.mul=d.multiply;d.translate=function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4],u=b[5],g=b[6],h=b[7];b=b[8];var j=c[0];c=c[1];a[0]=d;a[1]=e;a[2]=n;a[3]=l;a[4]=x;a[5]=u;a[6]=j*d+c*l+g;a[7]=j*e+c*x+h;a[8]=j*n+c*u+b;return a};d.rotate=
-function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4],u=b[5],g=b[6],h=b[7];b=b[8];var j=Math.sin(c);c=Math.cos(c);a[0]=c*d+j*l;a[1]=c*e+j*x;a[2]=c*n+j*u;a[3]=c*l-j*d;a[4]=c*x-j*e;a[5]=c*u-j*n;a[6]=g;a[7]=h;a[8]=b;return a};d.scale=function(a,b,c){var d=c[0];c=c[1];a[0]=d*b[0];a[1]=d*b[1];a[2]=d*b[2];a[3]=c*b[3];a[4]=c*b[4];a[5]=c*b[5];a[6]=b[6];a[7]=b[7];a[8]=b[8];return a};d.fromMat2d=function(a,b){a[0]=b[0];a[1]=b[1];a[2]=0;a[3]=b[2];a[4]=b[3];a[5]=0;a[6]=b[4];a[7]=b[5];a[8]=1;return a};d.fromQuat=
-function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=c+c,x=d+d,u=e+e,c=c*l,g=d*l,d=d*x,h=e*l,j=e*x,e=e*u,l=n*l,x=n*x,n=n*u;a[0]=1-d-e;a[3]=g-n;a[6]=h+x;a[1]=g+n;a[4]=1-c-e;a[7]=j-l;a[2]=h-x;a[5]=j+l;a[8]=1-c-d;return a};d.normalFromMat4=function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=b[6],g=b[7],h=b[8],j=b[9],m=b[10],i=b[11],k=b[12],q=b[13],t=b[14],s=b[15],r=c*x-d*l,z=c*u-e*l,w=c*g-n*l,A=d*u-e*x,E=d*g-n*x,F=e*g-n*u,G=h*q-j*k,H=h*t-m*k,h=h*s-i*k,I=j*t-m*q,j=j*s-i*q,m=m*s-i*t,i=r*m-z*j+w*I+
-A*h-E*H+F*G;if(!i)return null;i=1/i;a[0]=(x*m-u*j+g*I)*i;a[1]=(u*h-l*m-g*H)*i;a[2]=(l*j-x*h+g*G)*i;a[3]=(e*j-d*m-n*I)*i;a[4]=(c*m-e*h+n*H)*i;a[5]=(d*h-c*j-n*G)*i;a[6]=(q*F-t*E+s*A)*i;a[7]=(t*w-k*F-s*z)*i;a[8]=(k*E-q*w+s*r)*i;return a};d.str=function(a){return"mat3("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+")"};d.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2)+Math.pow(a[4],2)+Math.pow(a[5],2)+Math.pow(a[6],
-2)+Math.pow(a[7],2)+Math.pow(a[8],2))};"undefined"!==typeof a&&(a.mat3=d);var r={create:function(){var a=new c(16);a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a},clone:function(a){var b=new c(16);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=
-b[2];a[3]=b[3];a[4]=b[4];a[5]=b[5];a[6]=b[6];a[7]=b[7];a[8]=b[8];a[9]=b[9];a[10]=b[10];a[11]=b[11];a[12]=b[12];a[13]=b[13];a[14]=b[14];a[15]=b[15];return a},identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a},transpose:function(a,b){if(a===b){var c=b[1],d=b[2],e=b[3],n=b[6],l=b[7],g=b[11];a[1]=b[4];a[2]=b[8];a[3]=b[12];a[4]=c;a[6]=b[9];a[7]=b[13];a[8]=d;a[9]=n;a[11]=b[14];a[12]=e;a[13]=l;a[14]=g}else a[0]=
-b[0],a[1]=b[4],a[2]=b[8],a[3]=b[12],a[4]=b[1],a[5]=b[5],a[6]=b[9],a[7]=b[13],a[8]=b[2],a[9]=b[6],a[10]=b[10],a[11]=b[14],a[12]=b[3],a[13]=b[7],a[14]=b[11],a[15]=b[15];return a},invert:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],g=b[5],u=b[6],h=b[7],j=b[8],m=b[9],i=b[10],k=b[11],q=b[12],t=b[13],s=b[14],r=b[15],z=c*g-d*l,w=c*u-e*l,B=c*h-n*l,A=d*u-e*g,E=d*h-n*g,F=e*h-n*u,G=j*t-m*q,H=j*s-i*q,I=j*r-k*q,L=m*s-i*t,M=m*r-k*t,O=i*r-k*s,D=z*O-w*M+B*L+A*I-E*H+F*G;if(!D)return null;D=1/D;a[0]=(g*O-u*
-M+h*L)*D;a[1]=(e*M-d*O-n*L)*D;a[2]=(t*F-s*E+r*A)*D;a[3]=(i*E-m*F-k*A)*D;a[4]=(u*I-l*O-h*H)*D;a[5]=(c*O-e*I+n*H)*D;a[6]=(s*B-q*F-r*w)*D;a[7]=(j*F-i*B+k*w)*D;a[8]=(l*M-g*I+h*G)*D;a[9]=(d*I-c*M-n*G)*D;a[10]=(q*E-t*B+r*z)*D;a[11]=(m*B-j*E-k*z)*D;a[12]=(g*H-l*L-u*G)*D;a[13]=(c*L-d*H+e*G)*D;a[14]=(t*w-q*A-s*z)*D;a[15]=(j*A-m*w+i*z)*D;return a},adjoint:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],g=b[5],h=b[6],j=b[7],m=b[8],i=b[9],k=b[10],q=b[11],t=b[12],s=b[13],r=b[14],z=b[15];a[0]=g*(k*z-q*r)-
-i*(h*z-j*r)+s*(h*q-j*k);a[1]=-(d*(k*z-q*r)-i*(e*z-n*r)+s*(e*q-n*k));a[2]=d*(h*z-j*r)-g*(e*z-n*r)+s*(e*j-n*h);a[3]=-(d*(h*q-j*k)-g*(e*q-n*k)+i*(e*j-n*h));a[4]=-(l*(k*z-q*r)-m*(h*z-j*r)+t*(h*q-j*k));a[5]=c*(k*z-q*r)-m*(e*z-n*r)+t*(e*q-n*k);a[6]=-(c*(h*z-j*r)-l*(e*z-n*r)+t*(e*j-n*h));a[7]=c*(h*q-j*k)-l*(e*q-n*k)+m*(e*j-n*h);a[8]=l*(i*z-q*s)-m*(g*z-j*s)+t*(g*q-j*i);a[9]=-(c*(i*z-q*s)-m*(d*z-n*s)+t*(d*q-n*i));a[10]=c*(g*z-j*s)-l*(d*z-n*s)+t*(d*j-n*g);a[11]=-(c*(g*q-j*i)-l*(d*q-n*i)+m*(d*j-n*g));a[12]=
--(l*(i*r-k*s)-m*(g*r-h*s)+t*(g*k-h*i));a[13]=c*(i*r-k*s)-m*(d*r-e*s)+t*(d*k-e*i);a[14]=-(c*(g*r-h*s)-l*(d*r-e*s)+t*(d*h-e*g));a[15]=c*(g*k-h*i)-l*(d*k-e*i)+m*(d*h-e*g);return a},determinant:function(a){var b=a[0],c=a[1],d=a[2],e=a[3],n=a[4],l=a[5],g=a[6],h=a[7],j=a[8],i=a[9],m=a[10],k=a[11],q=a[12],s=a[13],t=a[14];a=a[15];return(b*l-c*n)*(m*a-k*t)-(b*g-d*n)*(i*a-k*s)+(b*h-e*n)*(i*t-m*s)+(c*g-d*l)*(j*a-k*q)-(c*h-e*l)*(j*t-m*q)+(d*h-e*g)*(j*s-i*q)},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2],
-l=b[3],g=b[4],h=b[5],j=b[6],i=b[7],m=b[8],k=b[9],q=b[10],s=b[11],t=b[12],r=b[13],z=b[14];b=b[15];var w=c[0],C=c[1],B=c[2],A=c[3];a[0]=w*d+C*g+B*m+A*t;a[1]=w*e+C*h+B*k+A*r;a[2]=w*n+C*j+B*q+A*z;a[3]=w*l+C*i+B*s+A*b;w=c[4];C=c[5];B=c[6];A=c[7];a[4]=w*d+C*g+B*m+A*t;a[5]=w*e+C*h+B*k+A*r;a[6]=w*n+C*j+B*q+A*z;a[7]=w*l+C*i+B*s+A*b;w=c[8];C=c[9];B=c[10];A=c[11];a[8]=w*d+C*g+B*m+A*t;a[9]=w*e+C*h+B*k+A*r;a[10]=w*n+C*j+B*q+A*z;a[11]=w*l+C*i+B*s+A*b;w=c[12];C=c[13];B=c[14];A=c[15];a[12]=w*d+C*g+B*m+A*t;a[13]=
-w*e+C*h+B*k+A*r;a[14]=w*n+C*j+B*q+A*z;a[15]=w*l+C*i+B*s+A*b;return a}};r.mul=r.multiply;r.translate=function(a,b,c){var d=c[0],e=c[1];c=c[2];var n,l,g,h,j,i,m,k,q,s,t,r;b===a?(a[12]=b[0]*d+b[4]*e+b[8]*c+b[12],a[13]=b[1]*d+b[5]*e+b[9]*c+b[13],a[14]=b[2]*d+b[6]*e+b[10]*c+b[14],a[15]=b[3]*d+b[7]*e+b[11]*c+b[15]):(n=b[0],l=b[1],g=b[2],h=b[3],j=b[4],i=b[5],m=b[6],k=b[7],q=b[8],s=b[9],t=b[10],r=b[11],a[0]=n,a[1]=l,a[2]=g,a[3]=h,a[4]=j,a[5]=i,a[6]=m,a[7]=k,a[8]=q,a[9]=s,a[10]=t,a[11]=r,a[12]=n*d+j*e+q*c+
-b[12],a[13]=l*d+i*e+s*c+b[13],a[14]=g*d+m*e+t*c+b[14],a[15]=h*d+k*e+r*c+b[15]);return a};r.scale=function(a,b,c){var d=c[0],e=c[1];c=c[2];a[0]=b[0]*d;a[1]=b[1]*d;a[2]=b[2]*d;a[3]=b[3]*d;a[4]=b[4]*e;a[5]=b[5]*e;a[6]=b[6]*e;a[7]=b[7]*e;a[8]=b[8]*c;a[9]=b[9]*c;a[10]=b[10]*c;a[11]=b[11]*c;a[12]=b[12];a[13]=b[13];a[14]=b[14];a[15]=b[15];return a};r.rotate=function(a,c,d,e){var g=e[0],n=e[1];e=e[2];var l=Math.sqrt(g*g+n*n+e*e),h,j,i,m,k,q,s,t,r,z,w,Q,C,B,A,E,F,G,H,I;if(Math.abs(l)<b)return null;l=1/l;g*=
-l;n*=l;e*=l;h=Math.sin(d);j=Math.cos(d);i=1-j;d=c[0];l=c[1];m=c[2];k=c[3];q=c[4];s=c[5];t=c[6];r=c[7];z=c[8];w=c[9];Q=c[10];C=c[11];B=g*g*i+j;A=n*g*i+e*h;E=e*g*i-n*h;F=g*n*i-e*h;G=n*n*i+j;H=e*n*i+g*h;I=g*e*i+n*h;g=n*e*i-g*h;n=e*e*i+j;a[0]=d*B+q*A+z*E;a[1]=l*B+s*A+w*E;a[2]=m*B+t*A+Q*E;a[3]=k*B+r*A+C*E;a[4]=d*F+q*G+z*H;a[5]=l*F+s*G+w*H;a[6]=m*F+t*G+Q*H;a[7]=k*F+r*G+C*H;a[8]=d*I+q*g+z*n;a[9]=l*I+s*g+w*n;a[10]=m*I+t*g+Q*n;a[11]=k*I+r*g+C*n;c!==a&&(a[12]=c[12],a[13]=c[13],a[14]=c[14],a[15]=c[15]);return a};
-r.rotateX=function(a,b,c){var d=Math.sin(c);c=Math.cos(c);var e=b[4],g=b[5],l=b[6],h=b[7],j=b[8],i=b[9],m=b[10],k=b[11];b!==a&&(a[0]=b[0],a[1]=b[1],a[2]=b[2],a[3]=b[3],a[12]=b[12],a[13]=b[13],a[14]=b[14],a[15]=b[15]);a[4]=e*c+j*d;a[5]=g*c+i*d;a[6]=l*c+m*d;a[7]=h*c+k*d;a[8]=j*c-e*d;a[9]=i*c-g*d;a[10]=m*c-l*d;a[11]=k*c-h*d;return a};r.rotateY=function(a,b,c){var d=Math.sin(c);c=Math.cos(c);var e=b[0],g=b[1],l=b[2],h=b[3],j=b[8],i=b[9],m=b[10],k=b[11];b!==a&&(a[4]=b[4],a[5]=b[5],a[6]=b[6],a[7]=b[7],
-a[12]=b[12],a[13]=b[13],a[14]=b[14],a[15]=b[15]);a[0]=e*c-j*d;a[1]=g*c-i*d;a[2]=l*c-m*d;a[3]=h*c-k*d;a[8]=e*d+j*c;a[9]=g*d+i*c;a[10]=l*d+m*c;a[11]=h*d+k*c;return a};r.rotateZ=function(a,b,c){var d=Math.sin(c);c=Math.cos(c);var e=b[0],g=b[1],l=b[2],h=b[3],j=b[4],i=b[5],m=b[6],k=b[7];b!==a&&(a[8]=b[8],a[9]=b[9],a[10]=b[10],a[11]=b[11],a[12]=b[12],a[13]=b[13],a[14]=b[14],a[15]=b[15]);a[0]=e*c+j*d;a[1]=g*c+i*d;a[2]=l*c+m*d;a[3]=h*c+k*d;a[4]=j*c-e*d;a[5]=i*c-g*d;a[6]=m*c-l*d;a[7]=k*c-h*d;return a};r.fromRotationTranslation=
-function(a,b,c){var d=b[0],e=b[1],g=b[2],h=b[3],j=d+d,i=e+e,m=g+g;b=d*j;var k=d*i,d=d*m,q=e*i,e=e*m,g=g*m,j=h*j,i=h*i,h=h*m;a[0]=1-(q+g);a[1]=k+h;a[2]=d-i;a[3]=0;a[4]=k-h;a[5]=1-(b+g);a[6]=e+j;a[7]=0;a[8]=d+i;a[9]=e-j;a[10]=1-(b+q);a[11]=0;a[12]=c[0];a[13]=c[1];a[14]=c[2];a[15]=1;return a};r.fromQuat=function(a,b){var c=b[0],d=b[1],e=b[2],g=b[3],h=c+c,j=d+d,i=e+e,c=c*h,m=d*h,d=d*j,k=e*h,q=e*j,e=e*i,h=g*h,j=g*j,g=g*i;a[0]=1-d-e;a[1]=m+g;a[2]=k-j;a[3]=0;a[4]=m-g;a[5]=1-c-e;a[6]=q+h;a[7]=0;a[8]=k+j;
-a[9]=q-h;a[10]=1-c-d;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a};r.frustum=function(a,b,c,d,e,g,h){var j=1/(c-b),i=1/(e-d),m=1/(g-h);a[0]=2*g*j;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=2*g*i;a[6]=0;a[7]=0;a[8]=(c+b)*j;a[9]=(e+d)*i;a[10]=(h+g)*m;a[11]=-1;a[12]=0;a[13]=0;a[14]=2*(h*g)*m;a[15]=0;return a};r.perspective=function(a,b,c,d,e){b=1/Math.tan(b/2);var g=1/(d-e);a[0]=b/c;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=b;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=(e+d)*g;a[11]=-1;a[12]=0;a[13]=0;a[14]=2*e*d*g;a[15]=0;
-return a};r.ortho=function(a,b,c,d,e,g,h){var j=1/(b-c),i=1/(d-e),m=1/(g-h);a[0]=-2*j;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=-2*i;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=2*m;a[11]=0;a[12]=(b+c)*j;a[13]=(e+d)*i;a[14]=(h+g)*m;a[15]=1;return a};r.lookAt=function(a,c,d,e){var g,h,j,i,m,k,q,s,t=c[0],z=c[1];c=c[2];j=e[0];i=e[1];h=e[2];q=d[0];e=d[1];g=d[2];if(Math.abs(t-q)<b&&Math.abs(z-e)<b&&Math.abs(c-g)<b)return r.identity(a);d=t-q;e=z-e;q=c-g;s=1/Math.sqrt(d*d+e*e+q*q);d*=s;e*=s;q*=s;g=i*q-h*e;h=h*d-j*q;j=j*e-i*
-d;(s=Math.sqrt(g*g+h*h+j*j))?(s=1/s,g*=s,h*=s,j*=s):j=h=g=0;i=e*j-q*h;m=q*g-d*j;k=d*h-e*g;(s=Math.sqrt(i*i+m*m+k*k))?(s=1/s,i*=s,m*=s,k*=s):k=m=i=0;a[0]=g;a[1]=i;a[2]=d;a[3]=0;a[4]=h;a[5]=m;a[6]=e;a[7]=0;a[8]=j;a[9]=k;a[10]=q;a[11]=0;a[12]=-(g*t+h*z+j*c);a[13]=-(i*t+m*z+k*c);a[14]=-(d*t+e*z+q*c);a[15]=1;return a};r.str=function(a){return"mat4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+
-a[15]+")"};r.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2)+Math.pow(a[4],2)+Math.pow(a[5],2)+Math.pow(a[6],2)+Math.pow(a[7],2)+Math.pow(a[8],2)+Math.pow(a[9],2)+Math.pow(a[10],2)+Math.pow(a[11],2)+Math.pow(a[12],2)+Math.pow(a[13],2)+Math.pow(a[14],2)+Math.pow(a[15],2))};"undefined"!==typeof a&&(a.mat4=r);var m={create:function(){var a=new c(4);a[0]=0;a[1]=0;a[2]=0;a[3]=1;return a}},q=g.create(),s=g.fromValues(1,0,0),t=g.fromValues(0,1,0);m.rotationTo=
-function(a,b,c){var d=g.dot(b,c);if(-0.999999>d)return g.cross(q,s,b),1E-6>g.length(q)&&g.cross(q,t,b),g.normalize(q,q),m.setAxisAngle(a,q,Math.PI),a;if(0.999999<d)return a[0]=0,a[1]=0,a[2]=0,a[3]=1,a;g.cross(q,b,c);a[0]=q[0];a[1]=q[1];a[2]=q[2];a[3]=1+d;return m.normalize(a,a)};var z=d.create();m.setAxes=function(a,b,c,d){z[0]=c[0];z[3]=c[1];z[6]=c[2];z[1]=d[0];z[4]=d[1];z[7]=d[2];z[2]=-b[0];z[5]=-b[1];z[8]=-b[2];return m.normalize(a,m.fromMat3(a,z))};m.clone=i.clone;m.fromValues=i.fromValues;m.copy=
-i.copy;m.set=i.set;m.identity=function(a){a[0]=0;a[1]=0;a[2]=0;a[3]=1;return a};m.setAxisAngle=function(a,b,c){c*=0.5;var d=Math.sin(c);a[0]=d*b[0];a[1]=d*b[1];a[2]=d*b[2];a[3]=Math.cos(c);return a};m.add=i.add;m.multiply=function(a,b,c){var d=b[0],e=b[1],g=b[2];b=b[3];var h=c[0],j=c[1],i=c[2];c=c[3];a[0]=d*c+b*h+e*i-g*j;a[1]=e*c+b*j+g*h-d*i;a[2]=g*c+b*i+d*j-e*h;a[3]=b*c-d*h-e*j-g*i;return a};m.mul=m.multiply;m.scale=i.scale;m.rotateX=function(a,b,c){c*=0.5;var d=b[0],e=b[1],g=b[2];b=b[3];var h=Math.sin(c);
-c=Math.cos(c);a[0]=d*c+b*h;a[1]=e*c+g*h;a[2]=g*c-e*h;a[3]=b*c-d*h;return a};m.rotateY=function(a,b,c){c*=0.5;var d=b[0],e=b[1],g=b[2];b=b[3];var h=Math.sin(c);c=Math.cos(c);a[0]=d*c-g*h;a[1]=e*c+b*h;a[2]=g*c+d*h;a[3]=b*c-e*h;return a};m.rotateZ=function(a,b,c){c*=0.5;var d=b[0],e=b[1],g=b[2];b=b[3];var h=Math.sin(c);c=Math.cos(c);a[0]=d*c+e*h;a[1]=e*c-d*h;a[2]=g*c+b*h;a[3]=b*c-g*h;return a};m.calculateW=function(a,b){var c=b[0],d=b[1],e=b[2];a[0]=c;a[1]=d;a[2]=e;a[3]=Math.sqrt(Math.abs(1-c*c-d*d-
-e*e));return a};m.dot=i.dot;m.lerp=i.lerp;m.slerp=function(a,b,c,d){var e=b[0],g=b[1],h=b[2];b=b[3];var j=c[0],i=c[1],m=c[2];c=c[3];var k,q,s;q=e*j+g*i+h*m+b*c;0>q&&(q=-q,j=-j,i=-i,m=-m,c=-c);1E-6<1-q?(k=Math.acos(q),s=Math.sin(k),q=Math.sin((1-d)*k)/s,d=Math.sin(d*k)/s):q=1-d;a[0]=q*e+d*j;a[1]=q*g+d*i;a[2]=q*h+d*m;a[3]=q*b+d*c;return a};m.invert=function(a,b){var c=b[0],d=b[1],e=b[2],g=b[3],h=c*c+d*d+e*e+g*g,h=h?1/h:0;a[0]=-c*h;a[1]=-d*h;a[2]=-e*h;a[3]=g*h;return a};m.conjugate=function(a,b){a[0]=
--b[0];a[1]=-b[1];a[2]=-b[2];a[3]=b[3];return a};m.length=i.length;m.len=m.length;m.squaredLength=i.squaredLength;m.sqrLen=m.squaredLength;m.normalize=i.normalize;m.fromMat3=function(a,b){var c=b[0]+b[4]+b[8];if(0<c)c=Math.sqrt(c+1),a[3]=0.5*c,c=0.5/c,a[0]=(b[5]-b[7])*c,a[1]=(b[6]-b[2])*c,a[2]=(b[1]-b[3])*c;else{var d=0;b[4]>b[0]&&(d=1);b[8]>b[3*d+d]&&(d=2);var e=(d+1)%3,g=(d+2)%3,c=Math.sqrt(b[3*d+d]-b[3*e+e]-b[3*g+g]+1);a[d]=0.5*c;c=0.5/c;a[3]=(b[3*e+g]-b[3*g+e])*c;a[e]=(b[3*e+d]+b[3*d+e])*c;a[g]=
-(b[3*g+d]+b[3*d+g])*c}return a};m.str=function(a){return"quat("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};"undefined"!==typeof a&&(a.quat=m)})(GLMAT);try{module.exports=GLMAT}catch(e$$10){}try{glm.exists&&alert("glm.common.js loaded over exist glm instance: "+glm)}catch(e$$11){}glm=null;GLMJS_PREFIX="glm-js: ";
-GLM={$DEBUG:"undefined"!==typeof $GLM_DEBUG&&$GLM_DEBUG,version:"0.0.6b",GLM_VERSION:96,$outer:{polyfills:GLM_polyfills(),functions:{},intern:function(a,b){if(a)if(void 0===b&&"object"===typeof a)for(var c in a)GLM.$outer.intern(c,a[c]);else return GLM.$DEBUG&&GLM.$outer.console.debug("intern "+a,b&&(b.name||typeof b)),GLM.$outer[a]=b},$import:function(a){GLM.$outer.$import=function(){throw Error("glm.$outer.$import already called...");};GLM.$outer.intern(a.statics);GLM.$template.extend(GLM,GLM.$template["declare<T,V,number>"](a["declare<T,V,number>"]),
-GLM.$template["declare<T,V,...>"](a["declare<T,V,...>"]),GLM.$template["declare<T,...>"](a["declare<T,...>"]),GLM.$template["declare<T>"](a["declare<T>"]));GLM.$init(a)},console:$GLM_reset_logging(),quat_array_from_xyz:function(a){var b=glm.quat(),c=glm.mat3(1);b["*="](glm.angleAxis(a.x,c[0]));b["*="](glm.angleAxis(a.y,c[1]));b["*="](glm.angleAxis(a.z,c[2]));return b.elements},Array:Array,ArrayBuffer:ArrayBuffer,Float32Array:Float32Array,Float64Array:Float64Array,Uint8Array:Uint8Array,Uint16Array:Uint16Array,
-Uint32Array:Uint32Array,Int8Array:Int8Array,Int16Array:Int16Array,Int32Array:Int32Array,DataView:"undefined"!==typeof DataView&&DataView,$rebindTypedArrays:function(a){var b=Object.keys(GLM.$outer).filter(RegExp.prototype.test.bind(/.Array$|^ArrayBuffer$|^DataView$/)).map(function(b){var e=a.call(this,b,GLM.$outer[b]);e!==GLM.$outer[b]&&(GLM.$outer.console.warn("$rebindTypedArrays("+b+")... replacing"),GLM.$outer[b]=e);return e});GLM.$subarray=GLM.patch_subarray();return b}},$extern:$GLM_extern,$log:$GLM_log,
-GLMJSError:$GLM_GLMJSError("GLMJSError"),_radians:function(a){return a*this.PI/180}.bind(Math),_degrees:function(a){return 180*a/this.PI}.bind(Math),normalize:$GLM_extern("normalize"),inverse:$GLM_extern("inverse"),distance:$GLM_extern("distance"),length:$GLM_extern("length"),length2:$GLM_extern("length2"),transpose:$GLM_extern("transpose"),slerp:$GLM_extern("slerp"),mix:$GLM_extern("mix"),clamp:$GLM_extern("clamp"),angleAxis:$GLM_extern("angleAxis"),rotate:$GLM_extern("rotate"),scale:$GLM_extern("scale"),
-translate:$GLM_extern("translate"),lookAt:$GLM_extern("lookAt"),cross:$GLM_extern("cross"),dot:$GLM_extern("dot"),perspective:function(a,b,c,e){return GLM.$outer.mat4_perspective(a,b,c,e)},ortho:function(a,b,c,e,d,h){return GLM.$outer.mat4_ortho(a,b,c,e,d,h)},_eulerAngles:function(a){return GLM.$outer.vec3_eulerAngles(a)},angle:function(a){return 2*Math.acos(a.w)},axis:function(a){var b=1-a.w*a.w;if(0>=b)return glm.vec3(0,0,1);b=1/Math.sqrt(b);return glm.vec3(a.x*b,a.y*b,a.z*b)},$from_ptr:function(a,
-b,c){if(this!==GLM)throw new GLM.GLMJSError("... use glm.make_<type>() (not new glm.make<type>())");b=new GLM.$outer.Float32Array(b.buffer||b,c||0,a.componentLength);b=new GLM.$outer.Float32Array(b);return new a(b)},make_vec2:function(a,b){return GLM.$from_ptr.call(this,GLM.vec2,a,2===arguments.length?b:a.byteOffset)},make_vec3:function(a,b){return GLM.$from_ptr.call(this,GLM.vec3,a,2===arguments.length?b:a.byteOffset)},make_vec4:function(a,b){return GLM.$from_ptr.call(this,GLM.vec4,a,2===arguments.length?
-b:a.byteOffset)},make_quat:function(a,b){return GLM.$from_ptr.call(this,GLM.quat,a,2===arguments.length?b:a.byteOffset)},make_mat3:function(a,b){return GLM.$from_ptr.call(this,GLM.mat3,a,2===arguments.length?b:a.byteOffset)},make_mat4:function(a,b){return GLM.$from_ptr.call(this,GLM.mat4,a,2===arguments.length?b:a.byteOffset)},diagonal4x4:function(a){if("vec4"!==GLM.$typeof(a))throw new GLM.GLMJSError("unsupported argtype to GLM.diagonal4x4: "+["type:"+GLM.$typeof(a)]);a=a.elements;return new GLM.mat4([a[0],
-0,0,0,0,a[1],0,0,0,0,a[2],0,0,0,0,a[3]])},diagonal3x3:function(a){if("vec3"!==GLM.$typeof(a))throw new GLM.GLMJSError("unsupported argtype to GLM.diagonal3x3: "+["type:"+GLM.$typeof(a)]);a=a.elements;return new GLM.mat3([a[0],0,0,0,a[1],0,0,0,a[2]])},_toMat4:function(a){return new GLM.mat4(GLM.$outer.mat4_array_from_quat(a))},FAITHFUL:!0,to_string:function(a,b){try{var c=a.$type||typeof a;if(!GLM[c])throw new GLM.GLMJSError("unsupported argtype to GLM.to_string: "+["type:"+c,a]);return GLM.FAITHFUL?
-GLM.$to_string(a,b).replace(/[\t\n]/g,""):GLM.$to_string(a,b)}catch(e){return GLM.$DEBUG&&GLM.$outer.console.error("to_string error: ",c,a+"",e),e+""}},$sizeof:function(a){return a.BYTES_PER_ELEMENT},$types:[],$isGLMConstructor:function(a){return!!(a&&a.prototype instanceof GLM.$GLMBaseType)},$getGLMType:function(a){return a instanceof GLM.$GLMBaseType&&a.constructor||"string"===typeof a&&GLM[a]},$isGLMObject:function(a){return!!(a instanceof GLM.$GLMBaseType&&a.$type)},$typeof:function(a){return a instanceof
-GLM.$GLMBaseType?a.$type:"undefined"},$to_array:function(a){return[].slice.call(a.elements)},$to_json:function(a,b,c){this instanceof GLM.$GLMBaseType&&(c=b,b=a,a=this);return JSON.stringify(GLM.$to_object(a),b,c)},$inspect:function(a){this instanceof GLM.$GLMBaseType&&(a=this);return GLM.$to_json(a,null,2)},_clamp:function(a,b,c){return a<b?b:a>c?c:a},_abs:function(a){return Math.abs(a)},_equal:function(a,b){return a===b},_epsilonEqual:function(a,b,c){return Math.abs(a-b)<c},_fract:function(a){return a-
-Math.floor(a)},_frexp:function(){function a(b,c){var e=GLM.$outer.DataView||a._DataView;if(0==b)return c&&Array.isArray(c)?c[0]=c[1]=0:[0,0];e=new e(new GLM.$outer.ArrayBuffer(8));e.setFloat64(0,b);var d=e.getUint32(0)>>>20&2047;0===d&&(e.setFloat64(0,b*Math.pow(2,64)),d=(e.getUint32(0)>>>20&2047)-64);e=d-1022;d=GLM.ldexp(b,-e);return c&&Array.isArray(c)?(c[0]=e,c[1]=d):[d,e]}a._DataView=function(a){this.buffer=a;this.setFloat64=function(a,b){if(0!==a)throw Error("...this is a very limited DataView emulator");
-(new Uint8Array(this.buffer)).set([].reverse.call(new Uint8Array((new Float64Array([b])).buffer)),a)};this.getUint32=function(a){if(0!==a)throw Error("...this is a very limited DataView emulator");return(new Uint32Array((new Uint8Array([].slice.call(new Uint8Array(this.buffer)).reverse())).buffer))[1]}};return a}(),_ldexp:function(a,b){return 1023<b?a*Math.pow(2,1023)*Math.pow(2,b-1023):-1074>b?a*Math.pow(2,-1074)*Math.pow(2,b+1074):a*Math.pow(2,b)},_max:Math.max,_min:Math.min,sqrt:Math.sqrt,__sign:function(a){return 0<
-a?1:0>a?-1:+a},$constants:{epsilon:1E-6,euler:0.5772156649015329,e:Math.E,ln_ten:Math.LN10,ln_two:Math.LN2,pi:Math.PI,half_pi:Math.PI/2,quarter_pi:Math.PI/4,one_over_pi:1/Math.PI,two_over_pi:2/Math.PI,root_pi:Math.sqrt(Math.PI),root_two:Math.sqrt(2),root_three:Math.sqrt(3),two_over_root_pi:2/Math.sqrt(Math.PI),one_over_root_two:Math.SQRT1_2,root_two:Math.SQRT2},FIXEDPRECISION:6,$toFixedString:function(a,b,c,e){void 0===e&&(e=GLM.FIXEDPRECISION);if(!c||!c.map)throw Error("unsupported argtype to $toFixedString(..,..,props="+
-typeof c+")");try{var d="";c.map(function(c){c=b[d=c];if(!c.toFixed)throw Error("!toFixed in w"+[c,a,JSON.stringify(b)]);return c.toFixed(0)})}catch(h){throw GLM.$DEBUG&&GLM.$outer.console.error("$toFixedString error",a,typeof b,Object.prototype.toString.call(b),d),GLM.$DEBUG&&glm.$log("$toFixedString error",a,typeof b,Object.prototype.toString.call(b),d),new GLM.GLMJSError(h);}c=c.map(function(a){return b[a].toFixed(e)});return a+"("+c.join(", ")+")"}};GLM._sign=Math.sign||GLM.__sign;
-for(var p in GLM.$constants)(function(a,b){GLM[b]=function(){return a};GLM[b].valueOf=GLM[b]})(GLM.$constants[p],p);
-GLM.$GLMBaseType=function(){function a(a,c){var e=a.$||{};this.$type=c;this.$type_name=e.name||"<"+c+">";e.components&&(this.$components=e.components[0]);this.$len=this.components=a.componentLength;this.constructor=a;this.byteLength=a.BYTES_PER_ELEMENT;GLM.$types.push(c)}a.prototype={clone:function(){return new this.constructor(new this.elements.constructor(this.elements))},toString:function(){return GLM.$to_string(this)},inspect:function(){return GLM.$inspect(this)},toJSON:function(){return GLM.$to_object(this)}};
-Object.defineProperty(a.prototype,"address",{get:function(){var a=this.elements.byteOffset.toString(16);return"0x00000000".substr(0,10-a.length)+a}});return a}();
-(function(){function a(a,b,c){return a.subarray(b,c||a.length)}function b(a,b,c){var e=a.constructor;c=c||a.length;return new e(a.buffer,a.byteOffset+b*e.BYTES_PER_ELEMENT,c-b)}function c(){var a=new GLM.$outer.Float32Array([0,0]);a.subarray(1).subarray(0)[0]=1;var b=c.result=[a[1],(new GLM.$outer.Float32Array(16)).subarray(12,16).length];return!(a[1]!==b[0]||4!==b[1])}function e(a){var b=new GLM.$outer.Float32Array([0,0]);a(a(b,1),0)[0]=1;a=e.result=[b[1],a(new GLM.$outer.Float32Array(16),12,16).length];
-return!(b[1]!==a[0]||4!==a[1])}Object.defineProperty(GLM,"patch_subarray",{configurable:!0,value:function(){var d=!c()?b:a;d.workaround_broken_spidermonkey_subarray=b;d.native_subarray=a;if(!e(d))throw Error("failed to resolve working TypedArray.subarray implementation... "+e.result);return d}})})();GLM.$subarray=GLM.patch_subarray();
-var GLM_template=GLM.$template={_genArgError:function(a,b,c,e){~e.indexOf(void 0)&&(e=e.slice(0,e.indexOf(void 0)));var d=RegExp.prototype.test.bind(/^[^$_]/);return new GLM.GLMJSError("unsupported argtype to "+b+" "+a.$sig+": [typ="+c+"] :: got arg types: "+e.map(GLM.$template.jstypes.get)+" // supported types: "+Object.keys(a).filter(d).join("||"))},jstypes:{get:function(a){return null===a?"null":void 0===a?"undefined":a.$type||GLM.$template.jstypes[typeof a]||GLM.$template.jstypes[a+""]||function(a){if("object"===
-typeof a){if(a instanceof GLM.$outer.Float32Array)return"Float32Array";if(a instanceof GLM.$outer.ArrayBuffer)return"ArrayBuffer";if(Array.isArray(a))return"array"}return"<unknown "+[typeof a,a]+">"}(a)},"0":"float","boolean":"bool",number:"float",string:"string","[object Float32Array]":"Float32Array","[object ArrayBuffer]":"ArrayBuffer","function":"function"},_add_overrides:function(a,b){for(var c in b)b[c]&&GLM[c].override(a,b[c])},_add_inline_override:function(a,b,c){this[b]=eval(GLM.$template._traceable("glm_"+
-a+"_"+b,c))();return this},_inline_helpers:function(a,b){Object.defineProperty(a,"GLM",{value:GLM});return{$type:"built-in",$type_name:b,$template:a,F:a,dbg:b,override:this._add_inline_override.bind(a,b),link:function(c){var e=a[c];e||(e=a[[c,"undefined"]]);if(!e)throw new GLM.GLMJSError("error linking direct function for "+b+"<"+c+"> or "+b+"<"+[c,void 0]+">");return/\bthis[\[.]/.test(e+"")?e.bind(a):e}}},"template<T>":function(a,b){a.$sig="template<T>";var c=GLM.$template.jstypes,e=GLM.$template._genArgError,
-d=GLM.$GLMBaseType;return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("Tglm_"+b,function(b){this instanceof d&&(b=this);var j=[b&&b.$type||c[typeof b]||c.get(b)||"null"];if(!a[j])throw e(a,arguments.callee.dbg,j,[b]);return a[j](b)}))())},"template<T,...>":function(a,b){a.$sig="template<T,...>";var c=GLM.$template.jstypes,e=GLM.$template._genArgError,d=GLM.$GLMBaseType;return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("Tdotglm_"+b,function(b){for(var j=Array(arguments.length),
-g=0;g<j.length;g++)j[g]=arguments[g];this instanceof d&&j.unshift(b=this);g=[b&&b.$type||c[typeof b]||c.get(b)||"null"];if(!a[g])throw e(a,arguments.callee.dbg,g,j);return a[g].apply(a,j)}))())},"template<T,V,number>":function(a,b){a.$sig="template<T,V,number>";var c=GLM.$template.jstypes,e=GLM.$template._genArgError,d=GLM.GLMJSError,h=GLM.$GLMBaseType;return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("TVnglm_"+b,function(){for(var b=Array(arguments.length),g=0;g<b.length;g++)b[g]=
-arguments[g];this instanceof h&&b.unshift(this);var g=b[0],k=b[1],b=b[2],i=[g&&g.$type||c[typeof g]||c[g+""]||"<unknown "+g+">",k&&k.$type||c[typeof k]||c[k+""]||"<unknown "+k+">"];if(!a[i])throw e(a,arguments.callee.dbg,i,[g,k,b]);if("number"!==typeof b)throw new d(arguments.callee.dbg+a.$sig+": unsupported n type: "+[typeof b,b]);return a[i](g,k,b)}))())},"template<T,V,...>":function(a,b){a.$sig="template<T,V,...>";var c=GLM.$template.jstypes,e=GLM.$GLMBaseType,d=GLM.$template._genArgError,h=GLM.$outer.Array;
-return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("TVglm_"+b,function(){for(var b=new h(arguments.length),g=0;g<b.length;g++)b[g]=arguments[g];this instanceof e&&b.unshift(this);var g=b[0],k=b[1],g=[g&&g.$type||c[typeof g],k&&k.$type||c[typeof k]||c[k+""]||h.isArray(k)&&"array"+k.length+""||""+k+""];if(!a[g])throw d(a,arguments.callee.dbg,g,b);return a[g].apply(a,b)}))())},override:function(a,b,c,e,d){function h(a,c){GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+
-Object.keys(a.$template).filter(function(a){return!~a.indexOf("$")}).map(function(a){return!~c.indexOf(a)?"*"+a+"*":a}).join(" | "))}GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: ",a,b,c.$op?'$op: ["'+c.$op+'"]':"");if(!e)throw Error("unspecified target group "+e+' (expected override(<TV>, "p", {TSP}, ret={GROUP}))');var j=e[b];if(j&&j.$op!==c.$op)throw Error('glm.$template.override: mismatch merging existing override: .$op "'+[j.$op,"!=",c.$op].join(" ")+'" p='+[b,j.$op,c.$op,"||"+
-Object.keys(j.$template).join("||")]);var g=GLM.$template[a](GLM.$template.deNify(c,b),b);if(j&&j.F.$sig!==g.F.$sig)throw Error('glm.$template.override: mismatch merging existing override: .$sig "'+[j&&j.F.$sig,"!=",g.F.$sig].join(" ")+'" p='+[b,j&&j.F.$sig,g.F.$sig,"||"+Object.keys(j&&j.$template||{}).join("||")]);g.$op=c.$op;if(j){for(var k in g.$template)"$op"===k||"$sig"===k||(a=k in j.$template,!a||!0===d?(GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+k+" merged"),
-j.$template[k]=g.$template[k]):a&&GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+k+" skipped"));if(GLM.$DEBUG){var i=[];Object.keys(j.$template).forEach(function(a){a in g.$template||(GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+a+" carried-forward"),i.push(a))});h(e[b],i)}}else e[b]=g,GLM.$DEBUG&&h(e[b],[]);return e},_override:function(a,b,c){for(var e in b){if("mat4_scale"!==e&&"object"!==typeof b[e])throw new GLM.GLMJSError("expect object property overrides"+
-[e,b[e],Object.keys(c)]);"object"===typeof b[e]?this.override(a,e,b[e],c,!0):ret_scale=5}return c},slingshot:function(){return this.extend.apply(this,[].reverse.call(arguments))},extend:function(a,b){[].slice.call(arguments,1).forEach(function(b){if(b)for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e])});return a},"declare<T,V,...>":function(a){return!a?{}:this._override("template<T,V,...>",a,GLM.$outer.functions)},"declare<T>":function(a){return!a?{}:this._override("template<T>",a,GLM.$outer.functions)},
-"declare<T,...>":function(a){return!a?{}:this._override("template<T,...>",a,GLM.$outer.functions)},"declare<T,V,number>":function(a){return!a?{}:this._override("template<T,V,number>",a,GLM.$outer.functions)},_tojsname:function(a){return(a||"_").replace(/[^$a-zA-Z0-9_]/g,"_")},_traceable:function(a,b){var c=b;if("function"!==typeof c)throw new GLM.GLMJSError("_traceable expects tidy function as second arg "+c);if(!a)throw new GLM.GLMJSError("_traceable expects hint or what's the point"+[c,a]);a=this._tojsname(a||
-"_traceable");c=c.toString().replace(/^(\s*var\s*(\w+)\s*=\s*)__VA_ARGS__;/mg,function(a,b,c){return b+"new Array(arguments.length);for(var I=0;I<varname.length;I++)varname[I]=arguments[I];".replace(/I/g,"__VA_ARGS__I").replace(/varname/g,c)}).replace(/\barguments[.]callee\b/g,a);if(/^function _traceable/.test(c))throw new GLM.GLMJSError("already wrapped in a _traceable: "+[c,a]);c='function _traceable(){ "use strict"; SRC; return HINT; }'.replace("HINT",a.replace(/[$]/g,"$$$$")).replace("SRC",c.replace(/[$]/g,
-"$$$$").replace(/^function\s*\(/,"function "+a+"("));c="1,"+c;if(GLM.$DEBUG)try{eval(c)}catch(e){throw console.error("_traceable error",a,c,b,e),e;}return c},deNify:function(a,b){var c={vec:[2,3,4],mat:[3,4]},e=this._tojsname.bind(this),d;for(d in a){var h=!1;d.replace(/([vV]ec|[mM]at)(?:\w*)<N>/,function(j,g){h=!0;var k=a[d];delete a[d];c[g.toLowerCase()].forEach(function(c){var g=d.replace(/<N[*]N>/g,c*c).replace(/<N>/g,c);if(!(g in a)){var h=e("glm_"+b+"_"+g);a[g]=eval("'use strict'; 1,"+(k+"").replace(/^function\s*\(/,
-"function "+h+"(").replace(/N[*]N/g,c*c).replace(/N/g,c))}})}.bind(this));/^[$]/.test(d)?GLM.$DEBUG&&GLM.$outer.console.debug("@ NOT naming "+d):!h&&("function"===typeof a[d]&&!a[d].name)&&(GLM.$DEBUG&&GLM.$outer.console.debug("naming "+e(b+"_"+d)),a[d]=eval(this._traceable("glm_"+b+"_"+d,a[d]))())}return a},$_module_stamp:+new Date,_iso:"/[*][^/*]*[*]/",_get_argnames:function(a){return(a+"").replace(/\s+/g,"").replace(RegExp(this._iso,"g"),"").split("){",1)[0].replace(/^[^(]*[(]/,"").replace(/=[^,]+/g,
-"").split(",").filter(Boolean)},_fix_$_names:function(a,b){Object.keys(b).filter(function(a){return"function"===typeof b[a]&&!b[a].name}).map(function(c){var e=a+"_"+c;GLM.$DEBUG&&GLM.$outer.console.debug("naming $."+c+" == "+e,this._traceable(e,b[c]));b[c]=eval(this._traceable("glm_"+e,b[c]))()}.bind(this));return b},_typedArrayMaker:function(a,b){return function(c){if(c.length===a)return new b(c);var e=new b(a);e.set(c);return e}},GLMType:function(a,b){var c=this._fix_$_names(a,b),e=c.identity.length,
-d,h=Object,j=GLM.$template._get_argnames.bind(GLM.$template),g=GLM.GLMJSError,k={},i;for(i in c)"function"===typeof c[i]&&function(a){k[i]=function(b){return a.apply(c,b)}}(c[i]);d=function(b){var d=k[typeof b[0]+b.length];if(!d){var e="glm."+a;b=e+"("+b.map(function(a){return typeof a})+")";d=h.keys(c).filter(function(a){return"function"===typeof c[a]&&/^\w+\d+$/.test(a)}).map(function(a){return e+"("+j(c[a])+")"});throw new g("no constructor found for: "+b+"\nsupported signatures:\n\t"+d.join("\n\t"));
-}return d};var w,r=GLM;GLM.$template._get_argnames.bind(GLM.$template);w=function(b,c){2<r.$DEBUG&&r.$outer.console.info("adopting elements...",typeof b);if(b.length!=e){if(!1===c)return c;r.$outer.console.error(a+" elements size mismatch: "+["wanted:"+e,"handed:"+b.length]);var d=r.$subarray(b,0,e);throw new r.GLMJSError(a+" elements size mismatch: "+["wanted:"+e,"handed:"+b.length,"theoreticaly-correctable?:"+(d.length===e)]);}return b};var m=this._typedArrayMaker(e,GLM.$outer.Float32Array),q,s=
-GLM.$outer;q=function(a){return a instanceof s.Float32Array};var t=function(a,b,c,g,h,i,j,k){return eval(k("glm_"+h+"$class",function(c){for(var f=new a(arguments.length),g=0;g<f.length;g++)f[g]=arguments[g];var h=d(f),g=t;if(this instanceof g)f=q(c)?w(c):m(h(f)),b.defineProperty(this,"elements",{enumerable:!1,configurable:!0,value:f});else return f=q(c)&&c.length===e?m(c):h(f),new g(f)}))()}(Array,Object,GLM,c,a,GLM.$template._get_argnames.bind(GLM.$template),GLM.GLMJSError,GLM.$template._traceable.bind(GLM.$template));
-c.components=c.components?c.components.map(function(a){return"string"===typeof a?a.split(""):a}):[];t.$=c;t.componentLength=e;t.BYTES_PER_ELEMENT=e*GLM.$outer.Float32Array.BYTES_PER_ELEMENT;t.prototype=new GLM.$GLMBaseType(t,a);t.toJSON=function(){var b={glm$type:a,glm$class:t.prototype.$type_name,glm$eg:(new t).object},c;for(c in t)/function |^[$]/.test(c+t[c])||(b[c]=t[c]);return b};return t}};
-GLM.$template["declare<T,V,...>"]({cross:{"vec2,vec2":function(a,b){return this.GLM.vec3(0,0,a.x*b.y-a.y*b.x)}},distance:{"vec<N>,vec<N>":function(a,b){return this.GLM.length(b.sub(a))}}});
-GLM.$template["declare<T,V,number>"]({mix:{"float,float":function(a,b,c){return b*c+a*(1-c)},"vec<N>,vec<N>":function(a,b,c){var e=1-c,d=new this.GLM.vecN(new a.elements.constructor(N)),h=d.elements;a=a.elements;b=b.elements;for(var j=0;j<N;j++)h[j]=b[j]*c+a[j]*e;return d}},clamp:{"float,float":function(a,b,c){return GLM._clamp(a,b,c)},"vec<N>,float":function(a,b,c){return new GLM.vecN(GLM.$to_array(a).map(function(a){return GLM._clamp(a,b,c)}))}},epsilonEqual:{"float,float":GLM._epsilonEqual,"vec<N>,vec<N>":function(a,
-b,c){for(var e=this["float,float"],d=glm.bvecN(),h=0;h<N;h++)d[h]=e(a[h],b[h],c);return d},"ivec<N>,ivec<N>":function(a,b,c){return this["vecN,vecN"](a,b,c)},"uvec<N>,uvec<N>":function(a,b,c){return this["vecN,vecN"](a,b,c)},"quat,quat":function(a,b,c){for(var e=this["float,float"],d=glm.bvec4(),h=0;4>h;h++)d[h]=e(a[h],b[h],c);return d},"mat<N>,mat<N>":function(){throw new GLM.GLMJSError("error: 'epsilonEqual' only accept floating-point and integer scalar or vector inputs");}}});
-GLM.$template.extend(GLM,GLM.$template["declare<T>"]({degrees:{"float":function(a){return this.GLM._degrees(a)},"vec<N>":function(a){return new this.GLM.vecN(this.GLM.$to_array(a).map(this.GLM._degrees))}},radians:{"float":function(a){return this.GLM._radians(a)},"vec<N>":function(a){return new this.GLM.vecN(this.GLM.$to_array(a).map(this.GLM._radians))}},sign:{"null":function(){return 0},undefined:function(){return NaN},string:function(){return NaN},"float":function(a){return GLM._sign(a)},"vec<N>":function(a){return new GLM.vecN(GLM.$to_array(a).map(GLM._sign))},
-"ivec<N>":function(a){return new GLM.ivecN(GLM.$to_array(a).map(GLM._sign))}},abs:{"float":function(a){return GLM._abs(a)},"vec<N>":function(a){return new GLM.vecN(GLM.$to_array(a).map(GLM._abs))}},fract:{"float":function(a){return GLM._fract(a)},"vec<N>":function(a){return new GLM.vecN(GLM.$to_array(a).map(GLM._fract))}},all:{"vec<N>":function(a){return N===GLM.$to_array(a).filter(Boolean).length},"bvec<N>":function(a){return N===GLM.$to_array(a).filter(Boolean).length},"ivec<N>":function(a){return N===
-GLM.$to_array(a).filter(Boolean).length},"uvec<N>":function(a){return N===GLM.$to_array(a).filter(Boolean).length},quat:function(a){return 4===GLM.$to_array(a).filter(Boolean).length}},$to_object:{vec2:function(a){return{x:a.x,y:a.y}},vec3:function(a){return{x:a.x,y:a.y,z:a.z}},vec4:function(a){return{x:a.x,y:a.y,z:a.z,w:a.w}},uvec2:function(a){return{x:a.x,y:a.y}},uvec3:function(a){return{x:a.x,y:a.y,z:a.z}},uvec4:function(a){return{x:a.x,y:a.y,z:a.z,w:a.w}},ivec2:function(a){return{x:a.x,y:a.y}},
-ivec3:function(a){return{x:a.x,y:a.y,z:a.z}},ivec4:function(a){return{x:a.x,y:a.y,z:a.z,w:a.w}},bvec2:function(a){return{x:!!a.x,y:!!a.y}},bvec3:function(a){return{x:!!a.x,y:!!a.y,z:!!a.z}},bvec4:function(a){return{x:!!a.x,y:!!a.y,z:!!a.z,w:!!a.w}},quat:function(a){return{w:a.w,x:a.x,y:a.y,z:a.z}},mat3:function(a){return{"0":this.vec3(a[0]),1:this.vec3(a[1]),2:this.vec3(a[2])}},mat4:function(a){return{"0":this.vec4(a[0]),1:this.vec4(a[1]),2:this.vec4(a[2]),3:this.vec4(a[3])}}},roll:{$atan2:Math.atan2,
-quat:function(a){return this.$atan2(2*(a.x*a.y+a.w*a.z),a.w*a.w+a.x*a.x-a.y*a.y-a.z*a.z)}},pitch:{$atan2:Math.atan2,quat:function(a){return this.$atan2(2*(a.y*a.z+a.w*a.x),a.w*a.w-a.x*a.x-a.y*a.y+a.z*a.z)}},yaw:{$asin:Math.asin,quat:function(a){return this.$asin(this.GLM.clamp(-2*(a.x*a.z-a.w*a.y),-1,1))}},eulerAngles:{quat:function(a){return this.GLM.vec3(this.GLM.pitch(a),this.GLM.yaw(a),this.GLM.roll(a))}}}),GLM.$template["declare<T,...>"]({$from_glsl:{string:function(a,b){var c;a.replace(/^([$\w]+)\(([-.0-9ef, ]+)\)$/,
-function(a,d,h){a=glm[d]||glm["$"+d];if(!a)throw new GLM.GLMJSError("glsl decoding issue: unknown type '"+d+"'");c=h.split(",").map(parseFloat);if(!b||b===a)c=a.apply(glm,c);else{if(!0===b||b===Array){for(;c.length<a.componentLength;)c.push(c[c.length-1]);return c}throw new GLM.GLMJSError("glsl decoding issue: second argument expected to be undefined|true|Array");}});return c}},$to_glsl:{"vec<N>":function(a,b){var c=GLM.$to_array(a);b&&("object"===typeof b&&"precision"in b)&&(c=c.map(function(a){return a.toFixed(b.precision)}));
-for(;c.length&&c[c.length-2]===c[c.length-1];)c.pop();return a.$type+"("+c+")"},"uvec<N>":function(a,b){return this.vecN(a,b)},"ivec<N>":function(a,b){return this.vecN(a,b)},"bvec<N>":function(a,b){return this.vecN(a,b)},quat:function(a,b){var c;b&&("object"===typeof b&&"precision"in b)&&(c=b.precision);return 0===a.x+a.y+a.z?"quat("+(void 0===c?a.w:a.w.toFixed(c))+")":this.vec4(a,b)},"mat<N>":function(a,b){var c;b&&("object"===typeof b&&"precision"in b)&&(c=b.precision);var e=GLM.$to_array(a);void 0!==
-c&&(e=e.map(function(a){return a.toFixed(c)}));return e.reduce(function(a,b){return a+1*b},0)===e[0]*N?"matN("+e[0]+")":"matN("+e+")"}},frexp:{"float":function(a,b){return 1===arguments.length?this["float,undefined"](a):this["float,array"](a,b)},"vec<N>":function(a,b){if(2>arguments.length)throw new GLM.GLMJSError("frexp(vecN, ivecN) expected ivecN as second parameter");return GLM.vecN(GLM.$to_array(a).map(function(a,e){var d=GLM._frexp(a);b[e]=d[1];return d[0]}))},"float,undefined":function(a){return GLM._frexp(a)},
-"float,array":function(a,b){return GLM._frexp(a,b)}},ldexp:{"float":GLM._ldexp,"vec<N>":function(a,b){return GLM.vecN(GLM.$to_array(a).map(function(a,e){return GLM._ldexp(a,b[e])}))}}}));
-GLM.$template["declare<T,V,...>"]({rotate:{"float,vec3":function(a,b){return this.GLM.$outer.mat4_angleAxis(a,b)},"mat4,float":function(a,b,c){return a.mul(this.GLM.$outer.mat4_angleAxis(b,c))}},scale:{$outer:GLM.$outer,"mat4,vec3":function(a,b){return a.mul(this.$outer.mat4_scale(b))},"vec3,undefined":function(a){return this.$outer.mat4_scale(a)}},translate:{"mat4,vec3":function(a,b){return a.mul(this.GLM.$outer.mat4_translation(b))},"vec3,undefined":function(a){return this.GLM.$outer.mat4_translation(a)}},
-angleAxis:{"float,vec3":function(a,b){return this.GLM.$outer.quat_angleAxis(a,b)}},min:{"float,float":function(a,b){return this.GLM._min(a,b)},"vec<N>,float":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a){return this.GLM._min(a,b)}.bind(this)))}},max:{"float,float":function(a,b){return this.GLM._max(a,b)},"vec<N>,float":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a){return this.GLM._max(a,b)}.bind(this)))}},equal:{"float,float":GLM._equal,
-"vec<N>,vec<N>":function(a,b){for(var c=this["float,float"],e=glm.bvecN(),d=0;d<N;d++)e[d]=c(a[d],b[d]);return e},"bvec<N>,bvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"quat,quat":function(a,b){for(var c=this["float,float"],e=glm.bvec4(),d=0;4>d;d++)e[d]=c(a[d],b[d]);return e}},_slerp:{"quat,quat":function(a,b,c){var e=b,d=glm.dot(glm.vec4(a),glm.vec4(b));0>d&&(e=
-b.mul(-1),d=-d);if(d>1-glm.epsilon())return glm.quat(glm.mix(a.w,e.w,c),glm.mix(a.x,e.x,c),glm.mix(a.y,e.y,c),glm.mix(a.z,e.z,c));b=Math.acos(d);return(a.mul(Math.sin((1-c)*b))+e.mul(Math.sin(c*b)))/Math.sin(b)}},rotation:{"vec3,vec3":function(a,b){var c=this.$dot(a,b),e=new a.constructor(new a.elements.constructor(3));if(c>=1-this.$epsilon)return this.$quat();if(c<-1+this.$epsilon)return e=this.$cross(this.$m[2],a),this.$length2(e)<this.$epsilon&&(e=this.$cross(this.$m[0],a)),e=this.$normalize(e),
-this.$angleAxis(this.$pi,e);var e=this.$cross(a,b),c=this.$sqrt(2*(1+c)),d=1/c;return this.$quat(0.5*c,e.x*d,e.y*d,e.z*d)}},project:{"vec3,mat4":function(a,b,c,e){a=glm.vec4(a,1);a=b["*"](a);a=c["*"](a);a["/="](a.w);a=a["*"](0.5)["+"](0.5);a[0]=a[0]*e[2]+e[0];a[1]=a[1]*e[3]+e[1];return glm.vec3(a)}},unProject:{"vec3,mat4":function(a,b,c,e){b=glm.inverse(c["*"](b));a=glm.vec4(a,1);a.x=(a.x-e[0])/e[2];a.y=(a.y-e[1])/e[3];a=a["*"](2)["-"](glm.vec4(1));e=b["*"](a);e["/="](e.w);return glm.vec3(e)}},orientedAngle:{"vec3,vec3":function(a,
-b,c){var e=Math.acos(glm.clamp(glm.dot(a,b),0,1));return glm.mix(e,-e,0>glm.dot(c,glm.cross(a,b))?1:0)}}});
-GLM.$to_string=GLM.$template["declare<T,...>"]({$to_string:{"function":function(a){return"[function "+(a.name||"anonymous")+"]"},ArrayBuffer:function(a){return"[object ArrayBuffer "+JSON.stringify({byteLength:a.byteLength})+"]"},Float32Array:function(a){return"[object Float32Array "+JSON.stringify({length:a.length,byteOffset:a.byteOffset,byteLength:a.byteLength,BPE:a.BYTES_PER_ELEMENT})+"]"},"float":function(a,b){return GLM.$toFixedString("float",{value:a},["value"],b&&b.precision)},string:function(a){return a},
-bool:function(a){return"bool("+a+")"},"vec<N>":function(a,b){return GLM.$toFixedString(a.$type_name,a,a.$components,b&&b.precision)},"uvec<N>":function(a,b){return GLM.$toFixedString(a.$type_name,a,a.$components,b&&"object"===typeof b&&b.precision||0)},"ivec<N>":function(a,b){return GLM.$toFixedString(a.$type_name,a,a.$components,b&&"object"===typeof b&&b.precision||0)},"bvec<N>":function(a){return a.$type_name+"("+GLM.$to_array(a).map(Boolean).join(", ")+")"},"mat<N>":function(a,b){var c=[0,1,2,
-3].slice(0,N).map(function(b){return a[b]}).map(function(a){return GLM.$toFixedString("\t",a,a.$components,b&&b.precision)});return a.$type_name+"(\n"+c.join(", \n")+"\n)"},quat:function(a,b){a=GLM.degrees(GLM.eulerAngles(a));return GLM.$toFixedString("<quat>"+a.$type_name,a,["x","y","z"],b&&b.precision)}}}).$to_string;
-GLM.$template["declare<T,V,...>"]({copy:{$op:"=","vec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"vec<N>,array<N>":function(a,b){a.elements.set(b);return a},"vec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"vec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"vec<N>,bvec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,array<N>":function(a,b){a.elements.set(b);return a},
-"uvec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,bvec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,array<N>":function(a,b){a.elements.set(b);return a},"ivec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,bvec<N>":function(a,
-b){a.elements.set(b.elements);return a},"bvec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"bvec<N>,array<N>":function(a,b){a.elements.set(b);return a},"bvec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"bvec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"bvec<N>,bvec<N>":function(a,b){a.elements.set(b.elements);return a},"quat,quat":function(a,b){a.elements.set(b.elements);return a},"mat<N>,mat<N>":function(a,b){a.elements.set(b.elements);return a},
-"mat<N>,array<N>":function(a,b){b=b.reduce(function(a,b){if(!a.concat)throw new GLM.GLMJSError("matN,arrayN -- [[.length===4] x 4] expected");return a.concat(b)});if(b===N)throw new GLM.GLMJSError("matN,arrayN -- [[N],[N],[N],[N]] expected");return a["="](b)},"mat<N>,array<N*N>":function(a,b){a.elements.set(b);return a},"mat4,array9":function(a,b){a.elements.set((new GLM.mat4(b)).elements);return a}},sub:{$op:"-",_sub:function(a,b){return this.GLM.$to_array(a).map(function(a,e){return a-b[e]})},"vec<N>,vec<N>":function(a,
-b){return new this.GLM.vecN(this._sub(a,b))},"vec<N>,uvec<N>":function(a,b){return new this.GLM.vecN(this._sub(a,b))},"uvec<N>,uvec<N>":function(a,b){return new this.GLM.uvecN(this._sub(a,b))},"uvec<N>,ivec<N>":function(a,b){return new this.GLM.uvecN(this._sub(a,b))},"vec<N>,ivec<N>":function(a,b){return new this.GLM.vecN(this._sub(a,b))},"ivec<N>,uvec<N>":function(a,b){return new this.GLM.ivecN(this._sub(a,b))},"ivec<N>,ivec<N>":function(a,b){return new this.GLM.ivecN(this._sub(a,b))}},sub_eq:{$op:"-=",
-"vec<N>,vec<N>":function(a,b){for(var c=a.elements,e=b.elements,d=0;d<N;d++)c[d]-=e[d];return a},"vec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"vec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)}},add:{$op:"+",_add:function(a,
-b){return this.GLM.$to_array(a).map(function(a,e){return a+b[e]})},"vec<N>,float":function(a,b){return new this.GLM.vecN(this._add(a,[b,b,b,b]))},"vec<N>,vec<N>":function(a,b){return new this.GLM.vecN(this._add(a,b))},"vec<N>,uvec<N>":function(a,b){return new this.GLM.vecN(this._add(a,b))},"uvec<N>,uvec<N>":function(a,b){return new this.GLM.uvecN(this._add(a,b))},"uvec<N>,ivec<N>":function(a,b){return new this.GLM.uvecN(this._add(a,b))},"vec<N>,ivec<N>":function(a,b){return new this.GLM.vecN(this._add(a,
-b))},"ivec<N>,ivec<N>":function(a,b){return new this.GLM.ivecN(this._add(a,b))},"ivec<N>,uvec<N>":function(a,b){return new this.GLM.ivecN(this._add(a,b))}},add_eq:{$op:"+=","vec<N>,vec<N>":function(a,b){for(var c=a.elements,e=b.elements,d=0;d<N;d++)c[d]+=e[d];return a},"vec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"vec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,
-b)},"ivec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)}},div:{$op:"/","vec<N>,float":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a){return a/b}))}},div_eq:{$op:"/=","vec<N>,float":function(a,b){for(var c=0;c<N;c++)a.elements[c]/=b;return a}},mul:{$op:"*","vec<N>,vec<N>":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a,e){return a*b[e]}))}},eql_epsilon:function(a){return{$op:"~=",
-"vec<N>,vec<N>":a,"mat<N>,mat<N>":a,"quat,quat":a,"uvec<N>,uvec<N>":a,"ivec<N>,ivec<N>":a}}(function(a,b){return this.GLM.all(this.GLM.epsilonEqual(a,b,this.GLM.epsilon()))}),eql:function(a){return{$op:"==","mat<N>,mat<N>":function(a,c){return c.elements.length===glm.$to_array(a).filter(function(a,b){return a===c.elements[b]}).length},"vec<N>,vec<N>":a,"quat,quat":a,"uvec<N>,uvec<N>":a,"ivec<N>,ivec<N>":a,"bvec<N>,bvec<N>":a}}(function(a,b){return GLM.all(GLM.equal(a,b))})});
-GLM.string={$type_name:"string",$:{}};GLM.number={$type_name:"float",$:{}};GLM["boolean"]={$type:"bool",$type_name:"bool",$:{}};
-GLM.vec2=GLM.$template.GLMType("vec2",{name:"fvec2",identity:[0,0],components:["xy","01"],undefined0:function(){return this.identity},number1:function(a){return[a,a]},number2:function(a,b){return[a,b]},object1:function(a){if(null!==a)switch(a.length){case 4:case 3:case 2:return[a[0],a[1]];default:if("y"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new GLM.GLMJSError("unrecognized .x-ish object passed to GLM.vec2: "+a);return"string"===typeof a.x?[1*a.x,1*a.y]:[a.x,a.y]}}throw new GLM.GLMJSError("unrecognized object passed to GLM.vec2: "+
-a);}});
-GLM.uvec2=GLM.$template.GLMType("uvec2",{name:"uvec2",identity:[0,0],components:["xy","01"],_clamp:function(a){return~~a},undefined0:function(){return this.identity},number1:function(a){a=this._clamp(a);return[a,a]},number2:function(a,b){a=this._clamp(a);b=this._clamp(b);return[a,b]},object1:function(a){switch(a.length){case 4:case 3:case 2:return[a[0],a[1]].map(this._clamp);default:if("y"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new GLM.GLMJSError("unrecognized .x-ish object passed to GLM."+this.name+
-": "+a);return[a.x,a.y].map(this._clamp)}}throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+": "+a);}});
-GLM.vec3=GLM.$template.GLMType("vec3",{name:"fvec3",identity:[0,0,0],components:["xyz","012","rgb"],undefined0:function(){return GLM.vec3.$.identity},number1:function(a){return[a,a,a]},number2:function(a,b){return[a,b,b]},number3:function(a,b,c){return[a,b,c]},Error:GLM.GLMJSError,object1:function(a){if(a)switch(a.length){case 4:case 3:return[a[0],a[1],a[2]];case 2:return[a[0],a[1],a[1]];default:if("z"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new this.Error("unrecognized .x-ish object passed to GLM.vec3: "+
-a);return"string"===typeof a.x?[1*a.x,1*a.y,1*a.z]:[a.x,a.y,a.z]}}throw new this.Error("unrecognized object passed to GLM.vec3: "+a);},object2:function(a,b){if(a instanceof GLM.vec2||a instanceof GLM.uvec2||a instanceof GLM.ivec2||a instanceof GLM.bvec2)return[a.x,a.y,b];throw new GLM.GLMJSError("unrecognized object passed to GLM.vec3(o,z): "+[a,b]);}});
-GLM.uvec3=GLM.$template.GLMType("uvec3",{name:"uvec3",identity:[0,0,0],components:["xyz","012"],_clamp:GLM.uvec2.$._clamp,undefined0:function(){return this.identity},number1:function(a){a=this._clamp(a);return[a,a,a]},number2:function(a,b){a=this._clamp(a);b=this._clamp(b);return[a,b,b]},number3:function(a,b,c){a=this._clamp(a);b=this._clamp(b);c=this._clamp(c);return[a,b,c]},object1:function(a){if(a)switch(a.length){case 4:case 3:return[a[0],a[1],a[2]].map(this._clamp);case 2:return[a[0],a[1],a[1]].map(this._clamp);
-default:if("z"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new GLM.GLMJSError("unrecognized .x-ish object passed to GLM."+this.name+": "+a);return[a.x,a.y,a.z].map(this._clamp)}}throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+": "+a);},object2:function(a,b){if(a instanceof GLM.vec2)return[a.x,a.y,b].map(this._clamp);if(a instanceof GLM.uvec2||a instanceof GLM.ivec2||a instanceof GLM.bvec2)return[a.x,a.y,this._clamp(b)];throw new GLM.GLMJSError("unrecognized object passed to GLM."+
-this.name+"(o,z): "+[a,b]);}});
-GLM.vec4=GLM.$template.GLMType("vec4",{name:"fvec4",identity:[0,0,0,0],components:["xyzw","0123","rgba"],undefined0:function(){return this.identity},number1:function(a){return[a,a,a,a]},number2:function(a,b){return[a,b,b,b]},number3:function(a,b,c){return[a,b,c,c]},number4:function(a,b,c,e){return[a,b,c,e]},Error:GLM.GLMJSError,object1:function(a){if(a)switch(a.length){case 4:return[a[0],a[1],a[2],a[3]];case 3:return[a[0],a[1],a[2],a[2]];case 2:return[a[0],a[1],a[1],a[1]];default:if("w"in a&&"x"in
-a){if(typeof a.x!==typeof a.w)throw new this.Error("unrecognized .x-ish object passed to GLM.vec4: "+a);return"string"===typeof a.x?[1*a.x,1*a.y,1*a.z,1*a.w]:[a.x,a.y,a.z,a.w]}}throw new this.Error("unrecognized object passed to GLM.vec4: "+[a,a&&a.$type]);},$GLM:GLM,object2:function(a,b){if(a instanceof this.$GLM.vec3||a instanceof this.$GLM.uvec3||a instanceof this.$GLM.ivec3||a instanceof this.$GLM.bvec3)return[a.x,a.y,a.z,b];throw new this.$GLM.GLMJSError("unrecognized object passed to GLM.vec4(o,w): "+
-[a,b]);},object3:function(a,b,c){if(a instanceof this.$GLM.vec2||a instanceof this.$GLM.uvec2||a instanceof this.$GLM.ivec2||a instanceof this.$GLM.bvec2)return[a.x,a.y,b,c];throw new this.$GLM.GLMJSError("unrecognized object passed to GLM.vec4(o,z,w): "+[a,b,c]);}});
-GLM.uvec4=GLM.$template.GLMType("uvec4",{name:"uvec4",identity:[0,0,0,0],components:["xyzw","0123"],_clamp:GLM.uvec2.$._clamp,undefined0:function(){return this.identity},number1:function(a){a=this._clamp(a);return[a,a,a,a]},number2:function(a,b){a=this._clamp(a);b=this._clamp(b);return[a,b,b,b]},number3:function(a,b,c){a=this._clamp(a);b=this._clamp(b);c=this._clamp(c);return[a,b,c,c]},number4:function(a,b,c,e){return[a,b,c,e].map(this._clamp)},Error:GLM.GLMJSError,object1:function(a){if(a)switch(a.length){case 4:return[a[0],
-a[1],a[2],a[3]].map(this._clamp);case 3:return[a[0],a[1],a[2],a[2]].map(this._clamp);case 2:return[a[0],a[1],a[1],a[1]].map(this._clamp);default:if("w"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new this.Error("unrecognized .x-ish object passed to GLM."+this.name+": "+a);return[a.x,a.y,a.z,a.w].map(this._clamp)}}throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+": "+[a,a&&a.$type]);},object2:function(a,b){if(a instanceof GLM.vec3)return[a.x,a.y,a.z,b].map(this._clamp);if(a instanceof
-GLM.uvec3||a instanceof GLM.ivec3||a instanceof GLM.bvec3)return[a.x,a.y,a.z,this._clamp(b)];throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+"(o,w): "+[a,b]);},object3:function(a,b,c){if(a instanceof GLM.vec2)return[a.x,a.y,b,c].map(this._clamp);if(a instanceof GLM.uvec2||a instanceof GLM.ivec2||a instanceof GLM.bvec2)return[a.x,a.y,this._clamp(b),this._clamp(c)];throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+"(o,z,w): "+[a,b,c]);}});
-GLM.ivec2=GLM.$template.GLMType("ivec2",GLM.$template.extend({},GLM.uvec2.$,{name:"ivec2"}));GLM.ivec3=GLM.$template.GLMType("ivec3",GLM.$template.extend({},GLM.uvec3.$,{name:"ivec3"}));GLM.ivec4=GLM.$template.GLMType("ivec4",GLM.$template.extend({},GLM.uvec4.$,{name:"ivec4"}));GLM.bvec2=GLM.$template.GLMType("bvec2",GLM.$template.extend({},GLM.uvec2.$,{name:"bvec2",boolean1:GLM.uvec2.$.number1,boolean2:GLM.uvec2.$.number2}));
-GLM.bvec3=GLM.$template.GLMType("bvec3",GLM.$template.extend({},GLM.uvec3.$,{name:"bvec3",boolean1:GLM.uvec3.$.number1,boolean2:GLM.uvec3.$.number2,boolean3:GLM.uvec3.$.number3}));GLM.bvec4=GLM.$template.GLMType("bvec4",GLM.$template.extend({},GLM.uvec4.$,{name:"bvec4",boolean1:GLM.uvec4.$.number1,boolean2:GLM.uvec4.$.number2,boolean3:GLM.uvec4.$.number3,boolean4:GLM.uvec4.$.number4}));GLM.bvec2.$._clamp=GLM.bvec3.$._clamp=GLM.bvec4.$._clamp=function(a){return!!a};
-GLM.mat3=GLM.$template.GLMType("mat3",{name:"mat3x3",identity:[1,0,0,0,1,0,0,0,1],undefined0:function(){return this.identity},number1:function(a){return 1===a?this.identity:[a,0,0,0,a,0,0,0,a]},number9:function(a,b,c,e,d,h,j,g,k){return arguments},Error:GLM.GLMJSError,$vec3:GLM.vec3,object1:function(a){if(a){var b=a.elements||a;if(16===b.length)return[b[0],b[1],b[2],b[4],b[5],b[6],b[8],b[9],b[10]];if(9===b.length)return b;if(0 in b&&1 in b&&2 in b&&!(3 in b)&&"object"===typeof b[2])return[b[0],b[1],
-b[2]].map(this.$vec3.$.object1).reduce(function(a,b){return a.concat(b)})}throw new this.Error("unrecognized object passed to GLM.mat3: "+a);},object3:function(a,b,c){return[a,b,c].map(glm.$to_array).reduce(function(a,b){return a.concat(b)})}});
-GLM.mat4=GLM.$template.GLMType("mat4",{name:"mat4x4",identity:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],undefined0:function(){return this.identity},number16:function(a,b,c,e,d,h,j,g,k,i,w,r,m,q,s,t){return arguments},number1:function(a){return 1===a?this.identity:[a,0,0,0,0,a,0,0,0,0,a,0,0,0,0,a]},Error:GLM.GLMJSError,$vec4:GLM.vec4,object1:function(a){var b;if(a){b=a.elements||a;if(9===b.length)return[b[0],b[1],b[2],0,b[3],b[4],b[5],0,b[6],b[7],b[8],0,0,0,0,1];if(4===b.length&&b[0]&&4===b[0].length)return b[0].concat(b[1],
-b[2],b[3]);if(16===b.length)return b;if(0 in b&&1 in b&&2 in b&&3 in b&&!(4 in b)&&"object"===typeof b[3])return[b[0],b[1],b[2],b[3]].map(this.$vec4.$.object1).reduce(function(a,b){return a.concat(b)})}throw new this.Error("unrecognized object passed to GLM.mat4: "+[a,b&&b.length]);},object4:function(a,b,c,e){return[a,b,c,e].map(glm.$to_array).reduce(function(a,b){return a.concat(b)})}});
-GLM.quat=GLM.$template.GLMType("quat",{identity:[0,0,0,1],components:["xyzw","0123"],undefined0:function(){return this.identity},number1:function(a){if(1!==a)throw Error("only quat(1) syntax supported for quat(number1 args)...");return this.identity},number4:function(a,b,c,e){return[b,c,e,a]},$GLM:GLM,$M3:GLM.mat3(),$quat_array_from_zyx:function(a){var b=this.$M3;return this.$GLM.$outer.quat_angleAxis(a.z,b[2]).mul(this.$GLM.$outer.quat_angleAxis(a.y,b[1])).mul(this.$GLM.$outer.quat_angleAxis(a.x,
-b[0])).elements},object1:function(a){if(a){if(a instanceof this.$GLM.mat4)return this.$GLM.$outer.quat_array_from_mat4(a);if(4===a.length)return[a[0],a[1],a[2],a[3]];if(a instanceof this.$GLM.quat)return[a.x,a.y,a.z,a.w];if(a instanceof this.$GLM.vec3)return this.$quat_array_from_zyx(a);if("w"in a&&"x"in a)return"string"===typeof a.x?[1*a.x,1*a.y,1*a.z,1*a.w]:[a.x,a.y,a.z,a.w]}throw new this.$GLM.GLMJSError("unrecognized object passed to GLM.quat.object1: "+[a,a&&a.$type,typeof a,a&&a.constructor]);
-}});
-(function(){var a=function(a,b,c,e){var k={def:function(b,c){this[b]=c;Object.defineProperty(a.prototype,b,c)}};a.$properties=a.$properties||k;var i=a.$properties.def.bind(a.$properties),w=[0,1,2,3].map(function(a){return{enumerable:c,get:function(){return this.elements[a]},set:function(b){this.elements[a]=b}}});b.forEach(function(a,b){i(a,w[b])});if(isNaN(b[0])&&!/^_/.test(b[0])){var k=b.slice(),r=GLM.$subarray;do(function(a,b,c){"quat"===b&&(b="vec"+c);var d=GLM[b];i(a,{enumerable:!1,get:function(){return new d(r(this.elements,0*
-c,1*c))},set:function(a){return(new d(r(this.elements,0*c,1*c)))["="](a)}})})(k.join(""),a.prototype.$type.replace(/[1-9]$/,k.length),k.length);while(k[1]!=k.pop());if(e)return a.$properties;k=b.slice();if(b={xyz:{yz:1},xyzw:{yzw:1,yz:1,zw:2}}[k.join("")])for(var m in b)(function(a,b,c,d){i(a,{enumerable:!1,get:function(){return new GLM[b](GLM.$subarray(this.elements,0*c+d,1*c+d))},set:function(a){return(new GLM[b](GLM.$subarray(this.elements,0*c+d,1*c+d)))["="](a)}})})(m,a.prototype.$type.replace(/[1-9]$/,
-m.length),m.length,b[m])}return a.$properties};a(GLM.vec2,GLM.vec2.$.components[0],!0);a(GLM.vec2,GLM.vec2.$.components[1]);a(GLM.vec3,GLM.vec3.$.components[0],!0);a(GLM.vec3,GLM.vec3.$.components[1]);a(GLM.vec3,GLM.vec3.$.components[2]);a(GLM.vec4,GLM.vec4.$.components[0],!0);a(GLM.vec4,GLM.vec4.$.components[1]);a(GLM.vec4,GLM.vec4.$.components[2]);a(GLM.quat,GLM.quat.$.components[0],!0,"noswizzles");a(GLM.quat,GLM.quat.$.components[1]);GLM.quat.$properties.def("wxyz",{enumerable:!1,get:function(){return new GLM.vec4(this.w,
-this.x,this.y,this.z)},set:function(a){a=GLM.vec4(a);return this["="](GLM.quat(a.x,a.y,a.z,a.w))}});"uvec2 uvec3 uvec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4".split(" ").forEach(function(b){a(GLM[b],GLM[b].$.components[0],!0);a(GLM[b],GLM[b].$.components[1])});Object.defineProperty(GLM.quat.prototype,"_x",{get:function(){throw Error("erroneous quat._x access");}});var b={2:{yx:{enumerable:!1,get:function(){return new GLM.vec2(this.y,this.x)},set:function(a){a=GLM.vec2(a);this.y=a[0];this.x=a[1]}}},3:{xz:{enumerable:!1,
-get:function(){return new GLM.vec2(this.x,this.z)},set:function(a){a=GLM.vec2(a);this.x=a[0];this.z=a[1]}},zx:{enumerable:!1,get:function(){return new GLM.vec2(this.z,this.x)},set:function(a){a=GLM.vec2(a);this.z=a[0];this.x=a[1]}},xzy:{enumerable:!1,get:function(){return new GLM.vec3(this.x,this.z,this.y)},set:function(a){a=GLM.vec3(a);this.x=a[0];this.z=a[1];this.y=a[2]}}},4:{xw:{enumerable:!1,get:function(){return new GLM.vec2(this.x,this.w)},set:function(a){a=GLM.vec2(a);this.x=a[0];this.w=a[1]}},
-wz:{enumerable:!1,get:function(){return new GLM.vec2(this.w,this.z)},set:function(a){a=GLM.vec2(a);this.w=a[0];this.z=a[1]}},wxz:{enumerable:!1,get:function(){return new GLM.vec3(this.w,this.x,this.z)},set:function(a){a=GLM.vec3(a);this.w=a[0];this.x=a[1];this.z=a[2];return this}},xyw:{enumerable:!1,get:function(){return new GLM.vec3(this.x,this.y,this.w)},set:function(a){a=GLM.vec3(a);this.x=a[0];this.y=a[1];this.w=a[2];return this}},xzw:{enumerable:!1,get:function(){return new GLM.vec3(this.x,this.z,
-this.w)},set:function(a){a=GLM.vec3(a);this.x=a[0];this.z=a[1];this.w=a[2]}},wxyz:{enumerable:!1,get:function(){return new GLM.vec4(this.w,this.x,this.y,this.z)},set:function(a){a=GLM.vec4(a);this.w=a[0];this.x=a[1];this.y=a[2];this.z=a[3];return this}}}},c;for(c in b)for(var e in b[c])2>=c&&GLM.vec2.$properties.def(e,b[c][e]),3>=c&&GLM.vec3.$properties.def(e,b[c][e]),4>=c&&GLM.vec4.$properties.def(e,b[c][e]);GLM.$partition=function(a,b,c,e){if(void 0===c)throw new GLM.GLMJSError("nrows is undefined");
-var k=b.$.identity.length;c=c||k;for(var i=function(a){3<GLM.$DEBUG&&GLM.$outer.console.debug("CACHEDBG: "+a)},w=0;w<c;w++)(function(c){var j=e&&e+c,q=c*k;Object.defineProperty(a,c,{configurable:!0,enumerable:!0,set:function(e){if(e instanceof b)this.elements.set(e.elements,q);else if(e&&e.length===k)this.elements.set(e,q);else throw new GLM.GLMJSError("unsupported argtype to "+(a&&a.$type)+"["+c+"] setter: "+[typeof e,e]);},get:function(){if(e){if(this[j])return c||i("cache hit "+j),this[j];c||i("cache miss "+
-j)}var a,d=new b(a=GLM.$subarray(this.elements,q,q+k));if(d.elements!==a)throw new GLM.GLMJSError("v.elements !== t "+[GLM.$subarray,d.elements.constructor===a.constructor,d.elements.buffer===a.buffer]);e&&Object.defineProperty(this,j,{configurable:!0,enumerable:!1,value:d});return d}})})(w)};GLM.$partition(GLM.mat4.prototype,GLM.vec4,4,"_cache_");GLM.$partition(GLM.mat3.prototype,GLM.vec3,3,"_cache_")})();
-GLM.$dumpTypes=function(a){GLM.$types.forEach(function(b){GLM[b].componentLength&&a("GLM."+b,JSON.stringify({"#type":GLM[b].prototype.$type_name,"#floats":GLM[b].componentLength,"#bytes":GLM[b].BYTES_PER_ELEMENT}))})};
-GLM.$init=function(a){a.prefix&&(GLMJS_PREFIX=a.prefix);GLM.$prefix=GLMJS_PREFIX;var b=a.log||function(){};try{b("GLM-js: ENV: "+_ENV._VERSION)}catch(c){}b("GLM-JS: initializing: "+JSON.stringify(a,0,2));b(JSON.stringify({functions:Object.keys(GLM.$outer.functions)}));var e=GLM.mat4,d=GLM.$outer;GLM.toMat4=function(a){return new e(d.mat4_array_from_quat(a))};GLM.$template.extend(GLM.rotation.$template,{$quat:GLM.quat,$dot:GLM.dot.link("vec3,vec3"),$epsilon:GLM.epsilon(),$m:GLM.mat3(),$pi:GLM.pi(),
-$length2:GLM.length2.link("vec3"),$cross:GLM.cross.link("vec3,vec3"),$normalize:GLM.normalize.link("vec3"),$angleAxis:GLM.angleAxis.link("float,vec3"),$sqrt:GLM.sqrt});GLM.$symbols=[];for(var h in GLM)"function"===typeof GLM[h]&&/^[a-z]/.test(h)&&GLM.$symbols.push(h);GLM.$types.forEach(function(a){var b=GLM[a].prototype.$type,c;for(c in GLM.$outer.functions){var d=GLM.$outer.functions[c];d.$op&&(GLM.$DEBUG&&GLM.$outer.console.debug("mapping operator<"+b+"> "+c+" / "+d.$op),GLM[a].prototype[c]=d,GLM[a].prototype[d.$op]=
-d)}});b("GLM-JS: "+GLM.version+" emulating GLM_VERSION="+GLM.GLM_VERSION+" vendor_name="+a.vendor_name+" vendor_version="+a.vendor_version);glm.vendor=a};
-GLM.using_namespace=function(a){GLM.$DEBUG&&GLM.$outer.console.debug("GLM.using_namespace munges globals; it should probably not be used!");GLM.using_namespace.$tmp={ret:void 0,tpl:a,names:GLM.$symbols,saved:{},evals:[],restore:[],before:[],after:[]};eval(GLM.using_namespace.$tmp.names.map(function(a,c){return"GLM.using_namespace.$tmp.saved['"+a+"'] = GLM.using_namespace.$tmp.before["+c+"] = 'undefined' !== typeof "+a+";"}).join("\n"));GLM.$DEBUG&&console.warn("GLM.using_namespace before #globals: "+
-GLM.using_namespace.$tmp.before.length);GLM.using_namespace.$tmp.names.map(function(a){GLM.using_namespace.$tmp.restore.push(a+"=GLM.using_namespace.$tmp.saved['"+a+"'];"+("GLM.using_namespace.$tmp.saved['"+a+"']=undefined;delete GLM.using_namespace.$tmp.saved['"+a+"'];"));GLM.using_namespace.$tmp.evals.push(a+"=GLM."+a+";")});eval(GLM.using_namespace.$tmp.evals.join("\n"));GLM.using_namespace.$tmp.ret=a();eval(GLM.using_namespace.$tmp.restore.join("\n"));eval(GLM.using_namespace.$tmp.names.map(function(a,
-c){return"GLM.using_namespace.$tmp.after["+c+"] = 'undefined' !== typeof "+a+";"}).join("\n"));GLM.$DEBUG&&console.warn("GLM.using_namespace after #globals: "+GLM.using_namespace.$tmp.after.length);a=GLM.using_namespace.$tmp.ret;delete GLM.using_namespace.$tmp;return a};
-function $GLM_extern(a,b){b=b||a;return function(){GLM[b]=GLM.$outer.functions[a]||GLM.$outer[a];if(!GLM[b])throw new GLM.GLMJSError("$GLM_extern: unresolved external symbol: "+a);GLM.$DEBUG&&GLM.$outer.console.debug("$GLM_extern: resolved external symbol "+a+" "+typeof GLM[b]);return GLM[b].apply(this,arguments)}}
-function GLM_polyfills(){var a={};"bind"in Function.prototype||(a.bind=Function.prototype.bind=function(a){function c(){}if("function"!==typeof this)throw new TypeError("not callable");var e=[].slice,d=e.call(arguments,1),h=this,j=function(){return h.apply(this instanceof c?this:a||global,d.concat(e.call(arguments)))};c.prototype=this.prototype||c.prototype;j.prototype=new c;return j});return a}
-$GLM_reset_logging.current=function(){return{$GLM_log:"undefined"!==typeof $GLM_log&&$GLM_log,$GLM_console_log:"undefined"!==typeof $GLM_console_log&&$GLM_console_log,$GLM_console_prefixed:"undefined"!==typeof $GLM_console_prefixed&&$GLM_console_prefixed,console:GLM.$outer.console}};
-function $GLM_reset_logging(a){a&&"object"===typeof a&&($GLM_log=a.$GLM_log,$GLM_console_log=a.$GLM_console_log,$GLM_console_factory=a.$GLM_console_factory,GLM.$outer.console=a.console,a=!1);if(a||"undefined"===typeof $GLM_log)$GLM_log=function(a,b){GLM.$outer.console.log.apply(GLM.$outer.console,[].slice.call(arguments).map(function(a){var b=typeof a;return"xboolean"===b||"string"===b?a+"":GLM.$isGLMObject(a)||!isNaN(a)?GLM.to_string(a):a+""}))};if(a||"undefined"===typeof $GLM_console_log)$GLM_console_log=
-function(a,b){(console[a]||function(){}).apply(console,[].slice.call(arguments,1))};if(a||"undefined"===typeof $GLM_console_factory)$GLM_console_factory=function(a){return $GLM_console_log.bind($GLM_console_log,a)};var b=$GLM_console_factory,c={};"debug,warn,info,error,log,write".replace(/\w+/g,function(a){c[a]=b(a)});"object"===typeof GLM&&(GLM.$outer&&(GLM.$outer.console=c),GLM.$log=$GLM_log);return c}try{window.$GLM_reset_logging=this.$GLM_reset_logging=$GLM_reset_logging}catch(e$$19){}
-GLM.$reset_logging=$GLM_reset_logging;GLM.$log=GLM.$log||$GLM_log;function $GLM_GLMJSError(a,b){function c(c){this.name=a;this.stack=Error().stack;Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor);this.message=c;b&&b.apply(this,arguments)}c.prototype=Error();c.prototype.name=a;return c.prototype.constructor=c}GLMAT.mat4.exists;glm=GLM;var DLL={_version:"0.0.2",_name:"glm.gl-matrix.js",_glm_version:glm.version,prefix:"glm-js[glMatrix]: ",vendor_version:GLMAT.VERSION,vendor_name:"glMatrix"};
-DLL.statics={$outer:GLM.$outer,$typeArray:function(a){return new this.$outer.Float32Array(a)},$mat4:GLM.mat4,$quat:GLM.quat,$mat4$perspective:GLMAT.mat4.perspective,$mat4$ortho:GLMAT.mat4.ortho,mat4_perspective:function(a,b,c,e){return new this.$mat4(this.$mat4$perspective(this.$typeArray(16),a,b,c,e))},mat4_ortho:function(a,b,c,e,d,h){return new this.$mat4(this.$mat4$ortho(this.$typeArray(16),a,b,c,e,d||-1,h||1))},$quat$setAxisAngle:GLMAT.quat.setAxisAngle,$mat4$fromQuat:GLMAT.mat4.fromQuat,mat4_angleAxis:function(a,
-b){var c=this.$quat$setAxisAngle(this.$typeArray(4),b,a);return new this.$mat4(this.$mat4$fromQuat(this.$typeArray(16),c))},quat_angleAxis:function(a,b){return new this.$quat(this.$quat$setAxisAngle(this.$typeArray(4),b,a))},$mat4$translate:GLMAT.mat4.translate,mat4_translation:function(a){var b=new this.$mat4;this.$mat4$translate(b.elements,b.elements,a.elements);return b},$mat4$scale:GLMAT.mat4.scale,mat4_scale:function(a){var b=new this.$mat4;this.$mat4$scale(b.elements,b.elements,a.elements);
-return b},toJSON:function(){var a={},b;for(b in this)0!==b.indexOf("$")&&(a[b]=this[b]);return a},$vec3:GLM.vec3,$clamp:GLM.clamp,mat4_array_from_quat:function(a){return this.$mat4$fromQuat(this.$typeArray(16),a.elements)},$qtmp:new GLM.$outer.Float32Array(9),$quat$fromMat3:GLMAT.quat.fromMat3,$mat3$fromMat4:GLMAT.mat3.fromMat4,quat_array_from_mat4:function(a){return this.$quat$fromMat3(this.$typeArray(4),this.$mat3$fromMat4(this.$qtmp,a.elements))}};
-DLL["declare<T,V,...>"]={mul:{$op:"*",$typeArray:function(a){return new this.GLM.$outer.Float32Array(a)},$vec3$transformQuat:GLMAT.vec3.transformQuat,"quat,vec3":function(a,b){return new this.GLM.vec3(this.$vec3$transformQuat(this.$typeArray(3),b.elements,a.elements))},"vec3,quat":function(a,b){return this["quat,vec3"](this.GLM.inverse(b),a)},"quat,vec4":function(a,b){return this["mat4,vec4"](this.GLM.toMat4(a),b)},"vec4,quat":function(a,b){return this["quat,vec4"](this.GLM.inverse(b),a)},"$vec<N>$scale":"GLMAT.vecN.scale",
-"vec<N>,float":function(a,b){return new this.GLM.vecN(this.$vecN$scale(this.$typeArray(N),a.elements,b))},"quat,float":function(a,b){return new a.constructor(this["vec4,float"](a,b).elements)},$vec4$transformMat4:GLMAT.vec4.transformMat4,"mat4,vec4":function(a,b){return new GLM.vec4(this.$vec4$transformMat4(this.$typeArray(4),b.elements,a.elements))},"vec4,mat4":function(a,b){return this["mat4,vec4"](GLM.inverse(b),a)},"$mat<N>mul":"GLMAT.matN.mul","mat<N>,mat<N>":function(a,b){return new a.constructor(this.$matNmul(this.$typeArray(N*
-N),a.elements,b.elements))},$quat$multiply:GLMAT.quat.multiply,"quat,quat":function(a,b){return new a.constructor(this.$quat$multiply(this.$typeArray(4),a.elements,b.elements))}},mul_eq:{$op:"*=","$mat<N>$multiply":"GLMAT.matN.multiply","mat<N>,mat<N>":function(a,b){this.$matN$multiply(a.elements,a.elements,b.elements);return a},"$vec<N>$scale":"GLMAT.vecN.scale","vec<N>,float":function(a,b){this.$vecN$scale(a.elements,a.elements,b);return a},$quat$multiply:GLMAT.quat.multiply,"quat,quat":function(a,
-b){this.$quat$multiply(a.elements,a.elements,b.elements);return a},$quat$invert:GLMAT.quat.invert,$vec3$transformQuat:GLMAT.vec3.transformQuat,"inplace:vec3,quat":function(a,b){var c=this.$quat$invert(new this.GLM.$outer.Float32Array(4),b.elements);this.$vec3$transformQuat(a.elements,a.elements,c);return a},$mat4$invert:GLMAT.mat4.invert,$vec4$transformMat4:GLMAT.vec4.transformMat4,"inplace:vec4,mat4":function(a,b){var c=this.$mat4$invert(new this.GLM.$outer.Float32Array(16),b.elements);this.$vec4$transformMat4(a.elements,
-a.elements,c);return a}},cross:{$vec2$cross:GLMAT.vec2.cross,"vec2,vec2":function(a,b){return new this.GLM.vec3(this.$vec2$cross(new this.GLM.$outer.Float32Array(3),a,b))},$vec3$cross:GLMAT.vec3.cross,"vec3,vec3":function(a,b){return new this.GLM.vec3(this.$vec3$cross(new this.GLM.$outer.Float32Array(3),a,b))}},dot:{"$vec<N>$dot":"GLMAT.vecN.dot","vec<N>,vec<N>":function(a,b){return this.$vecN$dot(a,b)}},lookAt:{$mat4$lookAt:GLMAT.mat4.lookAt,"vec3,vec3":function(a,b,c){return new this.GLM.mat4(this.$mat4$lookAt(new this.GLM.$outer.Float32Array(16),
-a.elements,b.elements,c.elements))}}};DLL["declare<T,V,number>"]={mix:{$quat$slerp:GLMAT.quat.slerp,"quat,quat":function(a,b,c){return new GLM.quat(this.$quat$slerp(new GLM.$outer.Float32Array(4),a.elements,b.elements,c))}}};DLL["declare<T,V,number>"].slerp=DLL["declare<T,V,number>"].mix;
-DLL["declare<T>"]={normalize:{"$vec<N>normalize":"GLMAT.vecN.normalize",$typeArray:function(a){return new this.GLM.$outer.Float32Array(a)},"vec<N>":function(a){return new this.GLM.vecN(this.$vecNnormalize(this.$typeArray(N),a))},$quat$normalize:GLMAT.quat.normalize,quat:function(a){return new this.GLM.quat(this.$quat$normalize(new this.GLM.$outer.Float32Array(4),a.elements))}},length:{$quat$length:GLMAT.quat.length,quat:function(a){return this.$quat$length(a.elements)},"$vec<N>$length":"GLMAT.vecN.length",
-"vec<N>":function(a){return this.$vecN$length(a.elements)}},length2:{$quat$squaredLength:GLMAT.quat.squaredLength,quat:function(a){return this.$quat$squaredLength(a.elements)},"$vec<N>$squaredLength":"GLMAT.vecN.squaredLength","vec<N>":function(a){return this.$vecN$squaredLength(a.elements)}},inverse:{$quatinvert:GLMAT.quat.invert,quat:function(a){return this.GLM.quat(this.$quatinvert(new this.GLM.$outer.Float32Array(4),a.elements))},$mat4invert:GLMAT.mat4.invert,mat4:function(a){a=a.clone();return null===
-this.$mat4invert(a.elements,a.elements)?a["="](this.GLM.mat4()):a}},transpose:{$mat4$transpose:GLMAT.mat4.transpose,mat4:function(a){a=a.clone();this.$mat4$transpose(a.elements,a.elements);return a}}};glm.$outer.$import(DLL);try{module.exports=glm}catch(e$$20){}
-function $GLMVector(a,b,c){this.typearray=c=c||GLM.$outer.Float32Array;if(!(this instanceof $GLMVector))throw new GLM.GLMJSError("use new");if("function"!==typeof a||!GLM.$isGLMConstructor(a))throw new GLM.GLMJSError("expecting typ to be GLM.$isGLMConstructor: "+[typeof a,a?a.$type:a]+" // "+GLM.$isGLMConstructor(a));if(1===a.componentLength&&GLM[a.prototype.$type.replace("$","$$v")])throw new GLM.GLMJSError("unsupported argtype to glm.$vectorType - for single-value types use glm."+a.prototype.$type.replace("$",
-"$$v")+"..."+a.prototype.$type);this.glmtype=a;if(!this.glmtype.componentLength)throw Error("need .componentLength "+[a,b,c]);this.componentLength=this.glmtype.componentLength;this.BYTES_PER_ELEMENT=this.glmtype.BYTES_PER_ELEMENT;this._set_$elements=function(a){Object.defineProperty(this,"$elements",{enumerable:!1,configurable:!0,value:a});return this.$elements};Object.defineProperty(this,"elements",{enumerable:!0,configurable:!0,get:function(){return this.$elements},set:function(a){this._kv&&!this._kv.dynamic&&
-GLM.$DEBUG&&GLM.$outer.console.warn("WARNING: setting .elements on frozen (non-dynamic) GLMVector...");if(a){var b=this.length;this.length=a.length/this.componentLength;this.byteLength=a.length*this.BYTES_PER_ELEMENT;if(this.length!==Math.round(this.length))throw new GLM.GLMJSError("$vectorType.length alignment mismatch "+JSON.stringify({componentLength:this.componentLength,length:this.length,rounded_length:Math.round(this.length),elements_length:a.length,old_length:b}));}else this.length=this.byteLength=
-0;return this._set_$elements(a)}});this.elements=b&&new c(b*a.componentLength)}GLM.$vectorType=$GLMVector;GLM.$vectorType.version="0.0.2";
-$GLMVector.prototype=GLM.$template.extend(new GLM.$GLMBaseType($GLMVector,"$vectorType"),{toString:function(){return"[$GLMVector .elements=#"+(this.elements&&this.elements.length)+" .elements[0]="+(this.elements&&this.elements[0])+" ->[0]"+(this["->"]&&this["->"][0])+"]"},"=":function(a){if(a instanceof this.constructor||glm.$isGLMObject(a))a=a.elements;return this._set(new this.typearray(a))},_typed_concat:function(a,b,c){var e=a.length+b.length;c=c||new a.constructor(e);c.set(a);c.set(b,a.length);
-return c},"+":function(a){if(a instanceof this.constructor||glm.$isGLMObject(a))a=a.elements;return new this.constructor(this._typed_concat(this.elements,a))},"+=":function(a){if(a instanceof this.constructor||glm.$isGLMObject(a))a=a.elements;return this._set(this._typed_concat(this.elements,a))},_set:function(a){a instanceof this.constructor&&(a=new this.typearray(a.elements));if(!(a instanceof this.typearray))throw new GLM.GLMJSError("unsupported argtype to $GLMVector._set "+(a&&a.constructor));
-GLM.$DEBUG&&GLM.$outer.console.debug("$GLMVector.prototype.set...this.elements:"+[this.elements&&this.elements.constructor.name,this.elements&&this.elements.length]+"elements:"+[a.constructor.name,a.length]);var b=this._kv;this._kv=void 0;this.elements=a;if(this.elements!==a)throw new GLM.GLMJSError("err with .elements: "+[this.glmtype.prototype.$type,this.elements,a]);b&&this._setup(b);return this},arrayize:function(a,b){return this._setup({dynamic:b,setters:a},this.length)},$destroy:function(a){if(a){for(var b=
-Array.isArray(a),c=function(c){Object.defineProperty(a,c,{enumerable:!0,configurable:!0,value:void 0});delete a[c];b||(a[c]=void 0,delete a[c])},e=0;e<a.length;e++)e in a&&c(e);for(;e in a;)GLM.$DEBUG&&GLM.$outer.console.debug("$destroy",this.name,e),c(e++);b&&(a.length=0)}},_arrlike_toJSON:function(){return this.slice(0)},_mixinArray:function(a){a.toJSON=this._arrlike_toJSON;"forEach map slice filter join reduce".split(" ").forEach(function(b){a[b]=Array.prototype[b]});return a},_setup:function(a,
-b){var c=this.glmtype,e=this.typearray,d=this.length;this._kv=a;var h=a.stride||this.glmtype.BYTES_PER_ELEMENT,j=a.offset||this.elements.byteOffset,g=a.elements||this.elements,k=a.container||this.arr||[],i=a.setters||!1,w=a.dynamic||!1;"self"===k&&(k=this);if(!g)throw new GLMJSError("GLMVector._setup - neither kv.elements nor this.elements...");this.$destroy(this.arr,b);var r=this.arr=this["->"]=k;Array.isArray(r)||this._mixinArray(r);var m=this.componentLength;if(!m)throw new GLM.GLMJSError("no componentLength!?"+
-Object.keys(this));for(var q=g.buffer.byteLength,s=this,t=0;t<d;t++){var k=j+t*h,z=k+this.glmtype.BYTES_PER_ELEMENT,y=function(){a.i=t;a.next=z;a.last=q;a.offset=a.offset||j;a.stride=a.stride||h;return JSON.stringify(a)};if(k>q)throw Error("["+t+"] off "+k+" > last "+q+" "+y());if(z>q)throw Error("["+t+"] next "+z+" > last "+q+" "+y());r[t]=null;var f=function(a,b){var d=new c(new e(a.buffer,b,m));w&&Object.defineProperty(d,"$elements",{value:a});return d},y=f(g,k);!i&&!w?r[t]=y:function(a,b,c){Object.defineProperty(r,
-b,{enumerable:!0,configurable:!0,get:w?function(){a.$elements!==s.elements&&(GLM.$log("dynoget rebinding ti",b,c,a.$elements===s.elements),a=f(s.elements,c));return a}:function(){return a},set:i&&(w?function(d){GLM.$log("dynoset",b,c,a.$elements===s.elements);a.$elements!==s.elements&&(GLM.$log("dynoset rebinding ti",b,c,a.$elements===s.elements),a=f(s.elements,c));return a.copy(d)}:function(b){return a.copy(b)})||void 0})}(y,t,k)}return this},setFromBuffers:function(a){var b=this.elements,c=0;a.forEach(function(a){var d=
-a.length;if(c+d>b.length){d=Math.min(b.length-c,a.length);if(0>=d)return;a=glm.$subarray(a,0,d);d=a.length}if(c+d>b.length)throw new glm.GLMJSError("$vectorType.fromBuffers mismatch "+[c,d,b.length]);b.set(a,c);c+=a.length});return c},setFromPointer:function(a){if(!(a instanceof GLM.$outer.ArrayBuffer))throw new glm.GLMJSError("unsupported argtype "+[typeof a]+" - $GLMVector.setFromPointer");return this._set(new this.typearray(a))}});GLM.exists;GLM.$vectorType.exists;
-if(GLM.$toTypedArray)throw"error: glm.experimental.js double-included";
-GLM.$toTypedArray=function(a,b,c){var e=b||0,d=typeof e;if("number"===d){if("number"!==typeof c)throw new GLM.GLMJSError("GLM.$toTypedArray: unsupported argtype for componentLength ("+typeof c+")");return new a(e*c)}if("object"!==d)throw new GLM.GLMJSError("GLM.$toTypedArray: unsupported arrayType: "+[typeof a,a]);if(e instanceof a)return e;if(e instanceof GLM.$outer.ArrayBuffer||Array.isArray(e))return new a(e);GLM.$isGLMObject(e)&&(d=e.elements,e=new a(d.length),e.set(d));if(!(e instanceof a)&&
-"byteOffset"in e&&"buffer"in e)return GLM.$DEBUG&&GLM.$outer.console.warn("coercing "+e.constructor.name+".buffer into "+[a.name,e.byteOffset,e.byteLength+" bytes","~"+e.byteLength/a.BYTES_PER_ELEMENT+" coerced elements"]+"...",{byteOffset:e.byteOffset,byteLength:e.byteLength,ecount:e.byteLength/a.BYTES_PER_ELEMENT}),new a(e.buffer,e.byteOffset,e.byteLength/a.BYTES_PER_ELEMENT);if(e instanceof a)return e;throw new GLM.GLMJSError("GLM.$toTypedArray: unsupported argtype initializers: "+[a,b,c]);};
-GLM.$make_primitive=function(a,b){GLM[a]=function(c){if(!(this instanceof GLM[a]))return new GLM[a](c);"object"!==typeof c&&(c=[c]);this.elements=GLM.$toTypedArray(b,c,1)};GLM[a]=eval(GLM.$template._traceable("glm_"+a+"$class",GLM[a]))();GLM.$template._add_overrides(a,{$to_string:function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a.elements[0]+")"},$to_object:function(a){return a.elements[0]},$to_glsl:function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a.elements[0]+")"}});GLM.$template._add_overrides(a.substr(1),
-{$to_string:!(a.substr(1)in GLM.$to_string.$template)&&function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a.elements[0]+")"},$to_object:function(a){return a},$to_glsl:function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a+")"}});GLM.$template.extend(GLM[a],{componentLength:1,BYTES_PER_ELEMENT:b.BYTES_PER_ELEMENT,prototype:GLM.$template.extend(new GLM.$GLMBaseType(GLM[a],a),{copy:function(a){this.elements.set(GLM.$isGLMObject(a)?a.elements:[a]);return this},valueOf:function(){return this.elements[0]}})});
-GLM[a].prototype["="]=GLM[a].prototype.copy;return GLM[a]};GLM.$make_primitive("$bool",GLM.$outer.Int32Array);GLM.$template._add_overrides("$bool",{$to_object:function(a){return!!a}});GLM.$make_primitive("$int32",GLM.$outer.Int32Array);GLM.$make_primitive("$uint32",GLM.$outer.Uint32Array);GLM.$make_primitive("$uint16",GLM.$outer.Uint16Array);GLM.$make_primitive("$uint8",GLM.$outer.Uint8Array);GLM.$float32=GLM.$make_primitive("$float",GLM.$outer.Float32Array);
-GLM.$make_primitive_vector=function(a,b,c){c=c||(new b).elements.constructor;var e=function(d){if(!(this instanceof e))return new e(d);this.$type=a;this.$type_name="vector<"+a+">";(d=GLM.$toTypedArray(c,d,b.componentLength))&&this._set(d)},e=eval(GLM.$template._traceable("glm_"+a+"$class",e))();e.prototype=new GLM.$vectorType(b,0,c);GLM.$template._add_overrides(a,{$to_string:function(a){return"[GLM."+a.$type+" elements[0]="+(a.elements&&a.elements[0])+"]"},$to_object:function(a){return a.map(GLM.$to_object)},
-$to_glsl:function(a,b){var c=a.$type.substr(2).replace(/[^a-z]/g,"");b="string"===typeof b?b:"example";var e=[];b&&e.push(c+" "+b+"["+a.length+"]");return e.concat(a.map(function(a,c){return b+"["+c+"] = "+a})).join(";")+";"}});GLM.$types.push(a);GLM.$template.extend(e.prototype,{$type:a,constructor:e,_setup:function(){throw new GLM.GLMJSError("._setup not available on primitive vectors yet...");},_set:function(a){this.elements=a;this.length=!this.elements?0:this.elements.length/this.glmtype.componentLength;
-this.arrayize();return this},arrayize:function(){for(var a=Object.defineProperty.bind(Object,this),b=0;b<this.length;b++)(function(b){a(b,{configurable:!0,enumerable:!0,get:function(){return this.elements[b]},set:function(a){return this.elements[b]=a}})})(b);return this._mixinArray(this)},toString:function(){return"[vector<"+a+"> {"+[].slice.call(this.elements,0,5)+(5<this.elements.length?",...":"")+"}]"}});return e};GLM.$vint32=GLM.$make_primitive_vector("$vint32",GLM.$int32);
-GLM.$vfloat=GLM.$vfloat32=GLM.$make_primitive_vector("$vfloat32",GLM.$float32);GLM.$vuint8=GLM.$make_primitive_vector("$vuint8",GLM.$uint8);GLM.$vuint16=GLM.$make_primitive_vector("$vuint16",GLM.$uint16);GLM.$vuint32=GLM.$make_primitive_vector("$vuint32",GLM.$uint32);
-GLM.$make_componentized_vector=function(a,b,c){c=c||(new b).elements.constructor;var e=function(a,h){if(!(this instanceof e))return new e(a,h);this._set(GLM.$toTypedArray(c,a,b.componentLength));if(!this.elements)throw new GLM.GLMJSError("!this.elements: "+[GLM.$toTypedArray(c,a,b.componentLength)]);this._setup({setters:!0,dynamic:h,container:"self"})},e=eval(GLM.$template._traceable("glm_"+a+"$class",e))();e.prototype=new GLM.$vectorType(b,0,c);GLM.$template._add_overrides(a,{$to_string:function(a){return"[GLM."+
-a.$type+" elements[0]="+(a.elements&&a.elements[0])+"]"},$to_object:function(a){return a.map(GLM.$to_object)},$to_glsl:function(a,b){var c=a.$type.substr(2);b="string"===typeof b?b:"example";var e=[];b&&e.push(c+" "+b+"["+a.length+"]");return e.concat(a.map(GLM.$to_glsl).map(function(a,c){return b+"["+c+"] = "+a})).join(";\n ")+";"}});GLM.$types.push(a);GLM.$template.extend(e.prototype,{$type:a,constructor:e});e.prototype.componentLength||alert("!cmop "+p);return e};
-(function(){var a=GLM.$template.deNify({"$vvec<N>":function(){return GLM.$make_componentized_vector("$vvecN",GLM.vecN)},"$vuvec<N>":function(){return GLM.$make_componentized_vector("$vuvecN",GLM.uvecN)},"$vmat<N>":function(){return GLM.$make_componentized_vector("$vmatN",GLM.matN)},$vquat:function(){return GLM.$make_componentized_vector("$vquat",GLM.quat)}},"$v"),b;for(b in a)GLM[b]=a[b]()})();
-(GLM._redefine_base64_helpers=function define_base64_helpers(b,c){function e(b){return(b+"").replace(/\s/g,"")}function d(b){return new k(b.split("").map(function(b){return b.charCodeAt(0)}))}function h(b){b instanceof k||(b=new k(b));return[].map.call(b,function(b){return String.fromCharCode(b)}).join("")}function j(b){b=b instanceof i?b:d(b).buffer;return GLM.$b64.encode(b,b.byteOffset,b.byteLength)}function g(b){b=new String(h(GLM.$b64.decode(b)));b.array=d(b);b.buffer=b.array.buffer;return b}
-b=define_base64_helpers.atob=b||define_base64_helpers.atob||g;c=define_base64_helpers.btoa=c||define_base64_helpers.btoa||j;var k=GLM.$outer.Uint8Array,i=GLM.$outer.ArrayBuffer,w,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf.bind("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");w={encode:function(b,c,d){b=new k(b,c,d);d=b.length;var e="";for(c=0;c<d;c+=3)e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b[c]>>2],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(b[c]&
-3)<<4|b[c+1]>>4],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(b[c+1]&15)<<2|b[c+2]>>6],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b[c+2]&63];2===d%3?e=e.substring(0,e.length-1)+"=":1===d%3&&(e=e.substring(0,e.length-2)+"==");return e},decode:function(b){b=e(b);var c=b.length,d=0.75*c,g=0,h,j,f,v;"="===b[c-1]&&(d--,"="===b[c-2]&&d--);for(var w=new i(d),R=new k(w),d=0;d<c;d+=4)h=r(b[d]),j=r(b[d+1]),f=r(b[d+2]),v=r(b[d+3]),R[g++]=h<<2|j>>4,R[g++]=
-(j&15)<<4|f>>2,R[g++]=(f&3)<<6|v&63;return w}};GLM.$template.extend(w,{trim:e,atob:b,btoa:c,$atob:g,$btoa:j,toCharCodes:d,fromCharCodes:h,b64_to_utf8:function(c){return decodeURIComponent(escape(b(e(c))))},utf8_to_b64:function(b){return c(unescape(encodeURIComponent(b)))}});GLM.$template.extend(GLM,{$b64:w,$to_base64:function(b){return GLM.$b64.encode(b.elements.buffer,b.elements.byteOffset,b.elements.byteLength)},$from_base64:function(b,c){var d=GLM.$b64.decode(b);if(!0===c||c==GLM.$outer.ArrayBuffer)return d;
-void 0===c&&(c=GLM.$outer.Float32Array);return new c(d);throw new GLM.GLMJSError("TODO: $from_base64 not yet supported second argument type: ("+[typeof c,c]+")");}})})("function"===typeof atob&&atob.bind(this),"function"===typeof btoa&&btoa.bind(this));
-(function(){function a(a,c){return{get:function(){return a.call(this)},set:function(a){if(this.copy)return this.copy(new this.constructor(c.call(this,a)));this.elements.set(c.call(this,a))}}}"$bool $float32 $vfloat32 $vuint8 $vuint16 $vuint32 $vvec2 $vvec3 $vvec4 $vmat3 $vmat4 $vquat vec2 vec3 vec4 mat3 mat4 uvec2 uvec3 uvec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 quat".split(" ").map(GLM.$getGLMType).forEach(function(b){Object.defineProperty(b.prototype,"array",a(function(){return GLM.$to_array(this)},
-function(a){return a}));Object.defineProperty(b.prototype,"base64",a(function(){return GLM.$to_base64(this)},function(a){return GLM.$from_base64(a,this.elements.constructor)}));Object.defineProperty(b.prototype,"buffer",a(function(){return this.elements.buffer},function(a){return new this.elements.constructor(a)}));Object.defineProperty(b.prototype,"json",a(function(){return GLM.$to_json(this)},function(a){return JSON.parse(a)}));Object.defineProperty(b.prototype,"object",a(function(){return GLM.$to_object(this)},
-function(a){return a}));Object.defineProperty(b.prototype,"glsl",a(function(){return GLM.$to_glsl(this)},function(a){return GLM.$from_glsl(a,Array)}))})})();
-glm.GLMAT = GLMAT; globals.glm = glm; try { module.exports = glm; } catch(e) { }; try { window.glm = glm; } catch(e) {} ; try { declare.amd && declare(function() { return glm; }); } catch(e) {}; return this.glm = glm; })(this, typeof $GLM_log !== "undefined" ? $GLM_log : undefined, typeof $GLM_console_log !== "undefined" ? $GLM_console_log : undefined);