Repository: KdotJPG/OpenSimplex2 Branch: master Commit: 4cd120d35bfc Files: 35 Total size: 916.5 KB Directory structure: gitextract_r8vzkgd4/ ├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md ├── _old/ │ ├── c/ │ │ ├── Makefile │ │ ├── OpenSimplex2F.c │ │ ├── OpenSimplex2F.h │ │ ├── UNLICENSE │ │ └── test_OpenSimplex2F.c │ ├── cpp/ │ │ ├── OpenSimplex2S.cpp │ │ ├── OpenSimplex2S.hpp │ │ └── UNLICENSE │ ├── csharp/ │ │ ├── OpenSimplex2F.cs │ │ ├── OpenSimplex2S.cs │ │ └── legacy/ │ │ ├── OpenSimplex.cs │ │ └── UNLICENSE │ └── java/ │ ├── OpenSimplex2F.java │ ├── OpenSimplex2S.java │ ├── legacy/ │ │ ├── OpenSimplex.java │ │ └── UNLICENSE │ └── legacy_unoptimized/ │ └── OpenSimplexUnoptimized.java ├── csharp/ │ ├── OpenSimplex2.cs │ └── OpenSimplex2S.cs ├── glsl/ │ ├── OpenSimplex2.glsl │ └── OpenSimplex2S.glsl ├── hlsl/ │ ├── OpenSimplex2.hlsl │ ├── OpenSimplex2S.hlsl │ └── UNLICENSE ├── java/ │ ├── OpenSimplex2.java │ └── OpenSimplex2S.java └── rust/ ├── OpenSimplex2.h ├── fast.rs ├── ffi.rs ├── lib.rs └── smooth.rs ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ target ================================================ FILE: Cargo.toml ================================================ [package] name = "opensimplex2" version = "1.1.0" edition = "2021" description = "Port of OpenSimplex2" authors = ["KdotJPG"] license = "CC0-1.0" repository = "https://github.com/KdotJPG/OpenSimplex2" categories = ["algorithms", "graphics", "game-development"] keywords = ["OpenSimplex", "Simplex", "noise", "random", "Perlin"] # omit java, etc. from .crate file include = [ "Cargo.toml", "rust/*.rs", ] [lib] path = "rust/lib.rs" crate-type = ["rlib", "staticlib", "cdylib"] ================================================ FILE: LICENSE ================================================ Creative Commons Legal Code CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. ================================================ FILE: README.md ================================================ # OpenSimplex 2 Successors to OpenSimplex Noise, plus updated OpenSimplex. Includes 2D, 3D, and 4D noise. ## Motivation Legacy OpenSimplex used a different grid layout scheme to Simplex. It worked fine for common applications, but didn't produce as consistent contrast as the original Simplex point layout in 3D/4D. It also broke down completely when extended to 5D+, producing diagonal bands of visibly-varying value ranges. Instead of vertex rearrangement, OpenSimplex2 focuses on congruent layouts constructed and traversed using disparate methods where need was concluded. Gradient vector tables were also revisited to improve probability symmetry in both the old and new noise. ## Included ### OpenSimplex2(F) * Looks the most like Simplex. * Is about as fast as common Simplex implementations. * 3D is implemented by constructing a rotated body-centered-cubic grid as the offset union of two rotated cubic grids, and finding the closest two points on each. * 4D is implemented using 5 offset copies of the dual (reverse-skewed) grid to produce the target grid. This technique generalizes to any number of dimensions. * Bundled 2D function is just 2D Simplex with a nice gradient table. The 4D technique does extend to 2D, but this was found to be faster and I couldn't find evidence of limitations on its use. 3D and 4D are novel contributions to the field. ### OpenSimplex2S * Looks the most like 2014 OpenSimplex. * Uses large vertex contribution ranges like 2014 OpenSimplex, but has better uniformity in 3D and 4D. * 3D is implemented analogously to OpenSimplex2(F), but finds the closest four points on each to match the larger radius. * 4D is implemented using the ordinary skew and a pre-generated 4x4x4x4 lookup table. I have a work-in-progress more-procedural implementation in my project backlog, which I will swap in if I find it to be competitive in performance. * 2D is based on Simplex, but uses a different process to find which points are in range. * Recommended choice for ridged noise (if passing individual layers into `abs(x)`). ### Legacy OpenSimplex with updated gradients * In some code bases using original OpenSimplex, it may take fewer dev cycles to swap in the same noise that just has the new gradient tables. This brings moderate improvements without changing consistency characteristics or internal frequency. * Included in `_old/{language}/legacy`. ### Older OpenSimplex2 implementations * OpenSimplex2 noise implementations from before performance and portability re-engineering. * Can also be found in the `_old` directory. Note: area-generators have been moved to [their original repository](https://github.com/KdotJPG/Noise-VertexQueue-AreaGen). ## C FFI usage Install a [Rust toolchain](https://www.rust-lang.org/tools/install) if needed. Build debug or release artifacts with: ``` cargo build # or cargo build --release ``` Library files will be in `./target/{debug,release}/`. Copy header from [`./rust/OpenSimplex2.h`](./rust/OpenSimplex2.h). ## Changelog * Tuned up this `README.md`. (Mar 26, 2022) * Re-wrote functions to be instancelessly seedable and less dependent on lookup tables. Re-organized repository. Renamed `OpenSimplex2F` to just `OpenSimplex2` in file/class names. (Jan 16, 2022) * Shortened lookup table for Simplex/OpenSimplex2(F) 4D (July 5, 2020) * Added 4D to OpenSimplex2(F) Java/C#, port OpenSimplex2S 4D to C#. (July 5, 2020) * Added 4D to OpenSimplex2S Java. (Apr 30, 2020) * Replaced individual renders in `README.md` with consolidated renders. (Feb 10, 2020) * Replaced 12-direction 2D gradient set with a 24-direction set, to reduce visible feature repetition in thresholded single-octave 2D noise. (Feb 10, 2020) * Renamed filenames FastSimplexStyleNoise to OpenSimplex2F, and SuperSimplexNoise to OpenSimplex2S. (Feb 10, 2020) * Moved legacy OpenSimplex into legacy directories. (Feb 10, 2020) * Slightly reorganized description above, and added TODO/changelog. (Jan 23, 2020) * Renamed / additionally named the noise "OpenSimplex (2.0)", separated into two versions/variants. (Jan 23, 2020) * SuperSimplex and FastSimplexStyleNoise are very similar to each other algorithmically, and are in the same spirit as the original OpenSimplex. * OpenSimplex is used in a lot of projects, and the naming might help facilitate adoption of the new noise in its place. * Add C# ports of evaluators. (Jan 13, 2020) * Create separate files which include area generators. (Jan 13, 2020) * Renamed PlaneFirst evaluators to XYBeforeZ, and added XZBeforeY. (Jan 13, 2020) * Fixed equals() method in AreaGenLatticePoint3D for area generators. (Dec 24, 2019) ## Renders ### 2D Noise ![Renders 2D](https://user-images.githubusercontent.com/8829856/149676975-ba7cfc82-3bb5-4e0c-b6cb-8315eca51193.png) * OpenSimplex2S is a smoother copy of OpenSimplex2(F). * OpenSimplex2S and Updated OpenSimplex are effectively identical. * Original OpenSimplex produced more straight parts and was not as probabilistically symmetric. ### 3D Noise (ImproveXY Orientation) ![Renders 3D ImproveXY](https://user-images.githubusercontent.com/8829856/149676980-768775b4-f0ca-417b-aa0a-2379b61fb69d.png) * OpenSimplex2(F) and OpenSimplex2S, 2D slices of 3D ImproveXY, keep mostly the same properties as you move along the third axis. * Updated OpenSimplex looks good in both slices, but the slices look different from each other. In an animation, this is particularly noticeable. * Original OpenSimplex was less uniform and not as probabilistically symmetric. ### 3D Noise (Fallback Orientation) ![Renders 3D Fallback](https://user-images.githubusercontent.com/8829856/149676981-2d40fff9-b585-4fca-9a09-eb51d5927fec.png) * OpenSimplex2(F) and OpenSimplex2S, 2D slices of 3D in the classic lattice orientation, look decent but are less ideal for X/Y planes being the primary focus. * This Updated OpenSimplex render appears to show less directional bias than original OpenSimplex. ### 4D Noise (ImproveXY_ImproveZW Orientation) ![Renders 4D ImproveXY_ImproveZW](https://user-images.githubusercontent.com/8829856/149676999-14dc7dfc-a94c-4a8a-b654-00e25f33eb68.png) * OpenSimplex2S 4D has higher apparent contrast than original OpenSimplex. * OpenSimplex2(F) 4D has a very dotty appearance. Fine for fBm, but may pair best with extra steps if used for ridged noise. ### 4D Noise (ImproveXYZ Orientation) ![Renders 4D ImproveXYZ](https://user-images.githubusercontent.com/8829856/149677002-542aefc5-3e60-46d2-ac4a-6d947c0b94a7.png) * 2D slices look fine, but this rotation is most intended for texturing 3D objects with an additional time variable. ### 4D Noise (Fallback Orientation) ![Renders 4D Fallback](https://user-images.githubusercontent.com/8829856/149677011-267ab94c-3f3b-47bf-85a2-7b00befa95d6.png) * OpenSimplex2(F) has the most noticeable diagonal artifacts, followed by Old OpenSimplex. ### 4D Noise (Torus Mapping) ![Renders 4D Torus](https://user-images.githubusercontent.com/8829856/149677013-c0593b51-b757-41ed-9ece-1bf2f88feee7.png) * Seamless tileable 2D noise from 4D, mapped using noise4(r sin x, r cos x, r sin y, r cos y) ## Public Domain Dedication This is free and unencumbered software. The majority of files are released under CC0. Where marked, files in certain directories fall under UNLICENSE instead, as they were based off of UNLICENSE code other than mine (e.g. Pull Requests, legacy OpenSimplex with DigitalShadow's lookup tables). To the best of my non-lawyer knowledge, no patent claims cover anything implemented here (though also nothing here is legal advice). Please use this software to make cool things, rather than to make patents! Enjoy. ================================================ FILE: _old/c/Makefile ================================================ CFLAGS=-Wall -Wextra --pedantic -O3 # CFLAGS=-Wall -Wextra --pedantic -g -fsanitize=undefined # CFLAGS=-Wall -Wextra --pedantic -g -fsanitize=address all: OpenSimplex2F.o test_OpenSimplex2F OpenSimplex2F.o: OpenSimplex2F.c OpenSimplex2F.h Makefile $(CC) ${CFLAGS} -c OpenSimplex2F.c -lm test_OpenSimplex2F: test_OpenSimplex2F.c OpenSimplex2F.o Makefile $(CC) ${CFLAGS} -o test_OpenSimplex2F test_OpenSimplex2F.c OpenSimplex2F.o -lm -lpng clean: rm -f *.o test_OpenSimplex2F test2d.png test3d.png test4d.png ================================================ FILE: _old/c/OpenSimplex2F.c ================================================ /** * K.jpg's OpenSimplex 2, faster variant * * - 2D is standard simplex implemented using a lookup table. * - 3D is "Re-oriented 4-point BCC noise" which constructs a * congruent BCC lattice in a much different way than usual. * - 4D constructs the lattice as a union of five copies of its * reciprocal. It successively finds the closest point on each. * * Multiple versions of each function are provided. See the * documentation above each, for more info. */ #include #include #include #include #include "OpenSimplex2F.h" #define PSIZE (2048) #define PMASK (2047) static const double N2 = 0.01001634121365712; static const double N3 = 0.030485933181293584; static const double N4 = 0.009202377986303158; #define B0000 0x00 #define B0001 0x01 #define B0010 0x02 #define B0011 0x03 #define B0100 0x04 #define B0101 0x05 #define B0110 0x06 #define B0111 0x07 #define B1000 0x08 #define B1001 0x09 #define B1010 0x0a #define B1011 0x0b #define B1100 0x0c #define B1101 0x0d #define B1110 0x0e #define B1111 0x0f struct Grad2 { double dx, dy; }; struct Grad3 { double dx, dy, dz; }; struct Grad4 { double dx, dy, dz, dw; }; struct LatticePoint2D { int xsv, ysv; double dx, dy; }; static struct LatticePoint2D *new_LatticePoint2D(int xsv, int ysv) { struct LatticePoint2D *this = calloc(1, sizeof(*this)); this->xsv = xsv; this->ysv = ysv; double ssv = (xsv + ysv) * -0.211324865405187; this->dx = -xsv - ssv; this->dy = -ysv - ssv; return this; } struct LatticePoint3D { double dxr, dyr, dzr; int xrv, yrv, zrv; struct LatticePoint3D *nextOnFailure, *nextOnSuccess; }; static struct LatticePoint3D *new_LatticePoint3D(int xrv, int yrv, int zrv, int lattice) { struct LatticePoint3D *this = calloc(1, sizeof(*this)); this->dxr = -xrv + lattice * 0.5; this->dyr = -yrv + lattice * 0.5; this->dzr = -zrv + lattice * 0.5; this->xrv = xrv + lattice * 1024; this->yrv = yrv + lattice * 1024; this->zrv = zrv + lattice * 1024; return this; } static void find_unique_pointers(struct LatticePoint3D *tree, struct LatticePoint3D *list[], int *n) { if (!tree) return; int i, found; found = 0; for (i = 0; i < *n; i++) { if (list[i] == tree) { found = 1; break; } } if (!found) { list[*n] = tree; (*n)++; } find_unique_pointers(tree->nextOnFailure, list, n); find_unique_pointers(tree->nextOnSuccess, list, n); } static void free_LatticePoint3D(struct LatticePoint3D *list[], int n) { int i; for (i = 0; i < n; i++) free(list[i]); } struct LatticePoint4D { int xsv, ysv, zsv, wsv; double dx, dy, dz, dw; double xsi, ysi, zsi, wsi; double ssiDelta; }; static struct LatticePoint4D *new_LatticePoint4D(int xsv, int ysv, int zsv, int wsv) { struct LatticePoint4D *this = calloc(1, sizeof(*this)); this->xsv = xsv + 409; this->ysv = ysv + 409; this->zsv = zsv + 409; this->wsv = wsv + 409; double ssv = (xsv + ysv + zsv + wsv) * 0.309016994374947; this->dx = -xsv - ssv; this->dy = -ysv - ssv; this->dz = -zsv - ssv; this->dw = -wsv - ssv; this->xsi = 0.2 - xsv; this->ysi = 0.2 - ysv; this->zsi = 0.2 - zsv; this->wsi = 0.2 - wsv; this->ssiDelta = (0.8 - xsv - ysv - zsv - wsv) * 0.309016994374947; return this; } struct OpenSimplex2F_context { int16_t *perm; struct Grad2 *permGrad2; struct Grad3 *permGrad3; struct Grad4 *permGrad4; }; #define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0])) static struct Grad2 GRADIENTS_2D[PSIZE]; static struct Grad3 GRADIENTS_3D[PSIZE]; static struct Grad4 GRADIENTS_4D[PSIZE]; static struct LatticePoint2D *LOOKUP_2D[4]; static struct LatticePoint3D *LOOKUP_3D[8]; static struct LatticePoint4D *VERTICES_4D[16]; static struct Grad2 grad2[] = { { 0.130526192220052, 0.99144486137381}, { 0.38268343236509, 0.923879532511287}, { 0.608761429008721, 0.793353340291235}, { 0.793353340291235, 0.608761429008721}, { 0.923879532511287, 0.38268343236509}, { 0.99144486137381, 0.130526192220051}, { 0.99144486137381, -0.130526192220051}, { 0.923879532511287, -0.38268343236509}, { 0.793353340291235, -0.60876142900872}, { 0.608761429008721, -0.793353340291235}, { 0.38268343236509, -0.923879532511287}, { 0.130526192220052, -0.99144486137381}, {-0.130526192220052, -0.99144486137381}, {-0.38268343236509, -0.923879532511287}, {-0.608761429008721, -0.793353340291235}, {-0.793353340291235, -0.608761429008721}, {-0.923879532511287, -0.38268343236509}, {-0.99144486137381, -0.130526192220052}, {-0.99144486137381, 0.130526192220051}, {-0.923879532511287, 0.38268343236509}, {-0.793353340291235, 0.608761429008721}, {-0.608761429008721, 0.793353340291235}, {-0.38268343236509, 0.923879532511287}, {-0.130526192220052, 0.99144486137381} }; static struct Grad3 grad3[] = { {-2.22474487139, -2.22474487139, -1.0}, {-2.22474487139, -2.22474487139, 1.0}, {-3.0862664687972017, -1.1721513422464978, 0.0}, {-1.1721513422464978, -3.0862664687972017, 0.0}, {-2.22474487139, -1.0, -2.22474487139}, {-2.22474487139, 1.0, -2.22474487139}, {-1.1721513422464978, 0.0, -3.0862664687972017}, {-3.0862664687972017, 0.0, -1.1721513422464978}, {-2.22474487139, -1.0, 2.22474487139}, {-2.22474487139, 1.0, 2.22474487139}, {-3.0862664687972017, 0.0, 1.1721513422464978}, {-1.1721513422464978, 0.0, 3.0862664687972017}, {-2.22474487139, 2.22474487139, -1.0}, {-2.22474487139, 2.22474487139, 1.0}, {-1.1721513422464978, 3.0862664687972017, 0.0}, {-3.0862664687972017, 1.1721513422464978, 0.0}, {-1.0, -2.22474487139, -2.22474487139}, { 1.0, -2.22474487139, -2.22474487139}, { 0.0, -3.0862664687972017, -1.1721513422464978}, { 0.0, -1.1721513422464978, -3.0862664687972017}, {-1.0, -2.22474487139, 2.22474487139}, { 1.0, -2.22474487139, 2.22474487139}, { 0.0, -1.1721513422464978, 3.0862664687972017}, { 0.0, -3.0862664687972017, 1.1721513422464978}, {-1.0, 2.22474487139, -2.22474487139}, { 1.0, 2.22474487139, -2.22474487139}, { 0.0, 1.1721513422464978, -3.0862664687972017}, { 0.0, 3.0862664687972017, -1.1721513422464978}, {-1.0, 2.22474487139, 2.22474487139}, { 1.0, 2.22474487139, 2.22474487139}, { 0.0, 3.0862664687972017, 1.1721513422464978}, { 0.0, 1.1721513422464978, 3.0862664687972017}, { 2.22474487139, -2.22474487139, -1.0}, { 2.22474487139, -2.22474487139, 1.0}, { 1.1721513422464978, -3.0862664687972017, 0.0}, { 3.0862664687972017, -1.1721513422464978, 0.0}, { 2.22474487139, -1.0, -2.22474487139}, { 2.22474487139, 1.0, -2.22474487139}, { 3.0862664687972017, 0.0, -1.1721513422464978}, { 1.1721513422464978, 0.0, -3.0862664687972017}, { 2.22474487139, -1.0, 2.22474487139}, { 2.22474487139, 1.0, 2.22474487139}, { 1.1721513422464978, 0.0, 3.0862664687972017}, { 3.0862664687972017, 0.0, 1.1721513422464978}, { 2.22474487139, 2.22474487139, -1.0}, { 2.22474487139, 2.22474487139, 1.0}, { 3.0862664687972017, 1.1721513422464978, 0.0}, { 1.1721513422464978, 3.0862664687972017, 0.0} }; static struct Grad4 grad4[] = { {-0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624}, {-0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098}, {-0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301}, {-0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301}, {-0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174}, {-0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174}, {-0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796}, {-0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842}, {-0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624}, {-0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098}, {-0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301}, { 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301}, {-0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174}, { 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174}, { 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796}, {-0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842}, {-0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624}, {-0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098}, {-0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301}, { 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301}, {-0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174}, { 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174}, { 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796}, {-0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842}, {-0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078}, {-0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708}, {-0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708}, { 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708}, {-0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365}, { 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365}, { 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365}, {-0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062}, {-0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381}, {-0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724}, {-0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724}, {-0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712}, {-0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585}, {-0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602}, {-0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602}, {-0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944}, {-0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381}, {-0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724}, { 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724}, { 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712}, {-0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585}, {-0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602}, { 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602}, { 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944}, {-0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381}, {-0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724}, { 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724}, { 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712}, {-0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585}, {-0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602}, { 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602}, { 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944}, {-0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537}, {-0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164}, {-0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195}, {-0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945}, {-0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945}, {-0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195}, {-0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164}, {-0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537}, {-0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537}, {-0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164}, { 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195}, { 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945}, {-0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945}, {-0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195}, { 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164}, { 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537}, {-0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944}, {-0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602}, { 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602}, { 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585}, {-0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712}, {-0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724}, { 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724}, { 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381}, {-0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537}, {-0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164}, {-0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195}, {-0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945}, {-0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945}, {-0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195}, {-0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164}, {-0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537}, {-0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537}, {-0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164}, { 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195}, { 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945}, {-0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945}, {-0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195}, { 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164}, { 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537}, {-0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944}, {-0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602}, { 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602}, { 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585}, {-0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712}, {-0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724}, { 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724}, { 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381}, { 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537}, { 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164}, { 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195}, { 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945}, { 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945}, { 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195}, { 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164}, { 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537}, { 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537}, { 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164}, { 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195}, { 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945}, { 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945}, { 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195}, { 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164}, { 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537}, { 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944}, { 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602}, { 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602}, { 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585}, { 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712}, { 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724}, { 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724}, { 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381}, { 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062}, {-0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365}, {-0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365}, {-0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708}, { 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365}, { 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708}, { 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708}, { 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078}, { 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842}, {-0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796}, {-0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174}, {-0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301}, { 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174}, { 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301}, { 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098}, { 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624}, { 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842}, {-0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796}, {-0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174}, {-0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301}, { 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174}, { 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301}, { 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098}, { 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624}, { 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842}, { 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796}, { 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174}, { 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301}, { 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174}, { 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301}, { 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098}, { 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624} }; static void setup_gradients(void) { static int already_did = 0; int i; if (already_did) return; already_did = 1; for (i = 0; (size_t) i < ARRAYSIZE(grad2); i++) { grad2[i].dx /= N2; grad2[i].dy /= N2; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_2D[i] = grad2[i % ARRAYSIZE(grad2)]; } for (i = 0; (size_t) i < ARRAYSIZE(grad3); i++) { grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; } for (i = 0; i < PSIZE; i++) { GRADIENTS_3D[i] = grad3[i % ARRAYSIZE(grad3)]; } for (i = 0; (size_t) i < ARRAYSIZE(grad4); i++) { grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4; } for (i = 0; i < PSIZE; i++) { GRADIENTS_4D[i] = grad4[i % ARRAYSIZE(grad4)]; } } static void setup_lattice_points(void) { static int already_did = 0; int i; if (already_did) return; already_did = 1; LOOKUP_2D[0] = new_LatticePoint2D(1, 0); LOOKUP_2D[1] = new_LatticePoint2D(0, 0); LOOKUP_2D[2] = new_LatticePoint2D(1, 1); LOOKUP_2D[3] = new_LatticePoint2D(0, 1); for (i = 0; i < 8; i++) { int i1, j1, k1, i2, j2, k2; i1 = (i >> 0) & 1; j1 = (i >> 1) & 1; k1 = (i >> 2) & 1; i2 = i1 ^ 1; j2 = j1 ^ 1; k2 = k1 ^ 1; // The two points within this octant, one from each of the two cubic half-lattices. struct LatticePoint3D *c0 = new_LatticePoint3D(i1, j1, k1, 0); struct LatticePoint3D *c1 = new_LatticePoint3D(i1 + i2, j1 + j2, k1 + k2, 1); // Each single step away on the first half-lattice. struct LatticePoint3D *c2 = new_LatticePoint3D(i1 ^ 1, j1, k1, 0); struct LatticePoint3D *c3 = new_LatticePoint3D(i1, j1 ^ 1, k1, 0); struct LatticePoint3D *c4 = new_LatticePoint3D(i1, j1, k1 ^ 1, 0); // Each single step away on the second half-lattice. struct LatticePoint3D *c5 = new_LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + k2, 1); struct LatticePoint3D *c6 = new_LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + k2, 1); struct LatticePoint3D *c7 = new_LatticePoint3D(i1 + i2, j1 + j2, k1 + (k2 ^ 1), 1); // First two are guaranteed. c0->nextOnFailure = c0->nextOnSuccess = c1; c1->nextOnFailure = c1->nextOnSuccess = c2; // Once we find one on the first half-lattice, the rest are out. // In addition, knowing c2 rules out c5. c2->nextOnFailure = c3; c2->nextOnSuccess = c6; c3->nextOnFailure = c4; c3->nextOnSuccess = c5; c4->nextOnFailure = c4->nextOnSuccess = c5; // Once we find one on the second half-lattice, the rest are out. c5->nextOnFailure = c6; c5->nextOnSuccess = NULL; c6->nextOnFailure = c7; c6->nextOnSuccess = NULL; c7->nextOnFailure = c7->nextOnSuccess = NULL; LOOKUP_3D[i] = c0; } for (i = 0; i < 16; i++) { VERTICES_4D[i] = new_LatticePoint4D((i >> 0) & 1, (i >> 1) & 1, (i >> 2) & 1, (i >> 3) & 1); } } /* Free up all the LatticePoint stuff allocated in setup_lattice_points() */ void OpenSimplex2F_shutdown(void) { int i; struct LatticePoint3D *list[8]; int count = 0; for (i = 0; (size_t) i < ARRAYSIZE(LOOKUP_2D); i++) { if (LOOKUP_2D[i]) { free(LOOKUP_2D[i]); LOOKUP_2D[i] = NULL; } } for (i = 0; (size_t) i < ARRAYSIZE(LOOKUP_3D); i++) { if (LOOKUP_3D[i]) { /* There are cycles in the tree LOOKUP_3D[i], so we have to * make a list of unique pointers within the tree to free them. * We know there are only 8 unique pointers in the tree. */ count = 0; memset(list, 0, sizeof(list)); find_unique_pointers(LOOKUP_3D[i], list, &count); free_LatticePoint3D(list, count); LOOKUP_3D[i] = NULL; } } for (i = 0; (size_t) i < ARRAYSIZE(VERTICES_4D); i++) { if (VERTICES_4D[i]) { free(VERTICES_4D[i]); VERTICES_4D[i] = NULL; } } } void OpenSimplex2F_free(struct OpenSimplex2F_context *ctx) { if (ctx->perm) free(ctx->perm); if (ctx->permGrad2) free(ctx->permGrad2); if (ctx->permGrad3) free(ctx->permGrad3); if (ctx->permGrad4) free(ctx->permGrad4); free(ctx); } int OpenSimplex2F(int64_t seed, struct OpenSimplex2F_context **ctx) { struct OpenSimplex2F_context *c; int i, *source; setup_gradients(); setup_lattice_points(); source = calloc(1, sizeof(*source) * PSIZE); if (!source) return -1; c = calloc(1, sizeof(**ctx)); if (!c) { free(source); return -1; } *ctx = c; c->perm = calloc(1, sizeof(*c->perm) * PSIZE); c->permGrad2 = calloc(1, sizeof(*c->permGrad2) * PSIZE); c->permGrad3 = calloc(1, sizeof(*c->permGrad3) * PSIZE); c->permGrad4 = calloc(1, sizeof(*c->permGrad4) * PSIZE); if (!c->perm || !c->permGrad2 || !c->permGrad3 || !c->permGrad4) { OpenSimplex2F_free(*ctx); *ctx = NULL; free(source); return -1; } for (i = 0; i < PSIZE; i++) source[i] = (int16_t) i; for (int i = PSIZE - 1; i >= 0; i--) { seed = (uint64_t) seed * (uint64_t) 6364136223846793005LL + (uint64_t) 1442695040888963407LL; int r = (int)((seed + 31) % (i + 1)); if (r < 0) r += (i + 1); c->perm[i] = source[r]; c->permGrad2[i] = GRADIENTS_2D[c->perm[i]]; c->permGrad3[i] = GRADIENTS_3D[c->perm[i]]; c->permGrad4[i] = GRADIENTS_4D[c->perm[i]]; source[r] = source[i]; } free(source); return 0; } static int fastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } /* * 2D Simplex noise base. * Lookup table implementation inspired by DigitalShadow. */ static double noise2_Base(struct OpenSimplex2F_context *ctx, double xs, double ys) { double value = 0; int i; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys); double xsi = xs - xsb, ysi = ys - ysb; // Index to point list int index = (int)((ysi - xsi) / 2 + 1); double ssi = (xsi + ysi) * -0.211324865405187; double xi = xsi + ssi, yi = ysi + ssi; // Point contributions for (i = 0; i < 3; i++) { struct LatticePoint2D c = *(LOOKUP_2D[index + i]); double dx = xi + c.dx, dy = yi + c.dy; double attn = 0.5 - dx * dx - dy * dy; if (attn <= 0) continue; int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK; struct Grad2 grad = ctx->permGrad2[ctx->perm[pxm] ^ pym]; double extrapolation = grad.dx * dx + grad.dy * dy; attn *= attn; value += attn * attn * extrapolation; } return value; } /** * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. * Lookup table implementation inspired by DigitalShadow. * It was actually faster to narrow down the points in the loop itself, * than to build up the index with enough info to isolate 4 points. */ static double noise3_BCC(struct OpenSimplex2F_context *ctx, double xr, double yr, double zr) { // Get base and offsets inside cube of first lattice. int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr); double xri = xr - xrb, yri = yr - yrb, zri = zr - zrb; // Identify which octant of the cube we're in. This determines which cell // in the other cubic lattice we're in, and also narrows down one point on each. int xht = (int)(xri + 0.5), yht = (int)(yri + 0.5), zht = (int)(zri + 0.5); int index = (xht << 0) | (yht << 1) | (zht << 2); // Point contributions double value = 0; struct LatticePoint3D *c = LOOKUP_3D[index]; while (c != NULL) { double dxr = xri + c->dxr, dyr = yri + c->dyr, dzr = zri + c->dzr; double attn = 0.5 - dxr * dxr - dyr * dyr - dzr * dzr; if (attn < 0) { c = c->nextOnFailure; } else { int pxm = (xrb + c->xrv) & PMASK, pym = (yrb + c->yrv) & PMASK, pzm = (zrb + c->zrv) & PMASK; struct Grad3 grad = ctx->permGrad3[ctx->perm[ctx->perm[pxm] ^ pym] ^ pzm]; double extrapolation = grad.dx * dxr + grad.dy * dyr + grad.dz * dzr; attn *= attn; value += attn * attn * extrapolation; c = c->nextOnSuccess; } } return value; } /** * 2D Simplex noise, standard lattice orientation. */ double OpenSimplex2F_noise2(struct OpenSimplex2F_context *ctx, double x, double y) { // Get points for A2* lattice double s = 0.366025403784439 * (x + y); double xs = x + s, ys = y + s; return noise2_Base(ctx, xs, ys); } /** * 2D Simplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps. */ double OpenSimplex2F_noise2_XBeforeY(struct OpenSimplex2F_context *ctx, double x, double y) { // Skew transform and rotation baked into one. double xx = x * 0.7071067811865476; double yy = y * 1.224744871380249; return noise2_Base(ctx, yy + xx, yy - xx); } /** * 3D Re-oriented 4-point BCC noise, classic orientation. * Proper substitute for 3D Simplex in light of Forbidden Formulae. * Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. */ double OpenSimplex2F_noise3_Classic(struct OpenSimplex2F_context *ctx, double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce the expected look on cardinal planar slices. // If texturing objects that don't tend to have cardinal plane faces, you could even remove this. // Orthonormal rotation. Not a skew transform. double r = (2.0 / 3.0) * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(ctx, xr, yr, zr); } /** * 3D Re-oriented 4-point BCC noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). * For a time varied animation, call noise3_XYBeforeZ(x, y, T). */ double OpenSimplex2F_noise3_XYBeforeZ(struct OpenSimplex2F_context *ctx, double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Y triangular like 2D. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * -0.211324865405187; double zz = z * 0.577350269189626; double xr = x + s2 - zz, yr = y + s2 - zz; double zr = xy * 0.577350269189626 + zz; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(ctx, xr, yr, zr); } /** * 3D Re-oriented 4-point BCC noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). * If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. * For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ. */ double OpenSimplex2F_noise3_XZBeforeY(struct OpenSimplex2F_context *ctx, double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Z triangular like 2D. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * -0.211324865405187; double yy = y * 0.577350269189626; double xr = x + s2 - yy; double zr = z + s2 - yy; double yr = xz * 0.577350269189626 + yy; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(ctx, xr, yr, zr); } /** * 4D OpenSimplex2F noise base. * Current implementation not fully optimized by lookup tables. * But still comes out slightly ahead of Gustavson's Simplex in tests. */ static double noise4_Base(struct OpenSimplex2F_context *ctx, double xs, double ys, double zs, double ws) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys), zsb = fastFloor(zs), wsb = fastFloor(ws); double xsi = xs - xsb, ysi = ys - ysb, zsi = zs - zsb, wsi = ws - wsb; // If we're in the lower half, flip so we can repeat the code for the upper half. We'll flip back later. double siSum = xsi + ysi + zsi + wsi; double ssi = siSum * 0.309016994374947; // Prep for vertex contributions. bool inLowerHalf = (siSum < 2); if (inLowerHalf) { xsi = 1 - xsi; ysi = 1 - ysi; zsi = 1 - zsi; wsi = 1 - wsi; siSum = 4 - siSum; } // Consider opposing vertex pairs of the octahedron formed by the central cross-section of the stretched tesseract double aabb = xsi + ysi - zsi - wsi, abab = xsi - ysi + zsi - wsi, abba = xsi - ysi - zsi + wsi; double aabbScore = fabs(aabb), ababScore = fabs(abab), abbaScore = fabs(abba); // Find the closest point on the stretched tesseract as if it were the upper half int vertexIndex, via, vib; double asi, bsi; if (aabbScore > ababScore && aabbScore > abbaScore) { if (aabb > 0) { asi = zsi; bsi = wsi; vertexIndex = B0011; via = B0111; vib = B1011; } else { asi = xsi; bsi = ysi; vertexIndex = B1100; via = B1101; vib = B1110; } } else if (ababScore > abbaScore) { if (abab > 0) { asi = ysi; bsi = wsi; vertexIndex = B0101; via = B0111; vib = B1101; } else { asi = xsi; bsi = zsi; vertexIndex = B1010; via = B1011; vib = B1110; } } else { if (abba > 0) { asi = ysi; bsi = zsi; vertexIndex = B1001; via = B1011; vib = B1101; } else { asi = xsi; bsi = wsi; vertexIndex = B0110; via = B0111; vib = B1110; } } if (bsi > asi) { via = vib; double temp = bsi; bsi = asi; asi = temp; } if (siSum + asi > 3) { vertexIndex = via; if (siSum + bsi > 4) { vertexIndex = B1111; } } // Now flip back if we're actually in the lower half. if (inLowerHalf) { xsi = 1 - xsi; ysi = 1 - ysi; zsi = 1 - zsi; wsi = 1 - wsi; vertexIndex ^= B1111; } // Five points to add, total, from five copies of the A4 lattice. for (int i = 0; i < 5; i++) { // Update xsb/etc. and add the lattice point's contribution. struct LatticePoint4D c = *(VERTICES_4D[vertexIndex]); xsb += c.xsv; ysb += c.ysv; zsb += c.zsv; wsb += c.wsv; double xi = xsi + ssi, yi = ysi + ssi, zi = zsi + ssi, wi = wsi + ssi; double dx = xi + c.dx, dy = yi + c.dy, dz = zi + c.dz, dw = wi + c.dw; double attn = 0.5 - dx * dx - dy * dy - dz * dz - dw * dw; if (attn > 0) { int pxm = xsb & PMASK, pym = ysb & PMASK, pzm = zsb & PMASK, pwm = wsb & PMASK; struct Grad4 grad = ctx->permGrad4[ctx->perm[ctx->perm[ctx->perm[pxm] ^ pym] ^ pzm] ^ pwm]; double ramped = grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw; attn *= attn; value += attn * attn * ramped; } // Maybe this helps the compiler/JVM/LLVM/etc. know we can end the loop here. Maybe not. if (i == 4) break; // Update the relative skewed coordinates to reference the vertex we just added. // Rather, reference its counterpart on the lattice copy that is shifted down by // the vector <-0.2, -0.2, -0.2, -0.2> xsi += c.xsi; ysi += c.ysi; zsi += c.zsi; wsi += c.wsi; ssi += c.ssiDelta; // Next point is the closest vertex on the 4-simplex whose base vertex is the aforementioned vertex. double score0 = 1.0 + ssi * (-1.0 / 0.309016994374947); // Seems slightly faster than 1.0-xsi-ysi-zsi-wsi vertexIndex = B0000; if (xsi >= ysi && xsi >= zsi && xsi >= wsi && xsi >= score0) { vertexIndex = B0001; } else if (ysi > xsi && ysi >= zsi && ysi >= wsi && ysi >= score0) { vertexIndex = B0010; } else if (zsi > xsi && zsi > ysi && zsi >= wsi && zsi >= score0) { vertexIndex = B0100; } else if (wsi > xsi && wsi > ysi && wsi > zsi && wsi >= score0) { vertexIndex = B1000; } } return value; } /** * 4D OpenSimplex2F noise, classic lattice orientation. */ double OpenSimplex2F_noise4_Classic(struct OpenSimplex2F_context *ctx, double x, double y, double z, double w) { // Get points for A4 lattice double s = -0.138196601125011 * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return noise4_Base(ctx, xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ double OpenSimplex2F_noise4_XYBeforeZW(struct OpenSimplex2F_context *ctx, double x, double y, double z, double w) { double s2 = (x + y) * -0.178275657951399372 + (z + w) * 0.215623393288842828; double t2 = (z + w) * -0.403949762580207112 + (x + y) * -0.375199083010075342; double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; return noise4_Base(ctx, xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise, with XZ and YW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Z (or Y and W) are horizontal. */ double OpenSimplex2F_noise4_XZBeforeYW(struct OpenSimplex2F_context *ctx, double x, double y, double z, double w) { double s2 = (x + z) * -0.178275657951399372 + (y + w) * 0.215623393288842828; double t2 = (y + w) * -0.403949762580207112 + (x + z) * -0.375199083010075342; double xs = x + s2, ys = y + t2, zs = z + s2, ws = w + t2; return noise4_Base(ctx, xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise, with XYZ oriented like noise3_Classic, * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) */ double OpenSimplex2F_noise4_XYZBeforeW(struct OpenSimplex2F_context *ctx, double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 0.2236067977499788; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return noise4_Base(ctx, xs, ys, zs, ws); } ================================================ FILE: _old/c/OpenSimplex2F.h ================================================ #ifndef OpenSimplex2F_h__ #define OpenSimplex2F_h__ /** * K.jpg's OpenSimplex 2, faster variant * * - 2D is standard simplex implemented using a lookup table. * - 3D is "Re-oriented 4-point BCC noise" which constructs a * congruent BCC lattice in a much different way than usual. * - 4D constructs the lattice as a union of five copies of its * reciprocal. It successively finds the closest point on each. * * Multiple versions of each function are provided. See the * documentation above each, for more info. * * Ported from Java to C by Stephen M. Cameron * */ #if ((__GNUC_STDC_INLINE__) || (__STDC_VERSION__ >= 199901L)) #include #define INLINE inline #elif (defined (_MSC_VER) || defined (__GNUC_GNU_INLINE__)) #include #define INLINE __inline #else /* ANSI C doesn't have inline or stdint.h. */ #define INLINE #endif #ifdef __cplusplus extern "C" { #endif struct OpenSimplex2F_context; /* Allocate and initialize OpenSimplex2F context */ int OpenSimplex2F(int64_t seed, struct OpenSimplex2F_context **ctx); /* Free OpenSimplex2F context */ void OpenSimplex2F_free(struct OpenSimplex2F_context * ctx); /* Free singleton lattice point data */ void OpenSimplex2F_shutdown(void); /** * 2D Simplex noise, standard lattice orientation. */ double OpenSimplex2F_noise2(struct OpenSimplex2F_context *ctx, double x, double y); /** * 2D Simplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps. */ double OpenSimplex2F_noise2_XBeforeY(struct OpenSimplex2F_context *ctx, double x, double y); /** * 3D Re-oriented 4-point BCC noise, classic orientation. * Proper substitute for 3D Simplex in light of Forbidden Formulae. * Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. */ double OpenSimplex2F_noise3_Classic(struct OpenSimplex2F_context *ctx, double x, double y, double z); /** * 3D Re-oriented 4-point BCC noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). * For a time varied animation, call noise3_XYBeforeZ(x, y, T). */ double OpenSimplex2F_noise3_XYBeforeZ(struct OpenSimplex2F_context *ctx, double x, double y, double z); /** * 3D Re-oriented 4-point BCC noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). * If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. * For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ. */ double OpenSimplex2F_noise3_XZBeforeY(struct OpenSimplex2F_context *ctx, double x, double y, double z); /** * 4D OpenSimplex2F noise, classic lattice orientation. */ double OpenSimplex2F_noise4_Classic(struct OpenSimplex2F_context *ctx, double x, double y, double z, double w); /** * 4D OpenSimplex2F noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ double OpenSimplex2F_noise4_XYBeforeZW(struct OpenSimplex2F_context *ctx, double x, double y, double z, double w); /** * 4D OpenSimplex2F noise, with XZ and YW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Z (or Y and W) are horizontal. */ double OpenSimplex2F_noise4_XZBeforeYW(struct OpenSimplex2F_context *ctx, double x, double y, double z, double w); /** * 4D OpenSimplex2F noise, with XYZ oriented like noise3_Classic, * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) */ double OpenSimplex2F_noise4_XYZBeforeW(struct OpenSimplex2F_context *ctx, double x, double y, double z, double w); #ifdef __cplusplus } #endif #endif ================================================ FILE: _old/c/UNLICENSE ================================================ This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. 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 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. For more information, please refer to ================================================ FILE: _old/c/test_OpenSimplex2F.c ================================================ #include #if ((__STDC_VERSION__ >= 199901L) || (_MSC_VER)) #include #endif #include #include #include #include "OpenSimplex2F.h" #define WIDTH 512 #define HEIGHT 512 #define FEATURE_SIZE 24 static int write_png_image(const char *filename, unsigned char *pixels, int w, int h, int has_alpha) { png_structp png_ptr; png_infop info_ptr; png_byte **row; int x, y, rc, colordepth = 8; int bytes_per_pixel = has_alpha ? 4 : 3; FILE *f; f = fopen(filename, "w"); if (!f) { fprintf(stderr, "fopen: %s:%s\n", filename, strerror(errno)); return -1; } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) goto cleanup1; info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) goto cleanup2; if (setjmp(png_jmpbuf(png_ptr))) /* oh libpng, you're old as dirt, aren't you. */ goto cleanup2; png_set_IHDR(png_ptr, info_ptr, (size_t) w, (size_t) h, colordepth, has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); row = png_malloc(png_ptr, h * sizeof(*row)); for (y = 0; y < h; y++) { row[y] = png_malloc(png_ptr, w * bytes_per_pixel); for (x = 0; x < w; x++) { unsigned char *r = (unsigned char *) row[y]; unsigned char *src = (unsigned char *) &pixels[y * w * bytes_per_pixel + x * bytes_per_pixel]; unsigned char *dest = &r[x * bytes_per_pixel]; memcpy(dest, src, bytes_per_pixel); } } png_init_io(png_ptr, f); png_set_rows(png_ptr, info_ptr, row); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING, NULL); for (y = 0; y < h; y++) png_free(png_ptr, row[y]); png_free(png_ptr, row); rc = 0; cleanup2: png_destroy_write_struct(&png_ptr, &info_ptr); cleanup1: fclose(f); return rc; } int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[]) { int x, y; double value; double v0, v1, v2; /* values from different octaves. */ uint32_t rgb; uint32_t image2d[HEIGHT][WIDTH]; uint32_t image3d[HEIGHT][WIDTH]; uint32_t image4d[HEIGHT][WIDTH]; struct OpenSimplex2F_context *ctx; OpenSimplex2F(77374, &ctx); for (y = 0; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { #if defined(SINGLE_OCTAVE) value = open_simplex_noise4(ctx, (double) x / FEATURE_SIZE, (double) y / FEATURE_SIZE, 0.0, 0.0); #else /* Use three octaves: frequency N, N/2 and N/4 with relative amplitudes 4:2:1. */ v0 = OpenSimplex2F_noise4_Classic(ctx, (double) x / FEATURE_SIZE / 4, (double) y / FEATURE_SIZE / 4, 0.0, 0.0); v1 = OpenSimplex2F_noise4_Classic(ctx, (double) x / FEATURE_SIZE / 2, (double) y / FEATURE_SIZE / 2, 0.0, 0.0); v2 = OpenSimplex2F_noise4_Classic(ctx, (double) x / FEATURE_SIZE / 1, (double) y / FEATURE_SIZE / 1, 0.0, 0.0); value = v0 * 4 / 7.0 + v1 * 2 / 7.0 + v2 * 1 / 7.0; #endif rgb = 0x010101 * (uint32_t) ((value + 1) * 127.5); image2d[y][x] = ((uint32_t) 0x0ff << 24) | (rgb); value = OpenSimplex2F_noise2(ctx, (double) x / FEATURE_SIZE, (double) y / FEATURE_SIZE); rgb = 0x010101 * (uint32_t) ((value + 1) * 127.5); image3d[y][x] = ((uint32_t) 0x0ff << 24) | (rgb); value = OpenSimplex2F_noise3_Classic(ctx, (double) x / FEATURE_SIZE, (double) y / FEATURE_SIZE, 0.0); rgb = 0x010101 * (uint32_t) ((value + 1) * 127.5); image4d[y][x] = ((uint32_t) 0x0ff << 24) | (rgb); } } write_png_image("test2d.png", (unsigned char *) image2d, WIDTH, HEIGHT, 1); write_png_image("test3d.png", (unsigned char *) image3d, WIDTH, HEIGHT, 1); write_png_image("test4d.png", (unsigned char *) image4d, WIDTH, HEIGHT, 1); OpenSimplex2F_free(ctx); OpenSimplex2F_shutdown(); return 0; } ================================================ FILE: _old/cpp/OpenSimplex2S.cpp ================================================ #include "OpenSimplex2S.hpp" OpenSimplex2S::Grad2 OpenSimplex2S::GRADIENTS_2D[OpenSimplex2S::PSIZE] {}; OpenSimplex2S::Grad3 OpenSimplex2S::GRADIENTS_3D[OpenSimplex2S::PSIZE] {}; OpenSimplex2S::Grad4 OpenSimplex2S::GRADIENTS_4D[OpenSimplex2S::PSIZE] {}; OpenSimplex2S::LatticePoint2D OpenSimplex2S::LOOKUP_2D[8 * 4] {}; OpenSimplex2S::LatticePoint3D OpenSimplex2S::LOOKUP_3D[8] {}; OpenSimplex2S::LatticePoint4D OpenSimplex2S::LOOKUP_4D[256][20] {}; unsigned char OpenSimplex2S::LOOKUP_4D_SIZE[256] {}; OpenSimplex2S::Initializer::Initializer() { OpenSimplex2S::initLatticePoints(); OpenSimplex2S::initGradients(); } OpenSimplex2S::Initializer OpenSimplex2S::initializer {}; OpenSimplex2S::OpenSimplex2S(long seed) { short source[PSIZE] {}; for (short i = 0; i < PSIZE; i++) { source[i] = i; } for (int i = PSIZE - 1; i >= 0; i--) { seed = seed * 6364136223846793005L + 1442695040888963407L; int r = static_cast((seed + 31) % (i + 1)); if (r < 0) { r += (i + 1); } perm[i] = source[r]; permGrad2[i] = GRADIENTS_2D[perm[i]]; permGrad3[i] = GRADIENTS_3D[perm[i]]; permGrad4[i] = GRADIENTS_4D[perm[i]]; source[r] = source[i]; } } /** * 2D SuperSimplex noise, standard lattice orientation. */ double OpenSimplex2S::noise2(double x, double y) { // Get points for A2* lattice double s = 0.366025403784439 * (x + y); double xs = x + s; double ys = y + s; return noise2_Base(xs, ys); } /** * 2D SuperSimplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps. */ double OpenSimplex2S::noise2_XBeforeY(double x, double y) { // Skew transform and rotation baked into one. double xx = x * 0.7071067811865476; double yy = y * 1.224744871380249; return noise2_Base(yy + xx, yy - xx); } /** * 2D SuperSimplex noise base. * Lookup table implementation inspired by DigitalShadow. */ double OpenSimplex2S::noise2_Base(double xs, double ys) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs); int ysb = fastFloor(ys); double xsi = xs - xsb; double ysi = ys - ysb; // Index to point list int a = static_cast(xsi + ysi); int index = (a << 2) | static_cast(xsi - ysi / 2 + 1 - a / 2.0) << 3 | static_cast(ysi - xsi / 2 + 1 - a / 2.0) << 4; double ssi = (xsi + ysi) * -0.211324865405187; double xi = xsi + ssi; double yi = ysi + ssi; // Point contributions for (int i = 0; i < 4; i++) { LatticePoint2D c = LOOKUP_2D[index + i]; double dx = xi + c.dx; double dy = yi + c.dy; double attn = 2.0 / 3.0 - dx * dx - dy * dy; if (attn <= 0) { continue; } int pxm = (xsb + c.xsv) & PMASK; int pym = (ysb + c.ysv) & PMASK; Grad2 grad = permGrad2[perm[pxm] ^ pym]; double extrapolation = grad.dx * dx + grad.dy * dy; attn *= attn; value += attn * attn * extrapolation; } return value; } /** * 3D Re-oriented 8-point BCC noise, classic orientation * Proper substitute for what 3D SuperSimplex would be, * in light of Forbidden Formulae. * Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. */ double OpenSimplex2S::noise3_Classic(double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce the expected look on cardinal planar // slices. If texturing objects that don't tend to have cardinal plane faces, you could even // remove this. Orthonormal rotation. Not a skew transform. double r = (2.0 / 3.0) * (x + y + z); double xr = r - x; double yr = r - y; double zr = r - z; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). * For a time varied animation, call noise3_XYBeforeZ(x, y, T). */ double OpenSimplex2S::noise3_XYBeforeZ(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Y triangular like 2D. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * -0.211324865405187; double zz = z * 0.577350269189626; double xr = x + s2 - zz; double yr = y + s2 - zz; double zr = xy * 0.577350269189626 + zz; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). * If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. * For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ. */ double OpenSimplex2S::noise3_XZBeforeY(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Z triangular like 2D. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * -0.211324865405187; double yy = y * 0.577350269189626; double xr = x + s2 - yy; double zr = z + s2 - yy; double yr = xz * 0.577350269189626 + yy; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. * Lookup table implementation inspired by DigitalShadow. * It was actually faster to narrow down the points in the loop itself, * than to build up the index with enough info to isolate 8 points. */ double OpenSimplex2S::noise3_BCC(double xr, double yr, double zr) { // Get base and offsets inside cube of first lattice. int xrb = fastFloor(xr); int yrb = fastFloor(yr); int zrb = fastFloor(zr); double xri = xr - xrb; double yri = yr - yrb; double zri = zr - zrb; // Identify which octant of the cube we're in. This determines which cell // in the other cubic lattice we're in, and also narrows down one point on each. int xht = static_cast(xri + 0.5); int yht = static_cast(yri + 0.5); int zht = static_cast(zri + 0.5); int index = (xht << 0) | (yht << 1) | (zht << 2); // Point contributions double value = 0; LatticePoint3D* c = &LOOKUP_3D[index]; while (c != nullptr) { double dxr = xri + c->dxr; double dyr = yri + c->dyr; double dzr = zri + c->dzr; double attn = 0.75 - dxr * dxr - dyr * dyr - dzr * dzr; if (attn < 0) { c = c->nextOnFailure; } else { int pxm = (xrb + c->xrv) & PMASK; int pym = (yrb + c->yrv) & PMASK; int pzm = (zrb + c->zrv) & PMASK; Grad3 grad = permGrad3[perm[perm[pxm] ^ pym] ^ pzm]; double extrapolation = grad.dx * dxr + grad.dy * dyr + grad.dz * dzr; attn *= attn; value += attn * attn * extrapolation; c = c->nextOnSuccess; } } return value; } /** * 4D SuperSimplex noise, classic lattice orientation. */ double OpenSimplex2S::noise4_Classic(double x, double y, double z, double w) { // Get points for A4 lattice double s = 0.309016994374947 * (x + y + z + w); double xs = x + s; double ys = y + s; double zs = z + s; double ws = w + s; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ double OpenSimplex2S::noise4_XYBeforeZW(double x, double y, double z, double w) { double s2 = (x + y) * -0.28522513987434876941 + (z + w) * 0.83897065470611435718; double t2 = (z + w) * 0.21939749883706435719 + (x + y) * -0.48214856493302476942; double xs = x + s2; double ys = y + s2; double zs = z + t2; double ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XZ and YW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Z (or Y and W) are horizontal. */ double OpenSimplex2S::noise4_XZBeforeYW(double x, double y, double z, double w) { double s2 = (x + z) * -0.28522513987434876941 + (y + w) * 0.83897065470611435718; double t2 = (y + w) * 0.21939749883706435719 + (x + z) * -0.48214856493302476942; double xs = x + s2; double ys = y + t2; double zs = z + s2; double ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XYZ oriented like noise3_Classic, * and W for an extra degree of freedom. * Recommended for time-varied animations which texture a 3D object (W=time) */ double OpenSimplex2S::noise4_XYZBeforeW(double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 1.118033988749894; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2; double ys = y + s2; double zs = z + s2; double ws = -0.5 * xyz + ww; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise base. * Using ultra-simple 4x4x4x4 lookup partitioning. * This isn't as elegant or SIMD/GPU/etc. portable as other approaches, * but it does compete performance-wise with optimized OpenSimplex1. */ double OpenSimplex2S::noise4_Base(double xs, double ys, double zs, double ws) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs); int ysb = fastFloor(ys); int zsb = fastFloor(zs); int wsb = fastFloor(ws); double xsi = xs - xsb; double ysi = ys - ysb; double zsi = zs - zsb; double wsi = ws - wsb; // Unskewed offsets double ssi = (xsi + ysi + zsi + wsi) * -0.138196601125011; double xi = xsi + ssi; double yi = ysi + ssi; double zi = zsi + ssi; double wi = wsi + ssi; int index = ((fastFloor(xs * 4) & 3) << 0) | ((fastFloor(ys * 4) & 3) << 2) | ((fastFloor(zs * 4) & 3) << 4) | ((fastFloor(ws * 4) & 3) << 6); // Point contributions for (int i = 0; i < LOOKUP_4D_SIZE[index]; ++i) { auto& c = LOOKUP_4D[index][i]; double dx = xi + c.dx; double dy = yi + c.dy; double dz = zi + c.dz; double dw = wi + c.dw; double attn = 0.8 - dx * dx - dy * dy - dz * dz - dw * dw; if (attn > 0) { attn *= attn; int pxm = (xsb + c.xsv) & PMASK; int pym = (ysb + c.ysv) & PMASK; int pzm = (zsb + c.zsv) & PMASK; int pwm = (wsb + c.wsv) & PMASK; Grad4 grad = permGrad4[perm[perm[perm[pxm] ^ pym] ^ pzm] ^ pwm]; double extrapolation = grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw; value += attn * attn * extrapolation; } } return value; } int OpenSimplex2S::fastFloor(double x) { int xi = static_cast(x); return x < xi ? xi - 1 : xi; } OpenSimplex2S::LatticePoint2D::LatticePoint2D(int a_xsv, int a_ysv) { xsv = a_xsv; ysv = a_ysv; double ssv = (a_xsv + a_ysv) * -0.211324865405187; dx = -a_xsv - ssv; dy = -a_ysv - ssv; } OpenSimplex2S::LatticePoint2D::LatticePoint2D() = default; OpenSimplex2S::LatticePoint3D::LatticePoint3D(int a_xrv, int a_yrv, int a_zrv, int lattice) { dxr = -a_xrv + lattice * 0.5; dyr = -a_yrv + lattice * 0.5; dzr = -a_zrv + lattice * 0.5; xrv = a_xrv + lattice * 1024; yrv = a_yrv + lattice * 1024; zrv = a_zrv + lattice * 1024; } OpenSimplex2S::LatticePoint3D::LatticePoint3D() = default; OpenSimplex2S::LatticePoint4D::LatticePoint4D(int a_xsv, int a_ysv, int a_zsv, int a_wsv) { xsv = a_xsv; ysv = a_ysv; zsv = a_zsv; wsv = a_wsv; double ssv = (a_xsv + a_ysv + a_zsv + a_wsv) * -0.138196601125011; dx = -a_xsv - ssv; dy = -a_ysv - ssv; dz = -a_zsv - ssv; dw = -a_wsv - ssv; } OpenSimplex2S::LatticePoint4D::LatticePoint4D() = default; void OpenSimplex2S::initLatticePoints() { for (int i = 0; i < 8; i++) { int i1, j1, i2, j2; if ((i & 1) == 0) { if ((i & 2) == 0) { i1 = -1; j1 = 0; } else { i1 = 1; j1 = 0; } if ((i & 4) == 0) { i2 = 0; j2 = -1; } else { i2 = 0; j2 = 1; } } else { if ((i & 2) != 0) { i1 = 2; j1 = 1; } else { i1 = 0; j1 = 1; } if ((i & 4) != 0) { i2 = 1; j2 = 2; } else { i2 = 1; j2 = 0; } } LOOKUP_2D[i * 4 + 0] = { 0, 0 }; LOOKUP_2D[i * 4 + 1] = { 1, 1 }; LOOKUP_2D[i * 4 + 2] = { i1, j1 }; LOOKUP_2D[i * 4 + 3] = { i2, j2 }; } for (int i = 0; i < 8; i++) { int i1, j1, k1, i2, j2, k2; i1 = (i >> 0) & 1; j1 = (i >> 1) & 1; k1 = (i >> 2) & 1; i2 = i1 ^ 1; j2 = j1 ^ 1; k2 = k1 ^ 1; // The two points within this octant, one from each of the two cubic half-lattices. auto* c0 = new LatticePoint3D(i1, j1, k1, 0); auto* c1 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + k2, 1); // (1, 0, 0) vs (0, 1, 1) away from octant. auto* c2 = new LatticePoint3D(i1 ^ 1, j1, k1, 0); auto* c3 = new LatticePoint3D(i1, j1 ^ 1, k1 ^ 1, 0); // (1, 0, 0) vs (0, 1, 1) away from octant, on second half-lattice. auto* c4 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + k2, 1); auto* c5 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + (k2 ^ 1), 1); // (0, 1, 0) vs (1, 0, 1) away from octant. auto* c6 = new LatticePoint3D(i1, j1 ^ 1, k1, 0); auto* c7 = new LatticePoint3D(i1 ^ 1, j1, k1 ^ 1, 0); // (0, 1, 0) vs (1, 0, 1) away from octant, on second half-lattice. auto* c8 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + k2, 1); auto* c9 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + (k2 ^ 1), 1); // (0, 0, 1) vs (1, 1, 0) away from octant. auto* cA = new LatticePoint3D(i1, j1, k1 ^ 1, 0); auto* cB = new LatticePoint3D(i1 ^ 1, j1 ^ 1, k1, 0); // (0, 0, 1) vs (1, 1, 0) away from octant, on second half-lattice. auto* cC = new LatticePoint3D(i1 + i2, j1 + j2, k1 + (k2 ^ 1), 1); auto* cD = new LatticePoint3D(i1 + (i2 ^ 1), j1 + (j2 ^ 1), k1 + k2, 1); // First two points are guaranteed. c0->nextOnFailure = c0->nextOnSuccess = c1; c1->nextOnFailure = c1->nextOnSuccess = c2; // If c2 is in range, then we know c3 and c4 are not. c2->nextOnFailure = c3; c2->nextOnSuccess = c5; c3->nextOnFailure = c4; c3->nextOnSuccess = c4; // If c4 is in range, then we know c5 is not. c4->nextOnFailure = c5; c4->nextOnSuccess = c6; c5->nextOnFailure = c5->nextOnSuccess = c6; // If c6 is in range, then we know c7 and c8 are not. c6->nextOnFailure = c7; c6->nextOnSuccess = c9; c7->nextOnFailure = c8; c7->nextOnSuccess = c8; // If c8 is in range, then we know c9 is not. c8->nextOnFailure = c9; c8->nextOnSuccess = cA; c9->nextOnFailure = c9->nextOnSuccess = cA; // If cA is in range, then we know cB and cC are not. cA->nextOnFailure = cB; cA->nextOnSuccess = cD; cB->nextOnFailure = cC; cB->nextOnSuccess = cC; // If cC is in range, then we know cD is not. cC->nextOnFailure = cD; cC->nextOnSuccess = nullptr; cD->nextOnFailure = cD->nextOnSuccess = nullptr; LOOKUP_3D[i] = *c0; } unsigned char lookup4DPregenSize[256] { // clang-format off 20, 15, 16, 17, 15, 16, 12, 15, 16, 12, 10, 14, 17, 15, 14, 17, 15, 16, 12, 15, 16, 14, 14, 13, 12, 14, 11, 12, 15, 13, 12, 14, 16, 12, 10, 14, 12, 14, 11, 12, 10, 11, 10, 13, 14, 12, 13, 15, 17, 15, 14, 17, 15, 13, 12, 14, 14, 12, 13, 15, 17, 14, 15, 17, 15, 16, 12, 15, 16, 14, 14, 13, 12, 14, 11, 12, 15, 13, 12, 14, 16, 14, 14, 13, 14, 16, 16, 10, 14, 16, 19, 11, 13, 10, 11, 10, 12, 14, 11, 12, 14, 16, 19, 11, 11, 19, 13, 14, 12, 11, 14, 13, 15, 13, 12, 14, 13, 10, 11, 10, 12, 11, 14, 13, 14, 10, 13, 13, 16, 12, 10, 14, 12, 14, 11, 12, 10, 11, 10, 13, 14, 12, 13, 15, 12, 14, 11, 12, 14, 16, 19, 11, 11, 19, 13, 14, 12, 11, 14, 13, 10, 11, 10, 13, 11, 19, 13, 14, 10, 13, 16, 14, 13, 14, 14, 16, 14, 12, 13, 15, 12, 11, 14, 13, 13, 14, 14, 16, 15, 13, 16, 15, 17, 15, 14, 17, 15, 13, 12, 14, 14, 12, 13, 15, 17, 14, 15, 17, 15, 13, 12, 14, 13, 10, 11, 10, 12, 11, 14, 13, 14, 10, 13, 13, 14, 12, 13, 15, 12, 11, 14, 13, 13, 14, 14, 16, 15, 13, 16, 15, 17, 14, 15, 17, 14, 10, 13, 13, 15, 13, 16, 15, 17, 13, 15, 20, // clang-format on }; unsigned char lookup4DPregen[256][20] { // clang-format off { 0x15, 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x01, 0x05, 0x11, 0x15, 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x01, 0x15, 0x16, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00 }, { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x04, 0x05, 0x14, 0x15, 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x6A, 0x9A, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x04, 0x15, 0x19, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00 }, { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x5E, 0x6A, 0x9A, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x05, 0x15, 0x1A, 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x5E, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF, 0x00, 0x00, 0x00 }, { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x11, 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x11, 0x15, 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x14, 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x6B, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x14, 0x15, 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x6B, 0x9A, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x9A, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x1A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x10, 0x11, 0x14, 0x15, 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x67, 0x6A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x6B, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x6D, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x6E, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x10, 0x15, 0x25, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00 }, { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0x76, 0xA6, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x11, 0x15, 0x26, 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x67, 0x6A, 0x76, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB, 0x00, 0x00, 0x00 }, { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x25, 0x55, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x25, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA6, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x26, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0x79, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x25, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x25, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x14, 0x15, 0x29, 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0x6D, 0x79, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE, 0x00, 0x00, 0x00 }, { 0x15, 0x29, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x7A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF, 0x00, 0x00, 0x00 }, { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x44, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x9A, 0x9B, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x99, 0x9A, 0x9E, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x50, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x59, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x56, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xA7, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0x00 }, { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAD, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x6A, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x95, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x52, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA, 0x00 }, { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x58, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xAF, 0x00, 0x00, 0x00, 0x00 }, { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x61, 0x65, 0x66, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x64, 0x65, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xBB, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x40, 0x45, 0x51, 0x54, 0x55, 0x85, 0x91, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00 }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xD6, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x86, 0x92, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB, 0xD6, 0xEA, 0xEB, 0x00, 0x00, 0x00 }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xDA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xDA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x86, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xD9, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x59, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xDA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xDA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x89, 0x95, 0x98, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE, 0xD9, 0xEA, 0xEE, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x59, 0x89, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xDA, 0xEA, 0xEF, 0x00, 0x00, 0x00 }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x91, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x92, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x94, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x95, 0x98, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xEA, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xE5, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x65, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x65, 0x94, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x94, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA, 0xEB, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA1, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA, 0xE5, 0xEA, 0xFA, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x65, 0x95, 0xA1, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xE6, 0xEA, 0xFB, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x65, 0x95, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xEA, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xE9, 0xEA, 0xFE, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA, 0xEA }, // clang-format on }; LatticePoint4D latticePoints[256]; for (int i = 0; i < 256; i++) { int cx = ((i >> 0) & 3) - 1; int cy = ((i >> 2) & 3) - 1; int cz = ((i >> 4) & 3) - 1; int cw = ((i >> 6) & 3) - 1; latticePoints[i] = { cx, cy, cz, cw }; } for (unsigned int i = 0; i < 256; i++) { LOOKUP_4D_SIZE[i] = lookup4DPregenSize[i]; for (unsigned char j = 0; j < lookup4DPregenSize[i]; j++) { LOOKUP_4D[i][j] = latticePoints[lookup4DPregen[i][j]]; } } } void OpenSimplex2S::initGradients() { static const int grad2_size = 24; Grad2 grad2[grad2_size] { { 0.130526192220052, 0.99144486137381 }, { 0.38268343236509, 0.923879532511287 }, { 0.608761429008721, 0.793353340291235 }, { 0.793353340291235, 0.608761429008721 }, { 0.923879532511287, 0.38268343236509 }, { 0.99144486137381, 0.130526192220051 }, { 0.99144486137381, -0.130526192220051 }, { 0.923879532511287, -0.38268343236509 }, { 0.793353340291235, -0.60876142900872 }, { 0.608761429008721, -0.793353340291235 }, { 0.38268343236509, -0.923879532511287 }, { 0.130526192220052, -0.99144486137381 }, { -0.130526192220052, -0.99144486137381 }, { -0.38268343236509, -0.923879532511287 }, { -0.608761429008721, -0.793353340291235 }, { -0.793353340291235, -0.608761429008721 }, { -0.923879532511287, -0.38268343236509 }, { -0.99144486137381, -0.130526192220052 }, { -0.99144486137381, 0.130526192220051 }, { -0.923879532511287, 0.38268343236509 }, { -0.793353340291235, 0.608761429008721 }, { -0.608761429008721, 0.793353340291235 }, { -0.38268343236509, 0.923879532511287 }, { -0.130526192220052, 0.99144486137381 }, }; for (int i = 0; i < grad2_size; i++) { grad2[i].dx /= N2; grad2[i].dy /= N2; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_2D[i] = grad2[i % grad2_size]; } static const int grad3_size = 48; Grad3 grad3[grad3_size] { { -2.22474487139, -2.22474487139, -1.0 }, { -2.22474487139, -2.22474487139, 1.0 }, { -3.0862664687972017, -1.1721513422464978, 0.0 }, { -1.1721513422464978, -3.0862664687972017, 0.0 }, { -2.22474487139, -1.0, -2.22474487139 }, { -2.22474487139, 1.0, -2.22474487139 }, { -1.1721513422464978, 0.0, -3.0862664687972017 }, { -3.0862664687972017, 0.0, -1.1721513422464978 }, { -2.22474487139, -1.0, 2.22474487139 }, { -2.22474487139, 1.0, 2.22474487139 }, { -3.0862664687972017, 0.0, 1.1721513422464978 }, { -1.1721513422464978, 0.0, 3.0862664687972017 }, { -2.22474487139, 2.22474487139, -1.0 }, { -2.22474487139, 2.22474487139, 1.0 }, { -1.1721513422464978, 3.0862664687972017, 0.0 }, { -3.0862664687972017, 1.1721513422464978, 0.0 }, { -1.0, -2.22474487139, -2.22474487139 }, { 1.0, -2.22474487139, -2.22474487139 }, { 0.0, -3.0862664687972017, -1.1721513422464978 }, { 0.0, -1.1721513422464978, -3.0862664687972017 }, { -1.0, -2.22474487139, 2.22474487139 }, { 1.0, -2.22474487139, 2.22474487139 }, { 0.0, -1.1721513422464978, 3.0862664687972017 }, { 0.0, -3.0862664687972017, 1.1721513422464978 }, { -1.0, 2.22474487139, -2.22474487139 }, { 1.0, 2.22474487139, -2.22474487139 }, { 0.0, 1.1721513422464978, -3.0862664687972017 }, { 0.0, 3.0862664687972017, -1.1721513422464978 }, { -1.0, 2.22474487139, 2.22474487139 }, { 1.0, 2.22474487139, 2.22474487139 }, { 0.0, 3.0862664687972017, 1.1721513422464978 }, { 0.0, 1.1721513422464978, 3.0862664687972017 }, { 2.22474487139, -2.22474487139, -1.0 }, { 2.22474487139, -2.22474487139, 1.0 }, { 1.1721513422464978, -3.0862664687972017, 0.0 }, { 3.0862664687972017, -1.1721513422464978, 0.0 }, { 2.22474487139, -1.0, -2.22474487139 }, { 2.22474487139, 1.0, -2.22474487139 }, { 3.0862664687972017, 0.0, -1.1721513422464978 }, { 1.1721513422464978, 0.0, -3.0862664687972017 }, { 2.22474487139, -1.0, 2.22474487139 }, { 2.22474487139, 1.0, 2.22474487139 }, { 1.1721513422464978, 0.0, 3.0862664687972017 }, { 3.0862664687972017, 0.0, 1.1721513422464978 }, { 2.22474487139, 2.22474487139, -1.0 }, { 2.22474487139, 2.22474487139, 1.0 }, { 3.0862664687972017, 1.1721513422464978, 0.0 }, { 1.1721513422464978, 3.0862664687972017, 0.0 }, }; for (int i = 0; i < grad3_size; i++) { grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_3D[i] = grad3[i % grad3_size]; } static const int grad4_size = 160; Grad4 grad4[grad4_size] { { -0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624 }, { -0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098 }, { -0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301 }, { -0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301 }, { -0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174 }, { -0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174 }, { -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796 }, { -0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842 }, { -0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624 }, { -0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098 }, { -0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301 }, { 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301 }, { -0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174 }, { 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174 }, { 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796 }, { -0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842 }, { -0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624 }, { -0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098 }, { -0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301 }, { 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301 }, { -0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174 }, { 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174 }, { 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796 }, { -0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842 }, { -0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078 }, { -0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708 }, { -0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708 }, { 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708 }, { -0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365 }, { 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365 }, { 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365 }, { -0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062 }, { -0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381 }, { -0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724 }, { -0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724 }, { -0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712 }, { -0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585 }, { -0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602 }, { -0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602 }, { -0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944 }, { -0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381 }, { -0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724 }, { 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724 }, { 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712 }, { -0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585 }, { -0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602 }, { 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602 }, { 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944 }, { -0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381 }, { -0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724 }, { 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724 }, { 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712 }, { -0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585 }, { -0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602 }, { 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602 }, { 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944 }, { -0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537 }, { -0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164 }, { -0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195 }, { -0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945 }, { -0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945 }, { -0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195 }, { -0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164 }, { -0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537 }, { -0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537 }, { -0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164 }, { 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195 }, { 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945 }, { -0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945 }, { -0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195 }, { 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164 }, { 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537 }, { -0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944 }, { -0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602 }, { 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602 }, { 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585 }, { -0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712 }, { -0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724 }, { 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724 }, { 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381 }, { -0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537 }, { -0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164 }, { -0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195 }, { -0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945 }, { -0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945 }, { -0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195 }, { -0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164 }, { -0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537 }, { -0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537 }, { -0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164 }, { 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195 }, { 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945 }, { -0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945 }, { -0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195 }, { 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164 }, { 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537 }, { -0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944 }, { -0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602 }, { 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602 }, { 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585 }, { -0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712 }, { -0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724 }, { 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724 }, { 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381 }, { 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537 }, { 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164 }, { 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195 }, { 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945 }, { 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945 }, { 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195 }, { 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164 }, { 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537 }, { 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537 }, { 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164 }, { 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195 }, { 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945 }, { 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945 }, { 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195 }, { 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164 }, { 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537 }, { 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944 }, { 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602 }, { 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602 }, { 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585 }, { 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712 }, { 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724 }, { 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724 }, { 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381 }, { 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062 }, { -0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365 }, { -0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365 }, { -0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708 }, { 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365 }, { 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708 }, { 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708 }, { 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078 }, { 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842 }, { -0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796 }, { -0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174 }, { -0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301 }, { 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174 }, { 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301 }, { 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098 }, { 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624 }, { 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842 }, { -0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796 }, { -0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174 }, { -0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301 }, { 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174 }, { 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301 }, { 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098 }, { 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624 }, { 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842 }, { 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796 }, { 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174 }, { 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301 }, { 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174 }, { 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301 }, { 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098 }, { 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624 }, }; for (int i = 0; i < grad4_size; i++) { grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_4D[i] = grad4[i % grad4_size]; } } ================================================ FILE: _old/cpp/OpenSimplex2S.hpp ================================================ /** * Ported from https://github.com/KdotJPG/OpenSimplex2/blob/master/java/OpenSimplex2S.java * Probably not best implementation of static initialization. * Also changed some code to use fixed c-style arrays, to avoid using of std library. */ /** * K.jpg's OpenSimplex 2, smooth variant ("SuperSimplex") * * - 2D is standard simplex, modified to support larger kernels. * Implemented using a lookup table. * - 3D is "Re-oriented 8-point BCC noise" which constructs a * congruent BCC lattice in a much different way than usual. * - 4D uses a naïve pregenerated lookup table, and averages out * to the expected performance. * * Multiple versions of each function are provided. See the * documentation above each, for more info. */ class OpenSimplex2S { struct Grad2 { double dx {}; double dy {}; }; struct Grad3 { double dx {}; double dy {}; double dz {}; }; struct Grad4 { double dx {}; double dy {}; double dz {}; double dw {}; }; struct LatticePoint2D { int xsv {}; int ysv {}; double dx {}; double dy {}; LatticePoint2D(); LatticePoint2D(int xsv, int ysv); }; struct LatticePoint3D { double dxr {}; double dyr {}; double dzr {}; int xrv {}; int yrv {}; int zrv {}; LatticePoint3D* nextOnFailure {}; LatticePoint3D* nextOnSuccess {}; LatticePoint3D(); LatticePoint3D(int xrv, int yrv, int zrv, int lattice); }; struct LatticePoint4D { int xsv {}; int ysv {}; int zsv {}; int wsv {}; double dx {}; double dy {}; double dz {}; double dw {}; LatticePoint4D(); LatticePoint4D(int xsv, int ysv, int zsv, int wsv); }; static const int PSIZE = 2048; static const int PMASK = 2047; constexpr static const double N2 = 0.05481866495625118; constexpr static const double N3 = 0.2781926117527186; constexpr static const double N4 = 0.11127401889945551; static Grad2 GRADIENTS_2D[PSIZE]; static Grad3 GRADIENTS_3D[PSIZE]; static Grad4 GRADIENTS_4D[PSIZE]; static LatticePoint2D LOOKUP_2D[8 * 4]; static LatticePoint3D LOOKUP_3D[8]; static LatticePoint4D LOOKUP_4D[256][20]; static unsigned char LOOKUP_4D_SIZE[256]; short perm[PSIZE]; Grad2 permGrad2[PSIZE]; Grad3 permGrad3[PSIZE]; Grad4 permGrad4[PSIZE]; /** * 2D SuperSimplex noise base. * Lookup table implementation inspired by DigitalShadow. */ double noise2_Base(double xs, double ys); /** * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. * Lookup table implementation inspired by DigitalShadow. * It was actually faster to narrow down the points in the loop itself, * than to build up the index with enough info to isolate 8 points. */ double noise3_BCC(double xr, double yr, double zr); /** * 4D SuperSimplex noise base. * Using ultra-simple 4x4x4x4 lookup partitioning. * This isn't as elegant or SIMD/GPU/etc. portable as other approaches, * but it does compete performance-wise with optimized OpenSimplex1. */ double noise4_Base(double xs, double ys, double zs, double ws); static int fastFloor(double x); static void initLatticePoints(); static void initGradients(); struct Initializer { Initializer(); }; static Initializer initializer; public: explicit OpenSimplex2S(long seed = 0); /** * 2D SuperSimplex noise, standard lattice orientation. */ double noise2(double x, double y); /** * 2D SuperSimplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps. */ double noise2_XBeforeY(double x, double y); /** * 3D Re-oriented 8-point BCC noise, classic orientation * Proper substitute for what 3D SuperSimplex would be, * in light of Forbidden Formulae. * Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. */ double noise3_Classic(double x, double y, double z); /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). * For a time varied animation, call noise3_XYBeforeZ(x, y, T). */ double noise3_XYBeforeZ(double x, double y, double z); /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). * If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. * For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ. */ double noise3_XZBeforeY(double x, double y, double z); /** * 4D SuperSimplex noise, classic lattice orientation. */ double noise4_Classic(double x, double y, double z, double w); /** * 4D SuperSimplex noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ double noise4_XYBeforeZW(double x, double y, double z, double w); /** * 4D SuperSimplex noise, with XZ and YW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Z (or Y and W) are horizontal. */ double noise4_XZBeforeYW(double x, double y, double z, double w); /** * 4D SuperSimplex noise, with XYZ oriented like noise3_Classic, * and W for an extra degree of freedom. * Recommended for time-varied animations which texture a 3D object (W=time) */ double noise4_XYZBeforeW(double x, double y, double z, double w); }; ================================================ FILE: _old/cpp/UNLICENSE ================================================ This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. 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 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. For more information, please refer to ================================================ FILE: _old/csharp/OpenSimplex2F.cs ================================================ /** * K.jpg's OpenSimplex 2, faster variant * * - 2D is standard simplex implemented using a lookup table. * - 3D is "Re-oriented 4-point BCC noise" which constructs a * congruent BCC lattice in a much different way than usual. * - 4D constructs the lattice as a union of five copies of its * reciprocal. It successively finds the closest point on each. * * Multiple versions of each function are provided. See the * documentation above each, for more info. */ using System; using System.Runtime.CompilerServices; namespace Noise { public class OpenSimplex2F { private const int PSIZE = 2048; private const int PMASK = 2047; private short[] perm; private Grad2[] permGrad2; private Grad3[] permGrad3; private Grad4[] permGrad4; public OpenSimplex2F(long seed) { perm = new short[PSIZE]; permGrad2 = new Grad2[PSIZE]; permGrad3 = new Grad3[PSIZE]; permGrad4 = new Grad4[PSIZE]; short[] source = new short[PSIZE]; for (short i = 0; i < PSIZE; i++) source[i] = i; for (int i = PSIZE - 1; i >= 0; i--) { seed = seed * 6364136223846793005L + 1442695040888963407L; int r = (int)((seed + 31) % (i + 1)); if (r < 0) r += (i + 1); perm[i] = source[r]; permGrad2[i] = GRADIENTS_2D[perm[i]]; permGrad3[i] = GRADIENTS_3D[perm[i]]; permGrad4[i] = GRADIENTS_4D[perm[i]]; source[r] = source[i]; } } /* * Noise Evaluators */ /** * 2D Simplex noise, standard lattice orientation. */ public double Noise2(double x, double y) { // Get points for A2* lattice double s = 0.366025403784439 * (x + y); double xs = x + s, ys = y + s; return noise2_Base(xs, ys); } /** * 2D Simplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps. */ public double Noise2_XBeforeY(double x, double y) { // Skew transform and rotation baked into one. double xx = x * 0.7071067811865476; double yy = y * 1.224744871380249; return noise2_Base(yy + xx, yy - xx); } /** * 2D Simplex noise base. * Lookup table implementation inspired by DigitalShadow. */ private double noise2_Base(double xs, double ys) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys); double xsi = xs - xsb, ysi = ys - ysb; // Index to point list int index = (int)((ysi - xsi) / 2 + 1); double ssi = (xsi + ysi) * -0.211324865405187; double xi = xsi + ssi, yi = ysi + ssi; // Point contributions for (int i = 0; i < 3; i++) { LatticePoint2D c = LOOKUP_2D[index + i]; double dx = xi + c.dx, dy = yi + c.dy; double attn = 0.5 - dx * dx - dy * dy; if (attn <= 0) continue; int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK; Grad2 grad = permGrad2[perm[pxm] ^ pym]; double extrapolation = grad.dx * dx + grad.dy * dy; attn *= attn; value += attn * attn * extrapolation; } return value; } /** * 3D Re-oriented 4-point BCC noise, classic orientation. * Proper substitute for 3D Simplex in light of Forbidden Formulae. * Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. */ public double Noise3_Classic(double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce the expected look on cardinal planar slices. // If texturing objects that don't tend to have cardinal plane faces, you could even remove this. // Orthonormal rotation. Not a skew transform. double r = (2.0 / 3.0) * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 4-point BCC noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). * For a time varied animation, call noise3_XYBeforeZ(x, y, T). */ public double Noise3_XYBeforeZ(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Y triangular like 2D. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * -0.211324865405187; double zz = z * 0.577350269189626; double xr = x + s2 - zz, yr = y + s2 - zz; double zr = xy * 0.577350269189626 + zz; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 4-point BCC noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). * If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. * For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ. */ public double Noise3_XZBeforeY(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Z triangular like 2D. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * -0.211324865405187; double yy = y * 0.577350269189626; double xr = x + s2 - yy; double zr = z + s2 - yy; double yr = xz * 0.577350269189626 + yy; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. * Lookup table implementation inspired by DigitalShadow. * It was actually faster to narrow down the points in the loop itself, * than to build up the index with enough info to isolate 4 points. */ private double noise3_BCC(double xr, double yr, double zr) { // Get base and offsets inside cube of first lattice. int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr); double xri = xr - xrb, yri = yr - yrb, zri = zr - zrb; // Identify which octant of the cube we're in. This determines which cell // in the other cubic lattice we're in, and also narrows down one point on each. int xht = (int)(xri + 0.5), yht = (int)(yri + 0.5), zht = (int)(zri + 0.5); int index = (xht << 0) | (yht << 1) | (zht << 2); // Point contributions double value = 0; LatticePoint3D c = LOOKUP_3D[index]; while (c != null) { double dxr = xri + c.dxr, dyr = yri + c.dyr, dzr = zri + c.dzr; double attn = 0.5 - dxr * dxr - dyr * dyr - dzr * dzr; if (attn < 0) { c = c.NextOnFailure; } else { int pxm = (xrb + c.xrv) & PMASK, pym = (yrb + c.yrv) & PMASK, pzm = (zrb + c.zrv) & PMASK; Grad3 grad = permGrad3[perm[perm[pxm] ^ pym] ^ pzm]; double extrapolation = grad.dx * dxr + grad.dy * dyr + grad.dz * dzr; attn *= attn; value += attn * attn * extrapolation; c = c.NextOnSuccess; } } return value; } /** * 4D OpenSimplex2F noise, classic lattice orientation. */ public double Noise4_Classic(double x, double y, double z, double w) { // Get points for A4 lattice double s = -0.138196601125011 * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return noise4_Base(xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ public double Noise4_XYBeforeZW(double x, double y, double z, double w) { double s2 = (x + y) * -0.178275657951399372 + (z + w) * 0.215623393288842828; double t2 = (z + w) * -0.403949762580207112 + (x + y) * -0.375199083010075342; double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise, with XZ and YW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Z (or Y and W) are horizontal. */ public double Noise4_XZBeforeYW(double x, double y, double z, double w) { double s2 = (x + z) * -0.178275657951399372 + (y + w) * 0.215623393288842828; double t2 = (y + w) * -0.403949762580207112 + (x + z) * -0.375199083010075342; double xs = x + s2, ys = y + t2, zs = z + s2, ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise, with XYZ oriented like noise3_Classic, * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) */ public double Noise4_XYZBeforeW(double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 0.2236067977499788; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return noise4_Base(xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise base. * Current implementation not fully optimized by lookup tables. * But still comes out slightly ahead of Gustavson's Simplex in tests. */ private double noise4_Base(double xs, double ys, double zs, double ws) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys), zsb = fastFloor(zs), wsb = fastFloor(ws); double xsi = xs - xsb, ysi = ys - ysb, zsi = zs - zsb, wsi = ws - wsb; // If we're in the lower half, flip so we can repeat the code for the upper half. We'll flip back later. double siSum = xsi + ysi + zsi + wsi; double ssi = siSum * 0.309016994374947; // Prep for vertex contributions. bool inLowerHalf = (siSum < 2); if (inLowerHalf) { xsi = 1 - xsi; ysi = 1 - ysi; zsi = 1 - zsi; wsi = 1 - wsi; siSum = 4 - siSum; } // Consider opposing vertex pairs of the octahedron formed by the central cross-section of the stretched tesseract double aabb = xsi + ysi - zsi - wsi, abab = xsi - ysi + zsi - wsi, abba = xsi - ysi - zsi + wsi; double aabbScore = Math.Abs(aabb), ababScore = Math.Abs(abab), abbaScore = Math.Abs(abba); // Find the closest point on the stretched tesseract as if it were the upper half int vertexIndex, via, vib; double asi, bsi; if (aabbScore > ababScore && aabbScore > abbaScore) { if (aabb > 0) { asi = zsi; bsi = wsi; vertexIndex = 0b0011; via = 0b0111; vib = 0b1011; } else { asi = xsi; bsi = ysi; vertexIndex = 0b1100; via = 0b1101; vib = 0b1110; } } else if (ababScore > abbaScore) { if (abab > 0) { asi = ysi; bsi = wsi; vertexIndex = 0b0101; via = 0b0111; vib = 0b1101; } else { asi = xsi; bsi = zsi; vertexIndex = 0b1010; via = 0b1011; vib = 0b1110; } } else { if (abba > 0) { asi = ysi; bsi = zsi; vertexIndex = 0b1001; via = 0b1011; vib = 0b1101; } else { asi = xsi; bsi = wsi; vertexIndex = 0b0110; via = 0b0111; vib = 0b1110; } } if (bsi > asi) { via = vib; double temp = bsi; bsi = asi; asi = temp; } if (siSum + asi > 3) { vertexIndex = via; if (siSum + bsi > 4) { vertexIndex = 0b1111; } } // Now flip back if we're actually in the lower half. if (inLowerHalf) { xsi = 1 - xsi; ysi = 1 - ysi; zsi = 1 - zsi; wsi = 1 - wsi; vertexIndex ^= 0b1111; } // Five points to add, total, from five copies of the A4 lattice. for (int i = 0; i < 5; i++) { // Update xsb/etc. and add the lattice point's contribution. LatticePoint4D c = VERTICES_4D[vertexIndex]; xsb += c.xsv; ysb += c.ysv; zsb += c.zsv; wsb += c.wsv; double xi = xsi + ssi, yi = ysi + ssi, zi = zsi + ssi, wi = wsi + ssi; double dx = xi + c.dx, dy = yi + c.dy, dz = zi + c.dz, dw = wi + c.dw; double attn = 0.5 - dx * dx - dy * dy - dz * dz - dw * dw; if (attn > 0) { int pxm = xsb & PMASK, pym = ysb & PMASK, pzm = zsb & PMASK, pwm = wsb & PMASK; Grad4 grad = permGrad4[perm[perm[perm[pxm] ^ pym] ^ pzm] ^ pwm]; double ramped = grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw; attn *= attn; value += attn * attn * ramped; } // Maybe this helps the compiler/JVM/LLVM/etc. know we can end the loop here. Maybe not. if (i == 4) break; // Update the relative skewed coordinates to reference the vertex we just added. // Rather, reference its counterpart on the lattice copy that is shifted down by // the vector <-0.2, -0.2, -0.2, -0.2> xsi += c.xsi; ysi += c.ysi; zsi += c.zsi; wsi += c.wsi; ssi += c.ssiDelta; // Next point is the closest vertex on the 4-simplex whose base vertex is the aforementioned vertex. double score0 = 1.0 + ssi * (-1.0 / 0.309016994374947); // Seems slightly faster than 1.0-xsi-ysi-zsi-wsi vertexIndex = 0b0000; if (xsi >= ysi && xsi >= zsi && xsi >= wsi && xsi >= score0) { vertexIndex = 0b0001; } else if (ysi > xsi && ysi >= zsi && ysi >= wsi && ysi >= score0) { vertexIndex = 0b0010; } else if (zsi > xsi && zsi > ysi && zsi >= wsi && zsi >= score0) { vertexIndex = 0b0100; } else if (wsi > xsi && wsi > ysi && wsi > zsi && wsi >= score0) { vertexIndex = 0b1000; } } return value; } /* * Utility */ [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int fastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } /* * Lookup Tables & Gradients */ private static LatticePoint2D[] LOOKUP_2D; private static LatticePoint3D[] LOOKUP_3D; private static LatticePoint4D[] VERTICES_4D; private const double N2 = 0.01001634121365712; private const double N3 = 0.030485933181293584; private const double N4 = 0.009202377986303158; private static Grad2[] GRADIENTS_2D; private static Grad3[] GRADIENTS_3D; private static Grad4[] GRADIENTS_4D; static OpenSimplex2F() { LOOKUP_2D = new LatticePoint2D[4]; LOOKUP_3D = new LatticePoint3D[8]; VERTICES_4D = new LatticePoint4D[16]; LOOKUP_2D[0] = new LatticePoint2D(1, 0); LOOKUP_2D[1] = new LatticePoint2D(0, 0); LOOKUP_2D[2] = new LatticePoint2D(1, 1); LOOKUP_2D[3] = new LatticePoint2D(0, 1); for (int i = 0; i < 8; i++) { int i1, j1, k1, i2, j2, k2; i1 = (i >> 0) & 1; j1 = (i >> 1) & 1; k1 = (i >> 2) & 1; i2 = i1 ^ 1; j2 = j1 ^ 1; k2 = k1 ^ 1; // The two points within this octant, one from each of the two cubic half-lattices. LatticePoint3D c0 = new LatticePoint3D(i1, j1, k1, 0); LatticePoint3D c1 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + k2, 1); // Each single step away on the first half-lattice. LatticePoint3D c2 = new LatticePoint3D(i1 ^ 1, j1, k1, 0); LatticePoint3D c3 = new LatticePoint3D(i1, j1 ^ 1, k1, 0); LatticePoint3D c4 = new LatticePoint3D(i1, j1, k1 ^ 1, 0); // Each single step away on the second half-lattice. LatticePoint3D c5 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + k2, 1); LatticePoint3D c6 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + k2, 1); LatticePoint3D c7 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + (k2 ^ 1), 1); // First two are guaranteed. c0.NextOnFailure = c0.NextOnSuccess = c1; c1.NextOnFailure = c1.NextOnSuccess = c2; // Once we find one on the first half-lattice, the rest are out. // In addition, knowing c2 rules out c5. c2.NextOnFailure = c3; c2.NextOnSuccess = c6; c3.NextOnFailure = c4; c3.NextOnSuccess = c5; c4.NextOnFailure = c4.NextOnSuccess = c5; // Once we find one on the second half-lattice, the rest are out. c5.NextOnFailure = c6; c5.NextOnSuccess = null; c6.NextOnFailure = c7; c6.NextOnSuccess = null; c7.NextOnFailure = c7.NextOnSuccess = null; LOOKUP_3D[i] = c0; } for (int i = 0; i < 16; i++) { VERTICES_4D[i] = new LatticePoint4D((i >> 0) & 1, (i >> 1) & 1, (i >> 2) & 1, (i >> 3) & 1); } GRADIENTS_2D = new Grad2[PSIZE]; Grad2[] grad2 = { new Grad2( 0.130526192220052, 0.99144486137381), new Grad2( 0.38268343236509, 0.923879532511287), new Grad2( 0.608761429008721, 0.793353340291235), new Grad2( 0.793353340291235, 0.608761429008721), new Grad2( 0.923879532511287, 0.38268343236509), new Grad2( 0.99144486137381, 0.130526192220051), new Grad2( 0.99144486137381, -0.130526192220051), new Grad2( 0.923879532511287, -0.38268343236509), new Grad2( 0.793353340291235, -0.60876142900872), new Grad2( 0.608761429008721, -0.793353340291235), new Grad2( 0.38268343236509, -0.923879532511287), new Grad2( 0.130526192220052, -0.99144486137381), new Grad2(-0.130526192220052, -0.99144486137381), new Grad2(-0.38268343236509, -0.923879532511287), new Grad2(-0.608761429008721, -0.793353340291235), new Grad2(-0.793353340291235, -0.608761429008721), new Grad2(-0.923879532511287, -0.38268343236509), new Grad2(-0.99144486137381, -0.130526192220052), new Grad2(-0.99144486137381, 0.130526192220051), new Grad2(-0.923879532511287, 0.38268343236509), new Grad2(-0.793353340291235, 0.608761429008721), new Grad2(-0.608761429008721, 0.793353340291235), new Grad2(-0.38268343236509, 0.923879532511287), new Grad2(-0.130526192220052, 0.99144486137381) }; for (int i = 0; i < grad2.Length; i++) { grad2[i].dx /= N2; grad2[i].dy /= N2; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_2D[i] = grad2[i % grad2.Length]; } GRADIENTS_3D = new Grad3[PSIZE]; Grad3[] grad3 = { new Grad3(-2.22474487139, -2.22474487139, -1.0), new Grad3(-2.22474487139, -2.22474487139, 1.0), new Grad3(-3.0862664687972017, -1.1721513422464978, 0.0), new Grad3(-1.1721513422464978, -3.0862664687972017, 0.0), new Grad3(-2.22474487139, -1.0, -2.22474487139), new Grad3(-2.22474487139, 1.0, -2.22474487139), new Grad3(-1.1721513422464978, 0.0, -3.0862664687972017), new Grad3(-3.0862664687972017, 0.0, -1.1721513422464978), new Grad3(-2.22474487139, -1.0, 2.22474487139), new Grad3(-2.22474487139, 1.0, 2.22474487139), new Grad3(-3.0862664687972017, 0.0, 1.1721513422464978), new Grad3(-1.1721513422464978, 0.0, 3.0862664687972017), new Grad3(-2.22474487139, 2.22474487139, -1.0), new Grad3(-2.22474487139, 2.22474487139, 1.0), new Grad3(-1.1721513422464978, 3.0862664687972017, 0.0), new Grad3(-3.0862664687972017, 1.1721513422464978, 0.0), new Grad3(-1.0, -2.22474487139, -2.22474487139), new Grad3( 1.0, -2.22474487139, -2.22474487139), new Grad3( 0.0, -3.0862664687972017, -1.1721513422464978), new Grad3( 0.0, -1.1721513422464978, -3.0862664687972017), new Grad3(-1.0, -2.22474487139, 2.22474487139), new Grad3( 1.0, -2.22474487139, 2.22474487139), new Grad3( 0.0, -1.1721513422464978, 3.0862664687972017), new Grad3( 0.0, -3.0862664687972017, 1.1721513422464978), new Grad3(-1.0, 2.22474487139, -2.22474487139), new Grad3( 1.0, 2.22474487139, -2.22474487139), new Grad3( 0.0, 1.1721513422464978, -3.0862664687972017), new Grad3( 0.0, 3.0862664687972017, -1.1721513422464978), new Grad3(-1.0, 2.22474487139, 2.22474487139), new Grad3( 1.0, 2.22474487139, 2.22474487139), new Grad3( 0.0, 3.0862664687972017, 1.1721513422464978), new Grad3( 0.0, 1.1721513422464978, 3.0862664687972017), new Grad3( 2.22474487139, -2.22474487139, -1.0), new Grad3( 2.22474487139, -2.22474487139, 1.0), new Grad3( 1.1721513422464978, -3.0862664687972017, 0.0), new Grad3( 3.0862664687972017, -1.1721513422464978, 0.0), new Grad3( 2.22474487139, -1.0, -2.22474487139), new Grad3( 2.22474487139, 1.0, -2.22474487139), new Grad3( 3.0862664687972017, 0.0, -1.1721513422464978), new Grad3( 1.1721513422464978, 0.0, -3.0862664687972017), new Grad3( 2.22474487139, -1.0, 2.22474487139), new Grad3( 2.22474487139, 1.0, 2.22474487139), new Grad3( 1.1721513422464978, 0.0, 3.0862664687972017), new Grad3( 3.0862664687972017, 0.0, 1.1721513422464978), new Grad3( 2.22474487139, 2.22474487139, -1.0), new Grad3( 2.22474487139, 2.22474487139, 1.0), new Grad3( 3.0862664687972017, 1.1721513422464978, 0.0), new Grad3( 1.1721513422464978, 3.0862664687972017, 0.0) }; for (int i = 0; i < grad3.Length; i++) { grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_3D[i] = grad3[i % grad3.Length]; } GRADIENTS_4D = new Grad4[PSIZE]; Grad4[] grad4 = { new Grad4(-0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301), new Grad4(-0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796), new Grad4(-0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796), new Grad4(-0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301), new Grad4(-0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078), new Grad4(-0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708), new Grad4(-0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062), new Grad4(-0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724), new Grad4(-0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602), new Grad4(-0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381), new Grad4(-0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585), new Grad4(-0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944), new Grad4(-0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164), new Grad4( 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195), new Grad4( 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585), new Grad4(-0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381), new Grad4(-0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537), new Grad4(-0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945), new Grad4(-0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945), new Grad4(-0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537), new Grad4(-0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945), new Grad4(-0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164), new Grad4( 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195), new Grad4( 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195), new Grad4( 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164), new Grad4( 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944), new Grad4( 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712), new Grad4( 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062), new Grad4(-0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365), new Grad4(-0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796), new Grad4(-0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624), new Grad4( 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796), new Grad4(-0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624), new Grad4( 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842), new Grad4( 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796), new Grad4( 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174), new Grad4( 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624) }; for (int i = 0; i < grad4.Length; i++) { grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_4D[i] = grad4[i % grad4.Length]; } } private struct LatticePoint2D { public int xsv, ysv; public double dx, dy; public LatticePoint2D(int xsv, int ysv) { this.xsv = xsv; this.ysv = ysv; double ssv = (xsv + ysv) * -0.211324865405187; this.dx = -xsv - ssv; this.dy = -ysv - ssv; } } private class LatticePoint3D { public double dxr, dyr, dzr; public int xrv, yrv, zrv; public LatticePoint3D NextOnFailure, NextOnSuccess; public LatticePoint3D(int xrv, int yrv, int zrv, int lattice) { this.dxr = -xrv + lattice * 0.5; this.dyr = -yrv + lattice * 0.5; this.dzr = -zrv + lattice * 0.5; this.xrv = xrv + lattice * 1024; this.yrv = yrv + lattice * 1024; this.zrv = zrv + lattice * 1024; } } private struct LatticePoint4D { public int xsv, ysv, zsv, wsv; public double dx, dy, dz, dw; public double xsi, ysi, zsi, wsi; public double ssiDelta; public LatticePoint4D(int xsv, int ysv, int zsv, int wsv) { this.xsv = xsv + 409; this.ysv = ysv + 409; this.zsv = zsv + 409; this.wsv = wsv + 409; double ssv = (xsv + ysv + zsv + wsv) * 0.309016994374947; this.dx = -xsv - ssv; this.dy = -ysv - ssv; this.dz = -zsv - ssv; this.dw = -wsv - ssv; this.xsi = xsi = 0.2 - xsv; this.ysi = ysi = 0.2 - ysv; this.zsi = zsi = 0.2 - zsv; this.wsi = wsi = 0.2 - wsv; this.ssiDelta = (0.8 - xsv - ysv - zsv - wsv) * 0.309016994374947; } } private struct Grad2 { public double dx, dy; public Grad2(double dx, double dy) { this.dx = dx; this.dy = dy; } } private struct Grad3 { public double dx, dy, dz; public Grad3(double dx, double dy, double dz) { this.dx = dx; this.dy = dy; this.dz = dz; } } private struct Grad4 { public double dx, dy, dz, dw; public Grad4(double dx, double dy, double dz, double dw) { this.dx = dx; this.dy = dy; this.dz = dz; this.dw = dw; } } } } ================================================ FILE: _old/csharp/OpenSimplex2S.cs ================================================ /** * K.jpg's OpenSimplex 2, smooth variant ("SuperSimplex") * * - 2D is standard simplex, modified to support larger kernels. * Implemented using a lookup table. * - 3D is "Re-oriented 8-point BCC noise" which constructs a * congruent BCC lattice in a much different way than usual. * - 4D uses a naïve pregenerated lookup table, and averages out * to the expected performance. * * Multiple versions of each function are provided. See the * documentation above each, for more info. */ using System.Runtime.CompilerServices; namespace Noise { public class OpenSimplex2S { private const int PSIZE = 2048; private const int PMASK = 2047; private short[] perm; private Grad2[] permGrad2; private Grad3[] permGrad3; private Grad4[] permGrad4; public OpenSimplex2S(long seed) { perm = new short[PSIZE]; permGrad2 = new Grad2[PSIZE]; permGrad3 = new Grad3[PSIZE]; permGrad4 = new Grad4[PSIZE]; short[] source = new short[PSIZE]; for (short i = 0; i < PSIZE; i++) source[i] = i; for (int i = PSIZE - 1; i >= 0; i--) { seed = seed * 6364136223846793005L + 1442695040888963407L; int r = (int)((seed + 31) % (i + 1)); if (r < 0) r += (i + 1); perm[i] = source[r]; permGrad2[i] = GRADIENTS_2D[perm[i]]; permGrad3[i] = GRADIENTS_3D[perm[i]]; permGrad4[i] = GRADIENTS_4D[perm[i]]; source[r] = source[i]; } } /* * Noise Evaluators */ /** * 2D SuperSimplex noise, standard lattice orientation. */ public double Noise2(double x, double y) { // Get points for A2* lattice double s = 0.366025403784439 * (x + y); double xs = x + s, ys = y + s; return noise2_Base(xs, ys); } /** * 2D SuperSimplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps. */ public double Noise2_XBeforeY(double x, double y) { // Skew transform and rotation baked into one. double xx = x * 0.7071067811865476; double yy = y * 1.224744871380249; return noise2_Base(yy + xx, yy - xx); } /** * 2D SuperSimplex noise base. * Lookup table implementation inspired by DigitalShadow. */ private double noise2_Base(double xs, double ys) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys); double xsi = xs - xsb, ysi = ys - ysb; // Index to point list int a = (int)(xsi + ysi); int index = (a << 2) | (int)(xsi - ysi / 2 + 1 - a / 2.0) << 3 | (int)(ysi - xsi / 2 + 1 - a / 2.0) << 4; double ssi = (xsi + ysi) * -0.211324865405187; double xi = xsi + ssi, yi = ysi + ssi; // Point contributions for (int i = 0; i < 4; i++) { LatticePoint2D c = LOOKUP_2D[index + i]; double dx = xi + c.dx, dy = yi + c.dy; double attn = 2.0 / 3.0 - dx * dx - dy * dy; if (attn <= 0) continue; int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK; Grad2 grad = permGrad2[perm[pxm] ^ pym]; double extrapolation = grad.dx * dx + grad.dy * dy; attn *= attn; value += attn * attn * extrapolation; } return value; } /** * 3D Re-oriented 8-point BCC noise, classic orientation * Proper substitute for what 3D SuperSimplex "should" be, * in light of Forbidden Formulae. * Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. */ public double Noise3_Classic(double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce the expected look on cardinal planar slices. // If texturing objects that don't tend to have cardinal plane faces, you could even remove this. // Orthonormal rotation. Not a skew transform. double r = (2.0 / 3.0) * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). * For a time varied animation, call noise3_XYBeforeZ(x, y, T). */ public double Noise3_XYBeforeZ(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Y triangular like 2D. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * -0.211324865405187; double zz = z * 0.577350269189626; double xr = x + s2 - zz, yr = y + s2 - zz; double zr = xy * 0.577350269189626 + zz; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). * If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. * For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ. */ public double Noise3_XZBeforeY(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Z triangular like 2D. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * -0.211324865405187; double yy = y * 0.577350269189626; double xr = x + s2 - yy; double zr = z + s2 - yy; double yr = xz * 0.577350269189626 + yy; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. * Lookup table implementation inspired by DigitalShadow. * It was actually faster to narrow down the points in the loop itself, * than to build up the index with enough info to isolate 8 points. */ private double noise3_BCC(double xr, double yr, double zr) { // Get base and offsets inside cube of first lattice. int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr); double xri = xr - xrb, yri = yr - yrb, zri = zr - zrb; // Identify which octant of the cube we're in. This determines which cell // in the other cubic lattice we're in, and also narrows down one point on each. int xht = (int)(xri + 0.5), yht = (int)(yri + 0.5), zht = (int)(zri + 0.5); int index = (xht << 0) | (yht << 1) | (zht << 2); // Point contributions double value = 0; LatticePoint3D c = LOOKUP_3D[index]; while (c != null) { double dxr = xri + c.dxr, dyr = yri + c.dyr, dzr = zri + c.dzr; double attn = 0.75 - dxr * dxr - dyr * dyr - dzr * dzr; if (attn < 0) { c = c.NextOnFailure; } else { int pxm = (xrb + c.xrv) & PMASK, pym = (yrb + c.yrv) & PMASK, pzm = (zrb + c.zrv) & PMASK; Grad3 grad = permGrad3[perm[perm[pxm] ^ pym] ^ pzm]; double extrapolation = grad.dx * dxr + grad.dy * dyr + grad.dz * dzr; attn *= attn; value += attn * attn * extrapolation; c = c.NextOnSuccess; } } return value; } /** * 4D SuperSimplex noise, classic lattice orientation. */ public double Noise4_Classic(double x, double y, double z, double w) { // Get points for A4 lattice double s = 0.309016994374947 * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ public double Noise4_XYBeforeZW(double x, double y, double z, double w) { double s2 = (x + y) * -0.28522513987434876941 + (z + w) * 0.83897065470611435718; double t2 = (z + w) * 0.21939749883706435719 + (x + y) * -0.48214856493302476942; double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XZ and YW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Z (or Y and W) are horizontal. */ public double Noise4_XZBeforeYW(double x, double y, double z, double w) { double s2 = (x + z) * -0.28522513987434876941 + (y + w) * 0.83897065470611435718; double t2 = (y + w) * 0.21939749883706435719 + (x + z) * -0.48214856493302476942; double xs = x + s2, ys = y + t2, zs = z + s2, ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XYZ oriented like noise3_Classic, * and W for an extra degree of freedom. * Recommended for time-varied animations which texture a 3D object (W=time) */ public double Noise4_XYZBeforeW(double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 1.118033988749894; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise base. * Using ultra-simple 4x4x4x4 lookup partitioning. * This isn't as elegant or SIMD/GPU/etc. portable as other approaches, * but it does compete performance-wise with optimized OpenSimplex1. */ private double noise4_Base(double xs, double ys, double zs, double ws) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys), zsb = fastFloor(zs), wsb = fastFloor(ws); double xsi = xs - xsb, ysi = ys - ysb, zsi = zs - zsb, wsi = ws - wsb; // Unskewed offsets double ssi = (xsi + ysi + zsi + wsi) * -0.138196601125011; double xi = xsi + ssi, yi = ysi + ssi, zi = zsi + ssi, wi = wsi + ssi; int index = ((fastFloor(xs * 4) & 3) << 0) | ((fastFloor(ys * 4) & 3) << 2) | ((fastFloor(zs * 4) & 3) << 4) | ((fastFloor(ws * 4) & 3) << 6); // Point contributions foreach (LatticePoint4D c in LOOKUP_4D[index]) { double dx = xi + c.dx, dy = yi + c.dy, dz = zi + c.dz, dw = wi + c.dw; double attn = 0.8 - dx * dx - dy * dy - dz * dz - dw * dw; if (attn > 0) { attn *= attn; int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK; int pzm = (zsb + c.zsv) & PMASK, pwm = (wsb + c.wsv) & PMASK; Grad4 grad = permGrad4[perm[perm[perm[pxm] ^ pym] ^ pzm] ^ pwm]; double extrapolation = grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw; value += attn * attn * extrapolation; } } return value; } /* * Utility */ [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int fastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } /* * Lookup Tables & Gradients */ private static LatticePoint2D[] LOOKUP_2D; private static LatticePoint3D[] LOOKUP_3D; private static LatticePoint4D[][] LOOKUP_4D; private const double N2 = 0.05481866495625118; private const double N3 = 0.2781926117527186; private const double N4 = 0.11127401889945551; private static Grad2[] GRADIENTS_2D; private static Grad3[] GRADIENTS_3D; private static Grad4[] GRADIENTS_4D; static OpenSimplex2S() { LOOKUP_2D = new LatticePoint2D[8 * 4]; LOOKUP_3D = new LatticePoint3D[8]; LOOKUP_4D = new LatticePoint4D[256][]; for (int i = 0; i < 8; i++) { int i1, j1, i2, j2; if ((i & 1) == 0) { if ((i & 2) == 0) { i1 = -1; j1 = 0; } else { i1 = 1; j1 = 0; } if ((i & 4) == 0) { i2 = 0; j2 = -1; } else { i2 = 0; j2 = 1; } } else { if ((i & 2) != 0) { i1 = 2; j1 = 1; } else { i1 = 0; j1 = 1; } if ((i & 4) != 0) { i2 = 1; j2 = 2; } else { i2 = 1; j2 = 0; } } LOOKUP_2D[i * 4 + 0] = new LatticePoint2D(0, 0); LOOKUP_2D[i * 4 + 1] = new LatticePoint2D(1, 1); LOOKUP_2D[i * 4 + 2] = new LatticePoint2D(i1, j1); LOOKUP_2D[i * 4 + 3] = new LatticePoint2D(i2, j2); } for (int i = 0; i < 8; i++) { int i1, j1, k1, i2, j2, k2; i1 = (i >> 0) & 1; j1 = (i >> 1) & 1; k1 = (i >> 2) & 1; i2 = i1 ^ 1; j2 = j1 ^ 1; k2 = k1 ^ 1; // The two points within this octant, one from each of the two cubic half-lattices. LatticePoint3D c0 = new LatticePoint3D(i1, j1, k1, 0); LatticePoint3D c1 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + k2, 1); // (1, 0, 0) vs (0, 1, 1) away from octant. LatticePoint3D c2 = new LatticePoint3D(i1 ^ 1, j1, k1, 0); LatticePoint3D c3 = new LatticePoint3D(i1, j1 ^ 1, k1 ^ 1, 0); // (1, 0, 0) vs (0, 1, 1) away from octant, on second half-lattice. LatticePoint3D c4 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + k2, 1); LatticePoint3D c5 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + (k2 ^ 1), 1); // (0, 1, 0) vs (1, 0, 1) away from octant. LatticePoint3D c6 = new LatticePoint3D(i1, j1 ^ 1, k1, 0); LatticePoint3D c7 = new LatticePoint3D(i1 ^ 1, j1, k1 ^ 1, 0); // (0, 1, 0) vs (1, 0, 1) away from octant, on second half-lattice. LatticePoint3D c8 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + k2, 1); LatticePoint3D c9 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + (k2 ^ 1), 1); // (0, 0, 1) vs (1, 1, 0) away from octant. LatticePoint3D cA = new LatticePoint3D(i1, j1, k1 ^ 1, 0); LatticePoint3D cB = new LatticePoint3D(i1 ^ 1, j1 ^ 1, k1, 0); // (0, 0, 1) vs (1, 1, 0) away from octant, on second half-lattice. LatticePoint3D cC = new LatticePoint3D(i1 + i2, j1 + j2, k1 + (k2 ^ 1), 1); LatticePoint3D cD = new LatticePoint3D(i1 + (i2 ^ 1), j1 + (j2 ^ 1), k1 + k2, 1); // First two points are guaranteed. c0.NextOnFailure = c0.NextOnSuccess = c1; c1.NextOnFailure = c1.NextOnSuccess = c2; // If c2 is in range, then we know c3 and c4 are not. c2.NextOnFailure = c3; c2.NextOnSuccess = c5; c3.NextOnFailure = c4; c3.NextOnSuccess = c4; // If c4 is in range, then we know c5 is not. c4.NextOnFailure = c5; c4.NextOnSuccess = c6; c5.NextOnFailure = c5.NextOnSuccess = c6; // If c6 is in range, then we know c7 and c8 are not. c6.NextOnFailure = c7; c6.NextOnSuccess = c9; c7.NextOnFailure = c8; c7.NextOnSuccess = c8; // If c8 is in range, then we know c9 is not. c8.NextOnFailure = c9; c8.NextOnSuccess = cA; c9.NextOnFailure = c9.NextOnSuccess = cA; // If cA is in range, then we know cB and cC are not. cA.NextOnFailure = cB; cA.NextOnSuccess = cD; cB.NextOnFailure = cC; cB.NextOnSuccess = cC; // If cC is in range, then we know cD is not. cC.NextOnFailure = cD; cC.NextOnSuccess = null; cD.NextOnFailure = cD.NextOnSuccess = null; LOOKUP_3D[i] = c0; } int[][] lookup4DPregen = { new int[] { 0x15, 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x01, 0x05, 0x11, 0x15, 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x01, 0x15, 0x16, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA, 0xAB }, new int[] { 0x04, 0x05, 0x14, 0x15, 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x6A, 0x9A, 0xAA, 0xAB }, new int[] { 0x04, 0x15, 0x19, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA, 0xAE }, new int[] { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x5E, 0x6A, 0x9A, 0xAA, 0xAE }, new int[] { 0x05, 0x15, 0x1A, 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x5E, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x6B, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xAA }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x6B, 0x9A, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x9A, 0xAA, 0xAE }, new int[] { 0x15, 0x1A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x10, 0x11, 0x14, 0x15, 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x67, 0x6A, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x6B, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x6D, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x6E, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x10, 0x15, 0x25, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA, 0xBA }, new int[] { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0x76, 0xA6, 0xAA, 0xBA }, new int[] { 0x11, 0x15, 0x26, 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x67, 0x6A, 0x76, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA6, 0xAA, 0xBA }, new int[] { 0x15, 0x26, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0x79, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x14, 0x15, 0x29, 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0x6D, 0x79, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x29, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x7A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, new int[] { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x9A, 0x9B, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, new int[] { 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x59, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x56, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA }, new int[] { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, new int[] { 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x6A, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, new int[] { 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, new int[] { 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x95, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA }, new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, new int[] { 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA }, new int[] { 0x51, 0x55, 0x61, 0x65, 0x66, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x64, 0x65, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA }, new int[] { 0x40, 0x45, 0x51, 0x54, 0x55, 0x85, 0x91, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA, 0xEA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xD6, 0xEA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x86, 0x92, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB, 0xD6, 0xEA, 0xEB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x86, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xD9, 0xEA }, new int[] { 0x45, 0x55, 0x59, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x89, 0x95, 0x98, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE, 0xD9, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x59, 0x89, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xDA, 0xEA, 0xEF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x91, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x92, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x94, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x95, 0x98, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, new int[] { 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xEA, 0xEF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xE5, 0xEA }, new int[] { 0x51, 0x55, 0x65, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x65, 0x94, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x55, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x94, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x59, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, new int[] { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xEA }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA1, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA, 0xE5, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x65, 0x95, 0xA1, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xE6, 0xEA, 0xFB }, new int[] { 0x54, 0x55, 0x65, 0x95, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, new int[] { 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xEA, 0xFB }, new int[] { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, new int[] { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xEA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xE9, 0xEA, 0xFE }, new int[] { 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA, 0xFE }, new int[] { 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA, 0xEA }, }; LatticePoint4D[] latticePoints = new LatticePoint4D[256]; for (int i = 0; i < 256; i++) { int cx = ((i >> 0) & 3) - 1; int cy = ((i >> 2) & 3) - 1; int cz = ((i >> 4) & 3) - 1; int cw = ((i >> 6) & 3) - 1; latticePoints[i] = new LatticePoint4D(cx, cy, cz, cw); } for (int i = 0; i < 256; i++) { LOOKUP_4D[i] = new LatticePoint4D[lookup4DPregen[i].Length]; for (int j = 0; j < lookup4DPregen[i].Length; j++) { LOOKUP_4D[i][j] = latticePoints[lookup4DPregen[i][j]]; } } GRADIENTS_2D = new Grad2[PSIZE]; Grad2[] grad2 = { new Grad2( 0.130526192220052, 0.99144486137381), new Grad2( 0.38268343236509, 0.923879532511287), new Grad2( 0.608761429008721, 0.793353340291235), new Grad2( 0.793353340291235, 0.608761429008721), new Grad2( 0.923879532511287, 0.38268343236509), new Grad2( 0.99144486137381, 0.130526192220051), new Grad2( 0.99144486137381, -0.130526192220051), new Grad2( 0.923879532511287, -0.38268343236509), new Grad2( 0.793353340291235, -0.60876142900872), new Grad2( 0.608761429008721, -0.793353340291235), new Grad2( 0.38268343236509, -0.923879532511287), new Grad2( 0.130526192220052, -0.99144486137381), new Grad2(-0.130526192220052, -0.99144486137381), new Grad2(-0.38268343236509, -0.923879532511287), new Grad2(-0.608761429008721, -0.793353340291235), new Grad2(-0.793353340291235, -0.608761429008721), new Grad2(-0.923879532511287, -0.38268343236509), new Grad2(-0.99144486137381, -0.130526192220052), new Grad2(-0.99144486137381, 0.130526192220051), new Grad2(-0.923879532511287, 0.38268343236509), new Grad2(-0.793353340291235, 0.608761429008721), new Grad2(-0.608761429008721, 0.793353340291235), new Grad2(-0.38268343236509, 0.923879532511287), new Grad2(-0.130526192220052, 0.99144486137381) }; for (int i = 0; i < grad2.Length; i++) { grad2[i].dx /= N2; grad2[i].dy /= N2; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_2D[i] = grad2[i % grad2.Length]; } GRADIENTS_3D = new Grad3[PSIZE]; Grad3[] grad3 = { new Grad3(-2.22474487139, -2.22474487139, -1.0), new Grad3(-2.22474487139, -2.22474487139, 1.0), new Grad3(-3.0862664687972017, -1.1721513422464978, 0.0), new Grad3(-1.1721513422464978, -3.0862664687972017, 0.0), new Grad3(-2.22474487139, -1.0, -2.22474487139), new Grad3(-2.22474487139, 1.0, -2.22474487139), new Grad3(-1.1721513422464978, 0.0, -3.0862664687972017), new Grad3(-3.0862664687972017, 0.0, -1.1721513422464978), new Grad3(-2.22474487139, -1.0, 2.22474487139), new Grad3(-2.22474487139, 1.0, 2.22474487139), new Grad3(-3.0862664687972017, 0.0, 1.1721513422464978), new Grad3(-1.1721513422464978, 0.0, 3.0862664687972017), new Grad3(-2.22474487139, 2.22474487139, -1.0), new Grad3(-2.22474487139, 2.22474487139, 1.0), new Grad3(-1.1721513422464978, 3.0862664687972017, 0.0), new Grad3(-3.0862664687972017, 1.1721513422464978, 0.0), new Grad3(-1.0, -2.22474487139, -2.22474487139), new Grad3( 1.0, -2.22474487139, -2.22474487139), new Grad3( 0.0, -3.0862664687972017, -1.1721513422464978), new Grad3( 0.0, -1.1721513422464978, -3.0862664687972017), new Grad3(-1.0, -2.22474487139, 2.22474487139), new Grad3( 1.0, -2.22474487139, 2.22474487139), new Grad3( 0.0, -1.1721513422464978, 3.0862664687972017), new Grad3( 0.0, -3.0862664687972017, 1.1721513422464978), new Grad3(-1.0, 2.22474487139, -2.22474487139), new Grad3( 1.0, 2.22474487139, -2.22474487139), new Grad3( 0.0, 1.1721513422464978, -3.0862664687972017), new Grad3( 0.0, 3.0862664687972017, -1.1721513422464978), new Grad3(-1.0, 2.22474487139, 2.22474487139), new Grad3( 1.0, 2.22474487139, 2.22474487139), new Grad3( 0.0, 3.0862664687972017, 1.1721513422464978), new Grad3( 0.0, 1.1721513422464978, 3.0862664687972017), new Grad3( 2.22474487139, -2.22474487139, -1.0), new Grad3( 2.22474487139, -2.22474487139, 1.0), new Grad3( 1.1721513422464978, -3.0862664687972017, 0.0), new Grad3( 3.0862664687972017, -1.1721513422464978, 0.0), new Grad3( 2.22474487139, -1.0, -2.22474487139), new Grad3( 2.22474487139, 1.0, -2.22474487139), new Grad3( 3.0862664687972017, 0.0, -1.1721513422464978), new Grad3( 1.1721513422464978, 0.0, -3.0862664687972017), new Grad3( 2.22474487139, -1.0, 2.22474487139), new Grad3( 2.22474487139, 1.0, 2.22474487139), new Grad3( 1.1721513422464978, 0.0, 3.0862664687972017), new Grad3( 3.0862664687972017, 0.0, 1.1721513422464978), new Grad3( 2.22474487139, 2.22474487139, -1.0), new Grad3( 2.22474487139, 2.22474487139, 1.0), new Grad3( 3.0862664687972017, 1.1721513422464978, 0.0), new Grad3( 1.1721513422464978, 3.0862664687972017, 0.0) }; for (int i = 0; i < grad3.Length; i++) { grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_3D[i] = grad3[i % grad3.Length]; } GRADIENTS_4D = new Grad4[PSIZE]; Grad4[] grad4 = { new Grad4(-0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301), new Grad4(-0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796), new Grad4(-0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796), new Grad4(-0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301), new Grad4(-0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078), new Grad4(-0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708), new Grad4(-0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062), new Grad4(-0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724), new Grad4(-0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602), new Grad4(-0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381), new Grad4(-0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585), new Grad4(-0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944), new Grad4(-0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164), new Grad4( 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195), new Grad4( 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585), new Grad4(-0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381), new Grad4(-0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537), new Grad4(-0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945), new Grad4(-0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945), new Grad4(-0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537), new Grad4(-0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945), new Grad4(-0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164), new Grad4( 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195), new Grad4( 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195), new Grad4( 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164), new Grad4( 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944), new Grad4( 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712), new Grad4( 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062), new Grad4(-0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365), new Grad4(-0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796), new Grad4(-0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624), new Grad4( 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796), new Grad4(-0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624), new Grad4( 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842), new Grad4( 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796), new Grad4( 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174), new Grad4( 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624) }; for (int i = 0; i < grad4.Length; i++) { grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_4D[i] = grad4[i % grad4.Length]; } } private struct LatticePoint2D { public int xsv, ysv; public double dx, dy; public LatticePoint2D(int xsv, int ysv) { this.xsv = xsv; this.ysv = ysv; double ssv = (xsv + ysv) * -0.211324865405187; this.dx = -xsv - ssv; this.dy = -ysv - ssv; } } private class LatticePoint3D { public double dxr, dyr, dzr; public int xrv, yrv, zrv; public LatticePoint3D NextOnFailure, NextOnSuccess; public LatticePoint3D(int xrv, int yrv, int zrv, int lattice) { this.dxr = -xrv + lattice * 0.5; this.dyr = -yrv + lattice * 0.5; this.dzr = -zrv + lattice * 0.5; this.xrv = xrv + lattice * 1024; this.yrv = yrv + lattice * 1024; this.zrv = zrv + lattice * 1024; } } private class LatticePoint4D { public int xsv, ysv, zsv, wsv; public double dx, dy, dz, dw; public LatticePoint4D(int xsv, int ysv, int zsv, int wsv) { this.xsv = xsv; this.ysv = ysv; this.zsv = zsv; this.wsv = wsv; double ssv = (xsv + ysv + zsv + wsv) * -0.138196601125011; this.dx = -xsv - ssv; this.dy = -ysv - ssv; this.dz = -zsv - ssv; this.dw = -wsv - ssv; } } private struct Grad2 { public double dx, dy; public Grad2(double dx, double dy) { this.dx = dx; this.dy = dy; } } private struct Grad3 { public double dx, dy, dz; public Grad3(double dx, double dy, double dz) { this.dx = dx; this.dy = dy; this.dz = dz; } } private struct Grad4 { public double dx, dy, dz, dw; public Grad4(double dx, double dy, double dz, double dw) { this.dx = dx; this.dy = dy; this.dz = dz; this.dw = dw; } } } } ================================================ FILE: _old/csharp/legacy/OpenSimplex.cs ================================================ /** * K.jpg's original OpenSimplex Noise * DigitalShadow's optimized implementation, https://gist.github.com/digitalshadow/134a3a02b67cecd72181/ * with updated gradient sets (Dec 2019, Feb 2020) * * If 4D noise is not needed, is recommended to use OpenSimplex2 instead. * Choose OpenSimplex2S for comparable smoothness, or choose OpenSimplex2F for speed. * If 4D noise is needed, 4D OpenSimplex2 will come, but this can suffice. * * XYBeforeZ and XZBeforeY functions for 3D have been added, though they aren't as nice as in OpenSimplex2 */ using System; using System.Runtime.CompilerServices; namespace NoiseTest { public class OpenSimplex { private const double STRETCH_2D = -0.211324865405187; // (1/Math.sqrt(2+1)-1)/2; private const double STRETCH_3D = -1.0 / 6.0; // (1/Math.sqrt(3+1)-1)/3; private const double STRETCH_4D = -0.138196601125011; // (1/Math.sqrt(4+1)-1)/4; private const double SQUISH_2D = 0.366025403784439; // (Math.sqrt(2+1)-1)/2; private const double SQUISH_3D = 1.0 / 3.0; // (Math.sqrt(3+1)-1)/3; private const double SQUISH_4D = 0.309016994374947; // (Math.sqrt(4+1)-1)/4; private const int PSIZE = 2048; private const int PMASK = 2047; private const double N2 = 7.69084574549313; private const double N3 = 26.92263139946168; private const double N4 = 8.881759591352166; private short[] perm; private Grad2[] permGrad2; private Grad3[] permGrad3; private Grad4[] permGrad4; private static Grad2[] gradients2D; private static Grad3[] gradients3D; private static Grad4[] gradients4D; private static Contribution2[] lookup2D; private static Contribution3[] lookup3D; private static Contribution4[] lookup4D; static OpenSimplex() { gradients2D = new Grad2[PSIZE]; Grad2[] grad2 = { new Grad2( 0.130526192220052, 0.99144486137381), new Grad2( 0.38268343236509, 0.923879532511287), new Grad2( 0.608761429008721, 0.793353340291235), new Grad2( 0.793353340291235, 0.608761429008721), new Grad2( 0.923879532511287, 0.38268343236509), new Grad2( 0.99144486137381, 0.130526192220051), new Grad2( 0.99144486137381, -0.130526192220051), new Grad2( 0.923879532511287, -0.38268343236509), new Grad2( 0.793353340291235, -0.60876142900872), new Grad2( 0.608761429008721, -0.793353340291235), new Grad2( 0.38268343236509, -0.923879532511287), new Grad2( 0.130526192220052, -0.99144486137381), new Grad2(-0.130526192220052, -0.99144486137381), new Grad2(-0.38268343236509, -0.923879532511287), new Grad2(-0.608761429008721, -0.793353340291235), new Grad2(-0.793353340291235, -0.608761429008721), new Grad2(-0.923879532511287, -0.38268343236509), new Grad2(-0.99144486137381, -0.130526192220052), new Grad2(-0.99144486137381, 0.130526192220051), new Grad2(-0.923879532511287, 0.38268343236509), new Grad2(-0.793353340291235, 0.608761429008721), new Grad2(-0.608761429008721, 0.793353340291235), new Grad2(-0.38268343236509, 0.923879532511287), new Grad2(-0.130526192220052, 0.99144486137381) }; for (int i = 0; i < grad2.Length; i++) { grad2[i].dx /= N2; grad2[i].dy /= N2; } for (int i = 0; i < PSIZE; i++) { gradients2D[i] = grad2[i % grad2.Length]; } gradients3D = new Grad3[PSIZE]; Grad3[] grad3 = { new Grad3(-1.4082482904633333, -1.4082482904633333, -2.6329931618533333), new Grad3(-0.07491495712999985, -0.07491495712999985, -3.29965982852), new Grad3( 0.24732126143473554, -1.6667938651159684, -2.838945207362466), new Grad3(-1.6667938651159684, 0.24732126143473554, -2.838945207362466), new Grad3(-1.4082482904633333, -2.6329931618533333, -1.4082482904633333), new Grad3(-0.07491495712999985, -3.29965982852, -0.07491495712999985), new Grad3(-1.6667938651159684, -2.838945207362466, 0.24732126143473554), new Grad3( 0.24732126143473554, -2.838945207362466, -1.6667938651159684), new Grad3( 1.5580782047233335, 0.33333333333333337, -2.8914115380566665), new Grad3( 2.8914115380566665, -0.33333333333333337, -1.5580782047233335), new Grad3( 1.8101897177633992, -1.2760767510338025, -2.4482280932803), new Grad3( 2.4482280932803, 1.2760767510338025, -1.8101897177633992), new Grad3( 1.5580782047233335, -2.8914115380566665, 0.33333333333333337), new Grad3( 2.8914115380566665, -1.5580782047233335, -0.33333333333333337), new Grad3( 2.4482280932803, -1.8101897177633992, 1.2760767510338025), new Grad3( 1.8101897177633992, -2.4482280932803, -1.2760767510338025), new Grad3(-2.6329931618533333, -1.4082482904633333, -1.4082482904633333), new Grad3(-3.29965982852, -0.07491495712999985, -0.07491495712999985), new Grad3(-2.838945207362466, 0.24732126143473554, -1.6667938651159684), new Grad3(-2.838945207362466, -1.6667938651159684, 0.24732126143473554), new Grad3( 0.33333333333333337, 1.5580782047233335, -2.8914115380566665), new Grad3(-0.33333333333333337, 2.8914115380566665, -1.5580782047233335), new Grad3( 1.2760767510338025, 2.4482280932803, -1.8101897177633992), new Grad3(-1.2760767510338025, 1.8101897177633992, -2.4482280932803), new Grad3( 0.33333333333333337, -2.8914115380566665, 1.5580782047233335), new Grad3(-0.33333333333333337, -1.5580782047233335, 2.8914115380566665), new Grad3(-1.2760767510338025, -2.4482280932803, 1.8101897177633992), new Grad3( 1.2760767510338025, -1.8101897177633992, 2.4482280932803), new Grad3( 3.29965982852, 0.07491495712999985, 0.07491495712999985), new Grad3( 2.6329931618533333, 1.4082482904633333, 1.4082482904633333), new Grad3( 2.838945207362466, -0.24732126143473554, 1.6667938651159684), new Grad3( 2.838945207362466, 1.6667938651159684, -0.24732126143473554), new Grad3(-2.8914115380566665, 1.5580782047233335, 0.33333333333333337), new Grad3(-1.5580782047233335, 2.8914115380566665, -0.33333333333333337), new Grad3(-2.4482280932803, 1.8101897177633992, -1.2760767510338025), new Grad3(-1.8101897177633992, 2.4482280932803, 1.2760767510338025), new Grad3(-2.8914115380566665, 0.33333333333333337, 1.5580782047233335), new Grad3(-1.5580782047233335, -0.33333333333333337, 2.8914115380566665), new Grad3(-1.8101897177633992, 1.2760767510338025, 2.4482280932803), new Grad3(-2.4482280932803, -1.2760767510338025, 1.8101897177633992), new Grad3( 0.07491495712999985, 3.29965982852, 0.07491495712999985), new Grad3( 1.4082482904633333, 2.6329931618533333, 1.4082482904633333), new Grad3( 1.6667938651159684, 2.838945207362466, -0.24732126143473554), new Grad3(-0.24732126143473554, 2.838945207362466, 1.6667938651159684), new Grad3( 0.07491495712999985, 0.07491495712999985, 3.29965982852), new Grad3( 1.4082482904633333, 1.4082482904633333, 2.6329931618533333), new Grad3(-0.24732126143473554, 1.6667938651159684, 2.838945207362466), new Grad3( 1.6667938651159684, -0.24732126143473554, 2.838945207362466) }; for (int i = 0; i < grad3.Length; i++) { grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; } for (int i = 0; i < PSIZE; i++) { gradients3D[i] = grad3[i % grad3.Length]; } gradients4D = new Grad4[PSIZE]; Grad4[] grad4 = { new Grad4(-0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301), new Grad4(-0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796), new Grad4(-0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796), new Grad4(-0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301), new Grad4(-0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078), new Grad4(-0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708), new Grad4(-0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062), new Grad4(-0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724), new Grad4(-0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602), new Grad4(-0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381), new Grad4(-0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585), new Grad4(-0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944), new Grad4(-0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164), new Grad4( 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195), new Grad4( 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585), new Grad4(-0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381), new Grad4(-0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537), new Grad4(-0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945), new Grad4(-0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945), new Grad4(-0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537), new Grad4(-0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945), new Grad4(-0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164), new Grad4( 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195), new Grad4( 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195), new Grad4( 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164), new Grad4( 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944), new Grad4( 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712), new Grad4( 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062), new Grad4(-0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365), new Grad4(-0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796), new Grad4(-0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624), new Grad4( 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796), new Grad4(-0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624), new Grad4( 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842), new Grad4( 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796), new Grad4( 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174), new Grad4( 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624) }; for (int i = 0; i < grad4.Length; i++) { grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4; } for (int i = 0; i < PSIZE; i++) { gradients4D[i] = grad4[i % grad4.Length]; } var base2D = new int[][] { new int[] { 1, 1, 0, 1, 0, 1, 0, 0, 0 }, new int[] { 1, 1, 0, 1, 0, 1, 2, 1, 1 } }; var p2D = new int[] { 0, 0, 1, -1, 0, 0, -1, 1, 0, 2, 1, 1, 1, 2, 2, 0, 1, 2, 0, 2, 1, 0, 0, 0 }; var lookupPairs2D = new int[] { 0, 1, 1, 0, 4, 1, 17, 0, 20, 2, 21, 2, 22, 5, 23, 5, 26, 4, 39, 3, 42, 4, 43, 3 }; var contributions2D = new Contribution2[p2D.Length / 4]; for (int i = 0; i < p2D.Length; i += 4) { var baseSet = base2D[p2D[i]]; Contribution2 previous = null, current = null; for (int k = 0; k < baseSet.Length; k += 3) { current = new Contribution2(baseSet[k], baseSet[k + 1], baseSet[k + 2]); if (previous == null) { contributions2D[i / 4] = current; } else { previous.Next = current; } previous = current; } current.Next = new Contribution2(p2D[i + 1], p2D[i + 2], p2D[i + 3]); } lookup2D = new Contribution2[64]; for (var i = 0; i < lookupPairs2D.Length; i += 2) { lookup2D[lookupPairs2D[i]] = contributions2D[lookupPairs2D[i + 1]]; } var base3D = new int[][] { new int[] { 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1 }, new int[] { 2, 1, 1, 0, 2, 1, 0, 1, 2, 0, 1, 1, 3, 1, 1, 1 }, new int[] { 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 0, 2, 1, 0, 1, 2, 0, 1, 1 } }; var p3D = new int[] { 0, 0, 1, -1, 0, 0, 1, 0, -1, 0, 0, -1, 1, 0, 0, 0, 1, -1, 0, 0, -1, 0, 1, 0, 0, -1, 1, 0, 2, 1, 1, 0, 1, 1, 1, -1, 0, 2, 1, 0, 1, 1, 1, -1, 1, 0, 2, 0, 1, 1, 1, -1, 1, 1, 1, 3, 2, 1, 0, 3, 1, 2, 0, 1, 3, 2, 0, 1, 3, 1, 0, 2, 1, 3, 0, 2, 1, 3, 0, 1, 2, 1, 1, 1, 0, 0, 2, 2, 0, 0, 1, 1, 0, 1, 0, 2, 0, 2, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 2, 0, 0, 0, 0, 1, 1, -1, 1, 2, 0, 0, 0, 0, 1, -1, 1, 1, 2, 0, 0, 0, 0, 1, 1, 1, -1, 2, 3, 1, 1, 1, 2, 0, 0, 2, 2, 3, 1, 1, 1, 2, 2, 0, 0, 2, 3, 1, 1, 1, 2, 0, 2, 0, 2, 1, 1, -1, 1, 2, 0, 0, 2, 2, 1, 1, -1, 1, 2, 2, 0, 0, 2, 1, -1, 1, 1, 2, 0, 0, 2, 2, 1, -1, 1, 1, 2, 0, 2, 0, 2, 1, 1, 1, -1, 2, 2, 0, 0, 2, 1, 1, 1, -1, 2, 0, 2, 0 }; var lookupPairs3D = new int[] { 0, 2, 1, 1, 2, 2, 5, 1, 6, 0, 7, 0, 32, 2, 34, 2, 129, 1, 133, 1, 160, 5, 161, 5, 518, 0, 519, 0, 546, 4, 550, 4, 645, 3, 647, 3, 672, 5, 673, 5, 674, 4, 677, 3, 678, 4, 679, 3, 680, 13, 681, 13, 682, 12, 685, 14, 686, 12, 687, 14, 712, 20, 714, 18, 809, 21, 813, 23, 840, 20, 841, 21, 1198, 19, 1199, 22, 1226, 18, 1230, 19, 1325, 23, 1327, 22, 1352, 15, 1353, 17, 1354, 15, 1357, 17, 1358, 16, 1359, 16, 1360, 11, 1361, 10, 1362, 11, 1365, 10, 1366, 9, 1367, 9, 1392, 11, 1394, 11, 1489, 10, 1493, 10, 1520, 8, 1521, 8, 1878, 9, 1879, 9, 1906, 7, 1910, 7, 2005, 6, 2007, 6, 2032, 8, 2033, 8, 2034, 7, 2037, 6, 2038, 7, 2039, 6 }; var contributions3D = new Contribution3[p3D.Length / 9]; for (int i = 0; i < p3D.Length; i += 9) { var baseSet = base3D[p3D[i]]; Contribution3 previous = null, current = null; for (int k = 0; k < baseSet.Length; k += 4) { current = new Contribution3(baseSet[k], baseSet[k + 1], baseSet[k + 2], baseSet[k + 3]); if (previous == null) { contributions3D[i / 9] = current; } else { previous.Next = current; } previous = current; } current.Next = new Contribution3(p3D[i + 1], p3D[i + 2], p3D[i + 3], p3D[i + 4]); current.Next.Next = new Contribution3(p3D[i + 5], p3D[i + 6], p3D[i + 7], p3D[i + 8]); } lookup3D = new Contribution3[2048]; for (var i = 0; i < lookupPairs3D.Length; i += 2) { lookup3D[lookupPairs3D[i]] = contributions3D[lookupPairs3D[i + 1]]; } var base4D = new int[][] { new int[] { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1 }, new int[] { 3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 4, 1, 1, 1, 1 }, new int[] { 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1 }, new int[] { 3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1 } }; var p4D = new int[] { 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 2, 1, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 0, 2, 0, 1, 1, 0, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 2, 1, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 2, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 2, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 1, 4, 2, 1, 1, 0, 4, 1, 2, 1, 0, 4, 1, 1, 2, 0, 1, 4, 2, 1, 0, 1, 4, 1, 2, 0, 1, 4, 1, 1, 0, 2, 1, 4, 2, 0, 1, 1, 4, 1, 0, 2, 1, 4, 1, 0, 1, 2, 1, 4, 0, 2, 1, 1, 4, 0, 1, 2, 1, 4, 0, 1, 1, 2, 1, 2, 1, 1, 0, 0, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 1, 2, 1, 0, 1, 0, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 1, 2, 0, 1, 1, 0, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 1, 2, 1, 0, 0, 1, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 1, 2, 0, 1, 0, 1, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 1, 2, 0, 0, 1, 1, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 2, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 2, 0, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 2, 0, 0, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 0, 2, 0, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 0, 0, 2, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 0, 2, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 0, 2, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 0, 0, 0, 0, 0, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 2, 0, 0, 0, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 0, 2, 0, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 2, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 0, 2, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, 1, -1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, 1, -1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, 1, 1, -1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, 1, -1, 1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, -1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 4, 1, 1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 4, 1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, 1, -1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 2, 1, 1, 1, -1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, 1, 1, 1, -1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, -1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, 1, -1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 2, 1, 1, -1, 1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 2, 1, -1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, -1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 1, -1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, -1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 2, -1, 1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, -1, 1, 1, 1 }; var lookupPairs4D = new int[] { 0, 3, 1, 2, 2, 3, 5, 2, 6, 1, 7, 1, 8, 3, 9, 2, 10, 3, 13, 2, 16, 3, 18, 3, 22, 1, 23, 1, 24, 3, 26, 3, 33, 2, 37, 2, 38, 1, 39, 1, 41, 2, 45, 2, 54, 1, 55, 1, 56, 0, 57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 256, 3, 258, 3, 264, 3, 266, 3, 272, 3, 274, 3, 280, 3, 282, 3, 2049, 2, 2053, 2, 2057, 2, 2061, 2, 2081, 2, 2085, 2, 2089, 2, 2093, 2, 2304, 9, 2305, 9, 2312, 9, 2313, 9, 16390, 1, 16391, 1, 16406, 1, 16407, 1, 16422, 1, 16423, 1, 16438, 1, 16439, 1, 16642, 8, 16646, 8, 16658, 8, 16662, 8, 18437, 6, 18439, 6, 18469, 6, 18471, 6, 18688, 9, 18689, 9, 18690, 8, 18693, 6, 18694, 8, 18695, 6, 18696, 9, 18697, 9, 18706, 8, 18710, 8, 18725, 6, 18727, 6, 131128, 0, 131129, 0, 131130, 0, 131131, 0, 131132, 0, 131133, 0, 131134, 0, 131135, 0, 131352, 7, 131354, 7, 131384, 7, 131386, 7, 133161, 5, 133165, 5, 133177, 5, 133181, 5, 133376, 9, 133377, 9, 133384, 9, 133385, 9, 133400, 7, 133402, 7, 133417, 5, 133421, 5, 133432, 7, 133433, 5, 133434, 7, 133437, 5, 147510, 4, 147511, 4, 147518, 4, 147519, 4, 147714, 8, 147718, 8, 147730, 8, 147734, 8, 147736, 7, 147738, 7, 147766, 4, 147767, 4, 147768, 7, 147770, 7, 147774, 4, 147775, 4, 149509, 6, 149511, 6, 149541, 6, 149543, 6, 149545, 5, 149549, 5, 149558, 4, 149559, 4, 149561, 5, 149565, 5, 149566, 4, 149567, 4, 149760, 9, 149761, 9, 149762, 8, 149765, 6, 149766, 8, 149767, 6, 149768, 9, 149769, 9, 149778, 8, 149782, 8, 149784, 7, 149786, 7, 149797, 6, 149799, 6, 149801, 5, 149805, 5, 149814, 4, 149815, 4, 149816, 7, 149817, 5, 149818, 7, 149821, 5, 149822, 4, 149823, 4, 149824, 37, 149825, 37, 149826, 36, 149829, 34, 149830, 36, 149831, 34, 149832, 37, 149833, 37, 149842, 36, 149846, 36, 149848, 35, 149850, 35, 149861, 34, 149863, 34, 149865, 33, 149869, 33, 149878, 32, 149879, 32, 149880, 35, 149881, 33, 149882, 35, 149885, 33, 149886, 32, 149887, 32, 150080, 49, 150082, 48, 150088, 49, 150098, 48, 150104, 47, 150106, 47, 151873, 46, 151877, 45, 151881, 46, 151909, 45, 151913, 44, 151917, 44, 152128, 49, 152129, 46, 152136, 49, 152137, 46, 166214, 43, 166215, 42, 166230, 43, 166247, 42, 166262, 41, 166263, 41, 166466, 48, 166470, 43, 166482, 48, 166486, 43, 168261, 45, 168263, 42, 168293, 45, 168295, 42, 168512, 31, 168513, 28, 168514, 31, 168517, 28, 168518, 25, 168519, 25, 280952, 40, 280953, 39, 280954, 40, 280957, 39, 280958, 38, 280959, 38, 281176, 47, 281178, 47, 281208, 40, 281210, 40, 282985, 44, 282989, 44, 283001, 39, 283005, 39, 283208, 30, 283209, 27, 283224, 30, 283241, 27, 283256, 22, 283257, 22, 297334, 41, 297335, 41, 297342, 38, 297343, 38, 297554, 29, 297558, 24, 297562, 29, 297590, 24, 297594, 21, 297598, 21, 299365, 26, 299367, 23, 299373, 26, 299383, 23, 299389, 20, 299391, 20, 299584, 31, 299585, 28, 299586, 31, 299589, 28, 299590, 25, 299591, 25, 299592, 30, 299593, 27, 299602, 29, 299606, 24, 299608, 30, 299610, 29, 299621, 26, 299623, 23, 299625, 27, 299629, 26, 299638, 24, 299639, 23, 299640, 22, 299641, 22, 299642, 21, 299645, 20, 299646, 21, 299647, 20, 299648, 61, 299649, 60, 299650, 61, 299653, 60, 299654, 59, 299655, 59, 299656, 58, 299657, 57, 299666, 55, 299670, 54, 299672, 58, 299674, 55, 299685, 52, 299687, 51, 299689, 57, 299693, 52, 299702, 54, 299703, 51, 299704, 56, 299705, 56, 299706, 53, 299709, 50, 299710, 53, 299711, 50, 299904, 61, 299906, 61, 299912, 58, 299922, 55, 299928, 58, 299930, 55, 301697, 60, 301701, 60, 301705, 57, 301733, 52, 301737, 57, 301741, 52, 301952, 79, 301953, 79, 301960, 76, 301961, 76, 316038, 59, 316039, 59, 316054, 54, 316071, 51, 316086, 54, 316087, 51, 316290, 78, 316294, 78, 316306, 73, 316310, 73, 318085, 77, 318087, 77, 318117, 70, 318119, 70, 318336, 79, 318337, 79, 318338, 78, 318341, 77, 318342, 78, 318343, 77, 430776, 56, 430777, 56, 430778, 53, 430781, 50, 430782, 53, 430783, 50, 431000, 75, 431002, 72, 431032, 75, 431034, 72, 432809, 74, 432813, 69, 432825, 74, 432829, 69, 433032, 76, 433033, 76, 433048, 75, 433065, 74, 433080, 75, 433081, 74, 447158, 71, 447159, 68, 447166, 71, 447167, 68, 447378, 73, 447382, 73, 447386, 72, 447414, 71, 447418, 72, 447422, 71, 449189, 70, 449191, 70, 449197, 69, 449207, 68, 449213, 69, 449215, 68, 449408, 67, 449409, 67, 449410, 66, 449413, 64, 449414, 66, 449415, 64, 449416, 67, 449417, 67, 449426, 66, 449430, 66, 449432, 65, 449434, 65, 449445, 64, 449447, 64, 449449, 63, 449453, 63, 449462, 62, 449463, 62, 449464, 65, 449465, 63, 449466, 65, 449469, 63, 449470, 62, 449471, 62, 449472, 19, 449473, 19, 449474, 18, 449477, 16, 449478, 18, 449479, 16, 449480, 19, 449481, 19, 449490, 18, 449494, 18, 449496, 17, 449498, 17, 449509, 16, 449511, 16, 449513, 15, 449517, 15, 449526, 14, 449527, 14, 449528, 17, 449529, 15, 449530, 17, 449533, 15, 449534, 14, 449535, 14, 449728, 19, 449729, 19, 449730, 18, 449734, 18, 449736, 19, 449737, 19, 449746, 18, 449750, 18, 449752, 17, 449754, 17, 449784, 17, 449786, 17, 451520, 19, 451521, 19, 451525, 16, 451527, 16, 451528, 19, 451529, 19, 451557, 16, 451559, 16, 451561, 15, 451565, 15, 451577, 15, 451581, 15, 451776, 19, 451777, 19, 451784, 19, 451785, 19, 465858, 18, 465861, 16, 465862, 18, 465863, 16, 465874, 18, 465878, 18, 465893, 16, 465895, 16, 465910, 14, 465911, 14, 465918, 14, 465919, 14, 466114, 18, 466118, 18, 466130, 18, 466134, 18, 467909, 16, 467911, 16, 467941, 16, 467943, 16, 468160, 13, 468161, 13, 468162, 13, 468163, 13, 468164, 13, 468165, 13, 468166, 13, 468167, 13, 580568, 17, 580570, 17, 580585, 15, 580589, 15, 580598, 14, 580599, 14, 580600, 17, 580601, 15, 580602, 17, 580605, 15, 580606, 14, 580607, 14, 580824, 17, 580826, 17, 580856, 17, 580858, 17, 582633, 15, 582637, 15, 582649, 15, 582653, 15, 582856, 12, 582857, 12, 582872, 12, 582873, 12, 582888, 12, 582889, 12, 582904, 12, 582905, 12, 596982, 14, 596983, 14, 596990, 14, 596991, 14, 597202, 11, 597206, 11, 597210, 11, 597214, 11, 597234, 11, 597238, 11, 597242, 11, 597246, 11, 599013, 10, 599015, 10, 599021, 10, 599023, 10, 599029, 10, 599031, 10, 599037, 10, 599039, 10, 599232, 13, 599233, 13, 599234, 13, 599235, 13, 599236, 13, 599237, 13, 599238, 13, 599239, 13, 599240, 12, 599241, 12, 599250, 11, 599254, 11, 599256, 12, 599257, 12, 599258, 11, 599262, 11, 599269, 10, 599271, 10, 599272, 12, 599273, 12, 599277, 10, 599279, 10, 599282, 11, 599285, 10, 599286, 11, 599287, 10, 599288, 12, 599289, 12, 599290, 11, 599293, 10, 599294, 11, 599295, 10 }; var contributions4D = new Contribution4[p4D.Length / 16]; for (int i = 0; i < p4D.Length; i += 16) { var baseSet = base4D[p4D[i]]; Contribution4 previous = null, current = null; for (int k = 0; k < baseSet.Length; k += 5) { current = new Contribution4(baseSet[k], baseSet[k + 1], baseSet[k + 2], baseSet[k + 3], baseSet[k + 4]); if (previous == null) { contributions4D[i / 16] = current; } else { previous.Next = current; } previous = current; } current.Next = new Contribution4(p4D[i + 1], p4D[i + 2], p4D[i + 3], p4D[i + 4], p4D[i + 5]); current.Next.Next = new Contribution4(p4D[i + 6], p4D[i + 7], p4D[i + 8], p4D[i + 9], p4D[i + 10]); current.Next.Next.Next = new Contribution4(p4D[i + 11], p4D[i + 12], p4D[i + 13], p4D[i + 14], p4D[i + 15]); } lookup4D = new Contribution4[1048576]; for (var i = 0; i < lookupPairs4D.Length; i += 2) { lookup4D[lookupPairs4D[i]] = contributions4D[lookupPairs4D[i + 1]]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int FastFloor(double x) { var xi = (int)x; return x < xi ? xi - 1 : xi; } public OpenSimplex() : this(DateTime.Now.Ticks) { } public OpenSimplex(long seed) { perm = new short[PSIZE]; permGrad2 = new Grad2[PSIZE]; permGrad3 = new Grad3[PSIZE]; permGrad4 = new Grad4[PSIZE]; var source = new short[PSIZE]; for (int i = 0; i < PSIZE; i++) { source[i] = (short)i; } for (int i = PSIZE - 1; i >= 0; i--) { seed = seed * 6364136223846793005L + 1442695040888963407L; int r = (int)((seed + 31) % (i + 1)); if (r < 0) { r += (i + 1); } perm[i] = source[r]; permGrad2[i] = gradients2D[perm[i]]; permGrad3[i] = gradients3D[perm[i]]; permGrad4[i] = gradients4D[perm[i]]; source[r] = source[i]; } } public double Evaluate(double x, double y) { var stretchOffset = (x + y) * STRETCH_2D; var xs = x + stretchOffset; var ys = y + stretchOffset; var xsb = FastFloor(xs); var ysb = FastFloor(ys); var xins = xs - xsb; var yins = ys - ysb; var inSum = xins + yins; var squishOffsetIns = inSum * SQUISH_2D; var dx0 = xins + squishOffsetIns; var dy0 = yins + squishOffsetIns; var hash = (int)(xins - yins + 1) | (int)(inSum) << 1 | (int)(inSum + yins) << 2 | (int)(inSum + xins) << 4; var c = lookup2D[hash]; var value = 0.0; while (c != null) { var dx = dx0 + c.dx; var dy = dy0 + c.dy; var attn = 2 - dx * dx - dy * dy; if (attn > 0) { var px = xsb + c.xsb; var py = ysb + c.ysb; Grad2 grad = permGrad2[perm[px & PMASK] ^ (py & PMASK)]; var valuePart = grad.dx * dx + grad.dy * dy; attn *= attn; value += attn * attn * valuePart; } c = c.Next; } return value; } public double Evaluate(double x, double y, double z) { var stretchOffset = (x + y + z) * STRETCH_3D; var xs = x + stretchOffset; var ys = y + stretchOffset; var zs = z + stretchOffset; return evaluate3_Base(xs, ys, zs); } // Not as good as in SuperSimplex/OpenSimplex2S, since there are more visible differences between different slices. // The Z coordinate should always be the "different" coordinate in your use case. public double Evaluate3_XYBeforeZ(double x, double y, double z) { // Combine rotation with skew transform. var xy = x + y; var s2 = xy * 0.211324865405187; var zz = z * 0.288675134594813; double xs = s2 - x + zz, ys = s2 - y + zz; double zs = xy * 0.577350269189626 + zz; return evaluate3_Base(xs, ys, zs); } // Similar to the above, except the Y coordinate should always be the "different" coordinate in your use case. public double Evaluate3_XZBeforeY(double x, double y, double z) { // Combine rotation with skew transform. var xz = x + z; var s2 = xz * 0.211324865405187; var yy = y * 0.288675134594813; double xs = s2 - x + yy, zs = s2 - z + yy; double ys = xz * 0.577350269189626 + yy; return evaluate3_Base(xs, ys, zs); } private double evaluate3_Base(double xs, double ys, double zs) { var xsb = FastFloor(xs); var ysb = FastFloor(ys); var zsb = FastFloor(zs); var xins = xs - xsb; var yins = ys - ysb; var zins = zs - zsb; var inSum = xins + yins + zins; var squishOffsetIns = inSum * SQUISH_3D; var dx0 = xins + squishOffsetIns; var dy0 = yins + squishOffsetIns; var dz0 = zins + squishOffsetIns; var hash = (int)(yins - zins + 1) | (int)(xins - yins + 1) << 1 | (int)(xins - zins + 1) << 2 | (int)inSum << 3 | (int)(inSum + zins) << 5 | (int)(inSum + yins) << 7 | (int)(inSum + xins) << 9; var c = lookup3D[hash]; var value = 0.0; while (c != null) { var dx = dx0 + c.dx; var dy = dy0 + c.dy; var dz = dz0 + c.dz; var attn = 2 - dx * dx - dy * dy - dz * dz; if (attn > 0) { var px = xsb + c.xsb; var py = ysb + c.ysb; var pz = zsb + c.zsb; Grad3 grad = permGrad3[perm[perm[px & PMASK] ^ (py & PMASK)] ^ (pz & PMASK)]; var valuePart = grad.dx * dx + grad.dy * dy + grad.dz * dz; attn *= attn; value += attn * attn * valuePart; } c = c.Next; } return value; } public double Evaluate(double x, double y, double z, double w) { var stretchOffset = (x + y + z + w) * STRETCH_4D; var xs = x + stretchOffset; var ys = y + stretchOffset; var zs = z + stretchOffset; var ws = w + stretchOffset; var xsb = FastFloor(xs); var ysb = FastFloor(ys); var zsb = FastFloor(zs); var wsb = FastFloor(ws); var xins = xs - xsb; var yins = ys - ysb; var zins = zs - zsb; var wins = ws - wsb; var inSum = xins + yins + zins + wins; var squishOffsetIns = inSum * SQUISH_4D; var dx0 = xins + squishOffsetIns; var dy0 = yins + squishOffsetIns; var dz0 = zins + squishOffsetIns; var dw0 = wins + squishOffsetIns; var hash = (int)(zins - wins + 1) | (int)(yins - zins + 1) << 1 | (int)(yins - wins + 1) << 2 | (int)(xins - yins + 1) << 3 | (int)(xins - zins + 1) << 4 | (int)(xins - wins + 1) << 5 | (int)inSum << 6 | (int)(inSum + wins) << 8 | (int)(inSum + zins) << 11 | (int)(inSum + yins) << 14 | (int)(inSum + xins) << 17; var c = lookup4D[hash]; var value = 0.0; while (c != null) { var dx = dx0 + c.dx; var dy = dy0 + c.dy; var dz = dz0 + c.dz; var dw = dw0 + c.dw; var attn = 2 - dx * dx - dy * dy - dz * dz - dw * dw; if (attn > 0) { var px = xsb + c.xsb; var py = ysb + c.ysb; var pz = zsb + c.zsb; var pw = wsb + c.wsb; Grad4 grad = permGrad4[perm[perm[perm[px & PMASK] ^ (py & PMASK)] ^ (pz & PMASK)] ^ (pw & PMASK)]; var valuePart = grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw; attn *= attn; value += attn * attn * valuePart; } c = c.Next; } return value; } private class Contribution2 { public double dx, dy; public int xsb, ysb; public Contribution2 Next; public Contribution2(double multiplier, int xsb, int ysb) { dx = -xsb - multiplier * SQUISH_2D; dy = -ysb - multiplier * SQUISH_2D; this.xsb = xsb; this.ysb = ysb; } } private class Contribution3 { public double dx, dy, dz; public int xsb, ysb, zsb; public Contribution3 Next; public Contribution3(double multiplier, int xsb, int ysb, int zsb) { dx = -xsb - multiplier * SQUISH_3D; dy = -ysb - multiplier * SQUISH_3D; dz = -zsb - multiplier * SQUISH_3D; this.xsb = xsb; this.ysb = ysb; this.zsb = zsb; } } private class Contribution4 { public double dx, dy, dz, dw; public int xsb, ysb, zsb, wsb; public Contribution4 Next; public Contribution4(double multiplier, int xsb, int ysb, int zsb, int wsb) { dx = -xsb - multiplier * SQUISH_4D; dy = -ysb - multiplier * SQUISH_4D; dz = -zsb - multiplier * SQUISH_4D; dw = -wsb - multiplier * SQUISH_4D; this.xsb = xsb; this.ysb = ysb; this.zsb = zsb; this.wsb = wsb; } } public class Grad2 { public double dx, dy; public Grad2(double dx, double dy) { this.dx = dx; this.dy = dy; } } public class Grad3 { public double dx, dy, dz; public Grad3(double dx, double dy, double dz) { this.dx = dx; this.dy = dy; this.dz = dz; } } public class Grad4 { public double dx, dy, dz, dw; public Grad4(double dx, double dy, double dz, double dw) { this.dx = dx; this.dy = dy; this.dz = dz; this.dw = dw; } } } } ================================================ FILE: _old/csharp/legacy/UNLICENSE ================================================ This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. 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 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. For more information, please refer to ================================================ FILE: _old/java/OpenSimplex2F.java ================================================ /** * K.jpg's OpenSimplex 2, faster variant * * - 2D is standard simplex implemented using a lookup table. * - 3D is "Re-oriented 4-point BCC noise" which constructs a * congruent BCC lattice in a much different way than usual. * - 4D constructs the lattice as a union of five copies of its * reciprocal. It successively finds the closest point on each. * * Multiple versions of each function are provided. See the * documentation above each, for more info. */ public class OpenSimplex2F { private static final int PSIZE = 2048; private static final int PMASK = 2047; private short[] perm; private Grad2[] permGrad2; private Grad3[] permGrad3; private Grad4[] permGrad4; public OpenSimplex2F(long seed) { perm = new short[PSIZE]; permGrad2 = new Grad2[PSIZE]; permGrad3 = new Grad3[PSIZE]; permGrad4 = new Grad4[PSIZE]; short[] source = new short[PSIZE]; for (short i = 0; i < PSIZE; i++) source[i] = i; for (int i = PSIZE - 1; i >= 0; i--) { seed = seed * 6364136223846793005L + 1442695040888963407L; int r = (int)((seed + 31) % (i + 1)); if (r < 0) r += (i + 1); perm[i] = source[r]; permGrad2[i] = GRADIENTS_2D[perm[i]]; permGrad3[i] = GRADIENTS_3D[perm[i]]; permGrad4[i] = GRADIENTS_4D[perm[i]]; source[r] = source[i]; } } /* * Noise Evaluators */ /** * 2D Simplex noise, standard lattice orientation. */ public double noise2(double x, double y) { // Get points for A2* lattice double s = 0.366025403784439 * (x + y); double xs = x + s, ys = y + s; return noise2_Base(xs, ys); } /** * 2D Simplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps. */ public double noise2_XBeforeY(double x, double y) { // Skew transform and rotation baked into one. double xx = x * 0.7071067811865476; double yy = y * 1.224744871380249; return noise2_Base(yy + xx, yy - xx); } /** * 2D Simplex noise base. * Lookup table implementation inspired by DigitalShadow. */ private double noise2_Base(double xs, double ys) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys); double xsi = xs - xsb, ysi = ys - ysb; // Index to point list int index = (int)((ysi - xsi) / 2 + 1); double ssi = (xsi + ysi) * -0.211324865405187; double xi = xsi + ssi, yi = ysi + ssi; // Point contributions for (int i = 0; i < 3; i++) { LatticePoint2D c = LOOKUP_2D[index + i]; double dx = xi + c.dx, dy = yi + c.dy; double attn = 0.5 - dx * dx - dy * dy; if (attn <= 0) continue; int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK; Grad2 grad = permGrad2[perm[pxm] ^ pym]; double extrapolation = grad.dx * dx + grad.dy * dy; attn *= attn; value += attn * attn * extrapolation; } return value; } /** * 3D Re-oriented 4-point BCC noise, classic orientation. * Proper substitute for 3D Simplex in light of Forbidden Formulae. * Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. */ public double noise3_Classic(double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce the expected look on cardinal planar slices. // If texturing objects that don't tend to have cardinal plane faces, you could even remove this. // Orthonormal rotation. Not a skew transform. double r = (2.0 / 3.0) * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 4-point BCC noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). * For a time varied animation, call noise3_XYBeforeZ(x, y, T). */ public double noise3_XYBeforeZ(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Y triangular like 2D. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * -0.211324865405187; double zz = z * 0.577350269189626; double xr = x + s2 - zz, yr = y + s2 - zz; double zr = xy * 0.577350269189626 + zz; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 4-point BCC noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). * If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. * For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ. */ public double noise3_XZBeforeY(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Z triangular like 2D. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * -0.211324865405187; double yy = y * 0.577350269189626; double xr = x + s2 - yy; double zr = z + s2 - yy; double yr = xz * 0.577350269189626 + yy; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. * Lookup table implementation inspired by DigitalShadow. * It was actually faster to narrow down the points in the loop itself, * than to build up the index with enough info to isolate 4 points. */ private double noise3_BCC(double xr, double yr, double zr) { // Get base and offsets inside cube of first lattice. int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr); double xri = xr - xrb, yri = yr - yrb, zri = zr - zrb; // Identify which octant of the cube we're in. This determines which cell // in the other cubic lattice we're in, and also narrows down one point on each. int xht = (int)(xri + 0.5), yht = (int)(yri + 0.5), zht = (int)(zri + 0.5); int index = (xht << 0) | (yht << 1) | (zht << 2); // Point contributions double value = 0; LatticePoint3D c = LOOKUP_3D[index]; while (c != null) { double dxr = xri + c.dxr, dyr = yri + c.dyr, dzr = zri + c.dzr; double attn = 0.5 - dxr * dxr - dyr * dyr - dzr * dzr; if (attn < 0) { c = c.nextOnFailure; } else { int pxm = (xrb + c.xrv) & PMASK, pym = (yrb + c.yrv) & PMASK, pzm = (zrb + c.zrv) & PMASK; Grad3 grad = permGrad3[perm[perm[pxm] ^ pym] ^ pzm]; double extrapolation = grad.dx * dxr + grad.dy * dyr + grad.dz * dzr; attn *= attn; value += attn * attn * extrapolation; c = c.nextOnSuccess; } } return value; } /** * 4D OpenSimplex2F noise, classic lattice orientation. */ public double noise4_Classic(double x, double y, double z, double w) { // Get points for A4 lattice double s = -0.138196601125011 * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return noise4_Base(xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ public double noise4_XYBeforeZW(double x, double y, double z, double w) { double s2 = (x + y) * -0.178275657951399372 + (z + w) * 0.215623393288842828; double t2 = (z + w) * -0.403949762580207112 + (x + y) * -0.375199083010075342; double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise, with XZ and YW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Z (or Y and W) are horizontal. */ public double noise4_XZBeforeYW(double x, double y, double z, double w) { double s2 = (x + z) * -0.178275657951399372 + (y + w) * 0.215623393288842828; double t2 = (y + w) * -0.403949762580207112 + (x + z) * -0.375199083010075342; double xs = x + s2, ys = y + t2, zs = z + s2, ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise, with XYZ oriented like noise3_Classic, * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) */ public double noise4_XYZBeforeW(double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 0.2236067977499788; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return noise4_Base(xs, ys, zs, ws); } /** * 4D OpenSimplex2F noise base. * Current implementation not fully optimized by lookup tables. * But still comes out slightly ahead of Gustavson's Simplex in tests. */ private double noise4_Base(double xs, double ys, double zs, double ws) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys), zsb = fastFloor(zs), wsb = fastFloor(ws); double xsi = xs - xsb, ysi = ys - ysb, zsi = zs - zsb, wsi = ws - wsb; // If we're in the lower half, flip so we can repeat the code for the upper half. We'll flip back later. double siSum = xsi + ysi + zsi + wsi; double ssi = siSum * 0.309016994374947; // Prep for vertex contributions. boolean inLowerHalf = (siSum < 2); if (inLowerHalf) { xsi = 1 - xsi; ysi = 1 - ysi; zsi = 1 - zsi; wsi = 1 - wsi; siSum = 4 - siSum; } // Consider opposing vertex pairs of the octahedron formed by the central cross-section of the stretched tesseract double aabb = xsi + ysi - zsi - wsi, abab = xsi - ysi + zsi - wsi, abba = xsi - ysi - zsi + wsi; double aabbScore = Math.abs(aabb), ababScore = Math.abs(abab), abbaScore = Math.abs(abba); // Find the closest point on the stretched tesseract as if it were the upper half int vertexIndex, via, vib; double asi, bsi; if (aabbScore > ababScore && aabbScore > abbaScore) { if (aabb > 0) { asi = zsi; bsi = wsi; vertexIndex = 0b0011; via = 0b0111; vib = 0b1011; } else { asi = xsi; bsi = ysi; vertexIndex = 0b1100; via = 0b1101; vib = 0b1110; } } else if (ababScore > abbaScore) { if (abab > 0) { asi = ysi; bsi = wsi; vertexIndex = 0b0101; via = 0b0111; vib = 0b1101; } else { asi = xsi; bsi = zsi; vertexIndex = 0b1010; via = 0b1011; vib = 0b1110; } } else { if (abba > 0) { asi = ysi; bsi = zsi; vertexIndex = 0b1001; via = 0b1011; vib = 0b1101; } else { asi = xsi; bsi = wsi; vertexIndex = 0b0110; via = 0b0111; vib = 0b1110; } } if (bsi > asi) { via = vib; double temp = bsi; bsi = asi; asi = temp; } if (siSum + asi > 3) { vertexIndex = via; if (siSum + bsi > 4) { vertexIndex = 0b1111; } } // Now flip back if we're actually in the lower half. if (inLowerHalf) { xsi = 1 - xsi; ysi = 1 - ysi; zsi = 1 - zsi; wsi = 1 - wsi; vertexIndex ^= 0b1111; } // Five points to add, total, from five copies of the A4 lattice. for (int i = 0; i < 5; i++) { // Update xsb/etc. and add the lattice point's contribution. LatticePoint4D c = VERTICES_4D[vertexIndex]; xsb += c.xsv; ysb += c.ysv; zsb += c.zsv; wsb += c.wsv; double xi = xsi + ssi, yi = ysi + ssi, zi = zsi + ssi, wi = wsi + ssi; double dx = xi + c.dx, dy = yi + c.dy, dz = zi + c.dz, dw = wi + c.dw; double attn = 0.5 - dx * dx - dy * dy - dz * dz - dw * dw; if (attn > 0) { int pxm = xsb & PMASK, pym = ysb & PMASK, pzm = zsb & PMASK, pwm = wsb & PMASK; Grad4 grad = permGrad4[perm[perm[perm[pxm] ^ pym] ^ pzm] ^ pwm]; double ramped = grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw; attn *= attn; value += attn * attn * ramped; } // Maybe this helps the compiler/JVM/LLVM/etc. know we can end the loop here. Maybe not. if (i == 4) break; // Update the relative skewed coordinates to reference the vertex we just added. // Rather, reference its counterpart on the lattice copy that is shifted down by // the vector <-0.2, -0.2, -0.2, -0.2> xsi += c.xsi; ysi += c.ysi; zsi += c.zsi; wsi += c.wsi; ssi += c.ssiDelta; // Next point is the closest vertex on the 4-simplex whose base vertex is the aforementioned vertex. double score0 = 1.0 + ssi * (-1.0 / 0.309016994374947); // Seems slightly faster than 1.0-xsi-ysi-zsi-wsi vertexIndex = 0b0000; if (xsi >= ysi && xsi >= zsi && xsi >= wsi && xsi >= score0) { vertexIndex = 0b0001; } else if (ysi > xsi && ysi >= zsi && ysi >= wsi && ysi >= score0) { vertexIndex = 0b0010; } else if (zsi > xsi && zsi > ysi && zsi >= wsi && zsi >= score0) { vertexIndex = 0b0100; } else if (wsi > xsi && wsi > ysi && wsi > zsi && wsi >= score0) { vertexIndex = 0b1000; } } return value; } /* * Utility */ private static int fastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } /* * Definitions */ private static final LatticePoint2D[] LOOKUP_2D; private static final LatticePoint3D[] LOOKUP_3D; private static final LatticePoint4D[] VERTICES_4D; static { LOOKUP_2D = new LatticePoint2D[4]; LOOKUP_3D = new LatticePoint3D[8]; VERTICES_4D = new LatticePoint4D[16]; LOOKUP_2D[0] = new LatticePoint2D(1, 0); LOOKUP_2D[1] = new LatticePoint2D(0, 0); LOOKUP_2D[2] = new LatticePoint2D(1, 1); LOOKUP_2D[3] = new LatticePoint2D(0, 1); for (int i = 0; i < 8; i++) { int i1, j1, k1, i2, j2, k2; i1 = (i >> 0) & 1; j1 = (i >> 1) & 1; k1 = (i >> 2) & 1; i2 = i1 ^ 1; j2 = j1 ^ 1; k2 = k1 ^ 1; // The two points within this octant, one from each of the two cubic half-lattices. LatticePoint3D c0 = new LatticePoint3D(i1, j1, k1, 0); LatticePoint3D c1 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + k2, 1); // Each single step away on the first half-lattice. LatticePoint3D c2 = new LatticePoint3D(i1 ^ 1, j1, k1, 0); LatticePoint3D c3 = new LatticePoint3D(i1, j1 ^ 1, k1, 0); LatticePoint3D c4 = new LatticePoint3D(i1, j1, k1 ^ 1, 0); // Each single step away on the second half-lattice. LatticePoint3D c5 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + k2, 1); LatticePoint3D c6 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + k2, 1); LatticePoint3D c7 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + (k2 ^ 1), 1); // First two are guaranteed. c0.nextOnFailure = c0.nextOnSuccess = c1; c1.nextOnFailure = c1.nextOnSuccess = c2; // Once we find one on the first half-lattice, the rest are out. // In addition, knowing c2 rules out c5. c2.nextOnFailure = c3; c2.nextOnSuccess = c6; c3.nextOnFailure = c4; c3.nextOnSuccess = c5; c4.nextOnFailure = c4.nextOnSuccess = c5; // Once we find one on the second half-lattice, the rest are out. c5.nextOnFailure = c6; c5.nextOnSuccess = null; c6.nextOnFailure = c7; c6.nextOnSuccess = null; c7.nextOnFailure = c7.nextOnSuccess = null; LOOKUP_3D[i] = c0; } for (int i = 0; i < 16; i++) { VERTICES_4D[i] = new LatticePoint4D((i >> 0) & 1, (i >> 1) & 1, (i >> 2) & 1, (i >> 3) & 1); } } private static class LatticePoint2D { int xsv, ysv; double dx, dy; public LatticePoint2D(int xsv, int ysv) { this.xsv = xsv; this.ysv = ysv; double ssv = (xsv + ysv) * -0.211324865405187; this.dx = -xsv - ssv; this.dy = -ysv - ssv; } } private static class LatticePoint3D { public double dxr, dyr, dzr; public int xrv, yrv, zrv; LatticePoint3D nextOnFailure, nextOnSuccess; public LatticePoint3D(int xrv, int yrv, int zrv, int lattice) { this.dxr = -xrv + lattice * 0.5; this.dyr = -yrv + lattice * 0.5; this.dzr = -zrv + lattice * 0.5; this.xrv = xrv + lattice * 1024; this.yrv = yrv + lattice * 1024; this.zrv = zrv + lattice * 1024; } } private static class LatticePoint4D { int xsv, ysv, zsv, wsv; double dx, dy, dz, dw; double xsi, ysi, zsi, wsi; double ssiDelta; public LatticePoint4D(int xsv, int ysv, int zsv, int wsv) { this.xsv = xsv + 409; this.ysv = ysv + 409; this.zsv = zsv + 409; this.wsv = wsv + 409; double ssv = (xsv + ysv + zsv + wsv) * 0.309016994374947; this.dx = -xsv - ssv; this.dy = -ysv - ssv; this.dz = -zsv - ssv; this.dw = -wsv - ssv; this.xsi = 0.2 - xsv; this.ysi = 0.2 - ysv; this.zsi = 0.2 - zsv; this.wsi = 0.2 - wsv; this.ssiDelta = (0.8 - xsv - ysv - zsv - wsv) * 0.309016994374947; } } /* * Gradients */ private static class Grad2 { double dx, dy; public Grad2(double dx, double dy) { this.dx = dx; this.dy = dy; } } private static class Grad3 { double dx, dy, dz; public Grad3(double dx, double dy, double dz) { this.dx = dx; this.dy = dy; this.dz = dz; } } private static class Grad4 { double dx, dy, dz, dw; public Grad4(double dx, double dy, double dz, double dw) { this.dx = dx; this.dy = dy; this.dz = dz; this.dw = dw; } } private static final double N2 = 0.01001634121365712; private static final double N3 = 0.030485933181293584; private static final double N4 = 0.009202377986303158; private static final Grad2[] GRADIENTS_2D; private static final Grad3[] GRADIENTS_3D; private static final Grad4[] GRADIENTS_4D; static { GRADIENTS_2D = new Grad2[PSIZE]; Grad2[] grad2 = { new Grad2( 0.130526192220052, 0.99144486137381), new Grad2( 0.38268343236509, 0.923879532511287), new Grad2( 0.608761429008721, 0.793353340291235), new Grad2( 0.793353340291235, 0.608761429008721), new Grad2( 0.923879532511287, 0.38268343236509), new Grad2( 0.99144486137381, 0.130526192220051), new Grad2( 0.99144486137381, -0.130526192220051), new Grad2( 0.923879532511287, -0.38268343236509), new Grad2( 0.793353340291235, -0.60876142900872), new Grad2( 0.608761429008721, -0.793353340291235), new Grad2( 0.38268343236509, -0.923879532511287), new Grad2( 0.130526192220052, -0.99144486137381), new Grad2(-0.130526192220052, -0.99144486137381), new Grad2(-0.38268343236509, -0.923879532511287), new Grad2(-0.608761429008721, -0.793353340291235), new Grad2(-0.793353340291235, -0.608761429008721), new Grad2(-0.923879532511287, -0.38268343236509), new Grad2(-0.99144486137381, -0.130526192220052), new Grad2(-0.99144486137381, 0.130526192220051), new Grad2(-0.923879532511287, 0.38268343236509), new Grad2(-0.793353340291235, 0.608761429008721), new Grad2(-0.608761429008721, 0.793353340291235), new Grad2(-0.38268343236509, 0.923879532511287), new Grad2(-0.130526192220052, 0.99144486137381) }; for (int i = 0; i < grad2.length; i++) { grad2[i].dx /= N2; grad2[i].dy /= N2; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_2D[i] = grad2[i % grad2.length]; } GRADIENTS_3D = new Grad3[PSIZE]; Grad3[] grad3 = { new Grad3(-2.22474487139, -2.22474487139, -1.0), new Grad3(-2.22474487139, -2.22474487139, 1.0), new Grad3(-3.0862664687972017, -1.1721513422464978, 0.0), new Grad3(-1.1721513422464978, -3.0862664687972017, 0.0), new Grad3(-2.22474487139, -1.0, -2.22474487139), new Grad3(-2.22474487139, 1.0, -2.22474487139), new Grad3(-1.1721513422464978, 0.0, -3.0862664687972017), new Grad3(-3.0862664687972017, 0.0, -1.1721513422464978), new Grad3(-2.22474487139, -1.0, 2.22474487139), new Grad3(-2.22474487139, 1.0, 2.22474487139), new Grad3(-3.0862664687972017, 0.0, 1.1721513422464978), new Grad3(-1.1721513422464978, 0.0, 3.0862664687972017), new Grad3(-2.22474487139, 2.22474487139, -1.0), new Grad3(-2.22474487139, 2.22474487139, 1.0), new Grad3(-1.1721513422464978, 3.0862664687972017, 0.0), new Grad3(-3.0862664687972017, 1.1721513422464978, 0.0), new Grad3(-1.0, -2.22474487139, -2.22474487139), new Grad3( 1.0, -2.22474487139, -2.22474487139), new Grad3( 0.0, -3.0862664687972017, -1.1721513422464978), new Grad3( 0.0, -1.1721513422464978, -3.0862664687972017), new Grad3(-1.0, -2.22474487139, 2.22474487139), new Grad3( 1.0, -2.22474487139, 2.22474487139), new Grad3( 0.0, -1.1721513422464978, 3.0862664687972017), new Grad3( 0.0, -3.0862664687972017, 1.1721513422464978), new Grad3(-1.0, 2.22474487139, -2.22474487139), new Grad3( 1.0, 2.22474487139, -2.22474487139), new Grad3( 0.0, 1.1721513422464978, -3.0862664687972017), new Grad3( 0.0, 3.0862664687972017, -1.1721513422464978), new Grad3(-1.0, 2.22474487139, 2.22474487139), new Grad3( 1.0, 2.22474487139, 2.22474487139), new Grad3( 0.0, 3.0862664687972017, 1.1721513422464978), new Grad3( 0.0, 1.1721513422464978, 3.0862664687972017), new Grad3( 2.22474487139, -2.22474487139, -1.0), new Grad3( 2.22474487139, -2.22474487139, 1.0), new Grad3( 1.1721513422464978, -3.0862664687972017, 0.0), new Grad3( 3.0862664687972017, -1.1721513422464978, 0.0), new Grad3( 2.22474487139, -1.0, -2.22474487139), new Grad3( 2.22474487139, 1.0, -2.22474487139), new Grad3( 3.0862664687972017, 0.0, -1.1721513422464978), new Grad3( 1.1721513422464978, 0.0, -3.0862664687972017), new Grad3( 2.22474487139, -1.0, 2.22474487139), new Grad3( 2.22474487139, 1.0, 2.22474487139), new Grad3( 1.1721513422464978, 0.0, 3.0862664687972017), new Grad3( 3.0862664687972017, 0.0, 1.1721513422464978), new Grad3( 2.22474487139, 2.22474487139, -1.0), new Grad3( 2.22474487139, 2.22474487139, 1.0), new Grad3( 3.0862664687972017, 1.1721513422464978, 0.0), new Grad3( 1.1721513422464978, 3.0862664687972017, 0.0) }; for (int i = 0; i < grad3.length; i++) { grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_3D[i] = grad3[i % grad3.length]; } GRADIENTS_4D = new Grad4[PSIZE]; Grad4[] grad4 = { new Grad4(-0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301), new Grad4(-0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796), new Grad4(-0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796), new Grad4(-0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301), new Grad4(-0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078), new Grad4(-0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708), new Grad4(-0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062), new Grad4(-0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724), new Grad4(-0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602), new Grad4(-0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381), new Grad4(-0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585), new Grad4(-0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944), new Grad4(-0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164), new Grad4( 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195), new Grad4( 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585), new Grad4(-0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381), new Grad4(-0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537), new Grad4(-0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945), new Grad4(-0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945), new Grad4(-0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537), new Grad4(-0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945), new Grad4(-0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164), new Grad4( 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195), new Grad4( 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195), new Grad4( 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164), new Grad4( 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944), new Grad4( 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712), new Grad4( 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062), new Grad4(-0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365), new Grad4(-0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796), new Grad4(-0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624), new Grad4( 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796), new Grad4(-0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624), new Grad4( 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842), new Grad4( 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796), new Grad4( 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174), new Grad4( 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624) }; for (int i = 0; i < grad4.length; i++) { grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_4D[i] = grad4[i % grad4.length]; } } } ================================================ FILE: _old/java/OpenSimplex2S.java ================================================ /** * K.jpg's OpenSimplex 2, smooth variant ("SuperSimplex") * * - 2D is standard simplex, modified to support larger kernels. * Implemented using a lookup table. * - 3D is "Re-oriented 8-point BCC noise" which constructs a * congruent BCC lattice in a much different way than usual. * - 4D uses a naïve pregenerated lookup table, and averages out * to the expected performance. * * Multiple versions of each function are provided. See the * documentation above each, for more info. */ public class OpenSimplex2S { private static final int PSIZE = 2048; private static final int PMASK = 2047; private short[] perm; private Grad2[] permGrad2; private Grad3[] permGrad3; private Grad4[] permGrad4; public OpenSimplex2S(long seed) { perm = new short[PSIZE]; permGrad2 = new Grad2[PSIZE]; permGrad3 = new Grad3[PSIZE]; permGrad4 = new Grad4[PSIZE]; short[] source = new short[PSIZE]; for (short i = 0; i < PSIZE; i++) source[i] = i; for (int i = PSIZE - 1; i >= 0; i--) { seed = seed * 6364136223846793005L + 1442695040888963407L; int r = (int)((seed + 31) % (i + 1)); if (r < 0) r += (i + 1); perm[i] = source[r]; permGrad2[i] = GRADIENTS_2D[perm[i]]; permGrad3[i] = GRADIENTS_3D[perm[i]]; permGrad4[i] = GRADIENTS_4D[perm[i]]; source[r] = source[i]; } } /* * Noise Evaluators */ /** * 2D SuperSimplex noise, standard lattice orientation. */ public double noise2(double x, double y) { // Get points for A2* lattice double s = 0.366025403784439 * (x + y); double xs = x + s, ys = y + s; return noise2_Base(xs, ys); } /** * 2D SuperSimplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps. */ public double noise2_XBeforeY(double x, double y) { // Skew transform and rotation baked into one. double xx = x * 0.7071067811865476; double yy = y * 1.224744871380249; return noise2_Base(yy + xx, yy - xx); } /** * 2D SuperSimplex noise base. * Lookup table implementation inspired by DigitalShadow. */ private double noise2_Base(double xs, double ys) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys); double xsi = xs - xsb, ysi = ys - ysb; // Index to point list int a = (int)(xsi + ysi); int index = (a << 2) | (int)(xsi - ysi / 2 + 1 - a / 2.0) << 3 | (int)(ysi - xsi / 2 + 1 - a / 2.0) << 4; double ssi = (xsi + ysi) * -0.211324865405187; double xi = xsi + ssi, yi = ysi + ssi; // Point contributions for (int i = 0; i < 4; i++) { LatticePoint2D c = LOOKUP_2D[index + i]; double dx = xi + c.dx, dy = yi + c.dy; double attn = 2.0 / 3.0 - dx * dx - dy * dy; if (attn <= 0) continue; int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK; Grad2 grad = permGrad2[perm[pxm] ^ pym]; double extrapolation = grad.dx * dx + grad.dy * dy; attn *= attn; value += attn * attn * extrapolation; } return value; } /** * 3D Re-oriented 8-point BCC noise, classic orientation * Proper substitute for what 3D SuperSimplex would be, * in light of Forbidden Formulae. * Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. */ public double noise3_Classic(double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce the expected look on cardinal planar slices. // If texturing objects that don't tend to have cardinal plane faces, you could even remove this. // Orthonormal rotation. Not a skew transform. double r = (2.0 / 3.0) * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). * For a time varied animation, call noise3_XYBeforeZ(x, y, T). */ public double noise3_XYBeforeZ(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Y triangular like 2D. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * -0.211324865405187; double zz = z * 0.577350269189626; double xr = x + s2 - zz, yr = y + s2 - zz; double zr = xy * 0.577350269189626 + zz; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in your use case. * If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). * If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. * For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ. */ public double noise3_XZBeforeY(double x, double y, double z) { // Re-orient the cubic lattices without skewing, to make X and Z triangular like 2D. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * -0.211324865405187; double yy = y * 0.577350269189626; double xr = x + s2 - yy; double zr = z + s2 - yy; double yr = xz * 0.577350269189626 + yy; // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } /** * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. * Lookup table implementation inspired by DigitalShadow. * It was actually faster to narrow down the points in the loop itself, * than to build up the index with enough info to isolate 8 points. */ private double noise3_BCC(double xr, double yr, double zr) { // Get base and offsets inside cube of first lattice. int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr); double xri = xr - xrb, yri = yr - yrb, zri = zr - zrb; // Identify which octant of the cube we're in. This determines which cell // in the other cubic lattice we're in, and also narrows down one point on each. int xht = (int)(xri + 0.5), yht = (int)(yri + 0.5), zht = (int)(zri + 0.5); int index = (xht << 0) | (yht << 1) | (zht << 2); // Point contributions double value = 0; LatticePoint3D c = LOOKUP_3D[index]; while (c != null) { double dxr = xri + c.dxr, dyr = yri + c.dyr, dzr = zri + c.dzr; double attn = 0.75 - dxr * dxr - dyr * dyr - dzr * dzr; if (attn < 0) { c = c.nextOnFailure; } else { int pxm = (xrb + c.xrv) & PMASK, pym = (yrb + c.yrv) & PMASK, pzm = (zrb + c.zrv) & PMASK; Grad3 grad = permGrad3[perm[perm[pxm] ^ pym] ^ pzm]; double extrapolation = grad.dx * dxr + grad.dy * dyr + grad.dz * dzr; attn *= attn; value += attn * attn * extrapolation; c = c.nextOnSuccess; } } return value; } /** * 4D SuperSimplex noise, classic lattice orientation. */ public double noise4_Classic(double x, double y, double z, double w) { // Get points for A4 lattice double s = 0.309016994374947 * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ public double noise4_XYBeforeZW(double x, double y, double z, double w) { double s2 = (x + y) * -0.28522513987434876941 + (z + w) * 0.83897065470611435718; double t2 = (z + w) * 0.21939749883706435719 + (x + y) * -0.48214856493302476942; double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XZ and YW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Z (or Y and W) are horizontal. */ public double noise4_XZBeforeYW(double x, double y, double z, double w) { double s2 = (x + z) * -0.28522513987434876941 + (y + w) * 0.83897065470611435718; double t2 = (y + w) * 0.21939749883706435719 + (x + z) * -0.48214856493302476942; double xs = x + s2, ys = y + t2, zs = z + s2, ws = w + t2; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XYZ oriented like noise3_Classic, * and W for an extra degree of freedom. * Recommended for time-varied animations which texture a 3D object (W=time) */ public double noise4_XYZBeforeW(double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 1.118033988749894; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return noise4_Base(xs, ys, zs, ws); } /** * 4D SuperSimplex noise base. * Using ultra-simple 4x4x4x4 lookup partitioning. * This isn't as elegant or SIMD/GPU/etc. portable as other approaches, * but it does compete performance-wise with optimized OpenSimplex1. */ private double noise4_Base(double xs, double ys, double zs, double ws) { double value = 0; // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys), zsb = fastFloor(zs), wsb = fastFloor(ws); double xsi = xs - xsb, ysi = ys - ysb, zsi = zs - zsb, wsi = ws - wsb; // Unskewed offsets double ssi = (xsi + ysi + zsi + wsi) * -0.138196601125011; double xi = xsi + ssi, yi = ysi + ssi, zi = zsi + ssi, wi = wsi + ssi; int index = ((fastFloor(xs * 4) & 3) << 0) | ((fastFloor(ys * 4) & 3) << 2) | ((fastFloor(zs * 4) & 3) << 4) | ((fastFloor(ws * 4) & 3) << 6); // Point contributions for (LatticePoint4D c : LOOKUP_4D[index]) { double dx = xi + c.dx, dy = yi + c.dy, dz = zi + c.dz, dw = wi + c.dw; double attn = 0.8 - dx * dx - dy * dy - dz * dz - dw * dw; if (attn > 0) { attn *= attn; int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK; int pzm = (zsb + c.zsv) & PMASK, pwm = (wsb + c.wsv) & PMASK; Grad4 grad = permGrad4[perm[perm[perm[pxm] ^ pym] ^ pzm] ^ pwm]; double extrapolation = grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw; value += attn * attn * extrapolation; } } return value; } /* * Utility */ private static int fastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } /* * Definitions */ private static final LatticePoint2D[] LOOKUP_2D; private static final LatticePoint3D[] LOOKUP_3D; private static final LatticePoint4D[][] LOOKUP_4D; static { LOOKUP_2D = new LatticePoint2D[8 * 4]; LOOKUP_3D = new LatticePoint3D[8]; LOOKUP_4D = new LatticePoint4D[256][]; for (int i = 0; i < 8; i++) { int i1, j1, i2, j2; if ((i & 1) == 0) { if ((i & 2) == 0) { i1 = -1; j1 = 0; } else { i1 = 1; j1 = 0; } if ((i & 4) == 0) { i2 = 0; j2 = -1; } else { i2 = 0; j2 = 1; } } else { if ((i & 2) != 0) { i1 = 2; j1 = 1; } else { i1 = 0; j1 = 1; } if ((i & 4) != 0) { i2 = 1; j2 = 2; } else { i2 = 1; j2 = 0; } } LOOKUP_2D[i * 4 + 0] = new LatticePoint2D(0, 0); LOOKUP_2D[i * 4 + 1] = new LatticePoint2D(1, 1); LOOKUP_2D[i * 4 + 2] = new LatticePoint2D(i1, j1); LOOKUP_2D[i * 4 + 3] = new LatticePoint2D(i2, j2); } for (int i = 0; i < 8; i++) { int i1, j1, k1, i2, j2, k2; i1 = (i >> 0) & 1; j1 = (i >> 1) & 1; k1 = (i >> 2) & 1; i2 = i1 ^ 1; j2 = j1 ^ 1; k2 = k1 ^ 1; // The two points within this octant, one from each of the two cubic half-lattices. LatticePoint3D c0 = new LatticePoint3D(i1, j1, k1, 0); LatticePoint3D c1 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + k2, 1); // (1, 0, 0) vs (0, 1, 1) away from octant. LatticePoint3D c2 = new LatticePoint3D(i1 ^ 1, j1, k1, 0); LatticePoint3D c3 = new LatticePoint3D(i1, j1 ^ 1, k1 ^ 1, 0); // (1, 0, 0) vs (0, 1, 1) away from octant, on second half-lattice. LatticePoint3D c4 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + k2, 1); LatticePoint3D c5 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + (k2 ^ 1), 1); // (0, 1, 0) vs (1, 0, 1) away from octant. LatticePoint3D c6 = new LatticePoint3D(i1, j1 ^ 1, k1, 0); LatticePoint3D c7 = new LatticePoint3D(i1 ^ 1, j1, k1 ^ 1, 0); // (0, 1, 0) vs (1, 0, 1) away from octant, on second half-lattice. LatticePoint3D c8 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + k2, 1); LatticePoint3D c9 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + (k2 ^ 1), 1); // (0, 0, 1) vs (1, 1, 0) away from octant. LatticePoint3D cA = new LatticePoint3D(i1, j1, k1 ^ 1, 0); LatticePoint3D cB = new LatticePoint3D(i1 ^ 1, j1 ^ 1, k1, 0); // (0, 0, 1) vs (1, 1, 0) away from octant, on second half-lattice. LatticePoint3D cC = new LatticePoint3D(i1 + i2, j1 + j2, k1 + (k2 ^ 1), 1); LatticePoint3D cD = new LatticePoint3D(i1 + (i2 ^ 1), j1 + (j2 ^ 1), k1 + k2, 1); // First two points are guaranteed. c0.nextOnFailure = c0.nextOnSuccess = c1; c1.nextOnFailure = c1.nextOnSuccess = c2; // If c2 is in range, then we know c3 and c4 are not. c2.nextOnFailure = c3; c2.nextOnSuccess = c5; c3.nextOnFailure = c4; c3.nextOnSuccess = c4; // If c4 is in range, then we know c5 is not. c4.nextOnFailure = c5; c4.nextOnSuccess = c6; c5.nextOnFailure = c5.nextOnSuccess = c6; // If c6 is in range, then we know c7 and c8 are not. c6.nextOnFailure = c7; c6.nextOnSuccess = c9; c7.nextOnFailure = c8; c7.nextOnSuccess = c8; // If c8 is in range, then we know c9 is not. c8.nextOnFailure = c9; c8.nextOnSuccess = cA; c9.nextOnFailure = c9.nextOnSuccess = cA; // If cA is in range, then we know cB and cC are not. cA.nextOnFailure = cB; cA.nextOnSuccess = cD; cB.nextOnFailure = cC; cB.nextOnSuccess = cC; // If cC is in range, then we know cD is not. cC.nextOnFailure = cD; cC.nextOnSuccess = null; cD.nextOnFailure = cD.nextOnSuccess = null; LOOKUP_3D[i] = c0; } int[][] lookup4DPregen = { { 0x15, 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, { 0x01, 0x05, 0x11, 0x15, 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA }, { 0x01, 0x15, 0x16, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA }, { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA, 0xAB }, { 0x04, 0x05, 0x14, 0x15, 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA }, { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA }, { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA }, { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x6A, 0x9A, 0xAA, 0xAB }, { 0x04, 0x15, 0x19, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA, 0xAE }, { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x5E, 0x6A, 0x9A, 0xAA, 0xAE }, { 0x05, 0x15, 0x1A, 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x5E, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x11, 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, { 0x11, 0x15, 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA }, { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA, 0xAB }, { 0x14, 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA6, 0xA9, 0xAA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x6B, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x14, 0x15, 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xAA }, { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x6B, 0x9A, 0xAA, 0xAB }, { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAE }, { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x9A, 0xAA, 0xAE }, { 0x15, 0x1A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, { 0x10, 0x11, 0x14, 0x15, 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA }, { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA }, { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x67, 0x6A, 0xA6, 0xAA, 0xAB }, { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA }, { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x6B, 0xA6, 0xAA, 0xAB }, { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA }, { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0xAA, 0xAB }, { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x6D, 0xA9, 0xAA, 0xAE }, { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x6E, 0xA9, 0xAA, 0xAE }, { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0xAA, 0xAE }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, { 0x10, 0x15, 0x25, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA, 0xBA }, { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0x76, 0xA6, 0xAA, 0xBA }, { 0x11, 0x15, 0x26, 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x67, 0x6A, 0x76, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xBA }, { 0x15, 0x25, 0x55, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x15, 0x25, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA6, 0xAA, 0xBA }, { 0x15, 0x26, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0x79, 0xA9, 0xAA, 0xBA }, { 0x15, 0x25, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA9, 0xAA, 0xBA }, { 0x15, 0x25, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xAA, 0xBA }, { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, { 0x14, 0x15, 0x29, 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0x6D, 0x79, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, { 0x15, 0x29, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x7A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x44, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x9A, 0x9B, 0xAA, 0xAB }, { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, { 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, { 0x50, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x51, 0x55, 0x56, 0x59, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, { 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, { 0x54, 0x55, 0x56, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE }, { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xA7, 0xAA, 0xAB }, { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA }, { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, { 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAD, 0xAE }, { 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x51, 0x55, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, { 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x6A, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, { 0x54, 0x55, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, { 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, { 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, { 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, { 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, { 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA }, { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xAA, 0xAB }, { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x95, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE }, { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA }, { 0x51, 0x52, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA }, { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, { 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, { 0x54, 0x55, 0x58, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB }, { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE }, { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAE }, { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xAF }, { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA }, { 0x51, 0x55, 0x61, 0x65, 0x66, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, { 0x54, 0x55, 0x64, 0x65, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xBB }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, { 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA }, { 0x40, 0x45, 0x51, 0x54, 0x55, 0x85, 0x91, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA, 0xEA }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xD6, 0xEA }, { 0x41, 0x45, 0x51, 0x55, 0x56, 0x86, 0x92, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB, 0xD6, 0xEA, 0xEB }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xEA }, { 0x45, 0x55, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xDA, 0xEA }, { 0x45, 0x55, 0x56, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xDA, 0xEA }, { 0x45, 0x55, 0x56, 0x86, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xD9, 0xEA }, { 0x45, 0x55, 0x59, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xDA, 0xEA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xDA, 0xEA }, { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, { 0x44, 0x45, 0x54, 0x55, 0x59, 0x89, 0x95, 0x98, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE, 0xD9, 0xEA, 0xEE }, { 0x45, 0x55, 0x59, 0x89, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xDA, 0xEA, 0xEF }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x51, 0x55, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, { 0x51, 0x55, 0x56, 0x91, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, { 0x51, 0x55, 0x56, 0x92, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, { 0x54, 0x55, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, { 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, { 0x54, 0x55, 0x59, 0x94, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, { 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, { 0x54, 0x55, 0x59, 0x95, 0x98, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, { 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, { 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xEA, 0xEF }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xE5, 0xEA }, { 0x51, 0x55, 0x65, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, { 0x54, 0x55, 0x65, 0x94, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, { 0x55, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x94, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x55, 0x56, 0x59, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA, 0xEB }, { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xEA }, { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA1, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA, 0xE5, 0xEA, 0xFA }, { 0x51, 0x55, 0x65, 0x95, 0xA1, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xE6, 0xEA, 0xFB }, { 0x54, 0x55, 0x65, 0x95, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, { 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, { 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xEA, 0xFB }, { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, { 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xEA }, { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xE9, 0xEA, 0xFE }, { 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA, 0xFE }, { 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA }, { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA, 0xEA }, }; LatticePoint4D[] latticePoints = new LatticePoint4D[256]; for (int i = 0; i < 256; i++) { int cx = ((i >> 0) & 3) - 1; int cy = ((i >> 2) & 3) - 1; int cz = ((i >> 4) & 3) - 1; int cw = ((i >> 6) & 3) - 1; latticePoints[i] = new LatticePoint4D(cx, cy, cz, cw); } for (int i = 0; i < 256; i++) { LOOKUP_4D[i] = new LatticePoint4D[lookup4DPregen[i].length]; for (int j = 0; j < lookup4DPregen[i].length; j++) { LOOKUP_4D[i][j] = latticePoints[lookup4DPregen[i][j]]; } } } private static class LatticePoint2D { int xsv, ysv; double dx, dy; public LatticePoint2D(int xsv, int ysv) { this.xsv = xsv; this.ysv = ysv; double ssv = (xsv + ysv) * -0.211324865405187; this.dx = -xsv - ssv; this.dy = -ysv - ssv; } } private static class LatticePoint3D { public double dxr, dyr, dzr; public int xrv, yrv, zrv; LatticePoint3D nextOnFailure, nextOnSuccess; public LatticePoint3D(int xrv, int yrv, int zrv, int lattice) { this.dxr = -xrv + lattice * 0.5; this.dyr = -yrv + lattice * 0.5; this.dzr = -zrv + lattice * 0.5; this.xrv = xrv + lattice * 1024; this.yrv = yrv + lattice * 1024; this.zrv = zrv + lattice * 1024; } } private static class LatticePoint4D { int xsv, ysv, zsv, wsv; double dx, dy, dz, dw; public LatticePoint4D(int xsv, int ysv, int zsv, int wsv) { this.xsv = xsv; this.ysv = ysv; this.zsv = zsv; this.wsv = wsv; double ssv = (xsv + ysv + zsv + wsv) * -0.138196601125011; this.dx = -xsv - ssv; this.dy = -ysv - ssv; this.dz = -zsv - ssv; this.dw = -wsv - ssv; } } /* * Gradients */ private static class Grad2 { double dx, dy; public Grad2(double dx, double dy) { this.dx = dx; this.dy = dy; } } private static class Grad3 { double dx, dy, dz; public Grad3(double dx, double dy, double dz) { this.dx = dx; this.dy = dy; this.dz = dz; } } private static class Grad4 { double dx, dy, dz, dw; public Grad4(double dx, double dy, double dz, double dw) { this.dx = dx; this.dy = dy; this.dz = dz; this.dw = dw; } } private static final double N2 = 0.05481866495625118; private static final double N3 = 0.2781926117527186; private static final double N4 = 0.11127401889945551; private static final Grad2[] GRADIENTS_2D; private static final Grad3[] GRADIENTS_3D; private static final Grad4[] GRADIENTS_4D; static { GRADIENTS_2D = new Grad2[PSIZE]; Grad2[] grad2 = { new Grad2( 0.130526192220052, 0.99144486137381), new Grad2( 0.38268343236509, 0.923879532511287), new Grad2( 0.608761429008721, 0.793353340291235), new Grad2( 0.793353340291235, 0.608761429008721), new Grad2( 0.923879532511287, 0.38268343236509), new Grad2( 0.99144486137381, 0.130526192220051), new Grad2( 0.99144486137381, -0.130526192220051), new Grad2( 0.923879532511287, -0.38268343236509), new Grad2( 0.793353340291235, -0.60876142900872), new Grad2( 0.608761429008721, -0.793353340291235), new Grad2( 0.38268343236509, -0.923879532511287), new Grad2( 0.130526192220052, -0.99144486137381), new Grad2(-0.130526192220052, -0.99144486137381), new Grad2(-0.38268343236509, -0.923879532511287), new Grad2(-0.608761429008721, -0.793353340291235), new Grad2(-0.793353340291235, -0.608761429008721), new Grad2(-0.923879532511287, -0.38268343236509), new Grad2(-0.99144486137381, -0.130526192220052), new Grad2(-0.99144486137381, 0.130526192220051), new Grad2(-0.923879532511287, 0.38268343236509), new Grad2(-0.793353340291235, 0.608761429008721), new Grad2(-0.608761429008721, 0.793353340291235), new Grad2(-0.38268343236509, 0.923879532511287), new Grad2(-0.130526192220052, 0.99144486137381) }; for (int i = 0; i < grad2.length; i++) { grad2[i].dx /= N2; grad2[i].dy /= N2; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_2D[i] = grad2[i % grad2.length]; } GRADIENTS_3D = new Grad3[PSIZE]; Grad3[] grad3 = { new Grad3(-2.22474487139, -2.22474487139, -1.0), new Grad3(-2.22474487139, -2.22474487139, 1.0), new Grad3(-3.0862664687972017, -1.1721513422464978, 0.0), new Grad3(-1.1721513422464978, -3.0862664687972017, 0.0), new Grad3(-2.22474487139, -1.0, -2.22474487139), new Grad3(-2.22474487139, 1.0, -2.22474487139), new Grad3(-1.1721513422464978, 0.0, -3.0862664687972017), new Grad3(-3.0862664687972017, 0.0, -1.1721513422464978), new Grad3(-2.22474487139, -1.0, 2.22474487139), new Grad3(-2.22474487139, 1.0, 2.22474487139), new Grad3(-3.0862664687972017, 0.0, 1.1721513422464978), new Grad3(-1.1721513422464978, 0.0, 3.0862664687972017), new Grad3(-2.22474487139, 2.22474487139, -1.0), new Grad3(-2.22474487139, 2.22474487139, 1.0), new Grad3(-1.1721513422464978, 3.0862664687972017, 0.0), new Grad3(-3.0862664687972017, 1.1721513422464978, 0.0), new Grad3(-1.0, -2.22474487139, -2.22474487139), new Grad3( 1.0, -2.22474487139, -2.22474487139), new Grad3( 0.0, -3.0862664687972017, -1.1721513422464978), new Grad3( 0.0, -1.1721513422464978, -3.0862664687972017), new Grad3(-1.0, -2.22474487139, 2.22474487139), new Grad3( 1.0, -2.22474487139, 2.22474487139), new Grad3( 0.0, -1.1721513422464978, 3.0862664687972017), new Grad3( 0.0, -3.0862664687972017, 1.1721513422464978), new Grad3(-1.0, 2.22474487139, -2.22474487139), new Grad3( 1.0, 2.22474487139, -2.22474487139), new Grad3( 0.0, 1.1721513422464978, -3.0862664687972017), new Grad3( 0.0, 3.0862664687972017, -1.1721513422464978), new Grad3(-1.0, 2.22474487139, 2.22474487139), new Grad3( 1.0, 2.22474487139, 2.22474487139), new Grad3( 0.0, 3.0862664687972017, 1.1721513422464978), new Grad3( 0.0, 1.1721513422464978, 3.0862664687972017), new Grad3( 2.22474487139, -2.22474487139, -1.0), new Grad3( 2.22474487139, -2.22474487139, 1.0), new Grad3( 1.1721513422464978, -3.0862664687972017, 0.0), new Grad3( 3.0862664687972017, -1.1721513422464978, 0.0), new Grad3( 2.22474487139, -1.0, -2.22474487139), new Grad3( 2.22474487139, 1.0, -2.22474487139), new Grad3( 3.0862664687972017, 0.0, -1.1721513422464978), new Grad3( 1.1721513422464978, 0.0, -3.0862664687972017), new Grad3( 2.22474487139, -1.0, 2.22474487139), new Grad3( 2.22474487139, 1.0, 2.22474487139), new Grad3( 1.1721513422464978, 0.0, 3.0862664687972017), new Grad3( 3.0862664687972017, 0.0, 1.1721513422464978), new Grad3( 2.22474487139, 2.22474487139, -1.0), new Grad3( 2.22474487139, 2.22474487139, 1.0), new Grad3( 3.0862664687972017, 1.1721513422464978, 0.0), new Grad3( 1.1721513422464978, 3.0862664687972017, 0.0) }; for (int i = 0; i < grad3.length; i++) { grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_3D[i] = grad3[i % grad3.length]; } GRADIENTS_4D = new Grad4[PSIZE]; Grad4[] grad4 = { new Grad4(-0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301), new Grad4(-0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796), new Grad4(-0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796), new Grad4(-0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301), new Grad4(-0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078), new Grad4(-0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708), new Grad4(-0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062), new Grad4(-0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724), new Grad4(-0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602), new Grad4(-0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381), new Grad4(-0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585), new Grad4(-0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944), new Grad4(-0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164), new Grad4( 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195), new Grad4( 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585), new Grad4(-0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381), new Grad4(-0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537), new Grad4(-0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945), new Grad4(-0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945), new Grad4(-0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537), new Grad4(-0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945), new Grad4(-0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164), new Grad4( 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195), new Grad4( 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195), new Grad4( 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164), new Grad4( 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944), new Grad4( 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712), new Grad4( 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062), new Grad4(-0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365), new Grad4(-0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796), new Grad4(-0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624), new Grad4( 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796), new Grad4(-0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624), new Grad4( 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842), new Grad4( 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796), new Grad4( 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174), new Grad4( 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624) }; for (int i = 0; i < grad4.length; i++) { grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_4D[i] = grad4[i % grad4.length]; } } } ================================================ FILE: _old/java/legacy/OpenSimplex.java ================================================ /** * K.jpg's original OpenSimplex Noise * DigitalShadow's optimized implementation, https://gist.github.com/digitalshadow/134a3a02b67cecd72181/ * with updated gradient sets (Dec 2019, Feb 2020) * * If 4D noise is not needed, is recommended to use OpenSimplex2 instead. * Choose OpenSimplex2S for comparable smoothness, or choose OpenSimplex2F for speed. * If 4D noise is needed, 4D OpenSimplex2 will come, but this can suffice. * * XYBeforeZ and XZBeforeY functions for 3D have been added, though they aren't as nice as in OpenSimplex2 */ public class OpenSimplex { private static final double STRETCH_2D = -0.211324865405187; // (1/Math.sqrt(2+1)-1)/2; private static final double STRETCH_3D = -1.0 / 6.0; // (1/Math.sqrt(3+1)-1)/3; private static final double STRETCH_4D = -0.138196601125011; // (1/Math.sqrt(4+1)-1)/4; private static final double SQUISH_2D = 0.366025403784439; // (Math.sqrt(2+1)-1)/2; private static final double SQUISH_3D = 1.0 / 3.0; // (Math.sqrt(3+1)-1)/3; private static final double SQUISH_4D = 0.309016994374947; // (Math.sqrt(4+1)-1)/4; private static final int PSIZE = 2048; private static final int PMASK = 2047; private short[] perm; private Grad2[] permGrad2; private Grad3[] permGrad3; private Grad4[] permGrad4; public OpenSimplex(long seed) { perm = new short[PSIZE]; permGrad2 = new Grad2[PSIZE]; permGrad3 = new Grad3[PSIZE]; permGrad4 = new Grad4[PSIZE]; short[] source = new short[PSIZE]; for (int i = 0; i < PSIZE; i++) { source[i] = (short)i; } for (int i = PSIZE - 1 ; i >= 0; i--) { seed = seed * 6364136223846793005L + 1442695040888963407L; int r = (int)((seed + 31) % (i + 1)); if (r < 0) { r += (i + 1); } perm[i] = source[r]; permGrad2[i] = GRADIENTS_2D[perm[i]]; permGrad3[i] = GRADIENTS_3D[perm[i]]; permGrad4[i] = GRADIENTS_4D[perm[i]]; source[r] = source[i]; } } public double eval(double x, double y) { double stretchOffset = (x + y) * STRETCH_2D; double xs = x + stretchOffset; double ys = y + stretchOffset; int xsb = fastFloor(xs); int ysb = fastFloor(ys); double xins = xs - xsb; double yins = ys - ysb; double inSum = xins + yins; double squishOffsetIns = inSum * SQUISH_2D; double dx0 = xins + squishOffsetIns; double dy0 = yins + squishOffsetIns; int hash = (int)(xins - yins + 1) | (int)(inSum) << 1 | (int)(inSum + yins) << 2 | (int)(inSum + xins) << 4; Contribution2 c = LOOKUP_2D[hash]; double value = 0.0; while (c != null) { double dx = dx0 + c.dx; double dy = dy0 + c.dy; double attn = 2 - dx * dx - dy * dy; if (attn > 0) { int px = xsb + c.xsb; int py = ysb + c.ysb; Grad2 grad = permGrad2[perm[px & PMASK] ^ (py & PMASK)]; double valuePart = grad.dx * dx + grad.dy * dy; attn *= attn; value += attn * attn * valuePart; } c = c.next; } return value; } public double eval(double x, double y, double z) { double stretchOffset = (x + y + z) * STRETCH_3D; double xs = x + stretchOffset; double ys = y + stretchOffset; double zs = z + stretchOffset; return eval3_Base(xs, ys, zs); } // Not as good as in SuperSimplex/OpenSimplex2S, since there are more visible differences between different slices. // The Z coordinate should always be the "different" coordinate in your use case. public double eval3_XYBeforeZ(double x, double y, double z) { // Combine rotation with skew transform. double xy = x + y; double s2 = xy * 0.211324865405187; double zz = z * 0.288675134594813; double xs = s2 - x + zz, ys = s2 - y + zz; double zs = xy * 0.577350269189626 + zz; return eval3_Base(xs, ys, zs); } // Similar to the above, except the Y coordinate should always be the "different" coordinate in your use case. public double eval3_XZBeforeY(double x, double y, double z) { // Combine rotation with skew transform. double xz = x + z; double s2 = xz * 0.211324865405187; double yy = y * 0.288675134594813; double xs = s2 - x + yy, zs = s2 - z + yy; double ys = xz * 0.577350269189626 + yy; return eval3_Base(xs, ys, zs); } private double eval3_Base(double xs, double ys, double zs) { int xsb = fastFloor(xs); int ysb = fastFloor(ys); int zsb = fastFloor(zs); double xins = xs - xsb; double yins = ys - ysb; double zins = zs - zsb; double inSum = xins + yins + zins; double squishOffsetIns = inSum * SQUISH_3D; double dx0 = xins + squishOffsetIns; double dy0 = yins + squishOffsetIns; double dz0 = zins + squishOffsetIns; int hash = (int)(yins - zins + 1) | (int)(xins - yins + 1) << 1 | (int)(xins - zins + 1) << 2 | (int)inSum << 3 | (int)(inSum + zins) << 5 | (int)(inSum + yins) << 7 | (int)(inSum + xins) << 9; Contribution3 c = LOOKUP_3D[hash]; double value = 0.0; while (c != null) { double dx = dx0 + c.dx; double dy = dy0 + c.dy; double dz = dz0 + c.dz; double attn = 2 - dx * dx - dy * dy - dz * dz; if (attn > 0) { int px = xsb + c.xsb; int py = ysb + c.ysb; int pz = zsb + c.zsb; Grad3 grad = permGrad3[perm[perm[px & PMASK] ^ (py & PMASK)] ^ (pz & PMASK)]; double valuePart = grad.dx * dx + grad.dy * dy + grad.dz * dz; attn *= attn; value += attn * attn * valuePart; } c = c.next; } return value; } public double eval(double x, double y, double z, double w) { // Get points for A4 lattice double s = -0.138196601125011 * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return eval4_Base(xs, ys, zs, ws); } public double eval4_XYBeforeZW(double x, double y, double z, double w) { double s2 = (x + y) * -0.178275657951399372 + (z + w) * 0.215623393288842828; double t2 = (z + w) * -0.403949762580207112 + (x + y) * -0.375199083010075342; double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; return eval4_Base(xs, ys, zs, ws); } public double eval4_XZBeforeYW(double x, double y, double z, double w) { double s2 = (x + z) * -0.178275657951399372 + (y + w) * 0.215623393288842828; double t2 = (y + w) * -0.403949762580207112 + (x + z) * -0.375199083010075342; double xs = x + s2, ys = y + t2, zs = z + s2, ws = w + t2; return eval4_Base(xs, ys, zs, ws); } public double eval4_XYZBeforeW(double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 0.2236067977499788; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return eval4_Base(xs, ys, zs, ws); } private double eval4_Base(double xs, double ys, double zs, double ws) { int xsb = fastFloor(xs); int ysb = fastFloor(ys); int zsb = fastFloor(zs); int wsb = fastFloor(ws); double xins = xs - xsb; double yins = ys - ysb; double zins = zs - zsb; double wins = ws - wsb; double inSum = xins + yins + zins + wins; double squishOffsetIns = inSum * SQUISH_4D; double dx0 = xins + squishOffsetIns; double dy0 = yins + squishOffsetIns; double dz0 = zins + squishOffsetIns; double dw0 = wins + squishOffsetIns; int hash = (int)(zins - wins + 1) | (int)(yins - zins + 1) << 1 | (int)(yins - wins + 1) << 2 | (int)(xins - yins + 1) << 3 | (int)(xins - zins + 1) << 4 | (int)(xins - wins + 1) << 5 | (int)inSum << 6 | (int)(inSum + wins) << 8 | (int)(inSum + zins) << 11 | (int)(inSum + yins) << 14 | (int)(inSum + xins) << 17; Contribution4 c = LOOKUP_4D[hash]; double value = 0.0; while (c != null) { double dx = dx0 + c.dx; double dy = dy0 + c.dy; double dz = dz0 + c.dz; double dw = dw0 + c.dw; double attn = 2 - dx * dx - dy * dy - dz * dz - dw * dw; if (attn > 0) { int px = xsb + c.xsb; int py = ysb + c.ysb; int pz = zsb + c.zsb; int pw = wsb + c.wsb; Grad4 grad = permGrad4[perm[perm[perm[px & PMASK] ^ (py & PMASK)] ^ (pz & PMASK)] ^ (pw & PMASK)]; double valuePart = grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw; attn *= attn; value += attn * attn * valuePart; } c = c.next; } return value; } private static class Contribution2 { double dx, dy; int xsb, ysb; Contribution2 next; public Contribution2(double multiplier, int xsb, int ysb) { dx = -xsb - multiplier * SQUISH_2D; dy = -ysb - multiplier * SQUISH_2D; this.xsb = xsb; this.ysb = ysb; } } private static class Contribution3 { double dx, dy, dz; int xsb, ysb, zsb; Contribution3 next; public Contribution3(double multiplier, int xsb, int ysb, int zsb) { dx = -xsb - multiplier * SQUISH_3D; dy = -ysb - multiplier * SQUISH_3D; dz = -zsb - multiplier * SQUISH_3D; this.xsb = xsb; this.ysb = ysb; this.zsb = zsb; } } private static class Contribution4 { double dx, dy, dz, dw; int xsb, ysb, zsb, wsb; Contribution4 next; public Contribution4(double multiplier, int xsb, int ysb, int zsb, int wsb) { dx = -xsb - multiplier * SQUISH_4D; dy = -ysb - multiplier * SQUISH_4D; dz = -zsb - multiplier * SQUISH_4D; dw = -wsb - multiplier * SQUISH_4D; this.xsb = xsb; this.ysb = ysb; this.zsb = zsb; this.wsb = wsb; } } public static class Grad2 { double dx, dy; public Grad2(double dx, double dy) { this.dx = dx; this.dy = dy; } } public static class Grad3 { double dx, dy, dz; public Grad3(double dx, double dy, double dz) { this.dx = dx; this.dy = dy; this.dz = dz; } } public static class Grad4 { double dx, dy, dz, dw; public Grad4(double dx, double dy, double dz, double dw) { this.dx = dx; this.dy = dy; this.dz = dz; this.dw = dw; } } /* * Utility */ private static int fastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } /* * Gradients and lookup tables */ private static final Grad2[] GRADIENTS_2D; private static final Grad3[] GRADIENTS_3D; private static final Grad4[] GRADIENTS_4D; private static Contribution2[] LOOKUP_2D; private static Contribution3[] LOOKUP_3D; private static Contribution4[] LOOKUP_4D; private static final double N2 = 7.69084574549313; private static final double N3 = 26.92263139946168; private static final double N4 = 8.881759591352166; static { GRADIENTS_2D = new Grad2[PSIZE]; Grad2[] grad2 = { new Grad2( 0.130526192220052, 0.99144486137381), new Grad2( 0.38268343236509, 0.923879532511287), new Grad2( 0.608761429008721, 0.793353340291235), new Grad2( 0.793353340291235, 0.608761429008721), new Grad2( 0.923879532511287, 0.38268343236509), new Grad2( 0.99144486137381, 0.130526192220051), new Grad2( 0.99144486137381, -0.130526192220051), new Grad2( 0.923879532511287, -0.38268343236509), new Grad2( 0.793353340291235, -0.60876142900872), new Grad2( 0.608761429008721, -0.793353340291235), new Grad2( 0.38268343236509, -0.923879532511287), new Grad2( 0.130526192220052, -0.99144486137381), new Grad2(-0.130526192220052, -0.99144486137381), new Grad2(-0.38268343236509, -0.923879532511287), new Grad2(-0.608761429008721, -0.793353340291235), new Grad2(-0.793353340291235, -0.608761429008721), new Grad2(-0.923879532511287, -0.38268343236509), new Grad2(-0.99144486137381, -0.130526192220052), new Grad2(-0.99144486137381, 0.130526192220051), new Grad2(-0.923879532511287, 0.38268343236509), new Grad2(-0.793353340291235, 0.608761429008721), new Grad2(-0.608761429008721, 0.793353340291235), new Grad2(-0.38268343236509, 0.923879532511287), new Grad2(-0.130526192220052, 0.99144486137381) }; for (int i = 0; i < grad2.length; i++) { grad2[i].dx /= N2; grad2[i].dy /= N2; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_2D[i] = grad2[i % grad2.length]; } GRADIENTS_3D = new Grad3[PSIZE]; Grad3[] grad3 = { new Grad3(-1.4082482904633333, -1.4082482904633333, -2.6329931618533333), new Grad3(-0.07491495712999985, -0.07491495712999985, -3.29965982852), new Grad3( 0.24732126143473554, -1.6667938651159684, -2.838945207362466), new Grad3(-1.6667938651159684, 0.24732126143473554, -2.838945207362466), new Grad3(-1.4082482904633333, -2.6329931618533333, -1.4082482904633333), new Grad3(-0.07491495712999985, -3.29965982852, -0.07491495712999985), new Grad3(-1.6667938651159684, -2.838945207362466, 0.24732126143473554), new Grad3( 0.24732126143473554, -2.838945207362466, -1.6667938651159684), new Grad3( 1.5580782047233335, 0.33333333333333337, -2.8914115380566665), new Grad3( 2.8914115380566665, -0.33333333333333337, -1.5580782047233335), new Grad3( 1.8101897177633992, -1.2760767510338025, -2.4482280932803), new Grad3( 2.4482280932803, 1.2760767510338025, -1.8101897177633992), new Grad3( 1.5580782047233335, -2.8914115380566665, 0.33333333333333337), new Grad3( 2.8914115380566665, -1.5580782047233335, -0.33333333333333337), new Grad3( 2.4482280932803, -1.8101897177633992, 1.2760767510338025), new Grad3( 1.8101897177633992, -2.4482280932803, -1.2760767510338025), new Grad3(-2.6329931618533333, -1.4082482904633333, -1.4082482904633333), new Grad3(-3.29965982852, -0.07491495712999985, -0.07491495712999985), new Grad3(-2.838945207362466, 0.24732126143473554, -1.6667938651159684), new Grad3(-2.838945207362466, -1.6667938651159684, 0.24732126143473554), new Grad3( 0.33333333333333337, 1.5580782047233335, -2.8914115380566665), new Grad3(-0.33333333333333337, 2.8914115380566665, -1.5580782047233335), new Grad3( 1.2760767510338025, 2.4482280932803, -1.8101897177633992), new Grad3(-1.2760767510338025, 1.8101897177633992, -2.4482280932803), new Grad3( 0.33333333333333337, -2.8914115380566665, 1.5580782047233335), new Grad3(-0.33333333333333337, -1.5580782047233335, 2.8914115380566665), new Grad3(-1.2760767510338025, -2.4482280932803, 1.8101897177633992), new Grad3( 1.2760767510338025, -1.8101897177633992, 2.4482280932803), new Grad3( 3.29965982852, 0.07491495712999985, 0.07491495712999985), new Grad3( 2.6329931618533333, 1.4082482904633333, 1.4082482904633333), new Grad3( 2.838945207362466, -0.24732126143473554, 1.6667938651159684), new Grad3( 2.838945207362466, 1.6667938651159684, -0.24732126143473554), new Grad3(-2.8914115380566665, 1.5580782047233335, 0.33333333333333337), new Grad3(-1.5580782047233335, 2.8914115380566665, -0.33333333333333337), new Grad3(-2.4482280932803, 1.8101897177633992, -1.2760767510338025), new Grad3(-1.8101897177633992, 2.4482280932803, 1.2760767510338025), new Grad3(-2.8914115380566665, 0.33333333333333337, 1.5580782047233335), new Grad3(-1.5580782047233335, -0.33333333333333337, 2.8914115380566665), new Grad3(-1.8101897177633992, 1.2760767510338025, 2.4482280932803), new Grad3(-2.4482280932803, -1.2760767510338025, 1.8101897177633992), new Grad3( 0.07491495712999985, 3.29965982852, 0.07491495712999985), new Grad3( 1.4082482904633333, 2.6329931618533333, 1.4082482904633333), new Grad3( 1.6667938651159684, 2.838945207362466, -0.24732126143473554), new Grad3(-0.24732126143473554, 2.838945207362466, 1.6667938651159684), new Grad3( 0.07491495712999985, 0.07491495712999985, 3.29965982852), new Grad3( 1.4082482904633333, 1.4082482904633333, 2.6329931618533333), new Grad3(-0.24732126143473554, 1.6667938651159684, 2.838945207362466), new Grad3( 1.6667938651159684, -0.24732126143473554, 2.838945207362466) }; for (int i = 0; i < grad3.length; i++) { grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_3D[i] = grad3[i % grad3.length]; } GRADIENTS_4D = new Grad4[PSIZE]; Grad4[] grad4 = { new Grad4(-0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301), new Grad4(-0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796), new Grad4(-0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796), new Grad4(-0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301), new Grad4(-0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078), new Grad4(-0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708), new Grad4(-0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062), new Grad4(-0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724), new Grad4(-0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602), new Grad4(-0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381), new Grad4(-0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585), new Grad4(-0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944), new Grad4(-0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164), new Grad4( 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195), new Grad4( 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585), new Grad4(-0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381), new Grad4(-0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537), new Grad4(-0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945), new Grad4(-0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945), new Grad4(-0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537), new Grad4(-0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945), new Grad4(-0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164), new Grad4( 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195), new Grad4( 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195), new Grad4( 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164), new Grad4( 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944), new Grad4( 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712), new Grad4( 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062), new Grad4(-0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365), new Grad4(-0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796), new Grad4(-0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624), new Grad4( 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796), new Grad4(-0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624), new Grad4( 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842), new Grad4( 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796), new Grad4( 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174), new Grad4( 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624) }; for (int i = 0; i < grad4.length; i++) { grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_4D[i] = grad4[i % grad4.length]; } int[][] base2D = new int[][] { new int[] { 1, 1, 0, 1, 0, 1, 0, 0, 0 }, new int[] { 1, 1, 0, 1, 0, 1, 2, 1, 1 } }; int[] p2D = new int[] { 0, 0, 1, -1, 0, 0, -1, 1, 0, 2, 1, 1, 1, 2, 2, 0, 1, 2, 0, 2, 1, 0, 0, 0 }; int[] lookupPairs2D = new int[] { 0, 1, 1, 0, 4, 1, 17, 0, 20, 2, 21, 2, 22, 5, 23, 5, 26, 4, 39, 3, 42, 4, 43, 3 }; Contribution2[] contributions2D = new Contribution2[p2D.length / 4]; for (int i = 0; i < p2D.length; i += 4) { int[] baseSet = base2D[p2D[i]]; Contribution2 previous = null, current = null; for (int k = 0; k < baseSet.length; k += 3) { current = new Contribution2(baseSet[k], baseSet[k + 1], baseSet[k + 2]); if (previous == null) { contributions2D[i / 4] = current; } else { previous.next = current; } previous = current; } current.next = new Contribution2(p2D[i + 1], p2D[i + 2], p2D[i + 3]); } LOOKUP_2D = new Contribution2[64]; for (int i = 0; i < lookupPairs2D.length; i += 2) { LOOKUP_2D[lookupPairs2D[i]] = contributions2D[lookupPairs2D[i + 1]]; } int[][] base3D = new int[][] { new int[] { 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1 }, new int[] { 2, 1, 1, 0, 2, 1, 0, 1, 2, 0, 1, 1, 3, 1, 1, 1 }, new int[] { 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 0, 2, 1, 0, 1, 2, 0, 1, 1 } }; int[] p3D = new int[] { 0, 0, 1, -1, 0, 0, 1, 0, -1, 0, 0, -1, 1, 0, 0, 0, 1, -1, 0, 0, -1, 0, 1, 0, 0, -1, 1, 0, 2, 1, 1, 0, 1, 1, 1, -1, 0, 2, 1, 0, 1, 1, 1, -1, 1, 0, 2, 0, 1, 1, 1, -1, 1, 1, 1, 3, 2, 1, 0, 3, 1, 2, 0, 1, 3, 2, 0, 1, 3, 1, 0, 2, 1, 3, 0, 2, 1, 3, 0, 1, 2, 1, 1, 1, 0, 0, 2, 2, 0, 0, 1, 1, 0, 1, 0, 2, 0, 2, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 2, 0, 0, 0, 0, 1, 1, -1, 1, 2, 0, 0, 0, 0, 1, -1, 1, 1, 2, 0, 0, 0, 0, 1, 1, 1, -1, 2, 3, 1, 1, 1, 2, 0, 0, 2, 2, 3, 1, 1, 1, 2, 2, 0, 0, 2, 3, 1, 1, 1, 2, 0, 2, 0, 2, 1, 1, -1, 1, 2, 0, 0, 2, 2, 1, 1, -1, 1, 2, 2, 0, 0, 2, 1, -1, 1, 1, 2, 0, 0, 2, 2, 1, -1, 1, 1, 2, 0, 2, 0, 2, 1, 1, 1, -1, 2, 2, 0, 0, 2, 1, 1, 1, -1, 2, 0, 2, 0 }; int[] lookupPairs3D = new int[] { 0, 2, 1, 1, 2, 2, 5, 1, 6, 0, 7, 0, 32, 2, 34, 2, 129, 1, 133, 1, 160, 5, 161, 5, 518, 0, 519, 0, 546, 4, 550, 4, 645, 3, 647, 3, 672, 5, 673, 5, 674, 4, 677, 3, 678, 4, 679, 3, 680, 13, 681, 13, 682, 12, 685, 14, 686, 12, 687, 14, 712, 20, 714, 18, 809, 21, 813, 23, 840, 20, 841, 21, 1198, 19, 1199, 22, 1226, 18, 1230, 19, 1325, 23, 1327, 22, 1352, 15, 1353, 17, 1354, 15, 1357, 17, 1358, 16, 1359, 16, 1360, 11, 1361, 10, 1362, 11, 1365, 10, 1366, 9, 1367, 9, 1392, 11, 1394, 11, 1489, 10, 1493, 10, 1520, 8, 1521, 8, 1878, 9, 1879, 9, 1906, 7, 1910, 7, 2005, 6, 2007, 6, 2032, 8, 2033, 8, 2034, 7, 2037, 6, 2038, 7, 2039, 6 }; Contribution3[] contributions3D = new Contribution3[p3D.length / 9]; for (int i = 0; i < p3D.length; i += 9) { int[] baseSet = base3D[p3D[i]]; Contribution3 previous = null, current = null; for (int k = 0; k < baseSet.length; k += 4) { current = new Contribution3(baseSet[k], baseSet[k + 1], baseSet[k + 2], baseSet[k + 3]); if (previous == null) { contributions3D[i / 9] = current; } else { previous.next = current; } previous = current; } current.next = new Contribution3(p3D[i + 1], p3D[i + 2], p3D[i + 3], p3D[i + 4]); current.next.next = new Contribution3(p3D[i + 5], p3D[i + 6], p3D[i + 7], p3D[i + 8]); } LOOKUP_3D = new Contribution3[2048]; for (int i = 0; i < lookupPairs3D.length; i += 2) { LOOKUP_3D[lookupPairs3D[i]] = contributions3D[lookupPairs3D[i + 1]]; } int[][] base4D = new int[][] { new int[] { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1 }, new int[] { 3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 4, 1, 1, 1, 1 }, new int[] { 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1 }, new int[] { 3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1 } }; int[] p4D = new int[] { 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 2, 1, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 0, 2, 0, 1, 1, 0, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 2, 1, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 2, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 2, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 1, 4, 2, 1, 1, 0, 4, 1, 2, 1, 0, 4, 1, 1, 2, 0, 1, 4, 2, 1, 0, 1, 4, 1, 2, 0, 1, 4, 1, 1, 0, 2, 1, 4, 2, 0, 1, 1, 4, 1, 0, 2, 1, 4, 1, 0, 1, 2, 1, 4, 0, 2, 1, 1, 4, 0, 1, 2, 1, 4, 0, 1, 1, 2, 1, 2, 1, 1, 0, 0, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 1, 2, 1, 0, 1, 0, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 1, 2, 0, 1, 1, 0, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 1, 2, 1, 0, 0, 1, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 1, 2, 0, 1, 0, 1, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 1, 2, 0, 0, 1, 1, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 2, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 2, 0, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 2, 0, 0, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 0, 2, 0, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 0, 0, 2, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 0, 2, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 0, 2, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 0, 0, 0, 0, 0, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 2, 0, 0, 0, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 0, 2, 0, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 2, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 0, 2, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, 1, -1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, 1, -1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, 1, 1, -1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, 1, -1, 1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, -1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 4, 1, 1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 4, 1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, 1, -1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 2, 1, 1, 1, -1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, 1, 1, 1, -1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, -1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, 1, -1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 2, 1, 1, -1, 1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 2, 1, -1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, -1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 1, -1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, -1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 2, -1, 1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, -1, 1, 1, 1 }; int[] lookupPairs4D = new int[] { 0, 3, 1, 2, 2, 3, 5, 2, 6, 1, 7, 1, 8, 3, 9, 2, 10, 3, 13, 2, 16, 3, 18, 3, 22, 1, 23, 1, 24, 3, 26, 3, 33, 2, 37, 2, 38, 1, 39, 1, 41, 2, 45, 2, 54, 1, 55, 1, 56, 0, 57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 256, 3, 258, 3, 264, 3, 266, 3, 272, 3, 274, 3, 280, 3, 282, 3, 2049, 2, 2053, 2, 2057, 2, 2061, 2, 2081, 2, 2085, 2, 2089, 2, 2093, 2, 2304, 9, 2305, 9, 2312, 9, 2313, 9, 16390, 1, 16391, 1, 16406, 1, 16407, 1, 16422, 1, 16423, 1, 16438, 1, 16439, 1, 16642, 8, 16646, 8, 16658, 8, 16662, 8, 18437, 6, 18439, 6, 18469, 6, 18471, 6, 18688, 9, 18689, 9, 18690, 8, 18693, 6, 18694, 8, 18695, 6, 18696, 9, 18697, 9, 18706, 8, 18710, 8, 18725, 6, 18727, 6, 131128, 0, 131129, 0, 131130, 0, 131131, 0, 131132, 0, 131133, 0, 131134, 0, 131135, 0, 131352, 7, 131354, 7, 131384, 7, 131386, 7, 133161, 5, 133165, 5, 133177, 5, 133181, 5, 133376, 9, 133377, 9, 133384, 9, 133385, 9, 133400, 7, 133402, 7, 133417, 5, 133421, 5, 133432, 7, 133433, 5, 133434, 7, 133437, 5, 147510, 4, 147511, 4, 147518, 4, 147519, 4, 147714, 8, 147718, 8, 147730, 8, 147734, 8, 147736, 7, 147738, 7, 147766, 4, 147767, 4, 147768, 7, 147770, 7, 147774, 4, 147775, 4, 149509, 6, 149511, 6, 149541, 6, 149543, 6, 149545, 5, 149549, 5, 149558, 4, 149559, 4, 149561, 5, 149565, 5, 149566, 4, 149567, 4, 149760, 9, 149761, 9, 149762, 8, 149765, 6, 149766, 8, 149767, 6, 149768, 9, 149769, 9, 149778, 8, 149782, 8, 149784, 7, 149786, 7, 149797, 6, 149799, 6, 149801, 5, 149805, 5, 149814, 4, 149815, 4, 149816, 7, 149817, 5, 149818, 7, 149821, 5, 149822, 4, 149823, 4, 149824, 37, 149825, 37, 149826, 36, 149829, 34, 149830, 36, 149831, 34, 149832, 37, 149833, 37, 149842, 36, 149846, 36, 149848, 35, 149850, 35, 149861, 34, 149863, 34, 149865, 33, 149869, 33, 149878, 32, 149879, 32, 149880, 35, 149881, 33, 149882, 35, 149885, 33, 149886, 32, 149887, 32, 150080, 49, 150082, 48, 150088, 49, 150098, 48, 150104, 47, 150106, 47, 151873, 46, 151877, 45, 151881, 46, 151909, 45, 151913, 44, 151917, 44, 152128, 49, 152129, 46, 152136, 49, 152137, 46, 166214, 43, 166215, 42, 166230, 43, 166247, 42, 166262, 41, 166263, 41, 166466, 48, 166470, 43, 166482, 48, 166486, 43, 168261, 45, 168263, 42, 168293, 45, 168295, 42, 168512, 31, 168513, 28, 168514, 31, 168517, 28, 168518, 25, 168519, 25, 280952, 40, 280953, 39, 280954, 40, 280957, 39, 280958, 38, 280959, 38, 281176, 47, 281178, 47, 281208, 40, 281210, 40, 282985, 44, 282989, 44, 283001, 39, 283005, 39, 283208, 30, 283209, 27, 283224, 30, 283241, 27, 283256, 22, 283257, 22, 297334, 41, 297335, 41, 297342, 38, 297343, 38, 297554, 29, 297558, 24, 297562, 29, 297590, 24, 297594, 21, 297598, 21, 299365, 26, 299367, 23, 299373, 26, 299383, 23, 299389, 20, 299391, 20, 299584, 31, 299585, 28, 299586, 31, 299589, 28, 299590, 25, 299591, 25, 299592, 30, 299593, 27, 299602, 29, 299606, 24, 299608, 30, 299610, 29, 299621, 26, 299623, 23, 299625, 27, 299629, 26, 299638, 24, 299639, 23, 299640, 22, 299641, 22, 299642, 21, 299645, 20, 299646, 21, 299647, 20, 299648, 61, 299649, 60, 299650, 61, 299653, 60, 299654, 59, 299655, 59, 299656, 58, 299657, 57, 299666, 55, 299670, 54, 299672, 58, 299674, 55, 299685, 52, 299687, 51, 299689, 57, 299693, 52, 299702, 54, 299703, 51, 299704, 56, 299705, 56, 299706, 53, 299709, 50, 299710, 53, 299711, 50, 299904, 61, 299906, 61, 299912, 58, 299922, 55, 299928, 58, 299930, 55, 301697, 60, 301701, 60, 301705, 57, 301733, 52, 301737, 57, 301741, 52, 301952, 79, 301953, 79, 301960, 76, 301961, 76, 316038, 59, 316039, 59, 316054, 54, 316071, 51, 316086, 54, 316087, 51, 316290, 78, 316294, 78, 316306, 73, 316310, 73, 318085, 77, 318087, 77, 318117, 70, 318119, 70, 318336, 79, 318337, 79, 318338, 78, 318341, 77, 318342, 78, 318343, 77, 430776, 56, 430777, 56, 430778, 53, 430781, 50, 430782, 53, 430783, 50, 431000, 75, 431002, 72, 431032, 75, 431034, 72, 432809, 74, 432813, 69, 432825, 74, 432829, 69, 433032, 76, 433033, 76, 433048, 75, 433065, 74, 433080, 75, 433081, 74, 447158, 71, 447159, 68, 447166, 71, 447167, 68, 447378, 73, 447382, 73, 447386, 72, 447414, 71, 447418, 72, 447422, 71, 449189, 70, 449191, 70, 449197, 69, 449207, 68, 449213, 69, 449215, 68, 449408, 67, 449409, 67, 449410, 66, 449413, 64, 449414, 66, 449415, 64, 449416, 67, 449417, 67, 449426, 66, 449430, 66, 449432, 65, 449434, 65, 449445, 64, 449447, 64, 449449, 63, 449453, 63, 449462, 62, 449463, 62, 449464, 65, 449465, 63, 449466, 65, 449469, 63, 449470, 62, 449471, 62, 449472, 19, 449473, 19, 449474, 18, 449477, 16, 449478, 18, 449479, 16, 449480, 19, 449481, 19, 449490, 18, 449494, 18, 449496, 17, 449498, 17, 449509, 16, 449511, 16, 449513, 15, 449517, 15, 449526, 14, 449527, 14, 449528, 17, 449529, 15, 449530, 17, 449533, 15, 449534, 14, 449535, 14, 449728, 19, 449729, 19, 449730, 18, 449734, 18, 449736, 19, 449737, 19, 449746, 18, 449750, 18, 449752, 17, 449754, 17, 449784, 17, 449786, 17, 451520, 19, 451521, 19, 451525, 16, 451527, 16, 451528, 19, 451529, 19, 451557, 16, 451559, 16, 451561, 15, 451565, 15, 451577, 15, 451581, 15, 451776, 19, 451777, 19, 451784, 19, 451785, 19, 465858, 18, 465861, 16, 465862, 18, 465863, 16, 465874, 18, 465878, 18, 465893, 16, 465895, 16, 465910, 14, 465911, 14, 465918, 14, 465919, 14, 466114, 18, 466118, 18, 466130, 18, 466134, 18, 467909, 16, 467911, 16, 467941, 16, 467943, 16, 468160, 13, 468161, 13, 468162, 13, 468163, 13, 468164, 13, 468165, 13, 468166, 13, 468167, 13, 580568, 17, 580570, 17, 580585, 15, 580589, 15, 580598, 14, 580599, 14, 580600, 17, 580601, 15, 580602, 17, 580605, 15, 580606, 14, 580607, 14, 580824, 17, 580826, 17, 580856, 17, 580858, 17, 582633, 15, 582637, 15, 582649, 15, 582653, 15, 582856, 12, 582857, 12, 582872, 12, 582873, 12, 582888, 12, 582889, 12, 582904, 12, 582905, 12, 596982, 14, 596983, 14, 596990, 14, 596991, 14, 597202, 11, 597206, 11, 597210, 11, 597214, 11, 597234, 11, 597238, 11, 597242, 11, 597246, 11, 599013, 10, 599015, 10, 599021, 10, 599023, 10, 599029, 10, 599031, 10, 599037, 10, 599039, 10, 599232, 13, 599233, 13, 599234, 13, 599235, 13, 599236, 13, 599237, 13, 599238, 13, 599239, 13, 599240, 12, 599241, 12, 599250, 11, 599254, 11, 599256, 12, 599257, 12, 599258, 11, 599262, 11, 599269, 10, 599271, 10, 599272, 12, 599273, 12, 599277, 10, 599279, 10, 599282, 11, 599285, 10, 599286, 11, 599287, 10, 599288, 12, 599289, 12, 599290, 11, 599293, 10, 599294, 11, 599295, 10 }; Contribution4[] contributions4D = new Contribution4[p4D.length / 16]; for (int i = 0; i < p4D.length; i += 16) { int[] baseSet = base4D[p4D[i]]; Contribution4 previous = null, current = null; for (int k = 0; k < baseSet.length; k += 5) { current = new Contribution4(baseSet[k], baseSet[k + 1], baseSet[k + 2], baseSet[k + 3], baseSet[k + 4]); if (previous == null) { contributions4D[i / 16] = current; } else { previous.next = current; } previous = current; } current.next = new Contribution4(p4D[i + 1], p4D[i + 2], p4D[i + 3], p4D[i + 4], p4D[i + 5]); current.next.next = new Contribution4(p4D[i + 6], p4D[i + 7], p4D[i + 8], p4D[i + 9], p4D[i + 10]); current.next.next.next = new Contribution4(p4D[i + 11], p4D[i + 12], p4D[i + 13], p4D[i + 14], p4D[i + 15]); } LOOKUP_4D = new Contribution4[1048576]; for (int i = 0; i < lookupPairs4D.length; i += 2) { LOOKUP_4D[lookupPairs4D[i]] = contributions4D[lookupPairs4D[i + 1]]; } } } ================================================ FILE: _old/java/legacy/UNLICENSE ================================================ This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. 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 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. For more information, please refer to ================================================ FILE: _old/java/legacy_unoptimized/OpenSimplexUnoptimized.java ================================================ /** * K.jpg's original OpenSimplex Noise, unoptimized version * With updated gradient sets (Dec 2019, Feb 2020) * This is mostly provided for reference and sake of completeness. * * If 4D noise is not needed, is recommended to use OpenSimplex2 instead. * Choose OpenSimplex2S for comparable smoothness, or choose OpenSimplex2F for speed. * If 4D noise is needed, it is recommended to use the optimized OpenSimplex instead, at the current time. * * XYBeforeZ and XZBeforeY functions for 3D have been added, though they aren't as nice as in OpenSimplex2 * XYBeforeZ replaces "PlaneFirst" which was added in Dec 2019, and XZBeforeY is similar. */ public class OpenSimplexUnoptimized { private static final double STRETCH_CONSTANT_2D = -0.211324865405187; // (1/Math.sqrt(2+1)-1)/2; private static final double SQUISH_CONSTANT_2D = 0.366025403784439; // (Math.sqrt(2+1)-1)/2; private static final double STRETCH_CONSTANT_3D = -1.0 / 6; // (1/Math.sqrt(3+1)-1)/3; private static final double SQUISH_CONSTANT_3D = 1.0 / 3; // (Math.sqrt(3+1)-1)/3; private static final double STRETCH_CONSTANT_4D = -0.138196601125011; // (1/Math.sqrt(4+1)-1)/4; private static final double SQUISH_CONSTANT_4D = 0.309016994374947; // (Math.sqrt(4+1)-1)/4; private static final long DEFAULT_SEED = 0; private static final int PSIZE = 2048; private static final int PMASK = 2047; private short[] perm; private Grad2[] permGrad2; private Grad3[] permGrad3; private Grad4[] permGrad4; public OpenSimplexUnoptimized() { this(DEFAULT_SEED); } public OpenSimplexUnoptimized(short[] perm) { this.perm = perm; permGrad2 = new Grad2[PSIZE]; permGrad3 = new Grad3[PSIZE]; permGrad4 = new Grad4[PSIZE]; for (int i = 0; i < PSIZE; i++) { permGrad2[i] = GRADIENTS_2D[perm[i]]; permGrad3[i] = GRADIENTS_3D[perm[i]]; permGrad4[i] = GRADIENTS_4D[perm[i]]; } } public OpenSimplexUnoptimized(long seed) { perm = new short[PSIZE]; permGrad2 = new Grad2[PSIZE]; permGrad3 = new Grad3[PSIZE]; permGrad4 = new Grad4[PSIZE]; short[] source = new short[PSIZE]; for (short i = 0; i < PSIZE; i++) source[i] = i; for (int i = PSIZE - 1; i >= 0; i--) { seed = seed * 6364136223846793005L + 1442695040888963407L; int r = (int)((seed + 31) % (i + 1)); if (r < 0) r += (i + 1); perm[i] = source[r]; permGrad2[i] = GRADIENTS_2D[perm[i]]; permGrad3[i] = GRADIENTS_3D[perm[i]]; permGrad4[i] = GRADIENTS_4D[perm[i]]; source[r] = source[i]; } } // 2D OpenSimplex Noise. public double eval(double x, double y) { // Place input coordinates onto grid. double stretchOffset = (x + y) * STRETCH_CONSTANT_2D; double xs = x + stretchOffset; double ys = y + stretchOffset; // Floor to get grid coordinates of rhombus (stretched square) super-cell origin. int xsb = fastFloor(xs); int ysb = fastFloor(ys); // Compute grid coordinates relative to rhombus origin. double xins = xs - xsb; double yins = ys - ysb; // Sum those together to get a value that determines which region we're in. double inSum = xins + yins; // Positions relative to origin point. double squishOffsetIns = inSum * SQUISH_CONSTANT_2D; double dx0 = xins + squishOffsetIns; double dy0 = yins + squishOffsetIns; // We'll be defining these inside the next block and using them afterwards. double dx_ext, dy_ext; int xsv_ext, ysv_ext; double value = 0; // Contribution (1,0) double dx1 = dx0 - 1 - SQUISH_CONSTANT_2D; double dy1 = dy0 - 0 - SQUISH_CONSTANT_2D; double attn1 = 2 - dx1 * dx1 - dy1 * dy1; if (attn1 > 0) { attn1 *= attn1; value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, dx1, dy1); } // Contribution (0,1) double dx2 = dx0 - 0 - SQUISH_CONSTANT_2D; double dy2 = dy0 - 1 - SQUISH_CONSTANT_2D; double attn2 = 2 - dx2 * dx2 - dy2 * dy2; if (attn2 > 0) { attn2 *= attn2; value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, dx2, dy2); } if (inSum <= 1) { // We're inside the triangle (2-Simplex) at (0,0) double zins = 1 - inSum; if (zins > xins || zins > yins) { // (0,0) is one of the closest two triangular vertices if (xins > yins) { xsv_ext = xsb + 1; ysv_ext = ysb - 1; dx_ext = dx0 - 1; dy_ext = dy0 + 1; } else { xsv_ext = xsb - 1; ysv_ext = ysb + 1; dx_ext = dx0 + 1; dy_ext = dy0 - 1; } } else { // (1,0) and (0,1) are the closest two vertices. xsv_ext = xsb + 1; ysv_ext = ysb + 1; dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; } } else { // We're inside the triangle (2-Simplex) at (1,1) double zins = 2 - inSum; if (zins < xins || zins < yins) { // (0,0) is one of the closest two triangular vertices if (xins > yins) { xsv_ext = xsb + 2; ysv_ext = ysb + 0; dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D; dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D; } else { xsv_ext = xsb + 0; ysv_ext = ysb + 2; dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D; dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D; } } else { // (1,0) and (0,1) are the closest two vertices. dx_ext = dx0; dy_ext = dy0; xsv_ext = xsb; ysv_ext = ysb; } xsb += 1; ysb += 1; dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; } // Contribution (0,0) or (1,1) double attn0 = 2 - dx0 * dx0 - dy0 * dy0; if (attn0 > 0) { attn0 *= attn0; value += attn0 * attn0 * extrapolate(xsb, ysb, dx0, dy0); } // Extra Vertex double attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext; if (attn_ext > 0) { attn_ext *= attn_ext; value += attn_ext * attn_ext * extrapolate(xsv_ext, ysv_ext, dx_ext, dy_ext); } return value; } // 3D OpenSimplex Noise. public double eval(double x, double y, double z) { // Place input coordinates on simplectic honeycomb. double stretchOffset = (x + y + z) * STRETCH_CONSTANT_3D; double xs = x + stretchOffset; double ys = y + stretchOffset; double zs = z + stretchOffset; return eval3_Base(xs, ys, zs); } // Not as good as in SuperSimplex/OpenSimplex2S, since there are more visible differences between different slices. // The Z coordinate should always be the "different" coordinate in your use case. public double eval3_XYBeforeZ(double x, double y, double z) { // Combine rotation with skew transform. double xy = x + y; double s2 = xy * 0.211324865405187; double zz = z * 0.288675134594813; double xs = s2 - x + zz, ys = s2 - y + zz; double zs = xy * 0.577350269189626 + zz; return eval3_Base(xs, ys, zs); } // Similar to the above, except the Y coordinate should always be the "different" coordinate in your use case. public double eval3_XZBeforeY(double x, double y, double z) { // Combine rotation with skew transform. double xz = x + z; double s2 = xz * 0.211324865405187; double yy = y * 0.288675134594813; double xs = s2 - x + yy, zs = s2 - z + yy; double ys = xz * 0.577350269189626 + yy; return eval3_Base(xs, ys, zs); } // 3D OpenSimplex Noise (base which takes skewed coordinates directly). private double eval3_Base(double xs, double ys, double zs) { // Floor to get simplectic honeycomb coordinates of rhombohedron (stretched cube) super-cell origin. int xsb = fastFloor(xs); int ysb = fastFloor(ys); int zsb = fastFloor(zs); // Compute simplectic honeycomb coordinates relative to rhombohedral origin. double xins = xs - xsb; double yins = ys - ysb; double zins = zs - zsb; // Sum those together to get a value that determines which region we're in. double inSum = xins + yins + zins; // Positions relative to origin point. double squishOffsetIns = inSum * SQUISH_CONSTANT_3D; double dx0 = xins + squishOffsetIns; double dy0 = yins + squishOffsetIns; double dz0 = zins + squishOffsetIns; // We'll be defining these inside the next block and using them afterwards. double dx_ext0, dy_ext0, dz_ext0; double dx_ext1, dy_ext1, dz_ext1; int xsv_ext0, ysv_ext0, zsv_ext0; int xsv_ext1, ysv_ext1, zsv_ext1; double value = 0; if (inSum <= 1) { // We're inside the tetrahedron (3-Simplex) at (0,0,0) // Determine which two of (0,0,1), (0,1,0), (1,0,0) are closest. byte aPoint = 0x01; double aScore = xins; byte bPoint = 0x02; double bScore = yins; if (aScore >= bScore && zins > bScore) { bScore = zins; bPoint = 0x04; } else if (aScore < bScore && zins > aScore) { aScore = zins; aPoint = 0x04; } // Now we determine the two lattice points not part of the tetrahedron that may contribute. // This depends on the closest two tetrahedral vertices, including (0,0,0) double wins = 1 - inSum; if (wins > aScore || wins > bScore) { // (0,0,0) is one of the closest two tetrahedral vertices. byte c = (bScore > aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b. if ((c & 0x01) == 0) { xsv_ext0 = xsb - 1; xsv_ext1 = xsb; dx_ext0 = dx0 + 1; dx_ext1 = dx0; } else { xsv_ext0 = xsv_ext1 = xsb + 1; dx_ext0 = dx_ext1 = dx0 - 1; } if ((c & 0x02) == 0) { ysv_ext0 = ysv_ext1 = ysb; dy_ext0 = dy_ext1 = dy0; if ((c & 0x01) == 0) { ysv_ext1 -= 1; dy_ext1 += 1; } else { ysv_ext0 -= 1; dy_ext0 += 1; } } else { ysv_ext0 = ysv_ext1 = ysb + 1; dy_ext0 = dy_ext1 = dy0 - 1; } if ((c & 0x04) == 0) { zsv_ext0 = zsb; zsv_ext1 = zsb - 1; dz_ext0 = dz0; dz_ext1 = dz0 + 1; } else { zsv_ext0 = zsv_ext1 = zsb + 1; dz_ext0 = dz_ext1 = dz0 - 1; } } else { // (0,0,0) is not one of the closest two tetrahedral vertices. byte c = (byte)(aPoint | bPoint); // Our two extra vertices are determined by the closest two. if ((c & 0x01) == 0) { xsv_ext0 = xsb; xsv_ext1 = xsb - 1; dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_3D; dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; } else { xsv_ext0 = xsv_ext1 = xsb + 1; dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; } if ((c & 0x02) == 0) { ysv_ext0 = ysb; ysv_ext1 = ysb - 1; dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_3D; dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; } else { ysv_ext0 = ysv_ext1 = ysb + 1; dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; } if ((c & 0x04) == 0) { zsv_ext0 = zsb; zsv_ext1 = zsb - 1; dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_3D; dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; } else { zsv_ext0 = zsv_ext1 = zsb + 1; dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; } } // Contribution (0,0,0) double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; if (attn0 > 0) { attn0 *= attn0; value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, dx0, dy0, dz0); } // Contribution (1,0,0) double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; if (attn1 > 0) { attn1 *= attn1; value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); } // Contribution (0,1,0) double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; double dz2 = dz1; double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; if (attn2 > 0) { attn2 *= attn2; value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); } // Contribution (0,0,1) double dx3 = dx2; double dy3 = dy1; double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; if (attn3 > 0) { attn3 *= attn3; value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); } } else if (inSum >= 2) { // We're inside the tetrahedron (3-Simplex) at (1,1,1) // Determine which two tetrahedral vertices are the closest, out of (1,1,0), (1,0,1), (0,1,1) but not (1,1,1). byte aPoint = 0x06; double aScore = xins; byte bPoint = 0x05; double bScore = yins; if (aScore <= bScore && zins < bScore) { bScore = zins; bPoint = 0x03; } else if (aScore > bScore && zins < aScore) { aScore = zins; aPoint = 0x03; } // Now we determine the two lattice points not part of the tetrahedron that may contribute. // This depends on the closest two tetrahedral vertices, including (1,1,1) double wins = 3 - inSum; if (wins < aScore || wins < bScore) { // (1,1,1) is one of the closest two tetrahedral vertices. byte c = (bScore < aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b. if ((c & 0x01) != 0) { xsv_ext0 = xsb + 2; xsv_ext1 = xsb + 1; dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_3D; dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; } else { xsv_ext0 = xsv_ext1 = xsb; dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_3D; } if ((c & 0x02) != 0) { ysv_ext0 = ysv_ext1 = ysb + 1; dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; if ((c & 0x01) != 0) { ysv_ext1 += 1; dy_ext1 -= 1; } else { ysv_ext0 += 1; dy_ext0 -= 1; } } else { ysv_ext0 = ysv_ext1 = ysb; dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_3D; } if ((c & 0x04) != 0) { zsv_ext0 = zsb + 1; zsv_ext1 = zsb + 2; dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 2 - 3 * SQUISH_CONSTANT_3D; } else { zsv_ext0 = zsv_ext1 = zsb; dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_3D; } } else { // (1,1,1) is not one of the closest two tetrahedral vertices. byte c = (byte)(aPoint & bPoint); // Our two extra vertices are determined by the closest two. if ((c & 0x01) != 0) { xsv_ext0 = xsb + 1; xsv_ext1 = xsb + 2; dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; } else { xsv_ext0 = xsv_ext1 = xsb; dx_ext0 = dx0 - SQUISH_CONSTANT_3D; dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; } if ((c & 0x02) != 0) { ysv_ext0 = ysb + 1; ysv_ext1 = ysb + 2; dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; } else { ysv_ext0 = ysv_ext1 = ysb; dy_ext0 = dy0 - SQUISH_CONSTANT_3D; dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; } if ((c & 0x04) != 0) { zsv_ext0 = zsb + 1; zsv_ext1 = zsb + 2; dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; } else { zsv_ext0 = zsv_ext1 = zsb; dz_ext0 = dz0 - SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; } } // Contribution (1,1,0) double dx3 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; double dy3 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; double dz3 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; if (attn3 > 0) { attn3 *= attn3; value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx3, dy3, dz3); } // Contribution (1,0,1) double dx2 = dx3; double dy2 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; double dz2 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; if (attn2 > 0) { attn2 *= attn2; value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx2, dy2, dz2); } // Contribution (0,1,1) double dx1 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; double dy1 = dy3; double dz1 = dz2; double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; if (attn1 > 0) { attn1 *= attn1; value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx1, dy1, dz1); } // Contribution (1,1,1) dx0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; dy0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; dz0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; if (attn0 > 0) { attn0 *= attn0; value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, dx0, dy0, dz0); } } else { // We're inside the octahedron (Rectified 3-Simplex) in between. double aScore; byte aPoint; boolean aIsFurtherSide; double bScore; byte bPoint; boolean bIsFurtherSide; // Decide between point (0,0,1) and (1,1,0) as closest double p1 = xins + yins; if (p1 > 1) { aScore = p1 - 1; aPoint = 0x03; aIsFurtherSide = true; } else { aScore = 1 - p1; aPoint = 0x04; aIsFurtherSide = false; } // Decide between point (0,1,0) and (1,0,1) as closest double p2 = xins + zins; if (p2 > 1) { bScore = p2 - 1; bPoint = 0x05; bIsFurtherSide = true; } else { bScore = 1 - p2; bPoint = 0x02; bIsFurtherSide = false; } // The closest out of the two (1,0,0) and (0,1,1) will replace the furthest out of the two decided above, if closer. double p3 = yins + zins; if (p3 > 1) { double score = p3 - 1; if (aScore <= bScore && aScore < score) { aScore = score; aPoint = 0x06; aIsFurtherSide = true; } else if (aScore > bScore && bScore < score) { bScore = score; bPoint = 0x06; bIsFurtherSide = true; } } else { double score = 1 - p3; if (aScore <= bScore && aScore < score) { aScore = score; aPoint = 0x01; aIsFurtherSide = false; } else if (aScore > bScore && bScore < score) { bScore = score; bPoint = 0x01; bIsFurtherSide = false; } } // Where each of the two closest points are determines how the extra two vertices are calculated. if (aIsFurtherSide == bIsFurtherSide) { if (aIsFurtherSide) { // Both closest points on (1,1,1) side // One of the two extra points is (1,1,1) dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; xsv_ext0 = xsb + 1; ysv_ext0 = ysb + 1; zsv_ext0 = zsb + 1; // Other extra point is based on the shared axis. byte c = (byte)(aPoint & bPoint); if ((c & 0x01) != 0) { dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; xsv_ext1 = xsb + 2; ysv_ext1 = ysb; zsv_ext1 = zsb; } else if ((c & 0x02) != 0) { dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; xsv_ext1 = xsb; ysv_ext1 = ysb + 2; zsv_ext1 = zsb; } else { dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; xsv_ext1 = xsb; ysv_ext1 = ysb; zsv_ext1 = zsb + 2; } } else {// Both closest points on (0,0,0) side // One of the two extra points is (0,0,0) dx_ext0 = dx0; dy_ext0 = dy0; dz_ext0 = dz0; xsv_ext0 = xsb; ysv_ext0 = ysb; zsv_ext0 = zsb; // Other extra point is based on the omitted axis. byte c = (byte)(aPoint | bPoint); if ((c & 0x01) == 0) { dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; xsv_ext1 = xsb - 1; ysv_ext1 = ysb + 1; zsv_ext1 = zsb + 1; } else if ((c & 0x02) == 0) { dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; xsv_ext1 = xsb + 1; ysv_ext1 = ysb - 1; zsv_ext1 = zsb + 1; } else { dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; xsv_ext1 = xsb + 1; ysv_ext1 = ysb + 1; zsv_ext1 = zsb - 1; } } } else { // One point on (0,0,0) side, one point on (1,1,1) side byte c1, c2; if (aIsFurtherSide) { c1 = aPoint; c2 = bPoint; } else { c1 = bPoint; c2 = aPoint; } // One contribution is a permutation of (1,1,-1) if ((c1 & 0x01) == 0) { dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_3D; dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; xsv_ext0 = xsb - 1; ysv_ext0 = ysb + 1; zsv_ext0 = zsb + 1; } else if ((c1 & 0x02) == 0) { dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; dy_ext0 = dy0 + 1 - SQUISH_CONSTANT_3D; dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; xsv_ext0 = xsb + 1; ysv_ext0 = ysb - 1; zsv_ext0 = zsb + 1; } else { dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; dz_ext0 = dz0 + 1 - SQUISH_CONSTANT_3D; xsv_ext0 = xsb + 1; ysv_ext0 = ysb + 1; zsv_ext0 = zsb - 1; } // One contribution is a permutation of (0,0,2) dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; xsv_ext1 = xsb; ysv_ext1 = ysb; zsv_ext1 = zsb; if ((c2 & 0x01) != 0) { dx_ext1 -= 2; xsv_ext1 += 2; } else if ((c2 & 0x02) != 0) { dy_ext1 -= 2; ysv_ext1 += 2; } else { dz_ext1 -= 2; zsv_ext1 += 2; } } // Contribution (1,0,0) double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; if (attn1 > 0) { attn1 *= attn1; value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); } // Contribution (0,1,0) double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; double dz2 = dz1; double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; if (attn2 > 0) { attn2 *= attn2; value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); } // Contribution (0,0,1) double dx3 = dx2; double dy3 = dy1; double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; if (attn3 > 0) { attn3 *= attn3; value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); } // Contribution (1,1,0) double dx4 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; double dy4 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; double dz4 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4; if (attn4 > 0) { attn4 *= attn4; value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx4, dy4, dz4); } // Contribution (1,0,1) double dx5 = dx4; double dy5 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; double dz5 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5; if (attn5 > 0) { attn5 *= attn5; value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx5, dy5, dz5); } // Contribution (0,1,1) double dx6 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; double dy6 = dy4; double dz6 = dz5; double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6; if (attn6 > 0) { attn6 *= attn6; value += attn6 * attn6 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx6, dy6, dz6); } } // First extra vertex double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0; if (attn_ext0 > 0) { attn_ext0 *= attn_ext0; value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, dx_ext0, dy_ext0, dz_ext0); } // Second extra vertex double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1; if (attn_ext1 > 0) { attn_ext1 *= attn_ext1; value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, dx_ext1, dy_ext1, dz_ext1); } return value; } public double eval(double x, double y, double z, double w) { // Get points for A4 lattice double s = -0.138196601125011 * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return eval4_Base(xs, ys, zs, ws); } public double eval4_XYBeforeZW(double x, double y, double z, double w) { double s2 = (x + y) * -0.178275657951399372 + (z + w) * 0.215623393288842828; double t2 = (z + w) * -0.403949762580207112 + (x + y) * -0.375199083010075342; double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; return eval4_Base(xs, ys, zs, ws); } public double eval4_XZBeforeYW(double x, double y, double z, double w) { double s2 = (x + z) * -0.178275657951399372 + (y + w) * 0.215623393288842828; double t2 = (y + w) * -0.403949762580207112 + (x + z) * -0.375199083010075342; double xs = x + s2, ys = y + t2, zs = z + s2, ws = w + t2; return eval4_Base(xs, ys, zs, ws); } public double eval4_XYZBeforeW(double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 0.2236067977499788; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return eval4_Base(xs, ys, zs, ws); } // 4D OpenSimplex Noise. private double eval4_Base(double xs, double ys, double zs, double ws) { // Floor to get simplectic honeycomb coordinates of rhombo-hypercube super-cell origin. int xsb = fastFloor(xs); int ysb = fastFloor(ys); int zsb = fastFloor(zs); int wsb = fastFloor(ws); // Compute simplectic honeycomb coordinates relative to rhombo-hypercube origin. double xins = xs - xsb; double yins = ys - ysb; double zins = zs - zsb; double wins = ws - wsb; // Sum those together to get a value that determines which region we're in. double inSum = xins + yins + zins + wins; // Positions relative to origin point. double squishOffsetIns = inSum * SQUISH_CONSTANT_4D; double dx0 = xins + squishOffsetIns; double dy0 = yins + squishOffsetIns; double dz0 = zins + squishOffsetIns; double dw0 = wins + squishOffsetIns; // We'll be defining these inside the next block and using them afterwards. double dx_ext0, dy_ext0, dz_ext0, dw_ext0; double dx_ext1, dy_ext1, dz_ext1, dw_ext1; double dx_ext2, dy_ext2, dz_ext2, dw_ext2; int xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0; int xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1; int xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2; double value = 0; if (inSum <= 1) { // We're inside the pentachoron (4-Simplex) at (0,0,0,0) // Determine which two of (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0) are closest. byte aPoint = 0x01; double aScore = xins; byte bPoint = 0x02; double bScore = yins; if (aScore >= bScore && zins > bScore) { bScore = zins; bPoint = 0x04; } else if (aScore < bScore && zins > aScore) { aScore = zins; aPoint = 0x04; } if (aScore >= bScore && wins > bScore) { bScore = wins; bPoint = 0x08; } else if (aScore < bScore && wins > aScore) { aScore = wins; aPoint = 0x08; } // Now we determine the three lattice points not part of the pentachoron that may contribute. // This depends on the closest two pentachoron vertices, including (0,0,0,0) double uins = 1 - inSum; if (uins > aScore || uins > bScore) { // (0,0,0,0) is one of the closest two pentachoron vertices. byte c = (bScore > aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b. if ((c & 0x01) == 0) { xsv_ext0 = xsb - 1; xsv_ext1 = xsv_ext2 = xsb; dx_ext0 = dx0 + 1; dx_ext1 = dx_ext2 = dx0; } else { xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1; dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 1; } if ((c & 0x02) == 0) { ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; dy_ext0 = dy_ext1 = dy_ext2 = dy0; if ((c & 0x01) == 0x01) { ysv_ext0 -= 1; dy_ext0 += 1; } else { ysv_ext1 -= 1; dy_ext1 += 1; } } else { ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1; } if ((c & 0x04) == 0) { zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; dz_ext0 = dz_ext1 = dz_ext2 = dz0; if ((c & 0x03) != 0) { if ((c & 0x03) == 0x03) { zsv_ext0 -= 1; dz_ext0 += 1; } else { zsv_ext1 -= 1; dz_ext1 += 1; } } else { zsv_ext2 -= 1; dz_ext2 += 1; } } else { zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1; } if ((c & 0x08) == 0) { wsv_ext0 = wsv_ext1 = wsb; wsv_ext2 = wsb - 1; dw_ext0 = dw_ext1 = dw0; dw_ext2 = dw0 + 1; } else { wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1; dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 1; } } else { // (0,0,0,0) is not one of the closest two pentachoron vertices. byte c = (byte)(aPoint | bPoint); // Our three extra vertices are determined by the closest two. if ((c & 0x01) == 0) { xsv_ext0 = xsv_ext2 = xsb; xsv_ext1 = xsb - 1; dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D; dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_4D; dx_ext2 = dx0 - SQUISH_CONSTANT_4D; } else { xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1; dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; dx_ext1 = dx_ext2 = dx0 - 1 - SQUISH_CONSTANT_4D; } if ((c & 0x02) == 0) { ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D; dy_ext1 = dy_ext2 = dy0 - SQUISH_CONSTANT_4D; if ((c & 0x01) == 0x01) { ysv_ext1 -= 1; dy_ext1 += 1; } else { ysv_ext2 -= 1; dy_ext2 += 1; } } else { ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; dy_ext1 = dy_ext2 = dy0 - 1 - SQUISH_CONSTANT_4D; } if ((c & 0x04) == 0) { zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D; dz_ext1 = dz_ext2 = dz0 - SQUISH_CONSTANT_4D; if ((c & 0x03) == 0x03) { zsv_ext1 -= 1; dz_ext1 += 1; } else { zsv_ext2 -= 1; dz_ext2 += 1; } } else { zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; dz_ext1 = dz_ext2 = dz0 - 1 - SQUISH_CONSTANT_4D; } if ((c & 0x08) == 0) { wsv_ext0 = wsv_ext1 = wsb; wsv_ext2 = wsb - 1; dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D; dw_ext1 = dw0 - SQUISH_CONSTANT_4D; dw_ext2 = dw0 + 1 - SQUISH_CONSTANT_4D; } else { wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1; dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; dw_ext1 = dw_ext2 = dw0 - 1 - SQUISH_CONSTANT_4D; } } // Contribution (0,0,0,0) double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0; if (attn0 > 0) { attn0 *= attn0; value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 0, dx0, dy0, dz0, dw0); } // Contribution (1,0,0,0) double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D; double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D; double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D; double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D; double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; if (attn1 > 0) { attn1 *= attn1; value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1); } // Contribution (0,1,0,0) double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D; double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D; double dz2 = dz1; double dw2 = dw1; double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; if (attn2 > 0) { attn2 *= attn2; value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2); } // Contribution (0,0,1,0) double dx3 = dx2; double dy3 = dy1; double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D; double dw3 = dw1; double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; if (attn3 > 0) { attn3 *= attn3; value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3); } // Contribution (0,0,0,1) double dx4 = dx2; double dy4 = dy1; double dz4 = dz1; double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D; double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; if (attn4 > 0) { attn4 *= attn4; value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4); } } else if (inSum >= 3) { // We're inside the pentachoron (4-Simplex) at (1,1,1,1) // Determine which two of (1,1,1,0), (1,1,0,1), (1,0,1,1), (0,1,1,1) are closest. byte aPoint = 0x0E; double aScore = xins; byte bPoint = 0x0D; double bScore = yins; if (aScore <= bScore && zins < bScore) { bScore = zins; bPoint = 0x0B; } else if (aScore > bScore && zins < aScore) { aScore = zins; aPoint = 0x0B; } if (aScore <= bScore && wins < bScore) { bScore = wins; bPoint = 0x07; } else if (aScore > bScore && wins < aScore) { aScore = wins; aPoint = 0x07; } // Now we determine the three lattice points not part of the pentachoron that may contribute. // This depends on the closest two pentachoron vertices, including (0,0,0,0) double uins = 4 - inSum; if (uins < aScore || uins < bScore) { // (1,1,1,1) is one of the closest two pentachoron vertices. byte c = (bScore < aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b. if ((c & 0x01) != 0) { xsv_ext0 = xsb + 2; xsv_ext1 = xsv_ext2 = xsb + 1; dx_ext0 = dx0 - 2 - 4 * SQUISH_CONSTANT_4D; dx_ext1 = dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; } else { xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb; dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 4 * SQUISH_CONSTANT_4D; } if ((c & 0x02) != 0) { ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; if ((c & 0x01) != 0) { ysv_ext1 += 1; dy_ext1 -= 1; } else { ysv_ext0 += 1; dy_ext0 -= 1; } } else { ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 4 * SQUISH_CONSTANT_4D; } if ((c & 0x04) != 0) { zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; if ((c & 0x03) != 0x03) { if ((c & 0x03) == 0) { zsv_ext0 += 1; dz_ext0 -= 1; } else { zsv_ext1 += 1; dz_ext1 -= 1; } } else { zsv_ext2 += 1; dz_ext2 -= 1; } } else { zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 4 * SQUISH_CONSTANT_4D; } if ((c & 0x08) != 0) { wsv_ext0 = wsv_ext1 = wsb + 1; wsv_ext2 = wsb + 2; dw_ext0 = dw_ext1 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; dw_ext2 = dw0 - 2 - 4 * SQUISH_CONSTANT_4D; } else { wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb; dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 4 * SQUISH_CONSTANT_4D; } } else { // (1,1,1,1) is not one of the closest two pentachoron vertices. byte c = (byte)(aPoint & bPoint); // Our three extra vertices are determined by the closest two. if ((c & 0x01) != 0) { xsv_ext0 = xsv_ext2 = xsb + 1; xsv_ext1 = xsb + 2; dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; dx_ext1 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; dx_ext2 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; } else { xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb; dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D; dx_ext1 = dx_ext2 = dx0 - 3 * SQUISH_CONSTANT_4D; } if ((c & 0x02) != 0) { ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; dy_ext1 = dy_ext2 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; if ((c & 0x01) != 0) { ysv_ext2 += 1; dy_ext2 -= 1; } else { ysv_ext1 += 1; dy_ext1 -= 1; } } else { ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D; dy_ext1 = dy_ext2 = dy0 - 3 * SQUISH_CONSTANT_4D; } if ((c & 0x04) != 0) { zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; dz_ext1 = dz_ext2 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; if ((c & 0x03) != 0) { zsv_ext2 += 1; dz_ext2 -= 1; } else { zsv_ext1 += 1; dz_ext1 -= 1; } } else { zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D; dz_ext1 = dz_ext2 = dz0 - 3 * SQUISH_CONSTANT_4D; } if ((c & 0x08) != 0) { wsv_ext0 = wsv_ext1 = wsb + 1; wsv_ext2 = wsb + 2; dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; dw_ext1 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; dw_ext2 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; } else { wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb; dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D; dw_ext1 = dw_ext2 = dw0 - 3 * SQUISH_CONSTANT_4D; } } // Contribution (1,1,1,0) double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D; double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; if (attn4 > 0) { attn4 *= attn4; value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4); } // Contribution (1,1,0,1) double dx3 = dx4; double dy3 = dy4; double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D; double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; if (attn3 > 0) { attn3 *= attn3; value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3); } // Contribution (1,0,1,1) double dx2 = dx4; double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D; double dz2 = dz4; double dw2 = dw3; double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; if (attn2 > 0) { attn2 *= attn2; value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2); } // Contribution (0,1,1,1) double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D; double dz1 = dz4; double dy1 = dy4; double dw1 = dw3; double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; if (attn1 > 0) { attn1 *= attn1; value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1); } // Contribution (1,1,1,1) dx0 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; dy0 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; dz0 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; dw0 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0; if (attn0 > 0) { attn0 *= attn0; value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 1, dx0, dy0, dz0, dw0); } } else if (inSum <= 2) { // We're inside the first dispentachoron (Rectified 4-Simplex) double aScore; byte aPoint; boolean aIsBiggerSide = true; double bScore; byte bPoint; boolean bIsBiggerSide = true; // Decide between (1,1,0,0) and (0,0,1,1) if (xins + yins > zins + wins) { aScore = xins + yins; aPoint = 0x03; } else { aScore = zins + wins; aPoint = 0x0C; } // Decide between (1,0,1,0) and (0,1,0,1) if (xins + zins > yins + wins) { bScore = xins + zins; bPoint = 0x05; } else { bScore = yins + wins; bPoint = 0x0A; } // Closer between (1,0,0,1) and (0,1,1,0) will replace the further of a and b, if closer. if (xins + wins > yins + zins) { double score = xins + wins; if (aScore >= bScore && score > bScore) { bScore = score; bPoint = 0x09; } else if (aScore < bScore && score > aScore) { aScore = score; aPoint = 0x09; } } else { double score = yins + zins; if (aScore >= bScore && score > bScore) { bScore = score; bPoint = 0x06; } else if (aScore < bScore && score > aScore) { aScore = score; aPoint = 0x06; } } // Decide if (1,0,0,0) is closer. double p1 = 2 - inSum + xins; if (aScore >= bScore && p1 > bScore) { bScore = p1; bPoint = 0x01; bIsBiggerSide = false; } else if (aScore < bScore && p1 > aScore) { aScore = p1; aPoint = 0x01; aIsBiggerSide = false; } // Decide if (0,1,0,0) is closer. double p2 = 2 - inSum + yins; if (aScore >= bScore && p2 > bScore) { bScore = p2; bPoint = 0x02; bIsBiggerSide = false; } else if (aScore < bScore && p2 > aScore) { aScore = p2; aPoint = 0x02; aIsBiggerSide = false; } // Decide if (0,0,1,0) is closer. double p3 = 2 - inSum + zins; if (aScore >= bScore && p3 > bScore) { bScore = p3; bPoint = 0x04; bIsBiggerSide = false; } else if (aScore < bScore && p3 > aScore) { aScore = p3; aPoint = 0x04; aIsBiggerSide = false; } // Decide if (0,0,0,1) is closer. double p4 = 2 - inSum + wins; if (aScore >= bScore && p4 > bScore) { bScore = p4; bPoint = 0x08; bIsBiggerSide = false; } else if (aScore < bScore && p4 > aScore) { aScore = p4; aPoint = 0x08; aIsBiggerSide = false; } // Where each of the two closest points are determines how the extra three vertices are calculated. if (aIsBiggerSide == bIsBiggerSide) { if (aIsBiggerSide) { // Both closest points on the bigger side byte c1 = (byte)(aPoint | bPoint); byte c2 = (byte)(aPoint & bPoint); if ((c1 & 0x01) == 0) { xsv_ext0 = xsb; xsv_ext1 = xsb - 1; dx_ext0 = dx0 - 3 * SQUISH_CONSTANT_4D; dx_ext1 = dx0 + 1 - 2 * SQUISH_CONSTANT_4D; } else { xsv_ext0 = xsv_ext1 = xsb + 1; dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; dx_ext1 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; } if ((c1 & 0x02) == 0) { ysv_ext0 = ysb; ysv_ext1 = ysb - 1; dy_ext0 = dy0 - 3 * SQUISH_CONSTANT_4D; dy_ext1 = dy0 + 1 - 2 * SQUISH_CONSTANT_4D; } else { ysv_ext0 = ysv_ext1 = ysb + 1; dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; dy_ext1 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; } if ((c1 & 0x04) == 0) { zsv_ext0 = zsb; zsv_ext1 = zsb - 1; dz_ext0 = dz0 - 3 * SQUISH_CONSTANT_4D; dz_ext1 = dz0 + 1 - 2 * SQUISH_CONSTANT_4D; } else { zsv_ext0 = zsv_ext1 = zsb + 1; dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; dz_ext1 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; } if ((c1 & 0x08) == 0) { wsv_ext0 = wsb; wsv_ext1 = wsb - 1; dw_ext0 = dw0 - 3 * SQUISH_CONSTANT_4D; dw_ext1 = dw0 + 1 - 2 * SQUISH_CONSTANT_4D; } else { wsv_ext0 = wsv_ext1 = wsb + 1; dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; dw_ext1 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; } // One combination is a permutation of (0,0,0,2) based on c2 xsv_ext2 = xsb; ysv_ext2 = ysb; zsv_ext2 = zsb; wsv_ext2 = wsb; dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D; dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D; dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D; dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D; if ((c2 & 0x01) != 0) { xsv_ext2 += 2; dx_ext2 -= 2; } else if ((c2 & 0x02) != 0) { ysv_ext2 += 2; dy_ext2 -= 2; } else if ((c2 & 0x04) != 0) { zsv_ext2 += 2; dz_ext2 -= 2; } else { wsv_ext2 += 2; dw_ext2 -= 2; } } else { // Both closest points on the smaller side // One of the two extra points is (0,0,0,0) xsv_ext2 = xsb; ysv_ext2 = ysb; zsv_ext2 = zsb; wsv_ext2 = wsb; dx_ext2 = dx0; dy_ext2 = dy0; dz_ext2 = dz0; dw_ext2 = dw0; // Other two points are based on the omitted axes. byte c = (byte)(aPoint | bPoint); if ((c & 0x01) == 0) { xsv_ext0 = xsb - 1; xsv_ext1 = xsb; dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D; dx_ext1 = dx0 - SQUISH_CONSTANT_4D; } else { xsv_ext0 = xsv_ext1 = xsb + 1; dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D; } if ((c & 0x02) == 0) { ysv_ext0 = ysv_ext1 = ysb; dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D; if ((c & 0x01) == 0x01) { ysv_ext0 -= 1; dy_ext0 += 1; } else { ysv_ext1 -= 1; dy_ext1 += 1; } } else { ysv_ext0 = ysv_ext1 = ysb + 1; dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D; } if ((c & 0x04) == 0) { zsv_ext0 = zsv_ext1 = zsb; dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D; if ((c & 0x03) == 0x03) { zsv_ext0 -= 1; dz_ext0 += 1; } else { zsv_ext1 -= 1; dz_ext1 += 1; } } else { zsv_ext0 = zsv_ext1 = zsb + 1; dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D; } if ((c & 0x08) == 0) { wsv_ext0 = wsb; wsv_ext1 = wsb - 1; dw_ext0 = dw0 - SQUISH_CONSTANT_4D; dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D; } else { wsv_ext0 = wsv_ext1 = wsb + 1; dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D; } } } else { // One point on each "side" byte c1, c2; if (aIsBiggerSide) { c1 = aPoint; c2 = bPoint; } else { c1 = bPoint; c2 = aPoint; } // Two contributions are the bigger-sided point with each 0 replaced with -1. if ((c1 & 0x01) == 0) { xsv_ext0 = xsb - 1; xsv_ext1 = xsb; dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D; dx_ext1 = dx0 - SQUISH_CONSTANT_4D; } else { xsv_ext0 = xsv_ext1 = xsb + 1; dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D; } if ((c1 & 0x02) == 0) { ysv_ext0 = ysv_ext1 = ysb; dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D; if ((c1 & 0x01) == 0x01) { ysv_ext0 -= 1; dy_ext0 += 1; } else { ysv_ext1 -= 1; dy_ext1 += 1; } } else { ysv_ext0 = ysv_ext1 = ysb + 1; dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D; } if ((c1 & 0x04) == 0) { zsv_ext0 = zsv_ext1 = zsb; dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D; if ((c1 & 0x03) == 0x03) { zsv_ext0 -= 1; dz_ext0 += 1; } else { zsv_ext1 -= 1; dz_ext1 += 1; } } else { zsv_ext0 = zsv_ext1 = zsb + 1; dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D; } if ((c1 & 0x08) == 0) { wsv_ext0 = wsb; wsv_ext1 = wsb - 1; dw_ext0 = dw0 - SQUISH_CONSTANT_4D; dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D; } else { wsv_ext0 = wsv_ext1 = wsb + 1; dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D; } // One contribution is a permutation of (0,0,0,2) based on the smaller-sided point xsv_ext2 = xsb; ysv_ext2 = ysb; zsv_ext2 = zsb; wsv_ext2 = wsb; dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D; dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D; dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D; dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D; if ((c2 & 0x01) != 0) { xsv_ext2 += 2; dx_ext2 -= 2; } else if ((c2 & 0x02) != 0) { ysv_ext2 += 2; dy_ext2 -= 2; } else if ((c2 & 0x04) != 0) { zsv_ext2 += 2; dz_ext2 -= 2; } else { wsv_ext2 += 2; dw_ext2 -= 2; } } // Contribution (1,0,0,0) double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D; double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D; double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D; double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D; double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; if (attn1 > 0) { attn1 *= attn1; value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1); } // Contribution (0,1,0,0) double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D; double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D; double dz2 = dz1; double dw2 = dw1; double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; if (attn2 > 0) { attn2 *= attn2; value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2); } // Contribution (0,0,1,0) double dx3 = dx2; double dy3 = dy1; double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D; double dw3 = dw1; double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; if (attn3 > 0) { attn3 *= attn3; value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3); } // Contribution (0,0,0,1) double dx4 = dx2; double dy4 = dy1; double dz4 = dz1; double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D; double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; if (attn4 > 0) { attn4 *= attn4; value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4); } // Contribution (1,1,0,0) double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5; if (attn5 > 0) { attn5 *= attn5; value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5); } // Contribution (1,0,1,0) double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6; if (attn6 > 0) { attn6 *= attn6; value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6); } // Contribution (1,0,0,1) double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7; if (attn7 > 0) { attn7 *= attn7; value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7); } // Contribution (0,1,1,0) double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8; if (attn8 > 0) { attn8 *= attn8; value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8); } // Contribution (0,1,0,1) double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9; if (attn9 > 0) { attn9 *= attn9; value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9); } // Contribution (0,0,1,1) double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10; if (attn10 > 0) { attn10 *= attn10; value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10); } } else { // We're inside the second dispentachoron (Rectified 4-Simplex) double aScore; byte aPoint; boolean aIsBiggerSide = true; double bScore; byte bPoint; boolean bIsBiggerSide = true; // Decide between (0,0,1,1) and (1,1,0,0) if (xins + yins < zins + wins) { aScore = xins + yins; aPoint = 0x0C; } else { aScore = zins + wins; aPoint = 0x03; } // Decide between (0,1,0,1) and (1,0,1,0) if (xins + zins < yins + wins) { bScore = xins + zins; bPoint = 0x0A; } else { bScore = yins + wins; bPoint = 0x05; } // Closer between (0,1,1,0) and (1,0,0,1) will replace the further of a and b, if closer. if (xins + wins < yins + zins) { double score = xins + wins; if (aScore <= bScore && score < bScore) { bScore = score; bPoint = 0x06; } else if (aScore > bScore && score < aScore) { aScore = score; aPoint = 0x06; } } else { double score = yins + zins; if (aScore <= bScore && score < bScore) { bScore = score; bPoint = 0x09; } else if (aScore > bScore && score < aScore) { aScore = score; aPoint = 0x09; } } // Decide if (0,1,1,1) is closer. double p1 = 3 - inSum + xins; if (aScore <= bScore && p1 < bScore) { bScore = p1; bPoint = 0x0E; bIsBiggerSide = false; } else if (aScore > bScore && p1 < aScore) { aScore = p1; aPoint = 0x0E; aIsBiggerSide = false; } // Decide if (1,0,1,1) is closer. double p2 = 3 - inSum + yins; if (aScore <= bScore && p2 < bScore) { bScore = p2; bPoint = 0x0D; bIsBiggerSide = false; } else if (aScore > bScore && p2 < aScore) { aScore = p2; aPoint = 0x0D; aIsBiggerSide = false; } // Decide if (1,1,0,1) is closer. double p3 = 3 - inSum + zins; if (aScore <= bScore && p3 < bScore) { bScore = p3; bPoint = 0x0B; bIsBiggerSide = false; } else if (aScore > bScore && p3 < aScore) { aScore = p3; aPoint = 0x0B; aIsBiggerSide = false; } // Decide if (1,1,1,0) is closer. double p4 = 3 - inSum + wins; if (aScore <= bScore && p4 < bScore) { bScore = p4; bPoint = 0x07; bIsBiggerSide = false; } else if (aScore > bScore && p4 < aScore) { aScore = p4; aPoint = 0x07; aIsBiggerSide = false; } // Where each of the two closest points are determines how the extra three vertices are calculated. if (aIsBiggerSide == bIsBiggerSide) { if (aIsBiggerSide) { // Both closest points on the bigger side byte c1 = (byte)(aPoint & bPoint); byte c2 = (byte)(aPoint | bPoint); // Two contributions are permutations of (0,0,0,1) and (0,0,0,2) based on c1 xsv_ext0 = xsv_ext1 = xsb; ysv_ext0 = ysv_ext1 = ysb; zsv_ext0 = zsv_ext1 = zsb; wsv_ext0 = wsv_ext1 = wsb; dx_ext0 = dx0 - SQUISH_CONSTANT_4D; dy_ext0 = dy0 - SQUISH_CONSTANT_4D; dz_ext0 = dz0 - SQUISH_CONSTANT_4D; dw_ext0 = dw0 - SQUISH_CONSTANT_4D; dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_4D; dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_4D; dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_4D; dw_ext1 = dw0 - 2 * SQUISH_CONSTANT_4D; if ((c1 & 0x01) != 0) { xsv_ext0 += 1; dx_ext0 -= 1; xsv_ext1 += 2; dx_ext1 -= 2; } else if ((c1 & 0x02) != 0) { ysv_ext0 += 1; dy_ext0 -= 1; ysv_ext1 += 2; dy_ext1 -= 2; } else if ((c1 & 0x04) != 0) { zsv_ext0 += 1; dz_ext0 -= 1; zsv_ext1 += 2; dz_ext1 -= 2; } else { wsv_ext0 += 1; dw_ext0 -= 1; wsv_ext1 += 2; dw_ext1 -= 2; } // One contribution is a permutation of (1,1,1,-1) based on c2 xsv_ext2 = xsb + 1; ysv_ext2 = ysb + 1; zsv_ext2 = zsb + 1; wsv_ext2 = wsb + 1; dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; if ((c2 & 0x01) == 0) { xsv_ext2 -= 2; dx_ext2 += 2; } else if ((c2 & 0x02) == 0) { ysv_ext2 -= 2; dy_ext2 += 2; } else if ((c2 & 0x04) == 0) { zsv_ext2 -= 2; dz_ext2 += 2; } else { wsv_ext2 -= 2; dw_ext2 += 2; } } else { // Both closest points on the smaller side // One of the two extra points is (1,1,1,1) xsv_ext2 = xsb + 1; ysv_ext2 = ysb + 1; zsv_ext2 = zsb + 1; wsv_ext2 = wsb + 1; dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; dw_ext2 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; // Other two points are based on the shared axes. byte c = (byte)(aPoint & bPoint); if ((c & 0x01) != 0) { xsv_ext0 = xsb + 2; xsv_ext1 = xsb + 1; dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; } else { xsv_ext0 = xsv_ext1 = xsb; dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D; } if ((c & 0x02) != 0) { ysv_ext0 = ysv_ext1 = ysb + 1; dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; if ((c & 0x01) == 0) { ysv_ext0 += 1; dy_ext0 -= 1; } else { ysv_ext1 += 1; dy_ext1 -= 1; } } else { ysv_ext0 = ysv_ext1 = ysb; dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D; } if ((c & 0x04) != 0) { zsv_ext0 = zsv_ext1 = zsb + 1; dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; if ((c & 0x03) == 0) { zsv_ext0 += 1; dz_ext0 -= 1; } else { zsv_ext1 += 1; dz_ext1 -= 1; } } else { zsv_ext0 = zsv_ext1 = zsb; dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D; } if ((c & 0x08) != 0) { wsv_ext0 = wsb + 1; wsv_ext1 = wsb + 2; dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; } else { wsv_ext0 = wsv_ext1 = wsb; dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D; } } } else { // One point on each "side" byte c1, c2; if (aIsBiggerSide) { c1 = aPoint; c2 = bPoint; } else { c1 = bPoint; c2 = aPoint; } // Two contributions are the bigger-sided point with each 1 replaced with 2. if ((c1 & 0x01) != 0) { xsv_ext0 = xsb + 2; xsv_ext1 = xsb + 1; dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; } else { xsv_ext0 = xsv_ext1 = xsb; dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D; } if ((c1 & 0x02) != 0) { ysv_ext0 = ysv_ext1 = ysb + 1; dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; if ((c1 & 0x01) == 0) { ysv_ext0 += 1; dy_ext0 -= 1; } else { ysv_ext1 += 1; dy_ext1 -= 1; } } else { ysv_ext0 = ysv_ext1 = ysb; dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D; } if ((c1 & 0x04) != 0) { zsv_ext0 = zsv_ext1 = zsb + 1; dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; if ((c1 & 0x03) == 0) { zsv_ext0 += 1; dz_ext0 -= 1; } else { zsv_ext1 += 1; dz_ext1 -= 1; } } else { zsv_ext0 = zsv_ext1 = zsb; dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D; } if ((c1 & 0x08) != 0) { wsv_ext0 = wsb + 1; wsv_ext1 = wsb + 2; dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; } else { wsv_ext0 = wsv_ext1 = wsb; dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D; } // One contribution is a permutation of (1,1,1,-1) based on the smaller-sided point xsv_ext2 = xsb + 1; ysv_ext2 = ysb + 1; zsv_ext2 = zsb + 1; wsv_ext2 = wsb + 1; dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; if ((c2 & 0x01) == 0) { xsv_ext2 -= 2; dx_ext2 += 2; } else if ((c2 & 0x02) == 0) { ysv_ext2 -= 2; dy_ext2 += 2; } else if ((c2 & 0x04) == 0) { zsv_ext2 -= 2; dz_ext2 += 2; } else { wsv_ext2 -= 2; dw_ext2 += 2; } } // Contribution (1,1,1,0) double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D; double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; if (attn4 > 0) { attn4 *= attn4; value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4); } // Contribution (1,1,0,1) double dx3 = dx4; double dy3 = dy4; double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D; double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; if (attn3 > 0) { attn3 *= attn3; value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3); } // Contribution (1,0,1,1) double dx2 = dx4; double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D; double dz2 = dz4; double dw2 = dw3; double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; if (attn2 > 0) { attn2 *= attn2; value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2); } // Contribution (0,1,1,1) double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D; double dz1 = dz4; double dy1 = dy4; double dw1 = dw3; double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; if (attn1 > 0) { attn1 *= attn1; value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1); } // Contribution (1,1,0,0) double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5; if (attn5 > 0) { attn5 *= attn5; value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5); } // Contribution (1,0,1,0) double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6; if (attn6 > 0) { attn6 *= attn6; value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6); } // Contribution (1,0,0,1) double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7; if (attn7 > 0) { attn7 *= attn7; value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7); } // Contribution (0,1,1,0) double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8; if (attn8 > 0) { attn8 *= attn8; value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8); } // Contribution (0,1,0,1) double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9; if (attn9 > 0) { attn9 *= attn9; value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9); } // Contribution (0,0,1,1) double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10; if (attn10 > 0) { attn10 *= attn10; value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10); } } // First extra vertex double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0 - dw_ext0 * dw_ext0; if (attn_ext0 > 0) { attn_ext0 *= attn_ext0; value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0, dx_ext0, dy_ext0, dz_ext0, dw_ext0); } // Second extra vertex double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1 - dw_ext1 * dw_ext1; if (attn_ext1 > 0) { attn_ext1 *= attn_ext1; value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1, dx_ext1, dy_ext1, dz_ext1, dw_ext1); } // Third extra vertex double attn_ext2 = 2 - dx_ext2 * dx_ext2 - dy_ext2 * dy_ext2 - dz_ext2 * dz_ext2 - dw_ext2 * dw_ext2; if (attn_ext2 > 0) { attn_ext2 *= attn_ext2; value += attn_ext2 * attn_ext2 * extrapolate(xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2, dx_ext2, dy_ext2, dz_ext2, dw_ext2); } return value; } private double extrapolate(int xsb, int ysb, double dx, double dy) { Grad2 grad = permGrad2[perm[xsb & PMASK] ^ (ysb & PMASK)]; return grad.dx * dx + grad.dy * dy; } private double extrapolate(int xsb, int ysb, int zsb, double dx, double dy, double dz) { Grad3 grad = permGrad3[perm[perm[xsb & PMASK] ^ (ysb & PMASK)] ^ (zsb & PMASK)]; return grad.dx * dx + grad.dy * dy + grad.dz * dz; } private double extrapolate(int xsb, int ysb, int zsb, int wsb, double dx, double dy, double dz, double dw) { Grad4 grad = permGrad4[perm[perm[perm[xsb & PMASK] ^ (ysb & PMASK)] ^ (zsb & PMASK)] ^ (wsb & PMASK)]; return grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw; } private static int fastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } public static class Grad2 { double dx, dy; public Grad2(double dx, double dy) { this.dx = dx; this.dy = dy; } } public static class Grad3 { double dx, dy, dz; public Grad3(double dx, double dy, double dz) { this.dx = dx; this.dy = dy; this.dz = dz; } } public static class Grad4 { double dx, dy, dz, dw; public Grad4(double dx, double dy, double dz, double dw) { this.dx = dx; this.dy = dy; this.dz = dz; this.dw = dw; } } private static final double N2 = 7.69084574549313; private static final double N3 = 26.92263139946168; private static final double N4 = 8.881759591352166; private static final Grad2[] GRADIENTS_2D = new Grad2[PSIZE]; private static final Grad3[] GRADIENTS_3D = new Grad3[PSIZE]; private static final Grad4[] GRADIENTS_4D = new Grad4[PSIZE]; static { Grad2[] grad2 = { new Grad2( 0.130526192220052, 0.99144486137381), new Grad2( 0.38268343236509, 0.923879532511287), new Grad2( 0.608761429008721, 0.793353340291235), new Grad2( 0.793353340291235, 0.608761429008721), new Grad2( 0.923879532511287, 0.38268343236509), new Grad2( 0.99144486137381, 0.130526192220051), new Grad2( 0.99144486137381, -0.130526192220051), new Grad2( 0.923879532511287, -0.38268343236509), new Grad2( 0.793353340291235, -0.60876142900872), new Grad2( 0.608761429008721, -0.793353340291235), new Grad2( 0.38268343236509, -0.923879532511287), new Grad2( 0.130526192220052, -0.99144486137381), new Grad2(-0.130526192220052, -0.99144486137381), new Grad2(-0.38268343236509, -0.923879532511287), new Grad2(-0.608761429008721, -0.793353340291235), new Grad2(-0.793353340291235, -0.608761429008721), new Grad2(-0.923879532511287, -0.38268343236509), new Grad2(-0.99144486137381, -0.130526192220052), new Grad2(-0.99144486137381, 0.130526192220051), new Grad2(-0.923879532511287, 0.38268343236509), new Grad2(-0.793353340291235, 0.608761429008721), new Grad2(-0.608761429008721, 0.793353340291235), new Grad2(-0.38268343236509, 0.923879532511287), new Grad2(-0.130526192220052, 0.99144486137381) }; for (int i = 0; i < grad2.length; i++) { grad2[i].dx /= N2; grad2[i].dy /= N2; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_2D[i] = grad2[i % grad2.length]; } Grad3[] grad3 = { new Grad3(-1.4082482904633333, -1.4082482904633333, -2.6329931618533333), new Grad3(-0.07491495712999985, -0.07491495712999985, -3.29965982852), new Grad3( 0.24732126143473554, -1.6667938651159684, -2.838945207362466), new Grad3(-1.6667938651159684, 0.24732126143473554, -2.838945207362466), new Grad3(-1.4082482904633333, -2.6329931618533333, -1.4082482904633333), new Grad3(-0.07491495712999985, -3.29965982852, -0.07491495712999985), new Grad3(-1.6667938651159684, -2.838945207362466, 0.24732126143473554), new Grad3( 0.24732126143473554, -2.838945207362466, -1.6667938651159684), new Grad3( 1.5580782047233335, 0.33333333333333337, -2.8914115380566665), new Grad3( 2.8914115380566665, -0.33333333333333337, -1.5580782047233335), new Grad3( 1.8101897177633992, -1.2760767510338025, -2.4482280932803), new Grad3( 2.4482280932803, 1.2760767510338025, -1.8101897177633992), new Grad3( 1.5580782047233335, -2.8914115380566665, 0.33333333333333337), new Grad3( 2.8914115380566665, -1.5580782047233335, -0.33333333333333337), new Grad3( 2.4482280932803, -1.8101897177633992, 1.2760767510338025), new Grad3( 1.8101897177633992, -2.4482280932803, -1.2760767510338025), new Grad3(-2.6329931618533333, -1.4082482904633333, -1.4082482904633333), new Grad3(-3.29965982852, -0.07491495712999985, -0.07491495712999985), new Grad3(-2.838945207362466, 0.24732126143473554, -1.6667938651159684), new Grad3(-2.838945207362466, -1.6667938651159684, 0.24732126143473554), new Grad3( 0.33333333333333337, 1.5580782047233335, -2.8914115380566665), new Grad3(-0.33333333333333337, 2.8914115380566665, -1.5580782047233335), new Grad3( 1.2760767510338025, 2.4482280932803, -1.8101897177633992), new Grad3(-1.2760767510338025, 1.8101897177633992, -2.4482280932803), new Grad3( 0.33333333333333337, -2.8914115380566665, 1.5580782047233335), new Grad3(-0.33333333333333337, -1.5580782047233335, 2.8914115380566665), new Grad3(-1.2760767510338025, -2.4482280932803, 1.8101897177633992), new Grad3( 1.2760767510338025, -1.8101897177633992, 2.4482280932803), new Grad3( 3.29965982852, 0.07491495712999985, 0.07491495712999985), new Grad3( 2.6329931618533333, 1.4082482904633333, 1.4082482904633333), new Grad3( 2.838945207362466, -0.24732126143473554, 1.6667938651159684), new Grad3( 2.838945207362466, 1.6667938651159684, -0.24732126143473554), new Grad3(-2.8914115380566665, 1.5580782047233335, 0.33333333333333337), new Grad3(-1.5580782047233335, 2.8914115380566665, -0.33333333333333337), new Grad3(-2.4482280932803, 1.8101897177633992, -1.2760767510338025), new Grad3(-1.8101897177633992, 2.4482280932803, 1.2760767510338025), new Grad3(-2.8914115380566665, 0.33333333333333337, 1.5580782047233335), new Grad3(-1.5580782047233335, -0.33333333333333337, 2.8914115380566665), new Grad3(-1.8101897177633992, 1.2760767510338025, 2.4482280932803), new Grad3(-2.4482280932803, -1.2760767510338025, 1.8101897177633992), new Grad3( 0.07491495712999985, 3.29965982852, 0.07491495712999985), new Grad3( 1.4082482904633333, 2.6329931618533333, 1.4082482904633333), new Grad3( 1.6667938651159684, 2.838945207362466, -0.24732126143473554), new Grad3(-0.24732126143473554, 2.838945207362466, 1.6667938651159684), new Grad3( 0.07491495712999985, 0.07491495712999985, 3.29965982852), new Grad3( 1.4082482904633333, 1.4082482904633333, 2.6329931618533333), new Grad3(-0.24732126143473554, 1.6667938651159684, 2.838945207362466), new Grad3( 1.6667938651159684, -0.24732126143473554, 2.838945207362466) }; for (int i = 0; i < grad3.length; i++) { grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_3D[i] = grad3[i % grad3.length]; } Grad4[] grad4 = { new Grad4(-0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301), new Grad4(-0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174), new Grad4(-0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796), new Grad4(-0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098), new Grad4(-0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301), new Grad4(-0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796), new Grad4(-0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624), new Grad4(-0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301), new Grad4(-0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842), new Grad4(-0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078), new Grad4(-0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708), new Grad4(-0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708), new Grad4( 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708), new Grad4(-0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365), new Grad4( 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365), new Grad4(-0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062), new Grad4(-0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724), new Grad4(-0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602), new Grad4(-0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944), new Grad4(-0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381), new Grad4(-0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724), new Grad4( 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712), new Grad4(-0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585), new Grad4(-0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602), new Grad4( 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944), new Grad4(-0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537), new Grad4(-0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164), new Grad4( 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195), new Grad4( 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945), new Grad4(-0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945), new Grad4(-0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195), new Grad4( 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164), new Grad4( 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537), new Grad4(-0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585), new Grad4(-0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381), new Grad4(-0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537), new Grad4(-0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164), new Grad4(-0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195), new Grad4(-0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945), new Grad4(-0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945), new Grad4(-0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195), new Grad4(-0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164), new Grad4(-0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537), new Grad4(-0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945), new Grad4(-0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537), new Grad4(-0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944), new Grad4(-0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585), new Grad4(-0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712), new Grad4(-0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164), new Grad4( 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195), new Grad4( 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195), new Grad4( 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164), new Grad4( 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537), new Grad4( 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195), new Grad4( 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945), new Grad4( 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164), new Grad4( 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537), new Grad4( 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944), new Grad4( 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602), new Grad4( 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602), new Grad4( 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585), new Grad4( 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712), new Grad4( 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724), new Grad4( 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724), new Grad4( 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062), new Grad4(-0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365), new Grad4(-0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708), new Grad4( 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078), new Grad4( 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796), new Grad4(-0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174), new Grad4( 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624), new Grad4( 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842), new Grad4(-0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796), new Grad4(-0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174), new Grad4(-0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624), new Grad4( 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842), new Grad4( 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796), new Grad4( 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174), new Grad4( 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301), new Grad4( 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174), new Grad4( 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301), new Grad4( 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098), new Grad4( 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624) }; for (int i = 0; i < grad4.length; i++) { grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4; } for (int i = 0; i < PSIZE; i++) { GRADIENTS_4D[i] = grad4[i % grad4.length]; } } } ================================================ FILE: csharp/OpenSimplex2.cs ================================================ /** * K.jpg's OpenSimplex 2, faster variant */ using System.Runtime.CompilerServices; public static class OpenSimplex2 { private const long PRIME_X = 0x5205402B9270C86FL; private const long PRIME_Y = 0x598CD327003817B5L; private const long PRIME_Z = 0x5BCC226E9FA0BACBL; private const long PRIME_W = 0x56CC5227E58F554BL; private const long HASH_MULTIPLIER = 0x53A3F72DEEC546F5L; private const long SEED_FLIP_3D = -0x52D547B2E96ED629L; private const long SEED_OFFSET_4D = 0xE83DC3E0DA7164DL; private const double ROOT2OVER2 = 0.7071067811865476; private const double SKEW_2D = 0.366025403784439; private const double UNSKEW_2D = -0.21132486540518713; private const double ROOT3OVER3 = 0.577350269189626; private const double FALLBACK_ROTATE_3D = 2.0 / 3.0; private const double ROTATE_3D_ORTHOGONALIZER = UNSKEW_2D; private const float SKEW_4D = -0.138196601125011f; private const float UNSKEW_4D = 0.309016994374947f; private const float LATTICE_STEP_4D = 0.2f; private const int N_GRADS_2D_EXPONENT = 7; private const int N_GRADS_3D_EXPONENT = 8; private const int N_GRADS_4D_EXPONENT = 9; private const int N_GRADS_2D = 1 << N_GRADS_2D_EXPONENT; private const int N_GRADS_3D = 1 << N_GRADS_3D_EXPONENT; private const int N_GRADS_4D = 1 << N_GRADS_4D_EXPONENT; private const double NORMALIZER_2D = 0.01001634121365712; private const double NORMALIZER_3D = 0.07969837668935331; private const double NORMALIZER_4D = 0.0220065933241897; private const float RSQUARED_2D = 0.5f; private const float RSQUARED_3D = 0.6f; private const float RSQUARED_4D = 0.6f; /* * Noise Evaluators */ /** * 2D Simplex noise, standard lattice orientation. */ public static float Noise2(long seed, double x, double y) { // Get points for A2* lattice double s = SKEW_2D * (x + y); double xs = x + s, ys = y + s; return Noise2_UnskewedBase(seed, xs, ys); } /** * 2D Simplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps, * unless your map is centered around an equator. It's a subtle * difference, but the option is here to make it an easy choice. */ public static float Noise2_ImproveX(long seed, double x, double y) { // Skew transform and rotation baked into one. double xx = x * ROOT2OVER2; double yy = y * (ROOT2OVER2 * (1 + 2 * SKEW_2D)); return Noise2_UnskewedBase(seed, yy + xx, yy - xx); } /** * 2D Simplex noise base. */ private static float Noise2_UnskewedBase(long seed, double xs, double ys) { // Get base points and offsets. int xsb = FastFloor(xs), ysb = FastFloor(ys); float xi = (float)(xs - xsb), yi = (float)(ys - ysb); // Prime pre-multiplication for hash. long xsbp = xsb * PRIME_X, ysbp = ysb * PRIME_Y; // Unskew. float t = (xi + yi) * (float)UNSKEW_2D; float dx0 = xi + t, dy0 = yi + t; // First vertex. float value = 0; float a0 = RSQUARED_2D - dx0 * dx0 - dy0 * dy0; if (a0 > 0) { value = (a0 * a0) * (a0 * a0) * Grad(seed, xsbp, ysbp, dx0, dy0); } // Second vertex. float a1 = (float)(2 * (1 + 2 * UNSKEW_2D) * (1 / UNSKEW_2D + 2)) * t + ((float)(-2 * (1 + 2 * UNSKEW_2D) * (1 + 2 * UNSKEW_2D)) + a0); if (a1 > 0) { float dx1 = dx0 - (float)(1 + 2 * UNSKEW_2D); float dy1 = dy0 - (float)(1 + 2 * UNSKEW_2D); value += (a1 * a1) * (a1 * a1) * Grad(seed, xsbp + PRIME_X, ysbp + PRIME_Y, dx1, dy1); } // Third vertex. if (dy0 > dx0) { float dx2 = dx0 - (float)UNSKEW_2D; float dy2 = dy0 - (float)(UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * Grad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2); } } else { float dx2 = dx0 - (float)(UNSKEW_2D + 1); float dy2 = dy0 - (float)UNSKEW_2D; float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * Grad(seed, xsbp + PRIME_X, ysbp, dx2, dy2); } } return value; } /** * 3D OpenSimplex2 noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in whatever your use case is. * If Y is vertical in world coordinates, call Noise3_ImproveXZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call Noise3_ImproveXZ(x, y, Z). * For a time varied animation, call Noise3_ImproveXY(x, y, T). */ public static float Noise3_ImproveXY(long seed, double x, double y, double z) { // Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal, // and the planes formed by XY are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * ROTATE_3D_ORTHOGONALIZER; double zz = z * ROOT3OVER3; double xr = x + s2 + zz; double yr = y + s2 + zz; double zr = xy * -ROOT3OVER3 + zz; // Evaluate both lattices to form a BCC lattice. return Noise3_UnrotatedBase(seed, xr, yr, zr); } /** * 3D OpenSimplex2 noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in whatever your use case is. * If Y is vertical in world coordinates, call Noise3_ImproveXZ(x, Y, z). * If Z is vertical in world coordinates, call Noise3_ImproveXZ(x, Z, y) or use Noise3_ImproveXY. * For a time varied animation, call Noise3_ImproveXZ(x, T, y) or use Noise3_ImproveXY. */ public static float Noise3_ImproveXZ(long seed, double x, double y, double z) { // Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal, // and the planes formed by XZ are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * ROTATE_3D_ORTHOGONALIZER; double yy = y * ROOT3OVER3; double xr = x + s2 + yy; double zr = z + s2 + yy; double yr = xz * -ROOT3OVER3 + yy; // Evaluate both lattices to form a BCC lattice. return Noise3_UnrotatedBase(seed, xr, yr, zr); } /** * 3D OpenSimplex2 noise, fallback rotation option * Use Noise3_ImproveXY or Noise3_ImproveXZ instead, wherever appropriate. * They have less diagonal bias. This function's best use is as a fallback. */ public static float Noise3_Fallback(long seed, double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce a familiar look. // Orthonormal rotation. Not a skew transform. double r = FALLBACK_ROTATE_3D * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; // Evaluate both lattices to form a BCC lattice. return Noise3_UnrotatedBase(seed, xr, yr, zr); } /** * Generate overlapping cubic lattices for 3D OpenSimplex2 noise. */ private static float Noise3_UnrotatedBase(long seed, double xr, double yr, double zr) { // Get base points and offsets. int xrb = FastRound(xr), yrb = FastRound(yr), zrb = FastRound(zr); float xri = (float)(xr - xrb), yri = (float)(yr - yrb), zri = (float)(zr - zrb); // -1 if positive, 1 if negative. int xNSign = (int)(-1.0f - xri) | 1, yNSign = (int)(-1.0f - yri) | 1, zNSign = (int)(-1.0f - zri) | 1; // Compute absolute values, using the above as a shortcut. This was faster in my tests for some reason. float ax0 = xNSign * -xri, ay0 = yNSign * -yri, az0 = zNSign * -zri; // Prime pre-multiplication for hash. long xrbp = xrb * PRIME_X, yrbp = yrb * PRIME_Y, zrbp = zrb * PRIME_Z; // Loop: Pick an edge on each lattice copy. float value = 0; float a = (RSQUARED_3D - xri * xri) - (yri * yri + zri * zri); for (int l = 0; ; l++) { // Closest point on cube. if (a > 0) { value += (a * a) * (a * a) * Grad(seed, xrbp, yrbp, zrbp, xri, yri, zri); } // Second-closest point. if (ax0 >= ay0 && ax0 >= az0) { float b = a + ax0 + ax0; if (b > 1) { b -= 1; value += (b * b) * (b * b) * Grad(seed, xrbp - xNSign * PRIME_X, yrbp, zrbp, xri + xNSign, yri, zri); } } else if (ay0 > ax0 && ay0 >= az0) { float b = a + ay0 + ay0; if (b > 1) { b -= 1; value += (b * b) * (b * b) * Grad(seed, xrbp, yrbp - yNSign * PRIME_Y, zrbp, xri, yri + yNSign, zri); } } else { float b = a + az0 + az0; if (b > 1) { b -= 1; value += (b * b) * (b * b) * Grad(seed, xrbp, yrbp, zrbp - zNSign * PRIME_Z, xri, yri, zri + zNSign); } } // Break from loop if we're done, skipping updates below. if (l == 1) break; // Update absolute value. ax0 = 0.5f - ax0; ay0 = 0.5f - ay0; az0 = 0.5f - az0; // Update relative coordinate. xri = xNSign * ax0; yri = yNSign * ay0; zri = zNSign * az0; // Update falloff. a += (0.75f - ax0) - (ay0 + az0); // Update prime for hash. xrbp += (xNSign >> 1) & PRIME_X; yrbp += (yNSign >> 1) & PRIME_Y; zrbp += (zNSign >> 1) & PRIME_Z; // Update the reverse sign indicators. xNSign = -xNSign; yNSign = -yNSign; zNSign = -zNSign; // And finally update the seed for the other lattice copy. seed ^= SEED_FLIP_3D; } return value; } /** * 4D OpenSimplex2 noise, with XYZ oriented like Noise3_ImproveXY * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * in a space where Z is vertical */ public static float Noise4_ImproveXYZ_ImproveXY(long seed, double x, double y, double z, double w) { double xy = x + y; double s2 = xy * -0.21132486540518699998; double zz = z * 0.28867513459481294226; double ww = w * 0.2236067977499788; double xr = x + (zz + ww + s2), yr = y + (zz + ww + s2); double zr = xy * -0.57735026918962599998 + (zz + ww); double wr = z * -0.866025403784439 + ww; return Noise4_UnskewedBase(seed, xr, yr, zr, wr); } /** * 4D OpenSimplex2 noise, with XYZ oriented like Noise3_ImproveXZ * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * in a space where Y is vertical */ public static float Noise4_ImproveXYZ_ImproveXZ(long seed, double x, double y, double z, double w) { double xz = x + z; double s2 = xz * -0.21132486540518699998; double yy = y * 0.28867513459481294226; double ww = w * 0.2236067977499788; double xr = x + (yy + ww + s2), zr = z + (yy + ww + s2); double yr = xz * -0.57735026918962599998 + (yy + ww); double wr = y * -0.866025403784439 + ww; return Noise4_UnskewedBase(seed, xr, yr, zr, wr); } /** * 4D OpenSimplex2 noise, with XYZ oriented like Noise3_Fallback * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * where there isn't a clear distinction between horizontal and vertical */ public static float Noise4_ImproveXYZ(long seed, double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 0.2236067977499788; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return Noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D OpenSimplex2 noise, fallback lattice orientation. */ public static float Noise4_Fallback(long seed, double x, double y, double z, double w) { // Get points for A4 lattice double s = SKEW_4D * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return Noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D OpenSimplex2 noise base. */ private static float Noise4_UnskewedBase(long seed, double xs, double ys, double zs, double ws) { // Get base points and offsets int xsb = FastFloor(xs), ysb = FastFloor(ys), zsb = FastFloor(zs), wsb = FastFloor(ws); float xsi = (float)(xs - xsb), ysi = (float)(ys - ysb), zsi = (float)(zs - zsb), wsi = (float)(ws - wsb); // Determine which lattice we can be confident has a contributing point its corresponding cell's base simplex. // We only look at the spaces between the diagonal planes. This proved effective in all of my tests. float siSum = (xsi + ysi) + (zsi + wsi); int startingLattice = (int)(siSum * 1.25); // Offset for seed based on first lattice copy. seed += startingLattice * SEED_OFFSET_4D; // Offset for lattice point relative positions (skewed) float startingLatticeOffset = startingLattice * -LATTICE_STEP_4D; xsi += startingLatticeOffset; ysi += startingLatticeOffset; zsi += startingLatticeOffset; wsi += startingLatticeOffset; // Prep for vertex contributions. float ssi = (siSum + startingLatticeOffset * 4) * UNSKEW_4D; // Prime pre-multiplication for hash. long xsvp = xsb * PRIME_X, ysvp = ysb * PRIME_Y, zsvp = zsb * PRIME_Z, wsvp = wsb * PRIME_W; // Five points to add, total, from five copies of the A4 lattice. float value = 0; for (int i = 0; ; i++) { // Next point is the closest vertex on the 4-simplex whose base vertex is the aforementioned vertex. double score0 = 1.0 + ssi * (-1.0 / UNSKEW_4D); // Seems slightly faster than 1.0-xsi-ysi-zsi-wsi if (xsi >= ysi && xsi >= zsi && xsi >= wsi && xsi >= score0) { xsvp += PRIME_X; xsi -= 1; ssi -= UNSKEW_4D; } else if (ysi > xsi && ysi >= zsi && ysi >= wsi && ysi >= score0) { ysvp += PRIME_Y; ysi -= 1; ssi -= UNSKEW_4D; } else if (zsi > xsi && zsi > ysi && zsi >= wsi && zsi >= score0) { zsvp += PRIME_Z; zsi -= 1; ssi -= UNSKEW_4D; } else if (wsi > xsi && wsi > ysi && wsi > zsi && wsi >= score0) { wsvp += PRIME_W; wsi -= 1; ssi -= UNSKEW_4D; } // Gradient contribution with falloff. float dx = xsi + ssi, dy = ysi + ssi, dz = zsi + ssi, dw = wsi + ssi; float a = (dx * dx + dy * dy) + (dz * dz + dw * dw); if (a < RSQUARED_4D) { a -= RSQUARED_4D; a *= a; value += a * a * Grad(seed, xsvp, ysvp, zsvp, wsvp, dx, dy, dz, dw); } // Break from loop if we're done, skipping updates below. if (i == 4) break; // Update for next lattice copy shifted down by <-0.2, -0.2, -0.2, -0.2>. xsi += LATTICE_STEP_4D; ysi += LATTICE_STEP_4D; zsi += LATTICE_STEP_4D; wsi += LATTICE_STEP_4D; ssi += LATTICE_STEP_4D * 4 * UNSKEW_4D; seed -= SEED_OFFSET_4D; // Because we don't always start on the same lattice copy, there's a special reset case. if (i == startingLattice) { xsvp -= PRIME_X; ysvp -= PRIME_Y; zsvp -= PRIME_Z; wsvp -= PRIME_W; seed += SEED_OFFSET_4D * 5; } } return value; } /* * Utility */ [MethodImpl(MethodImplOptions.AggressiveInlining)] private static float Grad(long seed, long xsvp, long ysvp, float dx, float dy) { long hash = seed ^ xsvp ^ ysvp; hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_2D_EXPONENT + 1); int gi = (int)hash & ((N_GRADS_2D - 1) << 1); return GRADIENTS_2D[gi | 0] * dx + GRADIENTS_2D[gi | 1] * dy; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static float Grad(long seed, long xrvp, long yrvp, long zrvp, float dx, float dy, float dz) { long hash = (seed ^ xrvp) ^ (yrvp ^ zrvp); hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_3D_EXPONENT + 2); int gi = (int)hash & ((N_GRADS_3D - 1) << 2); return GRADIENTS_3D[gi | 0] * dx + GRADIENTS_3D[gi | 1] * dy + GRADIENTS_3D[gi | 2] * dz; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static float Grad(long seed, long xsvp, long ysvp, long zsvp, long wsvp, float dx, float dy, float dz, float dw) { long hash = seed ^ (xsvp ^ ysvp) ^ (zsvp ^ wsvp); hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_4D_EXPONENT + 2); int gi = (int)hash & ((N_GRADS_4D - 1) << 2); return (GRADIENTS_4D[gi | 0] * dx + GRADIENTS_4D[gi | 1] * dy) + (GRADIENTS_4D[gi | 2] * dz + GRADIENTS_4D[gi | 3] * dw); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int FastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int FastRound(double x) { return x < 0 ? (int)(x - 0.5) : (int)(x + 0.5); } /* * Gradients */ private static readonly float[] GRADIENTS_2D; private static readonly float[] GRADIENTS_3D; private static readonly float[] GRADIENTS_4D; static OpenSimplex2() { GRADIENTS_2D = new float[N_GRADS_2D * 2]; float[] grad2 = { 0.38268343236509f, 0.923879532511287f, 0.923879532511287f, 0.38268343236509f, 0.923879532511287f, -0.38268343236509f, 0.38268343236509f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, 0.38268343236509f, -0.38268343236509f, 0.923879532511287f, //-------------------------------------// 0.130526192220052f, 0.99144486137381f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.130526192220052f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.130526192220052f, 0.99144486137381f, }; for (int i = 0; i < grad2.Length; i++) { grad2[i] = (float)(grad2[i] / NORMALIZER_2D); } for (int i = 0, j = 0; i < GRADIENTS_2D.Length; i++, j++) { if (j == grad2.Length) j = 0; GRADIENTS_2D[i] = grad2[j]; } GRADIENTS_3D = new float[N_GRADS_3D * 4]; float[] grad3 = { 2.22474487139f, 2.22474487139f, -1.0f, 0.0f, 2.22474487139f, 2.22474487139f, 1.0f, 0.0f, 3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, 1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -2.22474487139f, 2.22474487139f, -1.0f, 0.0f, -2.22474487139f, 2.22474487139f, 1.0f, 0.0f, -1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, -1.0f, -2.22474487139f, -2.22474487139f, 0.0f, 1.0f, -2.22474487139f, -2.22474487139f, 0.0f, 0.0f, -3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, -1.1721513422464978f, -3.0862664687972017f, 0.0f, -1.0f, -2.22474487139f, 2.22474487139f, 0.0f, 1.0f, -2.22474487139f, 2.22474487139f, 0.0f, 0.0f, -1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -3.0862664687972017f, 1.1721513422464978f, 0.0f, //--------------------------------------------------------------------// -2.22474487139f, -2.22474487139f, -1.0f, 0.0f, -2.22474487139f, -2.22474487139f, 1.0f, 0.0f, -3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, -1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, -2.22474487139f, -1.0f, -2.22474487139f, 0.0f, -2.22474487139f, 1.0f, -2.22474487139f, 0.0f, -1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, -3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, -2.22474487139f, -1.0f, 2.22474487139f, 0.0f, -2.22474487139f, 1.0f, 2.22474487139f, 0.0f, -3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, -1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, -1.0f, 2.22474487139f, -2.22474487139f, 0.0f, 1.0f, 2.22474487139f, -2.22474487139f, 0.0f, 0.0f, 1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, 3.0862664687972017f, -1.1721513422464978f, 0.0f, -1.0f, 2.22474487139f, 2.22474487139f, 0.0f, 1.0f, 2.22474487139f, 2.22474487139f, 0.0f, 0.0f, 3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, 1.1721513422464978f, 3.0862664687972017f, 0.0f, 2.22474487139f, -2.22474487139f, -1.0f, 0.0f, 2.22474487139f, -2.22474487139f, 1.0f, 0.0f, 1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, 3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, 2.22474487139f, -1.0f, -2.22474487139f, 0.0f, 2.22474487139f, 1.0f, -2.22474487139f, 0.0f, 3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, 1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, 2.22474487139f, -1.0f, 2.22474487139f, 0.0f, 2.22474487139f, 1.0f, 2.22474487139f, 0.0f, 1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, 3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, }; for (int i = 0; i < grad3.Length; i++) { grad3[i] = (float)(grad3[i] / NORMALIZER_3D); } for (int i = 0, j = 0; i < GRADIENTS_3D.Length; i++, j++) { if (j == grad3.Length) j = 0; GRADIENTS_3D[i] = grad3[j]; } GRADIENTS_4D = new float[N_GRADS_4D * 4]; float[] grad4 = { -0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, -0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, -0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, -0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, -0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, -0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, -0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, -0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, -0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, 0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, 0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, //------------------------------------------------------------------------------------------// -0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, -0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, -0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, -0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, -0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, -0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, -0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, -0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, -0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, -0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, -0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, -0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, -0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, -0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, -0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, 0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, -0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, -0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, 0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, 0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, 0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, -0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, -0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, 0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, -0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, 0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, -0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, 0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, 0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, -0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, -0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, 0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, -0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, 0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, -0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, 0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, -0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, -0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, 0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, 0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, 0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, 0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, 0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, 0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, 0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, 0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, 0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, 0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, -0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, 0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, 0.8586508742123365f, 0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, 0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, 0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, -0.044802370851755174f, 0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, 0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, 0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, 0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, -0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, -0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, 0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, 0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, 0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, 0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, 0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, 0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, }; for (int i = 0; i < grad4.Length; i++) { grad4[i] = (float)(grad4[i] / NORMALIZER_4D); } for (int i = 0, j = 0; i < GRADIENTS_4D.Length; i++, j++) { if (j == grad4.Length) j = 0; GRADIENTS_4D[i] = grad4[j]; } } } ================================================ FILE: csharp/OpenSimplex2S.cs ================================================ /** * K.jpg's OpenSimplex 2, smooth variant ("SuperSimplex") * * Note: Not yet compatible with Unity Burst. */ using System.Runtime.CompilerServices; public static class OpenSimplex2S { private const long PRIME_X = 0x5205402B9270C86FL; private const long PRIME_Y = 0x598CD327003817B5L; private const long PRIME_Z = 0x5BCC226E9FA0BACBL; private const long PRIME_W = 0x56CC5227E58F554BL; private const long HASH_MULTIPLIER = 0x53A3F72DEEC546F5L; private const long SEED_FLIP_3D = -0x52D547B2E96ED629L; private const double ROOT2OVER2 = 0.7071067811865476; private const double SKEW_2D = 0.366025403784439; private const double UNSKEW_2D = -0.21132486540518713; private const double ROOT3OVER3 = 0.577350269189626; private const double FALLBACK_ROTATE3 = 2.0 / 3.0; private const double ROTATE3_ORTHOGONALIZER = UNSKEW_2D; private const float SKEW_4D = 0.309016994374947f; private const float UNSKEW_4D = -0.138196601125011f; private const int N_GRADS_2D_EXPONENT = 7; private const int N_GRADS_3D_EXPONENT = 8; private const int N_GRADS_4D_EXPONENT = 9; private const int N_GRADS_2D = 1 << N_GRADS_2D_EXPONENT; private const int N_GRADS_3D = 1 << N_GRADS_3D_EXPONENT; private const int N_GRADS_4D = 1 << N_GRADS_4D_EXPONENT; private const double NORMALIZER_2D = 0.05481866495625118; private const double NORMALIZER_3D = 0.2781926117527186; private const double NORMALIZER_4D = 0.11127401889945551; private const float RSQUARED_2D = 2.0f / 3.0f; private const float RSQUARED_3D = 3.0f / 4.0f; private const float RSQUARED_4D = 4.0f / 5.0f; /* * Noise Evaluators */ /** * 2D OpenSimplex2S/SuperSimplex noise, standard lattice orientation. */ public static float Noise2(long seed, double x, double y) { // Get points for A2* lattice double s = SKEW_2D * (x + y); double xs = x + s, ys = y + s; return Noise2_UnskewedBase(seed, xs, ys); } /** * 2D OpenSimplex2S/SuperSimplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps, * unless your map is centered around an equator. It's a slight * difference, but the option is here to make it easy. */ public static float Noise2_ImproveX(long seed, double x, double y) { // Skew transform and rotation baked into one. double xx = x * ROOT2OVER2; double yy = y * (ROOT2OVER2 * (1 + 2 * SKEW_2D)); return Noise2_UnskewedBase(seed, yy + xx, yy - xx); } /** * 2D OpenSimplex2S/SuperSimplex noise base. */ private static float Noise2_UnskewedBase(long seed, double xs, double ys) { // Get base points and offsets. int xsb = FastFloor(xs), ysb = FastFloor(ys); float xi = (float)(xs - xsb), yi = (float)(ys - ysb); // Prime pre-multiplication for hash. long xsbp = xsb * PRIME_X, ysbp = ysb * PRIME_Y; // Unskew. float t = (xi + yi) * (float)UNSKEW_2D; float dx0 = xi + t, dy0 = yi + t; // First vertex. float a0 = RSQUARED_2D - dx0 * dx0 - dy0 * dy0; float value = (a0 * a0) * (a0 * a0) * Grad(seed, xsbp, ysbp, dx0, dy0); // Second vertex. float a1 = (float)(2 * (1 + 2 * UNSKEW_2D) * (1 / UNSKEW_2D + 2)) * t + ((float)(-2 * (1 + 2 * UNSKEW_2D) * (1 + 2 * UNSKEW_2D)) + a0); float dx1 = dx0 - (float)(1 + 2 * UNSKEW_2D); float dy1 = dy0 - (float)(1 + 2 * UNSKEW_2D); value += (a1 * a1) * (a1 * a1) * Grad(seed, xsbp + PRIME_X, ysbp + PRIME_Y, dx1, dy1); // Third and fourth vertices. // Nested conditionals were faster than compact bit logic/arithmetic. float xmyi = xi - yi; if (t < UNSKEW_2D) { if (xi + xmyi > 1) { float dx2 = dx0 - (float)(3 * UNSKEW_2D + 2); float dy2 = dy0 - (float)(3 * UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * Grad(seed, xsbp + (PRIME_X << 1), ysbp + PRIME_Y, dx2, dy2); } } else { float dx2 = dx0 - (float)UNSKEW_2D; float dy2 = dy0 - (float)(UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * Grad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2); } } if (yi - xmyi > 1) { float dx3 = dx0 - (float)(3 * UNSKEW_2D + 1); float dy3 = dy0 - (float)(3 * UNSKEW_2D + 2); float a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3; if (a3 > 0) { value += (a3 * a3) * (a3 * a3) * Grad(seed, xsbp + PRIME_X, ysbp + (PRIME_Y << 1), dx3, dy3); } } else { float dx3 = dx0 - (float)(UNSKEW_2D + 1); float dy3 = dy0 - (float)UNSKEW_2D; float a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3; if (a3 > 0) { value += (a3 * a3) * (a3 * a3) * Grad(seed, xsbp + PRIME_X, ysbp, dx3, dy3); } } } else { if (xi + xmyi < 0) { float dx2 = dx0 + (float)(1 + UNSKEW_2D); float dy2 = dy0 + (float)UNSKEW_2D; float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * Grad(seed, xsbp - PRIME_X, ysbp, dx2, dy2); } } else { float dx2 = dx0 - (float)(UNSKEW_2D + 1); float dy2 = dy0 - (float)UNSKEW_2D; float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * Grad(seed, xsbp + PRIME_X, ysbp, dx2, dy2); } } if (yi < xmyi) { float dx2 = dx0 + (float)UNSKEW_2D; float dy2 = dy0 + (float)(UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * Grad(seed, xsbp, ysbp - PRIME_Y, dx2, dy2); } } else { float dx2 = dx0 - (float)UNSKEW_2D; float dy2 = dy0 - (float)(UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * Grad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2); } } } return value; } /** * 3D OpenSimplex2S/SuperSimplex noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in whatever your use case is. * If Y is vertical in world coordinates, call Noise3_ImproveXZ(x, z, Y) or use Noise3_XZBeforeY. * If Z is vertical in world coordinates, call Noise3_ImproveXZ(x, y, Z). * For a time varied animation, call Noise3_ImproveXY(x, y, T). */ public static float Noise3_ImproveXY(long seed, double x, double y, double z) { // Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal, // and the planes formed by XY are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * ROTATE3_ORTHOGONALIZER; double zz = z * ROOT3OVER3; double xr = x + s2 + zz; double yr = y + s2 + zz; double zr = xy * -ROOT3OVER3 + zz; // Evaluate both lattices to form a BCC lattice. return Noise3_UnrotatedBase(seed, xr, yr, zr); } /** * 3D OpenSimplex2S/SuperSimplex noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in whatever your use case is. * If Y is vertical in world coordinates, call Noise3_ImproveXZ(x, Y, z). * If Z is vertical in world coordinates, call Noise3_ImproveXZ(x, Z, y) or use Noise3_ImproveXY. * For a time varied animation, call Noise3_ImproveXZ(x, T, y) or use Noise3_ImproveXY. */ public static float Noise3_ImproveXZ(long seed, double x, double y, double z) { // Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal, // and the planes formed by XZ are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * -0.211324865405187; double yy = y * ROOT3OVER3; double xr = x + s2 + yy; double zr = z + s2 + yy; double yr = xz * -ROOT3OVER3 + yy; // Evaluate both lattices to form a BCC lattice. return Noise3_UnrotatedBase(seed, xr, yr, zr); } /** * 3D OpenSimplex2S/SuperSimplex noise, fallback rotation option * Use Noise3_ImproveXY or Noise3_ImproveXZ instead, wherever appropriate. * They have less diagonal bias. This function's best use is as a fallback. */ public static float Noise3_Fallback(long seed, double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce a familiar look. // Orthonormal rotation. Not a skew transform. double r = FALLBACK_ROTATE3 * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; // Evaluate both lattices to form a BCC lattice. return Noise3_UnrotatedBase(seed, xr, yr, zr); } /** * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. * Lookup table implementation inspired by DigitalShadow. * It was actually faster to narrow down the points in the loop itself, * than to build up the index with enough info to isolate 8 points. */ private static float Noise3_UnrotatedBase(long seed, double xr, double yr, double zr) { // Get base points and offsets. int xrb = FastFloor(xr), yrb = FastFloor(yr), zrb = FastFloor(zr); float xi = (float)(xr - xrb), yi = (float)(yr - yrb), zi = (float)(zr - zrb); // Prime pre-multiplication for hash. Also flip seed for second lattice copy. long xrbp = xrb * PRIME_X, yrbp = yrb * PRIME_Y, zrbp = zrb * PRIME_Z; long seed2 = seed ^ -0x52D547B2E96ED629L; // -1 if positive, 0 if negative. int xNMask = (int)(-0.5f - xi), yNMask = (int)(-0.5f - yi), zNMask = (int)(-0.5f - zi); // First vertex. float x0 = xi + xNMask; float y0 = yi + yNMask; float z0 = zi + zNMask; float a0 = RSQUARED_3D - x0 * x0 - y0 * y0 - z0 * z0; float value = (a0 * a0) * (a0 * a0) * Grad(seed, xrbp + (xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), x0, y0, z0); // Second vertex. float x1 = xi - 0.5f; float y1 = yi - 0.5f; float z1 = zi - 0.5f; float a1 = RSQUARED_3D - x1 * x1 - y1 * y1 - z1 * z1; value += (a1 * a1) * (a1 * a1) * Grad(seed2, xrbp + PRIME_X, yrbp + PRIME_Y, zrbp + PRIME_Z, x1, y1, z1); // Shortcuts for building the remaining falloffs. // Derived by subtracting the polynomials with the offsets plugged in. float xAFlipMask0 = ((xNMask | 1) << 1) * x1; float yAFlipMask0 = ((yNMask | 1) << 1) * y1; float zAFlipMask0 = ((zNMask | 1) << 1) * z1; float xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0f; float yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0f; float zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0f; bool skip5 = false; float a2 = xAFlipMask0 + a0; if (a2 > 0) { float x2 = x0 - (xNMask | 1); float y2 = y0; float z2 = z0; value += (a2 * a2) * (a2 * a2) * Grad(seed, xrbp + (~xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), x2, y2, z2); } else { float a3 = yAFlipMask0 + zAFlipMask0 + a0; if (a3 > 0) { float x3 = x0; float y3 = y0 - (yNMask | 1); float z3 = z0 - (zNMask | 1); value += (a3 * a3) * (a3 * a3) * Grad(seed, xrbp + (xNMask & PRIME_X), yrbp + (~yNMask & PRIME_Y), zrbp + (~zNMask & PRIME_Z), x3, y3, z3); } float a4 = xAFlipMask1 + a1; if (a4 > 0) { float x4 = (xNMask | 1) + x1; float y4 = y1; float z4 = z1; value += (a4 * a4) * (a4 * a4) * Grad(seed2, xrbp + (xNMask & unchecked(PRIME_X * 2)), yrbp + PRIME_Y, zrbp + PRIME_Z, x4, y4, z4); skip5 = true; } } bool skip9 = false; float a6 = yAFlipMask0 + a0; if (a6 > 0) { float x6 = x0; float y6 = y0 - (yNMask | 1); float z6 = z0; value += (a6 * a6) * (a6 * a6) * Grad(seed, xrbp + (xNMask & PRIME_X), yrbp + (~yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), x6, y6, z6); } else { float a7 = xAFlipMask0 + zAFlipMask0 + a0; if (a7 > 0) { float x7 = x0 - (xNMask | 1); float y7 = y0; float z7 = z0 - (zNMask | 1); value += (a7 * a7) * (a7 * a7) * Grad(seed, xrbp + (~xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (~zNMask & PRIME_Z), x7, y7, z7); } float a8 = yAFlipMask1 + a1; if (a8 > 0) { float x8 = x1; float y8 = (yNMask | 1) + y1; float z8 = z1; value += (a8 * a8) * (a8 * a8) * Grad(seed2, xrbp + PRIME_X, yrbp + (yNMask & (PRIME_Y << 1)), zrbp + PRIME_Z, x8, y8, z8); skip9 = true; } } bool skipD = false; float aA = zAFlipMask0 + a0; if (aA > 0) { float xA = x0; float yA = y0; float zA = z0 - (zNMask | 1); value += (aA * aA) * (aA * aA) * Grad(seed, xrbp + (xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (~zNMask & PRIME_Z), xA, yA, zA); } else { float aB = xAFlipMask0 + yAFlipMask0 + a0; if (aB > 0) { float xB = x0 - (xNMask | 1); float yB = y0 - (yNMask | 1); float zB = z0; value += (aB * aB) * (aB * aB) * Grad(seed, xrbp + (~xNMask & PRIME_X), yrbp + (~yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), xB, yB, zB); } float aC = zAFlipMask1 + a1; if (aC > 0) { float xC = x1; float yC = y1; float zC = (zNMask | 1) + z1; value += (aC * aC) * (aC * aC) * Grad(seed2, xrbp + PRIME_X, yrbp + PRIME_Y, zrbp + (zNMask & (PRIME_Z << 1)), xC, yC, zC); skipD = true; } } if (!skip5) { float a5 = yAFlipMask1 + zAFlipMask1 + a1; if (a5 > 0) { float x5 = x1; float y5 = (yNMask | 1) + y1; float z5 = (zNMask | 1) + z1; value += (a5 * a5) * (a5 * a5) * Grad(seed2, xrbp + PRIME_X, yrbp + (yNMask & (PRIME_Y << 1)), zrbp + (zNMask & (PRIME_Z << 1)), x5, y5, z5); } } if (!skip9) { float a9 = xAFlipMask1 + zAFlipMask1 + a1; if (a9 > 0) { float x9 = (xNMask | 1) + x1; float y9 = y1; float z9 = (zNMask | 1) + z1; value += (a9 * a9) * (a9 * a9) * Grad(seed2, xrbp + (xNMask & unchecked(PRIME_X * 2)), yrbp + PRIME_Y, zrbp + (zNMask & (PRIME_Z << 1)), x9, y9, z9); } } if (!skipD) { float aD = xAFlipMask1 + yAFlipMask1 + a1; if (aD > 0) { float xD = (xNMask | 1) + x1; float yD = (yNMask | 1) + y1; float zD = z1; value += (aD * aD) * (aD * aD) * Grad(seed2, xrbp + (xNMask & (PRIME_X << 1)), yrbp + (yNMask & (PRIME_Y << 1)), zrbp + PRIME_Z, xD, yD, zD); } } return value; } /** * 4D SuperSimplex noise, with XYZ oriented like Noise3_ImproveXY * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * in a space where Z is vertical */ public static float Noise4_ImproveXYZ_ImproveXY(long seed, double x, double y, double z, double w) { double xy = x + y; double s2 = xy * -0.21132486540518699998; double zz = z * 0.28867513459481294226; double ww = w * 1.118033988749894; double xr = x + (zz + ww + s2), yr = y + (zz + ww + s2); double zr = xy * -0.57735026918962599998 + (zz + ww); double wr = z * -0.866025403784439 + ww; return Noise4_UnskewedBase(seed, xr, yr, zr, wr); } /** * 4D SuperSimplex noise, with XYZ oriented like Noise3_ImproveXZ * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * in a space where Y is vertical */ public static float Noise4_ImproveXYZ_ImproveXZ(long seed, double x, double y, double z, double w) { double xz = x + z; double s2 = xz * -0.21132486540518699998; double yy = y * 0.28867513459481294226; double ww = w * 1.118033988749894; double xr = x + (yy + ww + s2), zr = z + (yy + ww + s2); double yr = xz * -0.57735026918962599998 + (yy + ww); double wr = y * -0.866025403784439 + ww; return Noise4_UnskewedBase(seed, xr, yr, zr, wr); } /** * 4D SuperSimplex noise, with XYZ oriented like Noise3_Fallback * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * where there isn't a clear distinction between horizontal and vertical */ public static float Noise4_ImproveXYZ(long seed, double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 1.118033988749894; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return Noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D SuperSimplex noise, fallback lattice orientation. */ public static float Noise4_Fallback(long seed, double x, double y, double z, double w) { // Get points for A4 lattice double s = SKEW_4D * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return Noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D SuperSimplex noise base. * Using ultra-simple 4x4x4x4 lookup partitioning. * This isn't as elegant or SIMD/GPU/etc. portable as other approaches, * but it competes performance-wise with optimized 2014 OpenSimplex. */ private static float Noise4_UnskewedBase(long seed, double xs, double ys, double zs, double ws) { // Get base points and offsets int xsb = FastFloor(xs), ysb = FastFloor(ys), zsb = FastFloor(zs), wsb = FastFloor(ws); float xsi = (float)(xs - xsb), ysi = (float)(ys - ysb), zsi = (float)(zs - zsb), wsi = (float)(ws - wsb); // Unskewed offsets float ssi = (xsi + ysi + zsi + wsi) * UNSKEW_4D; float xi = xsi + ssi, yi = ysi + ssi, zi = zsi + ssi, wi = wsi + ssi; // Prime pre-multiplication for hash. long xsvp = xsb * PRIME_X, ysvp = ysb * PRIME_Y, zsvp = zsb * PRIME_Z, wsvp = wsb * PRIME_W; // Index into initial table. int index = ((FastFloor(xs * 4) & 3) << 0) | ((FastFloor(ys * 4) & 3) << 2) | ((FastFloor(zs * 4) & 3) << 4) | ((FastFloor(ws * 4) & 3) << 6); // Point contributions float value = 0; (int secondaryIndexStart, int secondaryIndexStop) = LOOKUP_4D_A[index]; for (int i = secondaryIndexStart; i < secondaryIndexStop; i++) { LatticeVertex4D c = LOOKUP_4D_B[i]; float dx = xi + c.dx, dy = yi + c.dy, dz = zi + c.dz, dw = wi + c.dw; float a = (dx * dx + dy * dy) + (dz * dz + dw * dw); if (a < RSQUARED_4D) { a -= RSQUARED_4D; a *= a; value += a * a * Grad(seed, xsvp + c.xsvp, ysvp + c.ysvp, zsvp + c.zsvp, wsvp + c.wsvp, dx, dy, dz, dw); } } return value; } /* * Utility */ [MethodImpl(MethodImplOptions.AggressiveInlining)] private static float Grad(long seed, long xsvp, long ysvp, float dx, float dy) { long hash = seed ^ xsvp ^ ysvp; hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_2D_EXPONENT + 1); int gi = (int)hash & ((N_GRADS_2D - 1) << 1); return GRADIENTS_2D[gi | 0] * dx + GRADIENTS_2D[gi | 1] * dy; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static float Grad(long seed, long xrvp, long yrvp, long zrvp, float dx, float dy, float dz) { long hash = (seed ^ xrvp) ^ (yrvp ^ zrvp); hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_3D_EXPONENT + 2); int gi = (int)hash & ((N_GRADS_3D - 1) << 2); return GRADIENTS_3D[gi | 0] * dx + GRADIENTS_3D[gi | 1] * dy + GRADIENTS_3D[gi | 2] * dz; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static float Grad(long seed, long xsvp, long ysvp, long zsvp, long wsvp, float dx, float dy, float dz, float dw) { long hash = seed ^ (xsvp ^ ysvp) ^ (zsvp ^ wsvp); hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_4D_EXPONENT + 2); int gi = (int)hash & ((N_GRADS_4D - 1) << 2); return (GRADIENTS_4D[gi | 0] * dx + GRADIENTS_4D[gi | 1] * dy) + (GRADIENTS_4D[gi | 2] * dz + GRADIENTS_4D[gi | 3] * dw); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int FastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } /* * Lookup Tables & Gradients */ private static readonly float[] GRADIENTS_2D; private static readonly float[] GRADIENTS_3D; private static readonly float[] GRADIENTS_4D; private static readonly (short SecondaryIndexStart, short SecondaryIndexStop)[] LOOKUP_4D_A; private static readonly LatticeVertex4D[] LOOKUP_4D_B; static OpenSimplex2S() { GRADIENTS_2D = new float[N_GRADS_2D * 2]; float[] grad2 = { 0.38268343236509f, 0.923879532511287f, 0.923879532511287f, 0.38268343236509f, 0.923879532511287f, -0.38268343236509f, 0.38268343236509f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, 0.38268343236509f, -0.38268343236509f, 0.923879532511287f, //-------------------------------------// 0.130526192220052f, 0.99144486137381f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.130526192220052f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.130526192220052f, 0.99144486137381f, }; for (int i = 0; i < grad2.Length; i++) { grad2[i] = (float)(grad2[i] / NORMALIZER_2D); } for (int i = 0, j = 0; i < GRADIENTS_2D.Length; i++, j++) { if (j == grad2.Length) j = 0; GRADIENTS_2D[i] = grad2[j]; } GRADIENTS_3D = new float[N_GRADS_3D * 4]; float[] grad3 = { 2.22474487139f, 2.22474487139f, -1.0f, 0.0f, 2.22474487139f, 2.22474487139f, 1.0f, 0.0f, 3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, 1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -2.22474487139f, 2.22474487139f, -1.0f, 0.0f, -2.22474487139f, 2.22474487139f, 1.0f, 0.0f, -1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, -1.0f, -2.22474487139f, -2.22474487139f, 0.0f, 1.0f, -2.22474487139f, -2.22474487139f, 0.0f, 0.0f, -3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, -1.1721513422464978f, -3.0862664687972017f, 0.0f, -1.0f, -2.22474487139f, 2.22474487139f, 0.0f, 1.0f, -2.22474487139f, 2.22474487139f, 0.0f, 0.0f, -1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -3.0862664687972017f, 1.1721513422464978f, 0.0f, //--------------------------------------------------------------------// -2.22474487139f, -2.22474487139f, -1.0f, 0.0f, -2.22474487139f, -2.22474487139f, 1.0f, 0.0f, -3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, -1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, -2.22474487139f, -1.0f, -2.22474487139f, 0.0f, -2.22474487139f, 1.0f, -2.22474487139f, 0.0f, -1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, -3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, -2.22474487139f, -1.0f, 2.22474487139f, 0.0f, -2.22474487139f, 1.0f, 2.22474487139f, 0.0f, -3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, -1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, -1.0f, 2.22474487139f, -2.22474487139f, 0.0f, 1.0f, 2.22474487139f, -2.22474487139f, 0.0f, 0.0f, 1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, 3.0862664687972017f, -1.1721513422464978f, 0.0f, -1.0f, 2.22474487139f, 2.22474487139f, 0.0f, 1.0f, 2.22474487139f, 2.22474487139f, 0.0f, 0.0f, 3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, 1.1721513422464978f, 3.0862664687972017f, 0.0f, 2.22474487139f, -2.22474487139f, -1.0f, 0.0f, 2.22474487139f, -2.22474487139f, 1.0f, 0.0f, 1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, 3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, 2.22474487139f, -1.0f, -2.22474487139f, 0.0f, 2.22474487139f, 1.0f, -2.22474487139f, 0.0f, 3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, 1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, 2.22474487139f, -1.0f, 2.22474487139f, 0.0f, 2.22474487139f, 1.0f, 2.22474487139f, 0.0f, 1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, 3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, }; for (int i = 0; i < grad3.Length; i++) { grad3[i] = (float)(grad3[i] / NORMALIZER_3D); } for (int i = 0, j = 0; i < GRADIENTS_3D.Length; i++, j++) { if (j == grad3.Length) j = 0; GRADIENTS_3D[i] = grad3[j]; } GRADIENTS_4D = new float[N_GRADS_4D * 4]; float[] grad4 = { -0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, -0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, -0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, -0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, -0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, -0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, -0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, -0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, -0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, 0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, 0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, //------------------------------------------------------------------------------------------// -0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, -0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, -0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, -0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, -0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, -0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, -0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, -0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, -0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, -0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, -0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, -0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, -0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, -0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, -0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, 0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, -0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, -0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, 0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, 0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, 0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, -0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, -0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, 0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, -0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, 0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, -0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, 0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, 0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, -0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, -0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, 0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, -0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, 0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, -0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, 0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, -0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, -0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, 0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, 0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, 0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, 0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, 0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, 0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, 0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, 0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, 0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, 0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, -0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, 0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, 0.8586508742123365f, 0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, 0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, 0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, -0.044802370851755174f, 0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, 0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, 0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, 0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, -0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, -0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, 0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, 0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, 0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, 0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, 0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, 0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, }; for (int i = 0; i < grad4.Length; i++) { grad4[i] = (float)(grad4[i] / NORMALIZER_4D); } for (int i = 0, j = 0; i < GRADIENTS_4D.Length; i++, j++) { if (j == grad4.Length) j = 0; GRADIENTS_4D[i] = grad4[j]; } int[][] lookup4DVertexCodes = { new int[] { 0x15, 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x01, 0x05, 0x11, 0x15, 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x01, 0x15, 0x16, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA, 0xAB }, new int[] { 0x04, 0x05, 0x14, 0x15, 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x6A, 0x9A, 0xAA, 0xAB }, new int[] { 0x04, 0x15, 0x19, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA, 0xAE }, new int[] { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x5E, 0x6A, 0x9A, 0xAA, 0xAE }, new int[] { 0x05, 0x15, 0x1A, 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x5E, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x6B, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xAA }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x6B, 0x9A, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x9A, 0xAA, 0xAE }, new int[] { 0x15, 0x1A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x10, 0x11, 0x14, 0x15, 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x67, 0x6A, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x6B, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x6D, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x6E, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x10, 0x15, 0x25, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA, 0xBA }, new int[] { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0x76, 0xA6, 0xAA, 0xBA }, new int[] { 0x11, 0x15, 0x26, 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x67, 0x6A, 0x76, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA6, 0xAA, 0xBA }, new int[] { 0x15, 0x26, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0x79, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x14, 0x15, 0x29, 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0x6D, 0x79, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x29, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x7A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, new int[] { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x9A, 0x9B, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, new int[] { 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x59, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x56, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA }, new int[] { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, new int[] { 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x6A, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, new int[] { 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, new int[] { 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x95, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA }, new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, new int[] { 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA }, new int[] { 0x51, 0x55, 0x61, 0x65, 0x66, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x64, 0x65, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA }, new int[] { 0x40, 0x45, 0x51, 0x54, 0x55, 0x85, 0x91, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA, 0xEA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xD6, 0xEA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x86, 0x92, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB, 0xD6, 0xEA, 0xEB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x86, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xD9, 0xEA }, new int[] { 0x45, 0x55, 0x59, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x89, 0x95, 0x98, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE, 0xD9, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x59, 0x89, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xDA, 0xEA, 0xEF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x91, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x92, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x94, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x95, 0x98, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, new int[] { 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xEA, 0xEF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xE5, 0xEA }, new int[] { 0x51, 0x55, 0x65, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x65, 0x94, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x55, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x94, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x59, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, new int[] { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xEA }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA1, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA, 0xE5, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x65, 0x95, 0xA1, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xE6, 0xEA, 0xFB }, new int[] { 0x54, 0x55, 0x65, 0x95, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, new int[] { 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xEA, 0xFB }, new int[] { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, new int[] { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xEA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xE9, 0xEA, 0xFE }, new int[] { 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA, 0xFE }, new int[] { 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA, 0xEA }, }; LatticeVertex4D[] latticeVerticesByCode = new LatticeVertex4D[256]; for (int i = 0; i < 256; i++) { int cx = ((i >> 0) & 3) - 1; int cy = ((i >> 2) & 3) - 1; int cz = ((i >> 4) & 3) - 1; int cw = ((i >> 6) & 3) - 1; latticeVerticesByCode[i] = new LatticeVertex4D(cx, cy, cz, cw); } int nLatticeVerticesTotal = 0; for (int i = 0; i < 256; i++) { nLatticeVerticesTotal += lookup4DVertexCodes[i].Length; } LOOKUP_4D_A = new (short SecondaryIndexStart, short SecondaryIndexStop)[256]; LOOKUP_4D_B = new LatticeVertex4D[nLatticeVerticesTotal]; for (int i = 0, j = 0; i < 256; i++) { LOOKUP_4D_A[i] = ((short)j, (short)(j + lookup4DVertexCodes[i].Length)); for (int k = 0; k < lookup4DVertexCodes[i].Length; k++) { LOOKUP_4D_B[j++] = latticeVerticesByCode[lookup4DVertexCodes[i][k]]; } } } private class LatticeVertex4D { public readonly float dx, dy, dz, dw; public readonly long xsvp, ysvp, zsvp, wsvp; public LatticeVertex4D(int xsv, int ysv, int zsv, int wsv) { this.xsvp = xsv * PRIME_X; this.ysvp = ysv * PRIME_Y; this.zsvp = zsv * PRIME_Z; this.wsvp = wsv * PRIME_W; float ssv = (xsv + ysv + zsv + wsv) * UNSKEW_4D; this.dx = -xsv - ssv; this.dy = -ysv - ssv; this.dz = -zsv - ssv; this.dw = -wsv - ssv; } } } ================================================ FILE: glsl/OpenSimplex2.glsl ================================================ //////////////// K.jpg's Re-oriented 4-Point BCC Noise (OpenSimplex2) //////////////// ////////////////////// Output: vec4(dF/dx, dF/dy, dF/dz, value) ////////////////////// // Inspired by Stefan Gustavson's noise vec4 permute(vec4 t) { return t * (t * 34.0 + 133.0); } // Gradient set is a normalized expanded rhombic dodecahedron vec3 grad(float hash) { // Random vertex of a cube, +/- 1 each vec3 cube = mod(floor(hash / vec3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0; // Random edge of the three edges connected to that vertex // Also a cuboctahedral vertex // And corresponds to the face of its dual, the rhombic dodecahedron vec3 cuboct = cube; cuboct[int(hash / 16.0)] = 0.0; // In a funky way, pick one of the four points on the rhombic face float type = mod(floor(hash / 8.0), 2.0); vec3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct)); // Expand it so that the new edges are the same length // as the existing ones vec3 grad = cuboct * 1.22474487139 + rhomb; // To make all gradients the same length, we only need to shorten the // second type of vector. We also put in the whole noise scale constant. // The compiler should reduce it into the existing floats. I think. grad *= (1.0 - 0.042942436724648037 * type) * 32.80201376986577; return grad; } // BCC lattice split up into 2 cube lattices vec4 openSimplex2Base(vec3 X) { // First half-lattice, closest edge vec3 v1 = round(X); vec3 d1 = X - v1; vec3 score1 = abs(d1); vec3 dir1 = step(max(score1.yzx, score1.zxy), score1); vec3 v2 = v1 + dir1 * sign(d1); vec3 d2 = X - v2; // Second half-lattice, closest edge vec3 X2 = X + 144.5; vec3 v3 = round(X2); vec3 d3 = X2 - v3; vec3 score2 = abs(d3); vec3 dir2 = step(max(score2.yzx, score2.zxy), score2); vec3 v4 = v3 + dir2 * sign(d3); vec3 d4 = X2 - v4; // Gradient hashes for the four points, two from each half-lattice vec4 hashes = permute(mod(vec4(v1.x, v2.x, v3.x, v4.x), 289.0)); hashes = permute(mod(hashes + vec4(v1.y, v2.y, v3.y, v4.y), 289.0)); hashes = mod(permute(mod(hashes + vec4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0); // Gradient extrapolations & kernel function vec4 a = max(0.5 - vec4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0); vec4 aa = a * a; vec4 aaaa = aa * aa; vec3 g1 = grad(hashes.x); vec3 g2 = grad(hashes.y); vec3 g3 = grad(hashes.z); vec3 g4 = grad(hashes.w); vec4 extrapolations = vec4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4)); // Derivatives of the noise vec3 derivative = -8.0 * mat4x3(d1, d2, d3, d4) * (aa * a * extrapolations) + mat4x3(g1, g2, g3, g4) * aaaa; // Return it all as a vec4 return vec4(derivative, dot(aaaa, extrapolations)); } // Use this if you don't want Z to look different from X and Y vec4 openSimplex2_Conventional(vec3 X) { // Rotate around the main diagonal. Not a skew transform. vec4 result = openSimplex2Base(dot(X, vec3(2.0/3.0)) - X); return vec4(dot(result.xyz, vec3(2.0/3.0)) - result.xyz, result.w); } // Use this if you want to show X and Y in a plane, then use Z for time, vertical, etc. vec4 openSimplex2_ImproveXY(vec3 X) { // Rotate so Z points down the main diagonal. Not a skew transform. mat3 orthonormalMap = mat3( 0.788675134594813, -0.211324865405187, -0.577350269189626, -0.211324865405187, 0.788675134594813, -0.577350269189626, 0.577350269189626, 0.577350269189626, 0.577350269189626); vec4 result = openSimplex2Base(orthonormalMap * X); return vec4(result.xyz * orthonormalMap, result.w); } //////////////////////////////// End noise code //////////////////////////////// ================================================ FILE: glsl/OpenSimplex2S.glsl ================================================ /////////////// K.jpg's Re-oriented 8-Point BCC Noise (OpenSimplex2S) //////////////// ////////////////////// Output: vec4(dF/dx, dF/dy, dF/dz, value) ////////////////////// // Borrowed from Stefan Gustavson's noise code vec4 permute(vec4 t) { return t * (t * 34.0 + 133.0); } // Gradient set is a normalized expanded rhombic dodecahedron vec3 grad(float hash) { // Random vertex of a cube, +/- 1 each vec3 cube = mod(floor(hash / vec3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0; // Random edge of the three edges connected to that vertex // Also a cuboctahedral vertex // And corresponds to the face of its dual, the rhombic dodecahedron vec3 cuboct = cube; cuboct[int(hash / 16.0)] = 0.0; // In a funky way, pick one of the four points on the rhombic face float type = mod(floor(hash / 8.0), 2.0); vec3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct)); // Expand it so that the new edges are the same length // as the existing ones vec3 grad = cuboct * 1.22474487139 + rhomb; // To make all gradients the same length, we only need to shorten the // second type of vector. We also put in the whole noise scale constant. // The compiler should reduce it into the existing floats. I think. grad *= (1.0 - 0.042942436724648037 * type) * 3.5946317686139184; return grad; } // BCC lattice split up into 2 cube lattices vec4 openSimplex2SDerivativesPart(vec3 X) { vec3 b = floor(X); vec4 i4 = vec4(X - b, 2.5); // Pick between each pair of oppposite corners in the cube. vec3 v1 = b + floor(dot(i4, vec4(.25))); vec3 v2 = b + vec3(1, 0, 0) + vec3(-1, 1, 1) * floor(dot(i4, vec4(-.25, .25, .25, .35))); vec3 v3 = b + vec3(0, 1, 0) + vec3(1, -1, 1) * floor(dot(i4, vec4(.25, -.25, .25, .35))); vec3 v4 = b + vec3(0, 0, 1) + vec3(1, 1, -1) * floor(dot(i4, vec4(.25, .25, -.25, .35))); // Gradient hashes for the four vertices in this half-lattice. vec4 hashes = permute(mod(vec4(v1.x, v2.x, v3.x, v4.x), 289.0)); hashes = permute(mod(hashes + vec4(v1.y, v2.y, v3.y, v4.y), 289.0)); hashes = mod(permute(mod(hashes + vec4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0); // Gradient extrapolations & kernel function vec3 d1 = X - v1; vec3 d2 = X - v2; vec3 d3 = X - v3; vec3 d4 = X - v4; vec4 a = max(0.75 - vec4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0); vec4 aa = a * a; vec4 aaaa = aa * aa; vec3 g1 = grad(hashes.x); vec3 g2 = grad(hashes.y); vec3 g3 = grad(hashes.z); vec3 g4 = grad(hashes.w); vec4 extrapolations = vec4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4)); // Derivatives of the noise vec3 derivative = -8.0 * mat4x3(d1, d2, d3, d4) * (aa * a * extrapolations) + mat4x3(g1, g2, g3, g4) * aaaa; // Return it all as a vec4 return vec4(derivative, dot(aaaa, extrapolations)); } // Use this if you don't want Z to look different from X and Y vec4 openSimplex2SDerivatives_Conventional(vec3 X) { X = dot(X, vec3(2.0/3.0)) - X; vec4 result = openSimplex2SDerivativesPart(X) + openSimplex2SDerivativesPart(X + 144.5); return vec4(dot(result.xyz, vec3(2.0/3.0)) - result.xyz, result.w); } // Use this if you want to show X and Y in a plane, then use Z for time, vertical, etc. vec4 openSimplex2SDerivatives_ImproveXY(vec3 X) { // Not a skew transform. mat3 orthonormalMap = mat3( 0.788675134594813, -0.211324865405187, -0.577350269189626, -0.211324865405187, 0.788675134594813, -0.577350269189626, 0.577350269189626, 0.577350269189626, 0.577350269189626); X = orthonormalMap * X; vec4 result = openSimplex2SDerivativesPart(X) + openSimplex2SDerivativesPart(X + 144.5); return vec4(result.xyz * orthonormalMap, result.w); } //////////////////////////////// End noise code //////////////////////////////// ================================================ FILE: hlsl/OpenSimplex2.hlsl ================================================ #ifndef __bcc_noise_4_hlsl_ #define __bcc_noise_4_hlsl_ /////////////// K.jpg's Simplex-like Re-oriented 4-Point BCC Noise /////////////// //////////////////// Output: float4(dF/dx, dF/dy, dF/dz, value) //////////////////// // Inspired by Stefan Gustavson's noise float4 permute(float4 t) { return t * (t * 34.0 + 133.0); } // https://stackoverflow.com/questions/7610631/glsl-mod-vs-hlsl-fmod float mod(float x, float y) { return x - y * floor(x / y); } float2 mod(float2 x, float2 y) { return x - y * floor(x / y); } float3 mod(float3 x, float3 y) { return x - y * floor(x / y); } float4 mod(float4 x, float4 y) { return x - y * floor(x / y); } // Gradient set is a normalized expanded rhombic dodecahedron float3 grad(float hash) { // Random vertex of a cube, +/- 1 each float3 cube = mod(floor(hash / float3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0; // Random edge of the three edges connected to that vertex // Also a cuboctahedral vertex // And corresponds to the face of its dual, the rhombic dodecahedron float3 cuboct = cube; int index = int(hash / 16.0); if (index == 0) cuboct.x = 0.0; else if (index == 1) cuboct.y = 0.0; else cuboct.z = 0.0; // In a funky way, pick one of the four points on the rhombic face float type = mod(floor(hash / 8.0), 2.0); float3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct)); // Expand it so that the new edges are the same length // as the existing ones float3 grad = cuboct * 1.22474487139 + rhomb; // To make all gradients the same length, we only need to shorten the // second type of vector. We also put in the whole noise scale constant. // The compiler should reduce it into the existing floats. I think. grad *= (1.0 - 0.042942436724648037 * type) * 32.80201376986577; return grad; } // BCC lattice split up into 2 cube lattices float4 openSimplex2Base(float3 X) { // First half-lattice, closest edge float3 v1 = round(X); float3 d1 = X - v1; float3 score1 = abs(d1); float3 dir1 = step(max(score1.yzx, score1.zxy), score1); float3 v2 = v1 + dir1 * sign(d1); float3 d2 = X - v2; // Second half-lattice, closest edge float3 X2 = X + 144.5; float3 v3 = round(X2); float3 d3 = X2 - v3; float3 score2 = abs(d3); float3 dir2 = step(max(score2.yzx, score2.zxy), score2); float3 v4 = v3 + dir2 * sign(d3); float3 d4 = X2 - v4; // Gradient hashes for the four points, two from each half-lattice float4 hashes = permute(mod(float4(v1.x, v2.x, v3.x, v4.x), 289.0)); hashes = permute(mod(hashes + float4(v1.y, v2.y, v3.y, v4.y), 289.0)); hashes = mod(permute(mod(hashes + float4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0); // Gradient extrapolations & kernel function float4 a = max(0.5 - float4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0); float4 aa = a * a; float4 aaaa = aa * aa; float3 g1 = grad(hashes.x); float3 g2 = grad(hashes.y); float3 g3 = grad(hashes.z); float3 g4 = grad(hashes.w); float4 extrapolations = float4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4)); float4x3 derivativeMatrix = { d1, d2, d3, d4 }; float4x3 gradientMatrix = { g1, g2, g3, g4 }; // Derivatives of the noise float3 derivative = -8.0 * mul(aa * a * extrapolations, derivativeMatrix) + mul(aaaa, gradientMatrix); // Return it all as a float4 return float4(derivative, dot(aaaa, extrapolations)); } // Use this if you don't want Z to look different from X and Y float4 openSimplex2_Conventional(float3 X) { // Rotate around the main diagonal. Not a skew transform. float4 result = openSimplex2Base(dot(X, float3(2.0 / 3.0, 2.0 / 3.0, 2.0 / 3.0)) - X); return float4(dot(result.xyz, float3(2.0 / 3.0, 2.0 / 3.0, 2.0 / 3.0)) - result.xyz, result.w); } // Use this if you want to show X and Y in a plane, then use Z for time, vertical, etc. float4 openSimplex2_ImproveXY(float3 X) { // Rotate so Z points down the main diagonal. Not a skew transform. float3x3 orthonormalMap = { 0.788675134594813, -0.211324865405187, -0.577350269189626, -0.211324865405187, 0.788675134594813, -0.577350269189626, 0.577350269189626, 0.577350269189626, 0.577350269189626 }; float4 result = openSimplex2Base(mul(X, orthonormalMap)); return float4(mul(orthonormalMap, result.xyz), result.w); } //////////////////////////////// End noise code //////////////////////////////// #endif ================================================ FILE: hlsl/OpenSimplex2S.hlsl ================================================ #ifndef __bcc_noise_8_hlsl_ #define __bcc_noise_8_hlsl_ ////////////////// K.jpg's Smooth Re-oriented 8-Point BCC Noise ////////////////// //////////////////// Output: float4(dF/dx, dF/dy, dF/dz, value) //////////////////// // Borrowed from Stefan Gustavson's noise code float4 permute(float4 t) { return t * (t * 34.0 + 133.0); } float mod(float x, float y) { return x - y * floor(x / y); } float2 mod(float2 x, float2 y) { return x - y * floor(x / y); } float3 mod(float3 x, float3 y) { return x - y * floor(x / y); } float4 mod(float4 x, float4 y) { return x - y * floor(x / y); } // Gradient set is a normalized expanded rhombic dodecahedron float3 grad(float hash) { // Random vertex of a cube, +/- 1 each float3 cube = mod(floor(hash / float3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0; // Random edge of the three edges connected to that vertex // Also a cuboctahedral vertex // And corresponds to the face of its dual, the rhombic dodecahedron float3 cuboct = cube; int index = int(hash / 16.0); if (index == 0) cuboct.x = 0.0; else if (index == 1) cuboct.y = 0.0; else cuboct.z = 0.0; // In a funky way, pick one of the four points on the rhombic face float type = mod(floor(hash / 8.0), 2.0); float3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct)); // Expand it so that the new edges are the same length // as the existing ones float3 grad = cuboct * 1.22474487139 + rhomb; // To make all gradients the same length, we only need to shorten the // second type of vector. We also put in the whole noise scale constant. // The compiler should reduce it into the existing floats. I think. grad *= (1.0 - 0.042942436724648037 * type) * 3.5946317686139184; return grad; } // BCC lattice split up into 2 cube lattices float4 openSimplex2SDerivativesPart(float3 X) { float3 b = floor(X); float4 i4 = float4(X - b, 2.5); // Pick between each pair of oppposite corners in the cube. float3 v1 = b + floor(dot(i4, float4(.25, .25, .25, .25))); float3 v2 = b + float3(1, 0, 0) + float3(-1, 1, 1) * floor(dot(i4, float4(-.25, .25, .25, .35))); float3 v3 = b + float3(0, 1, 0) + float3(1, -1, 1) * floor(dot(i4, float4(.25, -.25, .25, .35))); float3 v4 = b + float3(0, 0, 1) + float3(1, 1, -1) * floor(dot(i4, float4(.25, .25, -.25, .35))); // Gradient hashes for the four vertices in this half-lattice. float4 hashes = permute(mod(float4(v1.x, v2.x, v3.x, v4.x), 289.0)); hashes = permute(mod(hashes + float4(v1.y, v2.y, v3.y, v4.y), 289.0)); hashes = mod(permute(mod(hashes + float4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0); // Gradient extrapolations & kernel function float3 d1 = X - v1; float3 d2 = X - v2; float3 d3 = X - v3; float3 d4 = X - v4; float4 a = max(0.75 - float4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0); float4 aa = a * a; float4 aaaa = aa * aa; float3 g1 = grad(hashes.x); float3 g2 = grad(hashes.y); float3 g3 = grad(hashes.z); float3 g4 = grad(hashes.w); float4 extrapolations = float4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4)); float4x3 derivativeMatrix = { d1, d2, d3, d4 }; float4x3 gradientMatrix = { g1, g2, g3, g4 }; // Derivatives of the noise float3 derivative = -8.0 * mul(aa * a * extrapolations, derivativeMatrix) + mul(aaaa, gradientMatrix); // Return it all as a float4 return float4(derivative, dot(aaaa, extrapolations)); } // Use this if you don't want Z to look different from X and Y float4 openSimplex2SDerivatives_Conventional(float3 X) { X = dot(X, float3(2.0 / 3.0, 2.0 / 3.0, 2.0 / 3.0)) - X; float4 result = openSimplex2SDerivativesPart(X) + openSimplex2SDerivativesPart(X + 144.5); return float4(dot(result.xyz, float3(2.0 / 3.0, 2.0 / 3.0, 2.0 / 3.0)) - result.xyz, result.w); } // Use this if you want to show X and Y in a plane, then use Z for time, vertical, etc. float4 openSimplex2SDerivatives_ImproveXY(float3 X) { // Not a skew transform. float3x3 orthonormalMap = { 0.788675134594813, -0.211324865405187, -0.577350269189626, -0.211324865405187, 0.788675134594813, -0.577350269189626, 0.577350269189626, 0.577350269189626, 0.577350269189626 }; X = mul(X, orthonormalMap); float4 result = openSimplex2SDerivativesPart(X) + openSimplex2SDerivativesPart(X + 144.5); return float4(mul(orthonormalMap, result.xyz), result.w); } //////////////////////////////// End noise code //////////////////////////////// #endif ================================================ FILE: hlsl/UNLICENSE ================================================ This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. 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 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. For more information, please refer to ================================================ FILE: java/OpenSimplex2.java ================================================ /** * K.jpg's OpenSimplex 2, faster variant */ public class OpenSimplex2 { private static final long PRIME_X = 0x5205402B9270C86FL; private static final long PRIME_Y = 0x598CD327003817B5L; private static final long PRIME_Z = 0x5BCC226E9FA0BACBL; private static final long PRIME_W = 0x56CC5227E58F554BL; private static final long HASH_MULTIPLIER = 0x53A3F72DEEC546F5L; private static final long SEED_FLIP_3D = -0x52D547B2E96ED629L; private static final long SEED_OFFSET_4D = 0xE83DC3E0DA7164DL; private static final double ROOT2OVER2 = 0.7071067811865476; private static final double SKEW_2D = 0.366025403784439; private static final double UNSKEW_2D = -0.21132486540518713; private static final double ROOT3OVER3 = 0.577350269189626; private static final double FALLBACK_ROTATE_3D = 2.0 / 3.0; private static final double ROTATE_3D_ORTHOGONALIZER = UNSKEW_2D; private static final float SKEW_4D = -0.138196601125011f; private static final float UNSKEW_4D = 0.309016994374947f; private static final float LATTICE_STEP_4D = 0.2f; private static final int N_GRADS_2D_EXPONENT = 7; private static final int N_GRADS_3D_EXPONENT = 8; private static final int N_GRADS_4D_EXPONENT = 9; private static final int N_GRADS_2D = 1 << N_GRADS_2D_EXPONENT; private static final int N_GRADS_3D = 1 << N_GRADS_3D_EXPONENT; private static final int N_GRADS_4D = 1 << N_GRADS_4D_EXPONENT; private static final double NORMALIZER_2D = 0.01001634121365712; private static final double NORMALIZER_3D = 0.07969837668935331; private static final double NORMALIZER_4D = 0.0220065933241897; private static final float RSQUARED_2D = 0.5f; private static final float RSQUARED_3D = 0.6f; private static final float RSQUARED_4D = 0.6f; /* * Noise Evaluators */ /** * 2D Simplex noise, standard lattice orientation. */ public static float noise2(long seed, double x, double y) { // Get points for A2* lattice double s = SKEW_2D * (x + y); double xs = x + s, ys = y + s; return noise2_UnskewedBase(seed, xs, ys); } /** * 2D Simplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps, * unless your map is centered around an equator. It's a subtle * difference, but the option is here to make it an easy choice. */ public static float noise2_ImproveX(long seed, double x, double y) { // Skew transform and rotation baked into one. double xx = x * ROOT2OVER2; double yy = y * (ROOT2OVER2 * (1 + 2 * SKEW_2D)); return noise2_UnskewedBase(seed, yy + xx, yy - xx); } /** * 2D Simplex noise base. */ private static float noise2_UnskewedBase(long seed, double xs, double ys) { // Get base points and offsets. int xsb = fastFloor(xs), ysb = fastFloor(ys); float xi = (float)(xs - xsb), yi = (float)(ys - ysb); // Prime pre-multiplication for hash. long xsbp = xsb * PRIME_X, ysbp = ysb * PRIME_Y; // Unskew. float t = (xi + yi) * (float)UNSKEW_2D; float dx0 = xi + t, dy0 = yi + t; // First vertex. float value = 0; float a0 = RSQUARED_2D - dx0 * dx0 - dy0 * dy0; if (a0 > 0) { value = (a0 * a0) * (a0 * a0) * grad(seed, xsbp, ysbp, dx0, dy0); } // Second vertex. float a1 = (float)(2 * (1 + 2 * UNSKEW_2D) * (1 / UNSKEW_2D + 2)) * t + ((float)(-2 * (1 + 2 * UNSKEW_2D) * (1 + 2 * UNSKEW_2D)) + a0); if (a1 > 0) { float dx1 = dx0 - (float)(1 + 2 * UNSKEW_2D); float dy1 = dy0 - (float)(1 + 2 * UNSKEW_2D); value += (a1 * a1) * (a1 * a1) * grad(seed, xsbp + PRIME_X, ysbp + PRIME_Y, dx1, dy1); } // Third vertex. if (dy0 > dx0) { float dx2 = dx0 - (float)UNSKEW_2D; float dy2 = dy0 - (float)(UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2); } } else { float dx2 = dx0 - (float)(UNSKEW_2D + 1); float dy2 = dy0 - (float)UNSKEW_2D; float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp + PRIME_X, ysbp, dx2, dy2); } } return value; } /** * 3D OpenSimplex2 noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in whatever your use case is. * If Y is vertical in world coordinates, call noise3_ImproveXZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_ImproveXZ(x, y, Z). * For a time varied animation, call noise3_ImproveXY(x, y, T). */ public static float noise3_ImproveXY(long seed, double x, double y, double z) { // Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal, // and the planes formed by XY are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * ROTATE_3D_ORTHOGONALIZER; double zz = z * ROOT3OVER3; double xr = x + s2 + zz; double yr = y + s2 + zz; double zr = xy * -ROOT3OVER3 + zz; // Evaluate both lattices to form a BCC lattice. return noise3_UnrotatedBase(seed, xr, yr, zr); } /** * 3D OpenSimplex2 noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in whatever your use case is. * If Y is vertical in world coordinates, call noise3_ImproveXZ(x, Y, z). * If Z is vertical in world coordinates, call noise3_ImproveXZ(x, Z, y) or use noise3_ImproveXY. * For a time varied animation, call noise3_ImproveXZ(x, T, y) or use noise3_ImproveXY. */ public static float noise3_ImproveXZ(long seed, double x, double y, double z) { // Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal, // and the planes formed by XZ are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * ROTATE_3D_ORTHOGONALIZER; double yy = y * ROOT3OVER3; double xr = x + s2 + yy; double zr = z + s2 + yy; double yr = xz * -ROOT3OVER3 + yy; // Evaluate both lattices to form a BCC lattice. return noise3_UnrotatedBase(seed, xr, yr, zr); } /** * 3D OpenSimplex2 noise, fallback rotation option * Use noise3_ImproveXY or noise3_ImproveXZ instead, wherever appropriate. * They have less diagonal bias. This function's best use is as a fallback. */ public static float noise3_Fallback(long seed, double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce a familiar look. // Orthonormal rotation. Not a skew transform. double r = FALLBACK_ROTATE_3D * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; // Evaluate both lattices to form a BCC lattice. return noise3_UnrotatedBase(seed, xr, yr, zr); } /** * Generate overlapping cubic lattices for 3D OpenSimplex2 noise. */ private static float noise3_UnrotatedBase(long seed, double xr, double yr, double zr) { // Get base points and offsets. int xrb = fastRound(xr), yrb = fastRound(yr), zrb = fastRound(zr); float xri = (float)(xr - xrb), yri = (float)(yr - yrb), zri = (float)(zr - zrb); // -1 if positive, 1 if negative. int xNSign = (int)(-1.0f - xri) | 1, yNSign = (int)(-1.0f - yri) | 1, zNSign = (int)(-1.0f - zri) | 1; // Compute absolute values, using the above as a shortcut. This was faster in my tests for some reason. float ax0 = xNSign * -xri, ay0 = yNSign * -yri, az0 = zNSign * -zri; // Prime pre-multiplication for hash. long xrbp = xrb * PRIME_X, yrbp = yrb * PRIME_Y, zrbp = zrb * PRIME_Z; // Loop: Pick an edge on each lattice copy. float value = 0; float a = (RSQUARED_3D - xri * xri) - (yri * yri + zri * zri); for (int l = 0; ; l++) { // Closest point on cube. if (a > 0) { value += (a * a) * (a * a) * grad(seed, xrbp, yrbp, zrbp, xri, yri, zri); } // Second-closest point. if (ax0 >= ay0 && ax0 >= az0) { float b = a + ax0 + ax0; if (b > 1) { b -= 1; value += (b * b) * (b * b) * grad(seed, xrbp - xNSign * PRIME_X, yrbp, zrbp, xri + xNSign, yri, zri); } } else if (ay0 > ax0 && ay0 >= az0) { float b = a + ay0 + ay0; if (b > 1) { b -= 1; value += (b * b) * (b * b) * grad(seed, xrbp, yrbp - yNSign * PRIME_Y, zrbp, xri, yri + yNSign, zri); } } else { float b = a + az0 + az0; if (b > 1) { b -= 1; value += (b * b) * (b * b) * grad(seed, xrbp, yrbp, zrbp - zNSign * PRIME_Z, xri, yri, zri + zNSign); } } // Break from loop if we're done, skipping updates below. if (l == 1) break; // Update absolute value. ax0 = 0.5f - ax0; ay0 = 0.5f - ay0; az0 = 0.5f - az0; // Update relative coordinate. xri = xNSign * ax0; yri = yNSign * ay0; zri = zNSign * az0; // Update falloff. a += (0.75f - ax0) - (ay0 + az0); // Update prime for hash. xrbp += (xNSign >> 1) & PRIME_X; yrbp += (yNSign >> 1) & PRIME_Y; zrbp += (zNSign >> 1) & PRIME_Z; // Update the reverse sign indicators. xNSign = -xNSign; yNSign = -yNSign; zNSign = -zNSign; // And finally update the seed for the other lattice copy. seed ^= SEED_FLIP_3D; } return value; } /** * 4D OpenSimplex2 noise, with XYZ oriented like noise3_ImproveXY * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * in a space where Z is vertical */ public static float noise4_ImproveXYZ_ImproveXY(long seed, double x, double y, double z, double w) { double xy = x + y; double s2 = xy * -0.21132486540518699998; double zz = z * 0.28867513459481294226; double ww = w * 0.2236067977499788; double xr = x + (zz + ww + s2), yr = y + (zz + ww + s2); double zr = xy * -0.57735026918962599998 + (zz + ww); double wr = z * -0.866025403784439 + ww; return noise4_UnskewedBase(seed, xr, yr, zr, wr); } /** * 4D OpenSimplex2 noise, with XYZ oriented like noise3_ImproveXZ * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * in a space where Y is vertical */ public static float noise4_ImproveXYZ_ImproveXZ(long seed, double x, double y, double z, double w) { double xz = x + z; double s2 = xz * -0.21132486540518699998; double yy = y * 0.28867513459481294226; double ww = w * 0.2236067977499788; double xr = x + (yy + ww + s2), zr = z + (yy + ww + s2); double yr = xz * -0.57735026918962599998 + (yy + ww); double wr = y * -0.866025403784439 + ww; return noise4_UnskewedBase(seed, xr, yr, zr, wr); } /** * 4D OpenSimplex2 noise, with XYZ oriented like noise3_Fallback * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * where there isn't a clear distinction between horizontal and vertical */ public static float noise4_ImproveXYZ(long seed, double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 0.2236067977499788; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D OpenSimplex2 noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ public static float noise4_ImproveXY_ImproveZW(long seed, double x, double y, double z, double w) { double s2 = (x + y) * -0.178275657951399372 + (z + w) * 0.215623393288842828; double t2 = (z + w) * -0.403949762580207112 + (x + y) * -0.375199083010075342; double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; return noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D OpenSimplex2 noise, fallback lattice orientation. */ public static float noise4_Fallback(long seed, double x, double y, double z, double w) { // Get points for A4 lattice double s = SKEW_4D * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D OpenSimplex2 noise base. */ private static float noise4_UnskewedBase(long seed, double xs, double ys, double zs, double ws) { // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys), zsb = fastFloor(zs), wsb = fastFloor(ws); float xsi = (float)(xs - xsb), ysi = (float)(ys - ysb), zsi = (float)(zs - zsb), wsi = (float)(ws - wsb); // Determine which lattice we can be confident has a contributing point its corresponding cell's base simplex. // We only look at the spaces between the diagonal planes. This proved effective in all of my tests. float siSum = (xsi + ysi) + (zsi + wsi); int startingLattice = (int)(siSum * 1.25); // Offset for seed based on first lattice copy. seed += startingLattice * SEED_OFFSET_4D; // Offset for lattice point relative positions (skewed) float startingLatticeOffset = startingLattice * -LATTICE_STEP_4D; xsi += startingLatticeOffset; ysi += startingLatticeOffset; zsi += startingLatticeOffset; wsi += startingLatticeOffset; // Prep for vertex contributions. float ssi = (siSum + startingLatticeOffset * 4) * UNSKEW_4D; // Prime pre-multiplication for hash. long xsvp = xsb * PRIME_X, ysvp = ysb * PRIME_Y, zsvp = zsb * PRIME_Z, wsvp = wsb * PRIME_W; // Five points to add, total, from five copies of the A4 lattice. float value = 0; for (int i = 0; ; i++) { // Next point is the closest vertex on the 4-simplex whose base vertex is the aforementioned vertex. double score0 = 1.0 + ssi * (-1.0 / UNSKEW_4D); // Seems slightly faster than 1.0-xsi-ysi-zsi-wsi if (xsi >= ysi && xsi >= zsi && xsi >= wsi && xsi >= score0) { xsvp += PRIME_X; xsi -= 1; ssi -= UNSKEW_4D; } else if (ysi > xsi && ysi >= zsi && ysi >= wsi && ysi >= score0) { ysvp += PRIME_Y; ysi -= 1; ssi -= UNSKEW_4D; } else if (zsi > xsi && zsi > ysi && zsi >= wsi && zsi >= score0) { zsvp += PRIME_Z; zsi -= 1; ssi -= UNSKEW_4D; } else if (wsi > xsi && wsi > ysi && wsi > zsi && wsi >= score0) { wsvp += PRIME_W; wsi -= 1; ssi -= UNSKEW_4D; } // gradient contribution with falloff. float dx = xsi + ssi, dy = ysi + ssi, dz = zsi + ssi, dw = wsi + ssi; float a = (dx * dx + dy * dy) + (dz * dz + dw * dw); if (a < RSQUARED_4D) { a -= RSQUARED_4D; a *= a; value += a * a * grad(seed, xsvp, ysvp, zsvp, wsvp, dx, dy, dz, dw); } // Break from loop if we're done, skipping updates below. if (i == 4) break; // Update for next lattice copy shifted down by <-0.2, -0.2, -0.2, -0.2>. xsi += LATTICE_STEP_4D; ysi += LATTICE_STEP_4D; zsi += LATTICE_STEP_4D; wsi += LATTICE_STEP_4D; ssi += LATTICE_STEP_4D * 4 * UNSKEW_4D; seed -= SEED_OFFSET_4D; // Because we don't always start on the same lattice copy, there's a special reset case. if (i == startingLattice) { xsvp -= PRIME_X; ysvp -= PRIME_Y; zsvp -= PRIME_Z; wsvp -= PRIME_W; seed += SEED_OFFSET_4D * 5; } } return value; } /* * Utility */ private static float grad(long seed, long xsvp, long ysvp, float dx, float dy) { long hash = seed ^ xsvp ^ ysvp; hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_2D_EXPONENT + 1); int gi = (int)hash & ((N_GRADS_2D - 1) << 1); return GRADIENTS_2D[gi | 0] * dx + GRADIENTS_2D[gi | 1] * dy; } private static float grad(long seed, long xrvp, long yrvp, long zrvp, float dx, float dy, float dz) { long hash = (seed ^ xrvp) ^ (yrvp ^ zrvp); hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_3D_EXPONENT + 2); int gi = (int)hash & ((N_GRADS_3D - 1) << 2); return GRADIENTS_3D[gi | 0] * dx + GRADIENTS_3D[gi | 1] * dy + GRADIENTS_3D[gi | 2] * dz; } private static float grad(long seed, long xsvp, long ysvp, long zsvp, long wsvp, float dx, float dy, float dz, float dw) { long hash = seed ^ (xsvp ^ ysvp) ^ (zsvp ^ wsvp); hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_4D_EXPONENT + 2); int gi = (int)hash & ((N_GRADS_4D - 1) << 2); return (GRADIENTS_4D[gi | 0] * dx + GRADIENTS_4D[gi | 1] * dy) + (GRADIENTS_4D[gi | 2] * dz + GRADIENTS_4D[gi | 3] * dw); } private static int fastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } private static int fastRound(double x) { return x < 0 ? (int)(x - 0.5) : (int)(x + 0.5); } /* * gradients */ private static float[] GRADIENTS_2D; private static float[] GRADIENTS_3D; private static float[] GRADIENTS_4D; static { GRADIENTS_2D = new float[N_GRADS_2D * 2]; float[] grad2 = { 0.38268343236509f, 0.923879532511287f, 0.923879532511287f, 0.38268343236509f, 0.923879532511287f, -0.38268343236509f, 0.38268343236509f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, 0.38268343236509f, -0.38268343236509f, 0.923879532511287f, //-------------------------------------// 0.130526192220052f, 0.99144486137381f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.130526192220052f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.130526192220052f, 0.99144486137381f, }; for (int i = 0; i < grad2.length; i++) { grad2[i] = (float)(grad2[i] / NORMALIZER_2D); } for (int i = 0, j = 0; i < GRADIENTS_2D.length; i++, j++) { if (j == grad2.length) j = 0; GRADIENTS_2D[i] = grad2[j]; } GRADIENTS_3D = new float[N_GRADS_3D * 4]; float[] grad3 = { 2.22474487139f, 2.22474487139f, -1.0f, 0.0f, 2.22474487139f, 2.22474487139f, 1.0f, 0.0f, 3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, 1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -2.22474487139f, 2.22474487139f, -1.0f, 0.0f, -2.22474487139f, 2.22474487139f, 1.0f, 0.0f, -1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, -1.0f, -2.22474487139f, -2.22474487139f, 0.0f, 1.0f, -2.22474487139f, -2.22474487139f, 0.0f, 0.0f, -3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, -1.1721513422464978f, -3.0862664687972017f, 0.0f, -1.0f, -2.22474487139f, 2.22474487139f, 0.0f, 1.0f, -2.22474487139f, 2.22474487139f, 0.0f, 0.0f, -1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -3.0862664687972017f, 1.1721513422464978f, 0.0f, //--------------------------------------------------------------------// -2.22474487139f, -2.22474487139f, -1.0f, 0.0f, -2.22474487139f, -2.22474487139f, 1.0f, 0.0f, -3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, -1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, -2.22474487139f, -1.0f, -2.22474487139f, 0.0f, -2.22474487139f, 1.0f, -2.22474487139f, 0.0f, -1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, -3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, -2.22474487139f, -1.0f, 2.22474487139f, 0.0f, -2.22474487139f, 1.0f, 2.22474487139f, 0.0f, -3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, -1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, -1.0f, 2.22474487139f, -2.22474487139f, 0.0f, 1.0f, 2.22474487139f, -2.22474487139f, 0.0f, 0.0f, 1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, 3.0862664687972017f, -1.1721513422464978f, 0.0f, -1.0f, 2.22474487139f, 2.22474487139f, 0.0f, 1.0f, 2.22474487139f, 2.22474487139f, 0.0f, 0.0f, 3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, 1.1721513422464978f, 3.0862664687972017f, 0.0f, 2.22474487139f, -2.22474487139f, -1.0f, 0.0f, 2.22474487139f, -2.22474487139f, 1.0f, 0.0f, 1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, 3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, 2.22474487139f, -1.0f, -2.22474487139f, 0.0f, 2.22474487139f, 1.0f, -2.22474487139f, 0.0f, 3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, 1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, 2.22474487139f, -1.0f, 2.22474487139f, 0.0f, 2.22474487139f, 1.0f, 2.22474487139f, 0.0f, 1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, 3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, }; for (int i = 0; i < grad3.length; i++) { grad3[i] = (float)(grad3[i] / NORMALIZER_3D); } for (int i = 0, j = 0; i < GRADIENTS_3D.length; i++, j++) { if (j == grad3.length) j = 0; GRADIENTS_3D[i] = grad3[j]; } GRADIENTS_4D = new float[N_GRADS_4D * 4]; float[] grad4 = { -0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, -0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, -0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, -0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, -0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, -0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, -0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, -0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, -0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, 0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, 0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, //------------------------------------------------------------------------------------------// -0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, -0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, -0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, -0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, -0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, -0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, -0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, -0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, -0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, -0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, -0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, -0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, -0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, -0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, -0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, 0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, -0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, -0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, 0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, 0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, 0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, -0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, -0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, 0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, -0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, 0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, -0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, 0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, 0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, -0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, -0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, 0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, -0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, 0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, -0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, 0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, -0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, -0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, 0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, 0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, 0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, 0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, 0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, 0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, 0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, 0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, 0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, 0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, -0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, 0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, 0.8586508742123365f, 0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, 0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, 0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, -0.044802370851755174f, 0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, 0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, 0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, 0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, -0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, -0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, 0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, 0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, 0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, 0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, 0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, 0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, }; for (int i = 0; i < grad4.length; i++) { grad4[i] = (float)(grad4[i] / NORMALIZER_4D); } for (int i = 0, j = 0; i < GRADIENTS_4D.length; i++, j++) { if (j == grad4.length) j = 0; GRADIENTS_4D[i] = grad4[j]; } } } ================================================ FILE: java/OpenSimplex2S.java ================================================ /** * K.jpg's OpenSimplex 2, smooth variant ("SuperSimplex") */ public class OpenSimplex2S { private static final long PRIME_X = 0x5205402B9270C86FL; private static final long PRIME_Y = 0x598CD327003817B5L; private static final long PRIME_Z = 0x5BCC226E9FA0BACBL; private static final long PRIME_W = 0x56CC5227E58F554BL; private static final long HASH_MULTIPLIER = 0x53A3F72DEEC546F5L; private static final long SEED_FLIP_3D = -0x52D547B2E96ED629L; private static final double ROOT2OVER2 = 0.7071067811865476; private static final double SKEW_2D = 0.366025403784439; private static final double UNSKEW_2D = -0.21132486540518713; private static final double ROOT3OVER3 = 0.577350269189626; private static final double FALLBACK_ROTATE3 = 2.0 / 3.0; private static final double ROTATE3_ORTHOGONALIZER = UNSKEW_2D; private static final float SKEW_4D = 0.309016994374947f; private static final float UNSKEW_4D = -0.138196601125011f; private static final int N_GRADS_2D_EXPONENT = 7; private static final int N_GRADS_3D_EXPONENT = 8; private static final int N_GRADS_4D_EXPONENT = 9; private static final int N_GRADS_2D = 1 << N_GRADS_2D_EXPONENT; private static final int N_GRADS_3D = 1 << N_GRADS_3D_EXPONENT; private static final int N_GRADS_4D = 1 << N_GRADS_4D_EXPONENT; private static final double NORMALIZER_2D = 0.05481866495625118; private static final double NORMALIZER_3D = 0.2781926117527186; private static final double NORMALIZER_4D = 0.11127401889945551; private static final float RSQUARED_2D = 2.0f / 3.0f; private static final float RSQUARED_3D = 3.0f / 4.0f; private static final float RSQUARED_4D = 4.0f / 5.0f; /* * Noise Evaluators */ /** * 2D OpenSimplex2S/SuperSimplex noise, standard lattice orientation. */ public static float noise2(long seed, double x, double y) { // Get points for A2* lattice double s = SKEW_2D * (x + y); double xs = x + s, ys = y + s; return noise2_UnskewedBase(seed, xs, ys); } /** * 2D OpenSimplex2S/SuperSimplex noise, with Y pointing down the main diagonal. * Might be better for a 2D sandbox style game, where Y is vertical. * Probably slightly less optimal for heightmaps or continent maps, * unless your map is centered around an equator. It's a slight * difference, but the option is here to make it easy. */ public static float noise2_ImproveX(long seed, double x, double y) { // Skew transform and rotation baked into one. double xx = x * ROOT2OVER2; double yy = y * (ROOT2OVER2 * (1 + 2 * SKEW_2D)); return noise2_UnskewedBase(seed, yy + xx, yy - xx); } /** * 2D OpenSimplex2S/SuperSimplex noise base. */ private static float noise2_UnskewedBase(long seed, double xs, double ys) { // Get base points and offsets. int xsb = fastFloor(xs), ysb = fastFloor(ys); float xi = (float)(xs - xsb), yi = (float)(ys - ysb); // Prime pre-multiplication for hash. long xsbp = xsb * PRIME_X, ysbp = ysb * PRIME_Y; // Unskew. float t = (xi + yi) * (float)UNSKEW_2D; float dx0 = xi + t, dy0 = yi + t; // First vertex. float a0 = RSQUARED_2D - dx0 * dx0 - dy0 * dy0; float value = (a0 * a0) * (a0 * a0) * grad(seed, xsbp, ysbp, dx0, dy0); // Second vertex. float a1 = (float)(2 * (1 + 2 * UNSKEW_2D) * (1 / UNSKEW_2D + 2)) * t + ((float)(-2 * (1 + 2 * UNSKEW_2D) * (1 + 2 * UNSKEW_2D)) + a0); float dx1 = dx0 - (float)(1 + 2 * UNSKEW_2D); float dy1 = dy0 - (float)(1 + 2 * UNSKEW_2D); value += (a1 * a1) * (a1 * a1) * grad(seed, xsbp + PRIME_X, ysbp + PRIME_Y, dx1, dy1); // Third and fourth vertices. // Nested conditionals were faster than compact bit logic/arithmetic. float xmyi = xi - yi; if (t < UNSKEW_2D) { if (xi + xmyi > 1) { float dx2 = dx0 - (float)(3 * UNSKEW_2D + 2); float dy2 = dy0 - (float)(3 * UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp + (PRIME_X << 1), ysbp + PRIME_Y, dx2, dy2); } } else { float dx2 = dx0 - (float)UNSKEW_2D; float dy2 = dy0 - (float)(UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2); } } if (yi - xmyi > 1) { float dx3 = dx0 - (float)(3 * UNSKEW_2D + 1); float dy3 = dy0 - (float)(3 * UNSKEW_2D + 2); float a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3; if (a3 > 0) { value += (a3 * a3) * (a3 * a3) * grad(seed, xsbp + PRIME_X, ysbp + (PRIME_Y << 1), dx3, dy3); } } else { float dx3 = dx0 - (float)(UNSKEW_2D + 1); float dy3 = dy0 - (float)UNSKEW_2D; float a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3; if (a3 > 0) { value += (a3 * a3) * (a3 * a3) * grad(seed, xsbp + PRIME_X, ysbp, dx3, dy3); } } } else { if (xi + xmyi < 0) { float dx2 = dx0 + (float)(1 + UNSKEW_2D); float dy2 = dy0 + (float)UNSKEW_2D; float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp - PRIME_X, ysbp, dx2, dy2); } } else { float dx2 = dx0 - (float)(UNSKEW_2D + 1); float dy2 = dy0 - (float)UNSKEW_2D; float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp + PRIME_X, ysbp, dx2, dy2); } } if (yi < xmyi) { float dx2 = dx0 + (float)UNSKEW_2D; float dy2 = dy0 + (float)(UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp, ysbp - PRIME_Y, dx2, dy2); } } else { float dx2 = dx0 - (float)UNSKEW_2D; float dy2 = dy0 - (float)(UNSKEW_2D + 1); float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if (a2 > 0) { value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2); } } } return value; } /** * 3D OpenSimplex2S/SuperSimplex noise, with better visual isotropy in (X, Y). * Recommended for 3D terrain and time-varied animations. * The Z coordinate should always be the "different" coordinate in whatever your use case is. * If Y is vertical in world coordinates, call noise3_ImproveXZ(x, z, Y) or use noise3_XZBeforeY. * If Z is vertical in world coordinates, call noise3_ImproveXZ(x, y, Z). * For a time varied animation, call noise3_ImproveXY(x, y, T). */ public static float noise3_ImproveXY(long seed, double x, double y, double z) { // Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal, // and the planes formed by XY are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * ROTATE3_ORTHOGONALIZER; double zz = z * ROOT3OVER3; double xr = x + s2 + zz; double yr = y + s2 + zz; double zr = xy * -ROOT3OVER3 + zz; // Evaluate both lattices to form a BCC lattice. return noise3_UnrotatedBase(seed, xr, yr, zr); } /** * 3D OpenSimplex2S/SuperSimplex noise, with better visual isotropy in (X, Z). * Recommended for 3D terrain and time-varied animations. * The Y coordinate should always be the "different" coordinate in whatever your use case is. * If Y is vertical in world coordinates, call noise3_ImproveXZ(x, Y, z). * If Z is vertical in world coordinates, call noise3_ImproveXZ(x, Z, y) or use noise3_ImproveXY. * For a time varied animation, call noise3_ImproveXZ(x, T, y) or use noise3_ImproveXY. */ public static float noise3_ImproveXZ(long seed, double x, double y, double z) { // Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal, // and the planes formed by XZ are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * -0.211324865405187; double yy = y * ROOT3OVER3; double xr = x + s2 + yy; double zr = z + s2 + yy; double yr = xz * -ROOT3OVER3 + yy; // Evaluate both lattices to form a BCC lattice. return noise3_UnrotatedBase(seed, xr, yr, zr); } /** * 3D OpenSimplex2S/SuperSimplex noise, fallback rotation option * Use noise3_ImproveXY or noise3_ImproveXZ instead, wherever appropriate. * They have less diagonal bias. This function's best use is as a fallback. */ public static float noise3_Fallback(long seed, double x, double y, double z) { // Re-orient the cubic lattices via rotation, to produce a familiar look. // Orthonormal rotation. Not a skew transform. double r = FALLBACK_ROTATE3 * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; // Evaluate both lattices to form a BCC lattice. return noise3_UnrotatedBase(seed, xr, yr, zr); } /** * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. * Lookup table implementation inspired by DigitalShadow. * It was actually faster to narrow down the points in the loop itself, * than to build up the index with enough info to isolate 8 points. */ private static float noise3_UnrotatedBase(long seed, double xr, double yr, double zr) { // Get base points and offsets. int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr); float xi = (float)(xr - xrb), yi = (float)(yr - yrb), zi = (float)(zr - zrb); // Prime pre-multiplication for hash. Also flip seed for second lattice copy. long xrbp = xrb * PRIME_X, yrbp = yrb * PRIME_Y, zrbp = zrb * PRIME_Z; long seed2 = seed ^ -0x52D547B2E96ED629L; // -1 if positive, 0 if negative. int xNMask = (int)(-0.5f - xi), yNMask = (int)(-0.5f - yi), zNMask = (int)(-0.5f - zi); // First vertex. float x0 = xi + xNMask; float y0 = yi + yNMask; float z0 = zi + zNMask; float a0 = RSQUARED_3D - x0 * x0 - y0 * y0 - z0 * z0; float value = (a0 * a0) * (a0 * a0) * grad(seed, xrbp + (xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), x0, y0, z0); // Second vertex. float x1 = xi - 0.5f; float y1 = yi - 0.5f; float z1 = zi - 0.5f; float a1 = RSQUARED_3D - x1 * x1 - y1 * y1 - z1 * z1; value += (a1 * a1) * (a1 * a1) * grad(seed2, xrbp + PRIME_X, yrbp + PRIME_Y, zrbp + PRIME_Z, x1, y1, z1); // Shortcuts for building the remaining falloffs. // Derived by subtracting the polynomials with the offsets plugged in. float xAFlipMask0 = ((xNMask | 1) << 1) * x1; float yAFlipMask0 = ((yNMask | 1) << 1) * y1; float zAFlipMask0 = ((zNMask | 1) << 1) * z1; float xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0f; float yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0f; float zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0f; boolean skip5 = false; float a2 = xAFlipMask0 + a0; if (a2 > 0) { float x2 = x0 - (xNMask | 1); float y2 = y0; float z2 = z0; value += (a2 * a2) * (a2 * a2) * grad(seed, xrbp + (~xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), x2, y2, z2); } else { float a3 = yAFlipMask0 + zAFlipMask0 + a0; if (a3 > 0) { float x3 = x0; float y3 = y0 - (yNMask | 1); float z3 = z0 - (zNMask | 1); value += (a3 * a3) * (a3 * a3) * grad(seed, xrbp + (xNMask & PRIME_X), yrbp + (~yNMask & PRIME_Y), zrbp + (~zNMask & PRIME_Z), x3, y3, z3); } float a4 = xAFlipMask1 + a1; if (a4 > 0) { float x4 = (xNMask | 1) + x1; float y4 = y1; float z4 = z1; value += (a4 * a4) * (a4 * a4) * grad(seed2, xrbp + (xNMask & (PRIME_X * 2)), yrbp + PRIME_Y, zrbp + PRIME_Z, x4, y4, z4); skip5 = true; } } boolean skip9 = false; float a6 = yAFlipMask0 + a0; if (a6 > 0) { float x6 = x0; float y6 = y0 - (yNMask | 1); float z6 = z0; value += (a6 * a6) * (a6 * a6) * grad(seed, xrbp + (xNMask & PRIME_X), yrbp + (~yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), x6, y6, z6); } else { float a7 = xAFlipMask0 + zAFlipMask0 + a0; if (a7 > 0) { float x7 = x0 - (xNMask | 1); float y7 = y0; float z7 = z0 - (zNMask | 1); value += (a7 * a7) * (a7 * a7) * grad(seed, xrbp + (~xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (~zNMask & PRIME_Z), x7, y7, z7); } float a8 = yAFlipMask1 + a1; if (a8 > 0) { float x8 = x1; float y8 = (yNMask | 1) + y1; float z8 = z1; value += (a8 * a8) * (a8 * a8) * grad(seed2, xrbp + PRIME_X, yrbp + (yNMask & (PRIME_Y << 1)), zrbp + PRIME_Z, x8, y8, z8); skip9 = true; } } boolean skipD = false; float aA = zAFlipMask0 + a0; if (aA > 0) { float xA = x0; float yA = y0; float zA = z0 - (zNMask | 1); value += (aA * aA) * (aA * aA) * grad(seed, xrbp + (xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (~zNMask & PRIME_Z), xA, yA, zA); } else { float aB = xAFlipMask0 + yAFlipMask0 + a0; if (aB > 0) { float xB = x0 - (xNMask | 1); float yB = y0 - (yNMask | 1); float zB = z0; value += (aB * aB) * (aB * aB) * grad(seed, xrbp + (~xNMask & PRIME_X), yrbp + (~yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), xB, yB, zB); } float aC = zAFlipMask1 + a1; if (aC > 0) { float xC = x1; float yC = y1; float zC = (zNMask | 1) + z1; value += (aC * aC) * (aC * aC) * grad(seed2, xrbp + PRIME_X, yrbp + PRIME_Y, zrbp + (zNMask & (PRIME_Z << 1)), xC, yC, zC); skipD = true; } } if (!skip5) { float a5 = yAFlipMask1 + zAFlipMask1 + a1; if (a5 > 0) { float x5 = x1; float y5 = (yNMask | 1) + y1; float z5 = (zNMask | 1) + z1; value += (a5 * a5) * (a5 * a5) * grad(seed2, xrbp + PRIME_X, yrbp + (yNMask & (PRIME_Y << 1)), zrbp + (zNMask & (PRIME_Z << 1)), x5, y5, z5); } } if (!skip9) { float a9 = xAFlipMask1 + zAFlipMask1 + a1; if (a9 > 0) { float x9 = (xNMask | 1) + x1; float y9 = y1; float z9 = (zNMask | 1) + z1; value += (a9 * a9) * (a9 * a9) * grad(seed2, xrbp + (xNMask & (PRIME_X * 2)), yrbp + PRIME_Y, zrbp + (zNMask & (PRIME_Z << 1)), x9, y9, z9); } } if (!skipD) { float aD = xAFlipMask1 + yAFlipMask1 + a1; if (aD > 0) { float xD = (xNMask | 1) + x1; float yD = (yNMask | 1) + y1; float zD = z1; value += (aD * aD) * (aD * aD) * grad(seed2, xrbp + (xNMask & (PRIME_X << 1)), yrbp + (yNMask & (PRIME_Y << 1)), zrbp + PRIME_Z, xD, yD, zD); } } return value; } /** * 4D SuperSimplex noise, with XYZ oriented like noise3_ImproveXY * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * in a space where Z is vertical */ public static float noise4_ImproveXYZ_ImproveXY(long seed, double x, double y, double z, double w) { double xy = x + y; double s2 = xy * -0.21132486540518699998; double zz = z * 0.28867513459481294226; double ww = w * 1.118033988749894; double xr = x + (zz + ww + s2), yr = y + (zz + ww + s2); double zr = xy * -0.57735026918962599998 + (zz + ww); double wr = z * -0.866025403784439 + ww; return noise4_UnskewedBase(seed, xr, yr, zr, wr); } /** * 4D SuperSimplex noise, with XYZ oriented like noise3_ImproveXZ * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * in a space where Y is vertical */ public static float noise4_ImproveXYZ_ImproveXZ(long seed, double x, double y, double z, double w) { double xz = x + z; double s2 = xz * -0.21132486540518699998; double yy = y * 0.28867513459481294226; double ww = w * 1.118033988749894; double xr = x + (yy + ww + s2), zr = z + (yy + ww + s2); double yr = xz * -0.57735026918962599998 + (yy + ww); double wr = y * -0.866025403784439 + ww; return noise4_UnskewedBase(seed, xr, yr, zr, wr); } /** * 4D SuperSimplex noise, with XYZ oriented like noise3_Fallback * and W for an extra degree of freedom. W repeats eventually. * Recommended for time-varied animations which texture a 3D object (W=time) * where there isn't a clear distinction between horizontal and vertical */ public static float noise4_ImproveXYZ(long seed, double x, double y, double z, double w) { double xyz = x + y + z; double ww = w * 1.118033988749894; double s2 = xyz * -0.16666666666666666 + ww; double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; return noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D SuperSimplex noise, with XY and ZW forming orthogonal triangular-based planes. * Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. * Recommended for noise(x, y, sin(time), cos(time)) trick. */ public static float noise4_ImproveXY_ImproveZW(long seed, double x, double y, double z, double w) { double s2 = (x + y) * -0.28522513987434876941 + (z + w) * 0.83897065470611435718; double t2 = (z + w) * 0.21939749883706435719 + (x + y) * -0.48214856493302476942; double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; return noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D SuperSimplex noise, fallback lattice orientation. */ public static float noise4_Fallback(long seed, double x, double y, double z, double w) { // Get points for A4 lattice double s = SKEW_4D * (x + y + z + w); double xs = x + s, ys = y + s, zs = z + s, ws = w + s; return noise4_UnskewedBase(seed, xs, ys, zs, ws); } /** * 4D SuperSimplex noise base. * Using ultra-simple 4x4x4x4 lookup partitioning. * This isn't as elegant or SIMD/GPU/etc. portable as other approaches, * but it competes performance-wise with optimized 2014 OpenSimplex. */ private static float noise4_UnskewedBase(long seed, double xs, double ys, double zs, double ws) { // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys), zsb = fastFloor(zs), wsb = fastFloor(ws); float xsi = (float)(xs - xsb), ysi = (float)(ys - ysb), zsi = (float)(zs - zsb), wsi = (float)(ws - wsb); // Unskewed offsets float ssi = (xsi + ysi + zsi + wsi) * UNSKEW_4D; float xi = xsi + ssi, yi = ysi + ssi, zi = zsi + ssi, wi = wsi + ssi; // Prime pre-multiplication for hash. long xsvp = xsb * PRIME_X, ysvp = ysb * PRIME_Y, zsvp = zsb * PRIME_Z, wsvp = wsb * PRIME_W; // Index into initial table. int index = ((fastFloor(xs * 4) & 3) << 0) | ((fastFloor(ys * 4) & 3) << 2) | ((fastFloor(zs * 4) & 3) << 4) | ((fastFloor(ws * 4) & 3) << 6); // Point contributions float value = 0; int secondaryIndexStartAndStop = LOOKUP_4D_A[index]; int secondaryIndexStart = secondaryIndexStartAndStop & 0xFFFF; int secondaryIndexStop = secondaryIndexStartAndStop >> 16; for (int i = secondaryIndexStart; i < secondaryIndexStop; i++) { LatticeVertex4D c = LOOKUP_4D_B[i]; float dx = xi + c.dx, dy = yi + c.dy, dz = zi + c.dz, dw = wi + c.dw; float a = (dx * dx + dy * dy) + (dz * dz + dw * dw); if (a < RSQUARED_4D) { a -= RSQUARED_4D; a *= a; value += a * a * grad(seed, xsvp + c.xsvp, ysvp + c.ysvp, zsvp + c.zsvp, wsvp + c.wsvp, dx, dy, dz, dw); } } return value; } /* * Utility */ private static float grad(long seed, long xsvp, long ysvp, float dx, float dy) { long hash = seed ^ xsvp ^ ysvp; hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_2D_EXPONENT + 1); int gi = (int)hash & ((N_GRADS_2D - 1) << 1); return GRADIENTS_2D[gi | 0] * dx + GRADIENTS_2D[gi | 1] * dy; } private static float grad(long seed, long xrvp, long yrvp, long zrvp, float dx, float dy, float dz) { long hash = (seed ^ xrvp) ^ (yrvp ^ zrvp); hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_3D_EXPONENT + 2); int gi = (int)hash & ((N_GRADS_3D - 1) << 2); return GRADIENTS_3D[gi | 0] * dx + GRADIENTS_3D[gi | 1] * dy + GRADIENTS_3D[gi | 2] * dz; } private static float grad(long seed, long xsvp, long ysvp, long zsvp, long wsvp, float dx, float dy, float dz, float dw) { long hash = seed ^ (xsvp ^ ysvp) ^ (zsvp ^ wsvp); hash *= HASH_MULTIPLIER; hash ^= hash >> (64 - N_GRADS_4D_EXPONENT + 2); int gi = (int)hash & ((N_GRADS_4D - 1) << 2); return (GRADIENTS_4D[gi | 0] * dx + GRADIENTS_4D[gi | 1] * dy) + (GRADIENTS_4D[gi | 2] * dz + GRADIENTS_4D[gi | 3] * dw); } private static int fastFloor(double x) { int xi = (int)x; return x < xi ? xi - 1 : xi; } /* * Lookup Tables & Gradients */ private static float[] GRADIENTS_2D; private static float[] GRADIENTS_3D; private static float[] GRADIENTS_4D; private static int[] LOOKUP_4D_A; private static LatticeVertex4D[] LOOKUP_4D_B; static { GRADIENTS_2D = new float[N_GRADS_2D * 2]; float[] grad2 = { 0.38268343236509f, 0.923879532511287f, 0.923879532511287f, 0.38268343236509f, 0.923879532511287f, -0.38268343236509f, 0.38268343236509f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, 0.38268343236509f, -0.38268343236509f, 0.923879532511287f, //-------------------------------------// 0.130526192220052f, 0.99144486137381f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.130526192220052f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.130526192220052f, 0.99144486137381f, }; for (int i = 0; i < grad2.length; i++) { grad2[i] = (float)(grad2[i] / NORMALIZER_2D); } for (int i = 0, j = 0; i < GRADIENTS_2D.length; i++, j++) { if (j == grad2.length) j = 0; GRADIENTS_2D[i] = grad2[j]; } GRADIENTS_3D = new float[N_GRADS_3D * 4]; float[] grad3 = { 2.22474487139f, 2.22474487139f, -1.0f, 0.0f, 2.22474487139f, 2.22474487139f, 1.0f, 0.0f, 3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, 1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -2.22474487139f, 2.22474487139f, -1.0f, 0.0f, -2.22474487139f, 2.22474487139f, 1.0f, 0.0f, -1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, -1.0f, -2.22474487139f, -2.22474487139f, 0.0f, 1.0f, -2.22474487139f, -2.22474487139f, 0.0f, 0.0f, -3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, -1.1721513422464978f, -3.0862664687972017f, 0.0f, -1.0f, -2.22474487139f, 2.22474487139f, 0.0f, 1.0f, -2.22474487139f, 2.22474487139f, 0.0f, 0.0f, -1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, -3.0862664687972017f, 1.1721513422464978f, 0.0f, //--------------------------------------------------------------------// -2.22474487139f, -2.22474487139f, -1.0f, 0.0f, -2.22474487139f, -2.22474487139f, 1.0f, 0.0f, -3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, -1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, -2.22474487139f, -1.0f, -2.22474487139f, 0.0f, -2.22474487139f, 1.0f, -2.22474487139f, 0.0f, -1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, -3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, -2.22474487139f, -1.0f, 2.22474487139f, 0.0f, -2.22474487139f, 1.0f, 2.22474487139f, 0.0f, -3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, -1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, -1.0f, 2.22474487139f, -2.22474487139f, 0.0f, 1.0f, 2.22474487139f, -2.22474487139f, 0.0f, 0.0f, 1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, 3.0862664687972017f, -1.1721513422464978f, 0.0f, -1.0f, 2.22474487139f, 2.22474487139f, 0.0f, 1.0f, 2.22474487139f, 2.22474487139f, 0.0f, 0.0f, 3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, 1.1721513422464978f, 3.0862664687972017f, 0.0f, 2.22474487139f, -2.22474487139f, -1.0f, 0.0f, 2.22474487139f, -2.22474487139f, 1.0f, 0.0f, 1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, 3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, 2.22474487139f, -1.0f, -2.22474487139f, 0.0f, 2.22474487139f, 1.0f, -2.22474487139f, 0.0f, 3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, 1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, 2.22474487139f, -1.0f, 2.22474487139f, 0.0f, 2.22474487139f, 1.0f, 2.22474487139f, 0.0f, 1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, 3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, }; for (int i = 0; i < grad3.length; i++) { grad3[i] = (float)(grad3[i] / NORMALIZER_3D); } for (int i = 0, j = 0; i < GRADIENTS_3D.length; i++, j++) { if (j == grad3.length) j = 0; GRADIENTS_3D[i] = grad3[j]; } GRADIENTS_4D = new float[N_GRADS_4D * 4]; float[] grad4 = { -0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, -0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, -0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, -0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, -0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, -0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, -0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, -0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, -0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, 0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, 0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, //------------------------------------------------------------------------------------------// -0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, -0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, -0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, -0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, -0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, -0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, -0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, -0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, -0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, -0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, -0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, -0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, -0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, -0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, -0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, 0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, -0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, -0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, 0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, 0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, 0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, -0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, -0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, 0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, -0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, 0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, -0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, 0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, 0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, -0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, -0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, 0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, -0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, 0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, -0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, 0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, -0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, -0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, 0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, 0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, 0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, 0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, 0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, 0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, 0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, 0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, 0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, 0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, -0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, 0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, 0.8586508742123365f, 0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, 0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, 0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, -0.044802370851755174f, 0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, 0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, 0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, 0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, -0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, -0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, 0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, 0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, 0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, 0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, 0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, 0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, }; for (int i = 0; i < grad4.length; i++) { grad4[i] = (float)(grad4[i] / NORMALIZER_4D); } for (int i = 0, j = 0; i < GRADIENTS_4D.length; i++, j++) { if (j == grad4.length) j = 0; GRADIENTS_4D[i] = grad4[j]; } int[][] lookup4DVertexCodes = { new int[] { 0x15, 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x01, 0x05, 0x11, 0x15, 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x01, 0x15, 0x16, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA, 0xAB }, new int[] { 0x04, 0x05, 0x14, 0x15, 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA }, new int[] { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x6A, 0x9A, 0xAA, 0xAB }, new int[] { 0x04, 0x15, 0x19, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA, 0xAE }, new int[] { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x5E, 0x6A, 0x9A, 0xAA, 0xAE }, new int[] { 0x05, 0x15, 0x1A, 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x5E, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x6B, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xAA }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x6B, 0x9A, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x9A, 0xAA, 0xAE }, new int[] { 0x15, 0x1A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x10, 0x11, 0x14, 0x15, 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA }, new int[] { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x67, 0x6A, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x6B, 0xA6, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA }, new int[] { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0xAA, 0xAB }, new int[] { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x6D, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x6E, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x10, 0x15, 0x25, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA, 0xBA }, new int[] { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0x76, 0xA6, 0xAA, 0xBA }, new int[] { 0x11, 0x15, 0x26, 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x67, 0x6A, 0x76, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA6, 0xAA, 0xBA }, new int[] { 0x15, 0x26, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0x79, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x25, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x14, 0x15, 0x29, 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0x6D, 0x79, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x29, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x7A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, new int[] { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x9A, 0x9B, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, new int[] { 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x59, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x56, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA }, new int[] { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, new int[] { 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x6A, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, new int[] { 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, new int[] { 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, new int[] { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, new int[] { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xAA, 0xAB }, new int[] { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x95, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA }, new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, new int[] { 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, new int[] { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB }, new int[] { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE }, new int[] { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xAF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA }, new int[] { 0x51, 0x55, 0x61, 0x65, 0x66, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x64, 0x65, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, new int[] { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xBB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA }, new int[] { 0x40, 0x45, 0x51, 0x54, 0x55, 0x85, 0x91, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA, 0xEA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xD6, 0xEA }, new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x86, 0x92, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB, 0xD6, 0xEA, 0xEB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x86, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xD9, 0xEA }, new int[] { 0x45, 0x55, 0x59, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xDA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x89, 0x95, 0x98, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE, 0xD9, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x59, 0x89, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xDA, 0xEA, 0xEF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x91, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x92, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x94, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x95, 0x98, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, new int[] { 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xEA, 0xEF }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xE5, 0xEA }, new int[] { 0x51, 0x55, 0x65, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x65, 0x94, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x55, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x94, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x59, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA, 0xEB }, new int[] { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, new int[] { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xEA }, new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA1, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA, 0xE5, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x65, 0x95, 0xA1, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xE6, 0xEA, 0xFB }, new int[] { 0x54, 0x55, 0x65, 0x95, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, new int[] { 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xEA, 0xFB }, new int[] { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, new int[] { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, new int[] { 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xEA }, new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xE9, 0xEA, 0xFE }, new int[] { 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA, 0xFE }, new int[] { 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA }, new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA, 0xEA }, }; LatticeVertex4D[] latticeVerticesByCode = new LatticeVertex4D[256]; for (int i = 0; i < 256; i++) { int cx = ((i >> 0) & 3) - 1; int cy = ((i >> 2) & 3) - 1; int cz = ((i >> 4) & 3) - 1; int cw = ((i >> 6) & 3) - 1; latticeVerticesByCode[i] = new LatticeVertex4D(cx, cy, cz, cw); } int nLatticeVerticesTotal = 0; for (int i = 0; i < 256; i++) { nLatticeVerticesTotal += lookup4DVertexCodes[i].length; } LOOKUP_4D_A = new int[256]; LOOKUP_4D_B = new LatticeVertex4D[nLatticeVerticesTotal]; for (int i = 0, j = 0; i < 256; i++) { LOOKUP_4D_A[i] = j | ((j + lookup4DVertexCodes[i].length) << 16); for (int k = 0; k < lookup4DVertexCodes[i].length; k++) { LOOKUP_4D_B[j++] = latticeVerticesByCode[lookup4DVertexCodes[i][k]]; } } } private static class LatticeVertex4D { public final float dx, dy, dz, dw; public final long xsvp, ysvp, zsvp, wsvp; public LatticeVertex4D(int xsv, int ysv, int zsv, int wsv) { this.xsvp = xsv * PRIME_X; this.ysvp = ysv * PRIME_Y; this.zsvp = zsv * PRIME_Z; this.wsvp = wsv * PRIME_W; float ssv = (xsv + ysv + zsv + wsv) * UNSKEW_4D; this.dx = -xsv - ssv; this.dy = -ysv - ssv; this.dz = -zsv - ssv; this.dw = -wsv - ssv; } } } ================================================ FILE: rust/OpenSimplex2.h ================================================ #pragma once #ifndef OPENSIMPLEX2_H extern float opensimplex2_fast_noise2(long long seed, double x, double y); extern float opensimplex2_fast_noise2_ImproveX(long long seed, double x, double y); extern float opensimplex2_fast_noise3_ImproveXY(long long seed, double x, double y, double z); extern float opensimplex2_fast_noise3_ImproveXZ(long long seed, double x, double y, double z); extern float opensimplex2_fast_noise3_Fallback(long long seed, double x, double y, double z); extern float opensimplex2_fast_noise4_ImproveXYZ_ImproveXY(long long seed, double x, double y, double z, double w); extern float opensimplex2_fast_noise4_ImproveXYZ_ImproveXZ(long long seed, double x, double y, double z, double w); extern float opensimplex2_fast_noise4_ImproveXYZ(long long seed, double x, double y, double z, double w); extern float opensimplex2_fast_noise4_ImproveXY_ImproveZW(long long seed, double x, double y, double z, double w); extern float opensimplex2_fast_noise4_Fallback(long long seed, double x, double y, double z, double w); extern float opensimplex2_smooth_noise2(long long seed, double x, double y); extern float opensimplex2_smooth_noise2_ImproveX(long long seed, double x, double y); extern float opensimplex2_smooth_noise3_ImproveXY(long long seed, double x, double y, double z); extern float opensimplex2_smooth_noise3_ImproveXZ(long long seed, double x, double y, double z); extern float opensimplex2_smooth_noise3_Fallback(long long seed, double x, double y, double z); extern float opensimplex2_smooth_noise4_ImproveXYZ_ImproveXY(long long seed, double x, double y, double z, double w); extern float opensimplex2_smooth_noise4_ImproveXYZ_ImproveXZ(long long seed, double x, double y, double z, double w); extern float opensimplex2_smooth_noise4_ImproveXYZ(long long seed, double x, double y, double z, double w); extern float opensimplex2_smooth_noise4_ImproveXY_ImproveZW(long long seed, double x, double y, double z, double w); extern float opensimplex2_smooth_noise4_Fallback(long long seed, double x, double y, double z, double w); #endif ================================================ FILE: rust/fast.rs ================================================ /*! K.jpg's OpenSimplex 2, faster variant */ use std::{num::Wrapping, sync::Once}; const PRIME_X: i64 = 0x5205402B9270C86F; const PRIME_Y: i64 = 0x598CD327003817B5; const PRIME_Z: i64 = 0x5BCC226E9FA0BACB; const PRIME_W: i64 = 0x56CC5227E58F554B; const HASH_MULTIPLIER: i64 = 0x53A3F72DEEC546F5; const SEED_FLIP_3D: i64 = -0x52D547B2E96ED629; const SEED_OFFSET_4D: i64 = 0xE83DC3E0DA7164D; const ROOT2OVER2: f64 = 0.7071067811865476; const SKEW_2D: f64 = 0.366025403784439; const UNSKEW_2D: f64 = -0.21132486540518713; const ROOT3OVER3: f64 = 0.577350269189626; const FALLBACK_ROTATE_3D: f64 = 2.0 / 3.0; const ROTATE_3D_ORTHOGONALIZER: f64 = UNSKEW_2D; const SKEW_4D: f32 = -0.138196601125011; const UNSKEW_4D: f32 = 0.309016994374947; const LATTICE_STEP_4D: f32 = 0.2; const N_GRADS_2D_EXPONENT: i32 = 7; const N_GRADS_3D_EXPONENT: i32 = 8; const N_GRADS_4D_EXPONENT: i32 = 9; const N_GRADS_2D: i32 = 1 << N_GRADS_2D_EXPONENT; const N_GRADS_3D: i32 = 1 << N_GRADS_3D_EXPONENT; const N_GRADS_4D: i32 = 1 << N_GRADS_4D_EXPONENT; const NORMALIZER_2D: f64 = 0.01001634121365712; const NORMALIZER_3D: f64 = 0.07969837668935331; const NORMALIZER_4D: f64 = 0.0220065933241897; const RSQUARED_2D: f32 = 0.5; const RSQUARED_3D: f32 = 0.6; const RSQUARED_4D: f32 = 0.6; /* Noise Evaluators */ /** 2D Simplex noise, standard lattice orientation. */ pub fn noise2(seed: i64, x: f64, y: f64) -> f32 { // Get points for A2* lattice let s = SKEW_2D * (x + y); let xs = x + s; let ys = y + s; noise2_UnskewedBase(seed, xs, ys) } /** 2D Simplex noise, with Y pointing down the main diagonal. Might be better for a 2D sandbox style game, where Y is vertical. Probably slightly less optimal for heightmaps or continent maps, unless your map is centered around an equator. It's a subtle difference, but the option is here to make it an easy choice. */ pub fn noise2_ImproveX(seed: i64, x: f64, y: f64) -> f32 { // Skew transform and rotation baked into one. let xx = x * ROOT2OVER2; let yy = y * (ROOT2OVER2 * (1.0 + 2.0 * SKEW_2D)); noise2_UnskewedBase(seed, yy + xx, yy - xx) } /** 2D Simplex noise base. */ fn noise2_UnskewedBase(seed: i64, xs: f64, ys: f64) -> f32 { let seed = Wrapping(seed); // Get base points and offsets. let xsb = fastFloor(xs); let ysb = fastFloor(ys); let xi = (xs - xsb as f64) as f32; let yi = (ys - ysb as f64) as f32; // Prime pre-multiplication for hash. let xsbp = Wrapping(xsb as i64) * Wrapping(PRIME_X); let ysbp = Wrapping(ysb as i64) * Wrapping(PRIME_Y); // Unskew. let t = (xi + yi) * UNSKEW_2D as f32; let dx0 = xi + t; let dy0 = yi + t; // First vertex. let mut value = 0.0; let a0 = RSQUARED_2D - dx0 * dx0 - dy0 * dy0; if a0 > 0.0 { value = (a0 * a0) * (a0 * a0) * grad2(seed, xsbp, ysbp, dx0, dy0); } // Second vertex. let a1 = (2.0 * (1.0 + 2.0 * UNSKEW_2D) * (1.0 / UNSKEW_2D + 2.0)) as f32 * t + ((-2.0 * (1.0 + 2.0 * UNSKEW_2D) * (1.0 + 2.0 * UNSKEW_2D)) as f32 + a0); if a1 > 0.0 { let dx1 = dx0 - (1.0 + 2.0 * UNSKEW_2D) as f32; let dy1 = dy0 - (1.0 + 2.0 * UNSKEW_2D) as f32; value += (a1 * a1) * (a1 * a1) * grad2( seed, xsbp + Wrapping(PRIME_X), ysbp + Wrapping(PRIME_Y), dx1, dy1, ); } // Third vertex. if dy0 > dx0 { let dx2 = dx0 - UNSKEW_2D as f32; let dy2 = dy0 - (UNSKEW_2D + 1.0) as f32; let a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if a2 > 0.0 { value += (a2 * a2) * (a2 * a2) * grad2(seed, xsbp, ysbp + Wrapping(PRIME_Y), dx2, dy2); } } else { let dx2 = dx0 - (UNSKEW_2D + 1.0) as f32; let dy2 = dy0 - UNSKEW_2D as f32; let a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if a2 > 0.0 { value += (a2 * a2) * (a2 * a2) * grad2(seed, xsbp + Wrapping(PRIME_X), ysbp, dx2, dy2); } } value } /** 3D OpenSimplex2 noise, with better visual isotropy in (X, Y). Recommended for 3D terrain and time-varied animations. The Z coordinate should always be the "different" coordinate in whatever your use case is. If Y is vertical in world coordinates, call noise3_ImproveXZ(x, z, Y) or use noise3_XZBeforeY. If Z is vertical in world coordinates, call noise3_ImproveXZ(x, y, Z). For a time varied animation, call noise3_ImproveXY(x, y, T). */ pub fn noise3_ImproveXY(seed: i64, x: f64, y: f64, z: f64) -> f32 { // Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal, // and the planes formed by XY are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. let xy = x + y; let s2 = xy * ROTATE_3D_ORTHOGONALIZER; let zz = z * ROOT3OVER3; let xr = x + s2 + zz; let yr = y + s2 + zz; let zr = xy * -ROOT3OVER3 + zz; // Evaluate both lattices to form a BCC lattice. noise3_UnrotatedBase(seed, xr, yr, zr) } /** 3D OpenSimplex2 noise, with better visual isotropy in (X, Z). Recommended for 3D terrain and time-varied animations. The Y coordinate should always be the "different" coordinate in whatever your use case is. If Y is vertical in world coordinates, call noise3_ImproveXZ(x, Y, z). If Z is vertical in world coordinates, call noise3_ImproveXZ(x, Z, y) or use noise3_ImproveXY. For a time varied animation, call noise3_ImproveXZ(x, T, y) or use noise3_ImproveXY. */ pub fn noise3_ImproveXZ(seed: i64, x: f64, y: f64, z: f64) -> f32 { // Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal, // and the planes formed by XZ are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. let xz = x + z; let s2 = xz * ROTATE_3D_ORTHOGONALIZER; let yy = y * ROOT3OVER3; let xr = x + s2 + yy; let zr = z + s2 + yy; let yr = xz * -ROOT3OVER3 + yy; // Evaluate both lattices to form a BCC lattice. noise3_UnrotatedBase(seed, xr, yr, zr) } /** 3D OpenSimplex2 noise, fallback rotation option Use noise3_ImproveXY or noise3_ImproveXZ instead, wherever appropriate. They have less diagonal bias. This function's best use is as a fallback. */ pub fn noise3_Fallback(seed: i64, x: f64, y: f64, z: f64) -> f32 { // Re-orient the cubic lattices via rotation, to produce a familiar look. // Orthonormal rotation. Not a skew transform. let r = FALLBACK_ROTATE_3D * (x + y + z); let xr = r - x; let yr = r - y; let zr = r - z; // Evaluate both lattices to form a BCC lattice. noise3_UnrotatedBase(seed, xr, yr, zr) } /** Generate overlapping cubic lattices for 3D OpenSimplex2 noise. */ fn noise3_UnrotatedBase(seed: i64, xr: f64, yr: f64, zr: f64) -> f32 { let mut seed = Wrapping(seed); // Get base points and offsets. let xrb = fastRound(xr); let yrb = fastRound(yr); let zrb = fastRound(zr); let mut xri = (xr - xrb as f64) as f32; let mut yri = (yr - yrb as f64) as f32; let mut zri = (zr - zrb as f64) as f32; // -1 if positive, 1 if negative. let mut xNSign = (-1.0 - xri) as i32 | 1; let mut yNSign = (-1.0 - yri) as i32 | 1; let mut zNSign = (-1.0 - zri) as i32 | 1; // Compute absolute values, using the above as a shortcut. This was faster in my tests for some reason. let mut ax0 = xNSign as f32 * -xri; let mut ay0 = yNSign as f32 * -yri; let mut az0 = zNSign as f32 * -zri; // Prime pre-multiplication for hash. let mut xrbp = Wrapping(xrb as i64) * Wrapping(PRIME_X); let mut yrbp = Wrapping(yrb as i64) * Wrapping(PRIME_Y); let mut zrbp = Wrapping(zrb as i64) * Wrapping(PRIME_Z); // Loop: Pick an edge on each lattice copy. let mut value = 0.0; let mut a = (RSQUARED_3D - xri * xri) - (yri * yri + zri * zri); for l in 0.. { // Closest point on cube. if a > 0.0 { value += (a * a) * (a * a) * grad3(seed, xrbp, yrbp, zrbp, xri, yri, zri); } // Second-closest point. if ax0 >= ay0 && ax0 >= az0 { let mut b = a + ax0 + ax0; if b > 1.0 { b -= 1.0; value += (b * b) * (b * b) * grad3( seed, xrbp - Wrapping(xNSign as i64) * Wrapping(PRIME_X), yrbp, zrbp, xri + xNSign as f32, yri, zri, ); } } else if ay0 > ax0 && ay0 >= az0 { let mut b = a + ay0 + ay0; if b > 1.0 { b -= 1.0; value += (b * b) * (b * b) * grad3( seed, xrbp, yrbp - Wrapping(yNSign as i64) * Wrapping(PRIME_Y), zrbp, xri, yri + yNSign as f32, zri, ); } } else { let mut b = a + az0 + az0; if b > 1.0 { b -= 1.0; value += (b * b) * (b * b) * grad3( seed, xrbp, yrbp, zrbp - Wrapping(zNSign as i64) * Wrapping(PRIME_Z), xri, yri, zri + zNSign as f32, ); } } // Break from loop if we're done, skipping updates below. if l == 1 { break; } // Update absolute value. ax0 = 0.5 - ax0; ay0 = 0.5 - ay0; az0 = 0.5 - az0; // Update relative coordinate. xri = xNSign as f32 * ax0; yri = yNSign as f32 * ay0; zri = zNSign as f32 * az0; // Update falloff. a += (0.75 - ax0) - (ay0 + az0); // Update prime for hash. xrbp += (xNSign as i64 >> 1) & PRIME_X; yrbp += (yNSign as i64 >> 1) & PRIME_Y; zrbp += (zNSign as i64 >> 1) & PRIME_Z; // Update the reverse sign indicators. xNSign = -xNSign; yNSign = -yNSign; zNSign = -zNSign; // And finally update the seed for the other lattice copy. seed ^= SEED_FLIP_3D; } value } /** 4D OpenSimplex2 noise, with XYZ oriented like noise3_ImproveXY and W for an extra degree of freedom. W repeats eventually. Recommended for time-varied animations which texture a 3D object (W=time) in a space where Z is vertical */ pub fn noise4_ImproveXYZ_ImproveXY(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { let xy = x + y; let s2 = xy * -0.21132486540518699998; let zz = z * 0.28867513459481294226; let ww = w * 0.2236067977499788; let xr = x + (zz + ww + s2); let yr = y + (zz + ww + s2); let zr = xy * -0.57735026918962599998 + (zz + ww); let wr = z * -0.866025403784439 + ww; noise4_UnskewedBase(seed, xr, yr, zr, wr) } /** 4D OpenSimplex2 noise, with XYZ oriented like noise3_ImproveXZ and W for an extra degree of freedom. W repeats eventually. Recommended for time-varied animations which texture a 3D object (W=time) in a space where Y is vertical */ pub fn noise4_ImproveXYZ_ImproveXZ(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { let xz = x + z; let s2 = xz * -0.21132486540518699998; let yy = y * 0.28867513459481294226; let ww = w * 0.2236067977499788; let xr = x + (yy + ww + s2); let zr = z + (yy + ww + s2); let yr = xz * -0.57735026918962599998 + (yy + ww); let wr = y * -0.866025403784439 + ww; noise4_UnskewedBase(seed, xr, yr, zr, wr) } /** 4D OpenSimplex2 noise, with XYZ oriented like noise3_Fallback and W for an extra degree of freedom. W repeats eventually. Recommended for time-varied animations which texture a 3D object (W=time) where there isn't a clear distinction between horizontal and vertical */ pub fn noise4_ImproveXYZ(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { let xyz = x + y + z; let ww = w * 0.2236067977499788; let s2 = xyz * -0.16666666666666666 + ww; let xs = x + s2; let ys = y + s2; let zs = z + s2; let ws = -0.5 * xyz + ww; noise4_UnskewedBase(seed, xs, ys, zs, ws) } /** 4D OpenSimplex2 noise, with XY and ZW forming orthogonal triangular-based planes. Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. Recommended for noise(x, y, sin(time), cos(time)) trick. */ pub fn noise4_ImproveXY_ImproveZW(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { let s2 = (x + y) * -0.178275657951399372 + (z + w) * 0.215623393288842828; let t2 = (z + w) * -0.403949762580207112 + (x + y) * -0.375199083010075342; let xs = x + s2; let ys = y + s2; let zs = z + t2; let ws = w + t2; noise4_UnskewedBase(seed, xs, ys, zs, ws) } /** 4D OpenSimplex2 noise, fallback lattice orientation. */ pub fn noise4_Fallback(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { // Get points for A4 lattice let s = SKEW_4D as f64 * (x + y + z + w); let xs = x + s; let ys = y + s; let zs = z + s; let ws = w + s; noise4_UnskewedBase(seed, xs, ys, zs, ws) } /** 4D OpenSimplex2 noise base. */ fn noise4_UnskewedBase(seed: i64, xs: f64, ys: f64, zs: f64, ws: f64) -> f32 { let mut seed = Wrapping(seed); // Get base points and offsets let xsb = fastFloor(xs); let ysb = fastFloor(ys); let zsb = fastFloor(zs); let wsb = fastFloor(ws); let mut xsi = (xs - xsb as f64) as f32; let mut ysi = (ys - ysb as f64) as f32; let mut zsi = (zs - zsb as f64) as f32; let mut wsi = (ws - wsb as f64) as f32; // Determine which lattice we can be confident has a contributing point its corresponding cell's base simplex. // We only look at the spaces between the diagonal planes. This proved effective in all of my tests. let siSum = (xsi + ysi) + (zsi + wsi); let startingLattice = (siSum * 1.25) as i32; // Offset for seed based on first lattice copy. seed += Wrapping(startingLattice as i64) * Wrapping(SEED_OFFSET_4D); // Offset for lattice point relative positions (skewed) let startingLatticeOffset = startingLattice as f32 * -LATTICE_STEP_4D; xsi += startingLatticeOffset; ysi += startingLatticeOffset; zsi += startingLatticeOffset; wsi += startingLatticeOffset; // Prep for vertex contributions. let mut ssi = (siSum + startingLatticeOffset * 4.0) * UNSKEW_4D; // Prime pre-multiplication for hash. let mut xsvp = Wrapping(xsb as i64) * Wrapping(PRIME_X); let mut ysvp = Wrapping(ysb as i64) * Wrapping(PRIME_Y); let mut zsvp = Wrapping(zsb as i64) * Wrapping(PRIME_Z); let mut wsvp = Wrapping(wsb as i64) * Wrapping(PRIME_W); // Five points to add, total, from five copies of the A4 lattice. let mut value = 0.0; for i in 0.. { // Next point is the closest vertex on the 4-simplex whose base vertex is the aforementioned vertex. let score0 = 1.0 + ssi * (-1.0 / UNSKEW_4D); // Seems slightly faster than 1.0-xsi-ysi-zsi-wsi if xsi >= ysi && xsi >= zsi && xsi >= wsi && xsi >= score0 { xsvp += PRIME_X; xsi -= 1.0; ssi -= UNSKEW_4D; } else if ysi > xsi && ysi >= zsi && ysi >= wsi && ysi >= score0 { ysvp += PRIME_Y; ysi -= 1.0; ssi -= UNSKEW_4D; } else if zsi > xsi && zsi > ysi && zsi >= wsi && zsi >= score0 { zsvp += PRIME_Z; zsi -= 1.0; ssi -= UNSKEW_4D; } else if wsi > xsi && wsi > ysi && wsi > zsi && wsi >= score0 { wsvp += PRIME_W; wsi -= 1.0; ssi -= UNSKEW_4D; } // gradient contribution with falloff. let dx = xsi + ssi; let dy = ysi + ssi; let dz = zsi + ssi; let dw = wsi + ssi; let mut a = (dx * dx + dy * dy) + (dz * dz + dw * dw); if a < RSQUARED_4D { a -= RSQUARED_4D; a *= a; value += a * a * grad4(seed, xsvp, ysvp, zsvp, wsvp, dx, dy, dz, dw); } // Break from loop if we're done, skipping updates below. if i == 4 { break; } // Update for next lattice copy shifted down by <-0.2, -0.2, -0.2, -0.2>. xsi += LATTICE_STEP_4D; ysi += LATTICE_STEP_4D; zsi += LATTICE_STEP_4D; wsi += LATTICE_STEP_4D; ssi += LATTICE_STEP_4D * 4.0 * UNSKEW_4D; seed -= SEED_OFFSET_4D; // Because we don't always start on the same lattice copy, there's a special reset case. if i == startingLattice { xsvp -= PRIME_X; ysvp -= PRIME_Y; zsvp -= PRIME_Z; wsvp -= PRIME_W; seed += SEED_OFFSET_4D * 5; } } value } /* Utility */ fn grad2(seed: Wrapping, xsvp: Wrapping, ysvp: Wrapping, dx: f32, dy: f32) -> f32 { let mut hash = seed ^ xsvp ^ ysvp; hash *= HASH_MULTIPLIER; hash ^= hash.0 >> (64 - N_GRADS_2D_EXPONENT + 1); let gi = (hash.0 as i32 & ((N_GRADS_2D - 1) << 1)) as usize; let grads = &getGradients().gradients2D; grads[gi | 0] * dx + grads[gi | 1] * dy } fn grad3( seed: Wrapping, xrvp: Wrapping, yrvp: Wrapping, zrvp: Wrapping, dx: f32, dy: f32, dz: f32, ) -> f32 { let mut hash = (seed ^ xrvp) ^ (yrvp ^ zrvp); hash *= HASH_MULTIPLIER; hash ^= hash.0 >> (64 - N_GRADS_3D_EXPONENT + 2); let gi = (hash.0 as i32 & ((N_GRADS_3D - 1) << 2)) as usize; let grads = &getGradients().gradients3D; grads[gi | 0] * dx + grads[gi | 1] * dy + grads[gi | 2] * dz } fn grad4( seed: Wrapping, xsvp: Wrapping, ysvp: Wrapping, zsvp: Wrapping, wsvp: Wrapping, dx: f32, dy: f32, dz: f32, dw: f32, ) -> f32 { let mut hash = seed ^ (xsvp ^ ysvp) ^ (zsvp ^ wsvp); hash *= HASH_MULTIPLIER; hash ^= hash.0 >> (64 - N_GRADS_4D_EXPONENT + 2); let gi = (hash.0 as i32 & ((N_GRADS_4D - 1) << 2)) as usize; let grads = &getGradients().gradients4D; (grads[gi | 0] * dx + grads[gi | 1] * dy) + (grads[gi | 2] * dz + grads[gi | 3] * dw) } fn fastFloor(x: f64) -> i32 { let xi = x as i32; if x < xi as f64 { xi - 1 } else { xi } } fn fastRound(x: f64) -> i32 { if x < 0.0 { (x - 0.5) as i32 } else { (x + 0.5) as i32 } } /* gradients */ struct Gradients { gradients2D: Vec, gradients3D: Vec, gradients4D: Vec, } static mut GRADIENTS: (Once, Option) = (Once::new(), None); fn getGradients() -> &'static Gradients { unsafe { GRADIENTS.0.call_once(|| { GRADIENTS.1 = Some(initGradients()); }); GRADIENTS.1.as_ref().unwrap() } } fn initGradients() -> Gradients { let gradients2D: Vec<_> = GRAD2_SRC .into_iter() .map(|v| (v / NORMALIZER_2D) as f32) .collect::>() // cache divisions .into_iter() .cycle() .take((N_GRADS_2D * 2) as usize) .collect(); let gradients3D: Vec<_> = GRAD3_SRC .into_iter() .map(|v| (v / NORMALIZER_3D) as f32) .collect::>() // cache divisions .into_iter() .cycle() .take((N_GRADS_3D * 4) as usize) .collect(); let gradients4D: Vec<_> = GRAD4_SRC .into_iter() .map(|v| (v / NORMALIZER_4D) as f32) .collect::>() // cache divisions .into_iter() .cycle() .take((N_GRADS_4D * 4) as usize) .collect(); Gradients { gradients2D, gradients3D, gradients4D, } } #[rustfmt::skip] const GRAD2_SRC: &[f64] = &[ 0.38268343236509, 0.923879532511287, 0.923879532511287, 0.38268343236509, 0.923879532511287, -0.38268343236509, 0.38268343236509, -0.923879532511287, -0.38268343236509, -0.923879532511287, -0.923879532511287, -0.38268343236509, -0.923879532511287, 0.38268343236509, -0.38268343236509, 0.923879532511287, //-------------------------------------// 0.130526192220052, 0.99144486137381, 0.608761429008721, 0.793353340291235, 0.793353340291235, 0.608761429008721, 0.99144486137381, 0.130526192220051, 0.99144486137381, -0.130526192220051, 0.793353340291235, -0.60876142900872, 0.608761429008721, -0.793353340291235, 0.130526192220052, -0.99144486137381, -0.130526192220052, -0.99144486137381, -0.608761429008721, -0.793353340291235, -0.793353340291235, -0.608761429008721, -0.99144486137381, -0.130526192220052, -0.99144486137381, 0.130526192220051, -0.793353340291235, 0.608761429008721, -0.608761429008721, 0.793353340291235, -0.130526192220052, 0.99144486137381, ]; #[rustfmt::skip] const GRAD3_SRC: &[f64] = &[ 2.22474487139, 2.22474487139, -1.0, 0.0, 2.22474487139, 2.22474487139, 1.0, 0.0, 3.0862664687972017, 1.1721513422464978, 0.0, 0.0, 1.1721513422464978, 3.0862664687972017, 0.0, 0.0, -2.22474487139, 2.22474487139, -1.0, 0.0, -2.22474487139, 2.22474487139, 1.0, 0.0, -1.1721513422464978, 3.0862664687972017, 0.0, 0.0, -3.0862664687972017, 1.1721513422464978, 0.0, 0.0, -1.0, -2.22474487139, -2.22474487139, 0.0, 1.0, -2.22474487139, -2.22474487139, 0.0, 0.0, -3.0862664687972017, -1.1721513422464978, 0.0, 0.0, -1.1721513422464978, -3.0862664687972017, 0.0, -1.0, -2.22474487139, 2.22474487139, 0.0, 1.0, -2.22474487139, 2.22474487139, 0.0, 0.0, -1.1721513422464978, 3.0862664687972017, 0.0, 0.0, -3.0862664687972017, 1.1721513422464978, 0.0, //--------------------------------------------------------------------// -2.22474487139, -2.22474487139, -1.0, 0.0, -2.22474487139, -2.22474487139, 1.0, 0.0, -3.0862664687972017, -1.1721513422464978, 0.0, 0.0, -1.1721513422464978, -3.0862664687972017, 0.0, 0.0, -2.22474487139, -1.0, -2.22474487139, 0.0, -2.22474487139, 1.0, -2.22474487139, 0.0, -1.1721513422464978, 0.0, -3.0862664687972017, 0.0, -3.0862664687972017, 0.0, -1.1721513422464978, 0.0, -2.22474487139, -1.0, 2.22474487139, 0.0, -2.22474487139, 1.0, 2.22474487139, 0.0, -3.0862664687972017, 0.0, 1.1721513422464978, 0.0, -1.1721513422464978, 0.0, 3.0862664687972017, 0.0, -1.0, 2.22474487139, -2.22474487139, 0.0, 1.0, 2.22474487139, -2.22474487139, 0.0, 0.0, 1.1721513422464978, -3.0862664687972017, 0.0, 0.0, 3.0862664687972017, -1.1721513422464978, 0.0, -1.0, 2.22474487139, 2.22474487139, 0.0, 1.0, 2.22474487139, 2.22474487139, 0.0, 0.0, 3.0862664687972017, 1.1721513422464978, 0.0, 0.0, 1.1721513422464978, 3.0862664687972017, 0.0, 2.22474487139, -2.22474487139, -1.0, 0.0, 2.22474487139, -2.22474487139, 1.0, 0.0, 1.1721513422464978, -3.0862664687972017, 0.0, 0.0, 3.0862664687972017, -1.1721513422464978, 0.0, 0.0, 2.22474487139, -1.0, -2.22474487139, 0.0, 2.22474487139, 1.0, -2.22474487139, 0.0, 3.0862664687972017, 0.0, -1.1721513422464978, 0.0, 1.1721513422464978, 0.0, -3.0862664687972017, 0.0, 2.22474487139, -1.0, 2.22474487139, 0.0, 2.22474487139, 1.0, 2.22474487139, 0.0, 1.1721513422464978, 0.0, 3.0862664687972017, 0.0, 3.0862664687972017, 0.0, 1.1721513422464978, 0.0, ]; #[rustfmt::skip] const GRAD4_SRC: &[f64] = &[ -0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537, //------------------------------------------------------------------------------------------// -0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301, -0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301, -0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708, -0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, -0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, -0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, ]; ================================================ FILE: rust/ffi.rs ================================================ use std::ffi::{c_double, c_float, c_longlong}; use crate::{fast, smooth}; #[no_mangle] pub extern "C" fn opensimplex2_fast_noise2(seed: c_longlong, x: c_double, y: c_double) -> c_float { fast::noise2(seed, x, y) } #[no_mangle] pub extern "C" fn opensimplex2_fast_noise2_ImproveX( seed: c_longlong, x: c_double, y: c_double, ) -> c_float { fast::noise2_ImproveX(seed, x, y) } #[no_mangle] pub extern "C" fn opensimplex2_fast_noise3_ImproveXY( seed: c_longlong, x: c_double, y: c_double, z: c_double, ) -> c_float { fast::noise3_ImproveXY(seed, x, y, z) } #[no_mangle] pub extern "C" fn opensimplex2_fast_noise3_ImproveXZ( seed: c_longlong, x: c_double, y: c_double, z: c_double, ) -> c_float { fast::noise3_ImproveXZ(seed, x, y, z) } #[no_mangle] pub extern "C" fn opensimplex2_fast_noise3_Fallback( seed: c_longlong, x: c_double, y: c_double, z: c_double, ) -> c_float { fast::noise3_Fallback(seed, x, y, z) } #[no_mangle] pub extern "C" fn opensimplex2_fast_noise4_ImproveXYZ_ImproveXY( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { fast::noise4_ImproveXYZ_ImproveXY(seed, x, y, z, w) } #[no_mangle] pub extern "C" fn opensimplex2_fast_noise4_ImproveXYZ_ImproveXZ( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { fast::noise4_ImproveXYZ_ImproveXZ(seed, x, y, z, w) } #[no_mangle] pub extern "C" fn opensimplex2_fast_noise4_ImproveXYZ( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { fast::noise4_ImproveXYZ(seed, x, y, z, w) } #[no_mangle] pub extern "C" fn opensimplex2_fast_noise4_ImproveXY_ImproveZW( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { fast::noise4_ImproveXY_ImproveZW(seed, x, y, z, w) } #[no_mangle] pub extern "C" fn opensimplex2_fast_noise4_Fallback( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { fast::noise4_Fallback(seed, x, y, z, w) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise2( seed: c_longlong, x: c_double, y: c_double, ) -> c_float { smooth::noise2(seed, x, y) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise2_ImproveX( seed: c_longlong, x: c_double, y: c_double, ) -> c_float { smooth::noise2_ImproveX(seed, x, y) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise3_ImproveXY( seed: c_longlong, x: c_double, y: c_double, z: c_double, ) -> c_float { smooth::noise3_ImproveXY(seed, x, y, z) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise3_ImproveXZ( seed: c_longlong, x: c_double, y: c_double, z: c_double, ) -> c_float { smooth::noise3_ImproveXZ(seed, x, y, z) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise3_Fallback( seed: c_longlong, x: c_double, y: c_double, z: c_double, ) -> c_float { smooth::noise3_Fallback(seed, x, y, z) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise4_ImproveXYZ_ImproveXY( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { smooth::noise4_ImproveXYZ_ImproveXY(seed, x, y, z, w) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise4_ImproveXYZ_ImproveXZ( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { smooth::noise4_ImproveXYZ_ImproveXZ(seed, x, y, z, w) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise4_ImproveXYZ( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { smooth::noise4_ImproveXYZ(seed, x, y, z, w) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise4_ImproveXY_ImproveZW( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { smooth::noise4_ImproveXY_ImproveZW(seed, x, y, z, w) } #[no_mangle] pub extern "C" fn opensimplex2_smooth_noise4_Fallback( seed: c_longlong, x: c_double, y: c_double, z: c_double, w: c_double, ) -> c_float { smooth::noise4_Fallback(seed, x, y, z, w) } ================================================ FILE: rust/lib.rs ================================================ #![allow(non_snake_case)] pub mod fast; mod ffi; pub mod smooth; ================================================ FILE: rust/smooth.rs ================================================ /*! K.jpg's OpenSimplex 2, smooth variant ("SuperSimplex") */ use std::{num::Wrapping, sync::Once}; const PRIME_X: i64 = 0x5205402B9270C86F; const PRIME_Y: i64 = 0x598CD327003817B5; const PRIME_Z: i64 = 0x5BCC226E9FA0BACB; const PRIME_W: i64 = 0x56CC5227E58F554B; const HASH_MULTIPLIER: i64 = 0x53A3F72DEEC546F5; const SEED_FLIP_3D: i64 = -0x52D547B2E96ED629; const ROOT2OVER2: f64 = 0.7071067811865476; const SKEW_2D: f64 = 0.366025403784439; const UNSKEW_2D: f64 = -0.21132486540518713; const ROOT3OVER3: f64 = 0.577350269189626; const FALLBACK_ROTATE3: f64 = 2.0 / 3.0; const ROTATE3_ORTHOGONALIZER: f64 = UNSKEW_2D; const SKEW_4D: f32 = 0.309016994374947; const UNSKEW_4D: f32 = -0.138196601125011; const N_GRADS_2D_EXPONENT: i32 = 7; const N_GRADS_3D_EXPONENT: i32 = 8; const N_GRADS_4D_EXPONENT: i32 = 9; const N_GRADS_2D: i32 = 1 << N_GRADS_2D_EXPONENT; const N_GRADS_3D: i32 = 1 << N_GRADS_3D_EXPONENT; const N_GRADS_4D: i32 = 1 << N_GRADS_4D_EXPONENT; const NORMALIZER_2D: f64 = 0.05481866495625118; const NORMALIZER_3D: f64 = 0.2781926117527186; const NORMALIZER_4D: f64 = 0.11127401889945551; const RSQUARED_2D: f32 = 2.0 / 3.0; const RSQUARED_3D: f32 = 3.0 / 4.0; const RSQUARED_4D: f32 = 4.0 / 5.0; /* Noise Evaluators */ /** 2D OpenSimplex2S/SuperSimplex noise, standard lattice orientation. */ pub fn noise2(seed: i64, x: f64, y: f64) -> f32 { // Get points for A2* lattice let s = SKEW_2D * (x + y); let xs = x + s; let ys = y + s; noise2_UnskewedBase(seed, xs, ys) } /** 2D OpenSimplex2S/SuperSimplex noise, with Y pointing down the main diagonal. Might be better for a 2D sandbox style game, where Y is vertical. Probably slightly less optimal for heightmaps or continent maps, unless your map is centered around an equator. It's a slight difference, but the option is here to make it easy. */ pub fn noise2_ImproveX(seed: i64, x: f64, y: f64) -> f32 { // Skew transform and rotation baked into one. let xx = x * ROOT2OVER2; let yy = y * (ROOT2OVER2 * (1.0 + 2.0 * SKEW_2D)); noise2_UnskewedBase(seed, yy + xx, yy - xx) } /** 2D OpenSimplex2S/SuperSimplex noise base. */ fn noise2_UnskewedBase(seed: i64, xs: f64, ys: f64) -> f32 { let seed = Wrapping(seed); // Get base points and offsets. let xsb = fastFloor(xs); let ysb = fastFloor(ys); let xi = (xs - xsb as f64) as f32; let yi = (ys - ysb as f64) as f32; // Prime pre-multiplication for hash. let xsbp = Wrapping(xsb as i64) * Wrapping(PRIME_X); let ysbp = Wrapping(ysb as i64) * Wrapping(PRIME_Y); // Unskew. let t = (xi + yi) * UNSKEW_2D as f32; let dx0 = xi + t; let dy0 = yi + t; // First vertex. let a0 = RSQUARED_2D - dx0 * dx0 - dy0 * dy0; let mut value = (a0 * a0) * (a0 * a0) * grad2(seed, xsbp, ysbp, dx0, dy0); // Second vertex. let a1 = (2.0 * (1.0 + 2.0 * UNSKEW_2D) * (1.0 / UNSKEW_2D + 2.0)) as f32 * t + ((-2.0 * (1.0 + 2.0 * UNSKEW_2D) * (1.0 + 2.0 * UNSKEW_2D)) as f32 + a0); let dx1 = dx0 - (1.0 + 2.0 * UNSKEW_2D) as f32; let dy1 = dy0 - (1.0 + 2.0 * UNSKEW_2D) as f32; value += (a1 * a1) * (a1 * a1) * grad2( seed, xsbp + Wrapping(PRIME_X), ysbp + Wrapping(PRIME_Y), dx1, dy1, ); // Third and fourth vertices. // Nested conditionals were faster than compact bit logic/arithmetic. let xmyi = xi - yi; if t < UNSKEW_2D as f32 { if xi + xmyi > 1.0 { let dx2 = dx0 - (3.0 * UNSKEW_2D + 2.0) as f32; let dy2 = dy0 - (3.0 * UNSKEW_2D + 1.0) as f32; let a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if a2 > 0.0 { value += (a2 * a2) * (a2 * a2) * grad2( seed, xsbp + Wrapping(PRIME_X << 1), ysbp + Wrapping(PRIME_Y), dx2, dy2, ); } } else { let dx2 = dx0 - UNSKEW_2D as f32; let dy2 = dy0 - (UNSKEW_2D + 1.0) as f32; let a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if a2 > 0.0 { value += (a2 * a2) * (a2 * a2) * grad2(seed, xsbp, ysbp + Wrapping(PRIME_Y), dx2, dy2); } } if yi - xmyi > 1.0 { let dx3 = dx0 - (3.0 * UNSKEW_2D + 1.0) as f32; let dy3 = dy0 - (3.0 * UNSKEW_2D + 2.0) as f32; let a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3; if a3 > 0.0 { value += (a3 * a3) * (a3 * a3) * grad2( seed, xsbp + Wrapping(PRIME_X), ysbp + Wrapping(PRIME_Y << 1), dx3, dy3, ); } } else { let dx3 = dx0 - (UNSKEW_2D + 1.0) as f32; let dy3 = dy0 - UNSKEW_2D as f32; let a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3; if a3 > 0.0 { value += (a3 * a3) * (a3 * a3) * grad2(seed, xsbp + Wrapping(PRIME_X), ysbp, dx3, dy3); } } } else { if xi + xmyi < 0.0 { let dx2 = dx0 + (1.0 + UNSKEW_2D) as f32; let dy2 = dy0 + UNSKEW_2D as f32; let a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if a2 > 0.0 { value += (a2 * a2) * (a2 * a2) * grad2(seed, xsbp - Wrapping(PRIME_X), ysbp, dx2, dy2); } } else { let dx2 = dx0 - (UNSKEW_2D + 1.0) as f32; let dy2 = dy0 - UNSKEW_2D as f32; let a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if a2 > 0.0 { value += (a2 * a2) * (a2 * a2) * grad2(seed, xsbp + Wrapping(PRIME_X), ysbp, dx2, dy2); } } if yi < xmyi { let dx2 = dx0 + UNSKEW_2D as f32; let dy2 = dy0 + (UNSKEW_2D + 1.0) as f32; let a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if a2 > 0.0 { value += (a2 * a2) * (a2 * a2) * grad2(seed, xsbp, ysbp - Wrapping(PRIME_Y), dx2, dy2); } } else { let dx2 = dx0 - UNSKEW_2D as f32; let dy2 = dy0 - (UNSKEW_2D + 1.0) as f32; let a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; if a2 > 0.0 { value += (a2 * a2) * (a2 * a2) * grad2(seed, xsbp, ysbp + Wrapping(PRIME_Y), dx2, dy2); } } } value } /** 3D OpenSimplex2S/SuperSimplex noise, with better visual isotropy in (X, Y). Recommended for 3D terrain and time-varied animations. The Z coordinate should always be the "different" coordinate in whatever your use case is. If Y is vertical in world coordinates, call noise3_ImproveXZ(x, z, Y) or use noise3_XZBeforeY. If Z is vertical in world coordinates, call noise3_ImproveXZ(x, y, Z). For a time varied animation, call noise3_ImproveXY(x, y, T). */ pub fn noise3_ImproveXY(seed: i64, x: f64, y: f64, z: f64) -> f32 { // Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal, // and the planes formed by XY are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. let xy = x + y; let s2 = xy * ROTATE3_ORTHOGONALIZER; let zz = z * ROOT3OVER3; let xr = x + s2 + zz; let yr = y + s2 + zz; let zr = xy * -ROOT3OVER3 + zz; // Evaluate both lattices to form a BCC lattice. noise3_UnrotatedBase(seed, xr, yr, zr) } /** 3D OpenSimplex2S/SuperSimplex noise, with better visual isotropy in (X, Z). Recommended for 3D terrain and time-varied animations. The Y coordinate should always be the "different" coordinate in whatever your use case is. If Y is vertical in world coordinates, call noise3_ImproveXZ(x, Y, z). If Z is vertical in world coordinates, call noise3_ImproveXZ(x, Z, y) or use noise3_ImproveXY. For a time varied animation, call noise3_ImproveXZ(x, T, y) or use noise3_ImproveXY. */ pub fn noise3_ImproveXZ(seed: i64, x: f64, y: f64, z: f64) -> f32 { // Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal, // and the planes formed by XZ are moved far out of alignment with the cube faces. // Orthonormal rotation. Not a skew transform. let xz = x + z; let s2 = xz * -0.211324865405187; let yy = y * ROOT3OVER3; let xr = x + s2 + yy; let zr = z + s2 + yy; let yr = xz * -ROOT3OVER3 + yy; // Evaluate both lattices to form a BCC lattice. noise3_UnrotatedBase(seed, xr, yr, zr) } /** 3D OpenSimplex2S/SuperSimplex noise, fallback rotation option Use noise3_ImproveXY or noise3_ImproveXZ instead, wherever appropriate. They have less diagonal bias. This function's best use is as a fallback. */ pub fn noise3_Fallback(seed: i64, x: f64, y: f64, z: f64) -> f32 { // Re-orient the cubic lattices via rotation, to produce a familiar look. // Orthonormal rotation. Not a skew transform. let r = FALLBACK_ROTATE3 * (x + y + z); let xr = r - x; let yr = r - y; let zr = r - z; // Evaluate both lattices to form a BCC lattice. noise3_UnrotatedBase(seed, xr, yr, zr) } /** Generate overlapping cubic lattices for 3D Re-oriented BCC noise. Lookup table implementation inspired by DigitalShadow. It was actually faster to narrow down the points in the loop itself, than to build up the index with enough info to isolate 8 points. */ fn noise3_UnrotatedBase(seed: i64, xr: f64, yr: f64, zr: f64) -> f32 { let seed = Wrapping(seed); // Get base points and offsets. let xrb = fastFloor(xr); let yrb = fastFloor(yr); let zrb = fastFloor(zr); let xi = (xr - xrb as f64) as f32; let yi = (yr - yrb as f64) as f32; let zi = (zr - zrb as f64) as f32; // Prime pre-multiplication for hash. Also flip seed for second lattice copy. let xrbp = Wrapping(xrb as i64) * Wrapping(PRIME_X); let yrbp = Wrapping(yrb as i64) * Wrapping(PRIME_Y); let zrbp = Wrapping(zrb as i64) * Wrapping(PRIME_Z); let seed2 = seed ^ Wrapping(SEED_FLIP_3D); // -1 if positive, 0 if negative. let xNMask = (-0.5 - xi) as i32; let yNMask = (-0.5 - yi) as i32; let zNMask = (-0.5 - zi) as i32; // First vertex. let x0 = xi + xNMask as f32; let y0 = yi + yNMask as f32; let z0 = zi + zNMask as f32; let a0 = RSQUARED_3D - x0 * x0 - y0 * y0 - z0 * z0; let mut value = (a0 * a0) * (a0 * a0) * grad3( seed, xrbp + (Wrapping(xNMask as i64) & Wrapping(PRIME_X)), yrbp + (Wrapping(yNMask as i64) & Wrapping(PRIME_Y)), zrbp + (Wrapping(zNMask as i64) & Wrapping(PRIME_Z)), x0, y0, z0, ); // Second vertex. let x1 = xi - 0.5; let y1 = yi - 0.5; let z1 = zi - 0.5; let a1 = RSQUARED_3D - x1 * x1 - y1 * y1 - z1 * z1; value += (a1 * a1) * (a1 * a1) * grad3( seed2, xrbp + Wrapping(PRIME_X), yrbp + Wrapping(PRIME_Y), zrbp + Wrapping(PRIME_Z), x1, y1, z1, ); // Shortcuts for building the remaining falloffs. // Derived by subtracting the polynomials with the offsets plugged in. let xAFlipMask0 = ((xNMask | 1) << 1) as f32 * x1; let yAFlipMask0 = ((yNMask | 1) << 1) as f32 * y1; let zAFlipMask0 = ((zNMask | 1) << 1) as f32 * z1; let xAFlipMask1 = (-2 - (xNMask << 2)) as f32 * x1 - 1.0; let yAFlipMask1 = (-2 - (yNMask << 2)) as f32 * y1 - 1.0; let zAFlipMask1 = (-2 - (zNMask << 2)) as f32 * z1 - 1.0; let mut skip5 = false; let a2 = xAFlipMask0 + a0; if a2 > 0.0 { let x2 = x0 - (xNMask | 1) as f32; let y2 = y0; let z2 = z0; value += (a2 * a2) * (a2 * a2) * grad3( seed, xrbp + (Wrapping(!xNMask as i64) & Wrapping(PRIME_X)), yrbp + (Wrapping(yNMask as i64) & Wrapping(PRIME_Y)), zrbp + (Wrapping(zNMask as i64) & Wrapping(PRIME_Z)), x2, y2, z2, ); } else { let a3 = yAFlipMask0 + zAFlipMask0 + a0; if a3 > 0.0 { let x3 = x0; let y3 = y0 - (yNMask | 1) as f32; let z3 = z0 - (zNMask | 1) as f32; value += (a3 * a3) * (a3 * a3) * grad3( seed, xrbp + (Wrapping(xNMask as i64) & Wrapping(PRIME_X)), yrbp + (Wrapping(!yNMask as i64) & Wrapping(PRIME_Y)), zrbp + (Wrapping(!zNMask as i64) & Wrapping(PRIME_Z)), x3, y3, z3, ); } let a4 = xAFlipMask1 + a1; if a4 > 0.0 { let x4 = (xNMask | 1) as f32 + x1; let y4 = y1; let z4 = z1; value += (a4 * a4) * (a4 * a4) * grad3( seed2, xrbp + (Wrapping(xNMask as i64) & (Wrapping(PRIME_X) << 1)), yrbp + Wrapping(PRIME_Y), zrbp + Wrapping(PRIME_Z), x4, y4, z4, ); skip5 = true; } } let mut skip9 = false; let a6 = yAFlipMask0 + a0; if a6 > 0.0 { let x6 = x0; let y6 = y0 - (yNMask | 1) as f32; let z6 = z0; value += (a6 * a6) * (a6 * a6) * grad3( seed, xrbp + (Wrapping(xNMask as i64) & Wrapping(PRIME_X)), yrbp + (Wrapping(!yNMask as i64) & Wrapping(PRIME_Y)), zrbp + (Wrapping(zNMask as i64) & Wrapping(PRIME_Z)), x6, y6, z6, ); } else { let a7 = xAFlipMask0 + zAFlipMask0 + a0; if a7 > 0.0 { let x7 = x0 - (xNMask | 1) as f32; let y7 = y0; let z7 = z0 - (zNMask | 1) as f32; value += (a7 * a7) * (a7 * a7) * grad3( seed, xrbp + (Wrapping(!xNMask as i64) & Wrapping(PRIME_X)), yrbp + (Wrapping(yNMask as i64) & Wrapping(PRIME_Y)), zrbp + (Wrapping(!zNMask as i64) & Wrapping(PRIME_Z)), x7, y7, z7, ); } let a8 = yAFlipMask1 + a1; if a8 > 0.0 { let x8 = x1; let y8 = (yNMask | 1) as f32 + y1; let z8 = z1; value += (a8 * a8) * (a8 * a8) * grad3( seed2, xrbp + Wrapping(PRIME_X), yrbp + (Wrapping(yNMask as i64) & (Wrapping(PRIME_Y) << 1)), zrbp + Wrapping(PRIME_Z), x8, y8, z8, ); skip9 = true; } } let mut skipD = false; let aA = zAFlipMask0 + a0; if aA > 0.0 { let xA = x0; let yA = y0; let zA = z0 - (zNMask | 1) as f32; value += (aA * aA) * (aA * aA) * grad3( seed, xrbp + (Wrapping(xNMask as i64) & Wrapping(PRIME_X)), yrbp + (Wrapping(yNMask as i64) & Wrapping(PRIME_Y)), zrbp + (Wrapping(!zNMask as i64) & Wrapping(PRIME_Z)), xA, yA, zA, ); } else { let aB = xAFlipMask0 + yAFlipMask0 + a0; if aB > 0.0 { let xB = x0 - (xNMask | 1) as f32; let yB = y0 - (yNMask | 1) as f32; let zB = z0; value += (aB * aB) * (aB * aB) * grad3( seed, xrbp + (Wrapping(!xNMask as i64) & Wrapping(PRIME_X)), yrbp + (Wrapping(!yNMask as i64) & Wrapping(PRIME_Y)), zrbp + (Wrapping(zNMask as i64) & Wrapping(PRIME_Z)), xB, yB, zB, ); } let aC = zAFlipMask1 + a1; if aC > 0.0 { let xC = x1; let yC = y1; let zC = (zNMask | 1) as f32 + z1; value += (aC * aC) * (aC * aC) * grad3( seed2, xrbp + Wrapping(PRIME_X), yrbp + Wrapping(PRIME_Y), zrbp + (Wrapping(zNMask as i64) & (Wrapping(PRIME_Z) << 1)), xC, yC, zC, ); skipD = true; } } if !skip5 { let a5 = yAFlipMask1 + zAFlipMask1 + a1; if a5 > 0.0 { let x5 = x1; let y5 = (yNMask | 1) as f32 + y1; let z5 = (zNMask | 1) as f32 + z1; value += (a5 * a5) * (a5 * a5) * grad3( seed2, xrbp + Wrapping(PRIME_X), yrbp + (Wrapping(yNMask as i64) & (Wrapping(PRIME_Y) << 1)), zrbp + (Wrapping(zNMask as i64) & (Wrapping(PRIME_Z) << 1)), x5, y5, z5, ); } } if !skip9 { let a9 = xAFlipMask1 + zAFlipMask1 + a1; if a9 > 0.0 { let x9 = (xNMask | 1) as f32 + x1; let y9 = y1; let z9 = (zNMask | 1) as f32 + z1; value += (a9 * a9) * (a9 * a9) * grad3( seed2, xrbp + (Wrapping(xNMask as i64) & (Wrapping(PRIME_X) << 1)), yrbp + Wrapping(PRIME_Y), zrbp + (Wrapping(zNMask as i64) & (Wrapping(PRIME_Z) << 1)), x9, y9, z9, ); } } if !skipD { let aD = xAFlipMask1 + yAFlipMask1 + a1; if aD > 0.0 { let xD = (xNMask | 1) as f32 + x1; let yD = (yNMask | 1) as f32 + y1; let zD = z1; value += (aD * aD) * (aD * aD) * grad3( seed2, xrbp + (Wrapping(xNMask as i64) & (Wrapping(PRIME_X) << 1)), yrbp + (Wrapping(yNMask as i64) & (Wrapping(PRIME_Y) << 1)), zrbp + Wrapping(PRIME_Z), xD, yD, zD, ); } } value } /** 4D SuperSimplex noise, with XYZ oriented like noise3_ImproveXY and W for an extra degree of freedom. W repeats eventually. Recommended for time-varied animations which texture a 3D object (W=time) in a space where Z is vertical */ pub fn noise4_ImproveXYZ_ImproveXY(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { let xy = x + y; let s2 = xy * -0.21132486540518699998; let zz = z * 0.28867513459481294226; let ww = w * 1.118033988749894; let xr = x + (zz + ww + s2); let yr = y + (zz + ww + s2); let zr = xy * -0.57735026918962599998 + (zz + ww); let wr = z * -0.866025403784439 + ww; noise4_UnskewedBase(seed, xr, yr, zr, wr) } /** 4D SuperSimplex noise, with XYZ oriented like noise3_ImproveXZ and W for an extra degree of freedom. W repeats eventually. Recommended for time-varied animations which texture a 3D object (W=time) in a space where Y is vertical */ pub fn noise4_ImproveXYZ_ImproveXZ(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { let xz = x + z; let s2 = xz * -0.21132486540518699998; let yy = y * 0.28867513459481294226; let ww = w * 1.118033988749894; let xr = x + (yy + ww + s2); let zr = z + (yy + ww + s2); let yr = xz * -0.57735026918962599998 + (yy + ww); let wr = y * -0.866025403784439 + ww; noise4_UnskewedBase(seed, xr, yr, zr, wr) } /** 4D SuperSimplex noise, with XYZ oriented like noise3_Fallback and W for an extra degree of freedom. W repeats eventually. Recommended for time-varied animations which texture a 3D object (W=time) where there isn't a clear distinction between horizontal and vertical */ pub fn noise4_ImproveXYZ(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { let xyz = x + y + z; let ww = w * 1.118033988749894; let s2 = xyz * -0.16666666666666666 + ww; let xs = x + s2; let ys = y + s2; let zs = z + s2; let ws = -0.5 * xyz + ww; noise4_UnskewedBase(seed, xs, ys, zs, ws) } /** 4D SuperSimplex noise, with XY and ZW forming orthogonal triangular-based planes. Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. Recommended for noise(x, y, sin(time), cos(time)) trick. */ pub fn noise4_ImproveXY_ImproveZW(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { let s2 = (x + y) * -0.28522513987434876941 + (z + w) * 0.83897065470611435718; let t2 = (z + w) * 0.21939749883706435719 + (x + y) * -0.48214856493302476942; let xs = x + s2; let ys = y + s2; let zs = z + t2; let ws = w + t2; noise4_UnskewedBase(seed, xs, ys, zs, ws) } /** 4D SuperSimplex noise, fallback lattice orientation. */ pub fn noise4_Fallback(seed: i64, x: f64, y: f64, z: f64, w: f64) -> f32 { // Get points for A4 lattice let s = SKEW_4D as f64 * (x + y + z + w); let xs = x + s; let ys = y + s; let zs = z + s; let ws = w + s; noise4_UnskewedBase(seed, xs, ys, zs, ws) } /** 4D SuperSimplex noise base. Using ultra-simple 4x4x4x4 lookup partitioning. This isn't as elegant or SIMD/GPU/etc. portable as other approaches, but it competes performance-wise with optimized 2014 OpenSimplex. */ fn noise4_UnskewedBase(seed: i64, xs: f64, ys: f64, zs: f64, ws: f64) -> f32 { let seed = Wrapping(seed); // Get base points and offsets let xsb = fastFloor(xs); let ysb = fastFloor(ys); let zsb = fastFloor(zs); let wsb = fastFloor(ws); let xsi = (xs - xsb as f64) as f32; let ysi = (ys - ysb as f64) as f32; let zsi = (zs - zsb as f64) as f32; let wsi = (ws - wsb as f64) as f32; // Unskewed offsets let ssi = (xsi + ysi + zsi + wsi) * UNSKEW_4D; let xi = xsi + ssi; let yi = ysi + ssi; let zi = zsi + ssi; let wi = wsi + ssi; // Prime pre-multiplication for hash. let xsvp = Wrapping(xsb as i64) * Wrapping(PRIME_X); let ysvp = Wrapping(ysb as i64) * Wrapping(PRIME_Y); let zsvp = Wrapping(zsb as i64) * Wrapping(PRIME_Z); let wsvp = Wrapping(wsb as i64) * Wrapping(PRIME_W); // Index into initial table. let index = ((fastFloor(xs * 4.0) & 3) << 0) | ((fastFloor(ys * 4.0) & 3) << 2) | ((fastFloor(zs * 4.0) & 3) << 4) | ((fastFloor(ws * 4.0) & 3) << 6); // Point contributions let staticData = getStaticData(); let mut value = 0.0; let secondaryIndexStartAndStop = staticData.lookup4DA[index as usize]; let secondaryIndexStart = secondaryIndexStartAndStop & 0xFFFF; let secondaryIndexStop = secondaryIndexStartAndStop >> 16; for i in secondaryIndexStart..secondaryIndexStop { let c = &staticData.lookup4DB[i]; let dx = xi + c.dx; let dy = yi + c.dy; let dz = zi + c.dz; let dw = wi + c.dw; let mut a = (dx * dx + dy * dy) + (dz * dz + dw * dw); if a < RSQUARED_4D { a -= RSQUARED_4D; a *= a; value += a * a * grad4( seed, xsvp + Wrapping(c.xsvp), ysvp + Wrapping(c.ysvp), zsvp + Wrapping(c.zsvp), wsvp + Wrapping(c.wsvp), dx, dy, dz, dw, ); } } value } /* Utility */ fn grad2(seed: Wrapping, xsvp: Wrapping, ysvp: Wrapping, dx: f32, dy: f32) -> f32 { let mut hash = seed ^ xsvp ^ ysvp; hash *= HASH_MULTIPLIER; hash ^= hash.0 >> (64 - N_GRADS_2D_EXPONENT + 1); let gi = (hash.0 as i32 & ((N_GRADS_2D - 1) << 1)) as usize; let grads = &getStaticData().gradients2D; grads[gi | 0] * dx + grads[gi | 1] * dy } fn grad3( seed: Wrapping, xrvp: Wrapping, yrvp: Wrapping, zrvp: Wrapping, dx: f32, dy: f32, dz: f32, ) -> f32 { let mut hash = (seed ^ xrvp) ^ (yrvp ^ zrvp); hash *= HASH_MULTIPLIER; hash ^= hash.0 >> (64 - N_GRADS_3D_EXPONENT + 2); let gi = (hash.0 as i32 & ((N_GRADS_3D - 1) << 2)) as usize; let grads = &getStaticData().gradients3D; grads[gi | 0] * dx + grads[gi | 1] * dy + grads[gi | 2] * dz } fn grad4( seed: Wrapping, xsvp: Wrapping, ysvp: Wrapping, zsvp: Wrapping, wsvp: Wrapping, dx: f32, dy: f32, dz: f32, dw: f32, ) -> f32 { let mut hash = seed ^ (xsvp ^ ysvp) ^ (zsvp ^ wsvp); hash *= HASH_MULTIPLIER; hash ^= hash.0 >> (64 - N_GRADS_4D_EXPONENT + 2); let gi = (hash.0 as i32 & ((N_GRADS_4D - 1) << 2)) as usize; let grads = &getStaticData().gradients4D; (grads[gi | 0] * dx + grads[gi | 1] * dy) + (grads[gi | 2] * dz + grads[gi | 3] * dw) } fn fastFloor(x: f64) -> i32 { let xi = x as i32; if x < xi as f64 { xi - 1 } else { xi } } /* Lookup Tables & Gradients */ #[derive(Clone, Default)] struct LatticeVertex4D { pub dx: f32, pub dy: f32, pub dz: f32, pub dw: f32, pub xsvp: i64, pub ysvp: i64, pub zsvp: i64, pub wsvp: i64, } impl LatticeVertex4D { pub fn new(xsv: i32, ysv: i32, zsv: i32, wsv: i32) -> Self { let ssv = (xsv + ysv + zsv + wsv) as f32 * UNSKEW_4D; Self { xsvp: (Wrapping(xsv as i64) * Wrapping(PRIME_X)).0, ysvp: (Wrapping(ysv as i64) * Wrapping(PRIME_Y)).0, zsvp: (Wrapping(zsv as i64) * Wrapping(PRIME_Z)).0, wsvp: (Wrapping(wsv as i64) * Wrapping(PRIME_W)).0, dx: -xsv as f32 - ssv, dy: -ysv as f32 - ssv, dz: -zsv as f32 - ssv, dw: -wsv as f32 - ssv, } } } struct StaticData { gradients2D: Vec, gradients3D: Vec, gradients4D: Vec, lookup4DA: Vec, lookup4DB: Vec, } static mut STATIC_DATA: (Once, Option) = (Once::new(), None); fn getStaticData() -> &'static StaticData { unsafe { STATIC_DATA.0.call_once(|| { STATIC_DATA.1 = Some(initStaticData()); }); STATIC_DATA.1.as_ref().unwrap() } } fn initStaticData() -> StaticData { let gradients2D: Vec<_> = GRAD2_SRC .into_iter() .map(|v| (v / NORMALIZER_2D) as f32) .collect::>() // cache divisions .into_iter() .cycle() .take((N_GRADS_2D * 2) as usize) .collect(); let gradients3D: Vec<_> = GRAD3_SRC .into_iter() .map(|v| (v / NORMALIZER_3D) as f32) .collect::>() // cache divisions .into_iter() .cycle() .take((N_GRADS_3D * 4) as usize) .collect(); let gradients4D: Vec<_> = GRAD4_SRC .into_iter() .map(|v| (v / NORMALIZER_4D) as f32) .collect::>() // cache divisions .into_iter() .cycle() .take((N_GRADS_4D * 4) as usize) .collect(); let nLatticeVerticesTotal = LOOKUP_4D_VERTEX_CODES.iter().map(|v| v.len()).sum(); let latticeVerticesByCode: Vec<_> = (0..256) .map(|i| { let cx = ((i >> 0) & 3) - 1; let cy = ((i >> 2) & 3) - 1; let cz = ((i >> 4) & 3) - 1; let cw = ((i >> 6) & 3) - 1; LatticeVertex4D::new(cx, cy, cz, cw) }) .collect(); let mut lookup4DA = vec![0; 256]; let mut lookup4DB = vec![Default::default(); nLatticeVerticesTotal]; let mut j = 0; for i in 0..256 { lookup4DA[i] = j | ((j + LOOKUP_4D_VERTEX_CODES[i].len()) << 16); for k in 0..LOOKUP_4D_VERTEX_CODES[i].len() { lookup4DB[j] = latticeVerticesByCode[LOOKUP_4D_VERTEX_CODES[i][k] as usize].clone(); j += 1; } } StaticData { gradients2D, gradients3D, gradients4D, lookup4DA, lookup4DB, } } #[rustfmt::skip] const GRAD2_SRC: &[f64] = &[ 0.38268343236509, 0.923879532511287, 0.923879532511287, 0.38268343236509, 0.923879532511287, -0.38268343236509, 0.38268343236509, -0.923879532511287, -0.38268343236509, -0.923879532511287, -0.923879532511287, -0.38268343236509, -0.923879532511287, 0.38268343236509, -0.38268343236509, 0.923879532511287, //-------------------------------------// 0.130526192220052, 0.99144486137381, 0.608761429008721, 0.793353340291235, 0.793353340291235, 0.608761429008721, 0.99144486137381, 0.130526192220051, 0.99144486137381, -0.130526192220051, 0.793353340291235, -0.60876142900872, 0.608761429008721, -0.793353340291235, 0.130526192220052, -0.99144486137381, -0.130526192220052, -0.99144486137381, -0.608761429008721, -0.793353340291235, -0.793353340291235, -0.608761429008721, -0.99144486137381, -0.130526192220052, -0.99144486137381, 0.130526192220051, -0.793353340291235, 0.608761429008721, -0.608761429008721, 0.793353340291235, -0.130526192220052, 0.99144486137381, ]; #[rustfmt::skip] const GRAD3_SRC: &[f64] = &[ 2.22474487139, 2.22474487139, -1.0, 0.0, 2.22474487139, 2.22474487139, 1.0, 0.0, 3.0862664687972017, 1.1721513422464978, 0.0, 0.0, 1.1721513422464978, 3.0862664687972017, 0.0, 0.0, -2.22474487139, 2.22474487139, -1.0, 0.0, -2.22474487139, 2.22474487139, 1.0, 0.0, -1.1721513422464978, 3.0862664687972017, 0.0, 0.0, -3.0862664687972017, 1.1721513422464978, 0.0, 0.0, -1.0, -2.22474487139, -2.22474487139, 0.0, 1.0, -2.22474487139, -2.22474487139, 0.0, 0.0, -3.0862664687972017, -1.1721513422464978, 0.0, 0.0, -1.1721513422464978, -3.0862664687972017, 0.0, -1.0, -2.22474487139, 2.22474487139, 0.0, 1.0, -2.22474487139, 2.22474487139, 0.0, 0.0, -1.1721513422464978, 3.0862664687972017, 0.0, 0.0, -3.0862664687972017, 1.1721513422464978, 0.0, //--------------------------------------------------------------------// -2.22474487139, -2.22474487139, -1.0, 0.0, -2.22474487139, -2.22474487139, 1.0, 0.0, -3.0862664687972017, -1.1721513422464978, 0.0, 0.0, -1.1721513422464978, -3.0862664687972017, 0.0, 0.0, -2.22474487139, -1.0, -2.22474487139, 0.0, -2.22474487139, 1.0, -2.22474487139, 0.0, -1.1721513422464978, 0.0, -3.0862664687972017, 0.0, -3.0862664687972017, 0.0, -1.1721513422464978, 0.0, -2.22474487139, -1.0, 2.22474487139, 0.0, -2.22474487139, 1.0, 2.22474487139, 0.0, -3.0862664687972017, 0.0, 1.1721513422464978, 0.0, -1.1721513422464978, 0.0, 3.0862664687972017, 0.0, -1.0, 2.22474487139, -2.22474487139, 0.0, 1.0, 2.22474487139, -2.22474487139, 0.0, 0.0, 1.1721513422464978, -3.0862664687972017, 0.0, 0.0, 3.0862664687972017, -1.1721513422464978, 0.0, -1.0, 2.22474487139, 2.22474487139, 0.0, 1.0, 2.22474487139, 2.22474487139, 0.0, 0.0, 3.0862664687972017, 1.1721513422464978, 0.0, 0.0, 1.1721513422464978, 3.0862664687972017, 0.0, 2.22474487139, -2.22474487139, -1.0, 0.0, 2.22474487139, -2.22474487139, 1.0, 0.0, 1.1721513422464978, -3.0862664687972017, 0.0, 0.0, 3.0862664687972017, -1.1721513422464978, 0.0, 0.0, 2.22474487139, -1.0, -2.22474487139, 0.0, 2.22474487139, 1.0, -2.22474487139, 0.0, 3.0862664687972017, 0.0, -1.1721513422464978, 0.0, 1.1721513422464978, 0.0, -3.0862664687972017, 0.0, 2.22474487139, -1.0, 2.22474487139, 0.0, 2.22474487139, 1.0, 2.22474487139, 0.0, 1.1721513422464978, 0.0, 3.0862664687972017, 0.0, 3.0862664687972017, 0.0, 1.1721513422464978, 0.0, ]; #[rustfmt::skip] const GRAD4_SRC: &[f64] = &[ -0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537, //------------------------------------------------------------------------------------------// -0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301, -0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301, -0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708, -0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, -0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, -0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, ]; #[rustfmt::skip] const LOOKUP_4D_VERTEX_CODES: &[&[u8]] = &[ &[0x15, 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA], &[0x01, 0x05, 0x11, 0x15, 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA], &[0x01, 0x15, 0x16, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA], &[0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA], &[0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA], &[0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA, 0xAB], &[0x04, 0x05, 0x14, 0x15, 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA], &[0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA], &[0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA], &[0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x6A, 0x9A, 0xAA, 0xAB], &[0x04, 0x15, 0x19, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA, 0xAE], &[0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x5E, 0x6A, 0x9A, 0xAA, 0xAE], &[0x05, 0x15, 0x1A, 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x5E, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF], &[0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA], &[0x11, 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA], &[0x11, 0x15, 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA], &[0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA, 0xAB], &[0x14, 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA6, 0xA9, 0xAA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x15, 0x16, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x6B, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x14, 0x15, 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xAA], &[0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x6B, 0x9A, 0xAA, 0xAB], &[0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAE], &[0x15, 0x19, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x9A, 0xAA, 0xAE], &[0x15, 0x1A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF], &[0x10, 0x11, 0x14, 0x15, 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA], &[0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA], &[0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x67, 0x6A, 0xA6, 0xAA, 0xAB], &[0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA], &[0x15, 0x16, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x6B, 0xA6, 0xAA, 0xAB], &[0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA], &[0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0xAA, 0xAB], &[0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x6D, 0xA9, 0xAA, 0xAE], &[0x15, 0x19, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x6E, 0xA9, 0xAA, 0xAE], &[0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0xAA, 0xAE], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF], &[0x10, 0x15, 0x25, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA, 0xBA], &[0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0x76, 0xA6, 0xAA, 0xBA], &[0x11, 0x15, 0x26, 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x67, 0x6A, 0x76, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB], &[0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xBA], &[0x15, 0x25, 0x55, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x15, 0x25, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA6, 0xAA, 0xBA], &[0x15, 0x26, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB], &[0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0x79, 0xA9, 0xAA, 0xBA], &[0x15, 0x25, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA9, 0xAA, 0xBA], &[0x15, 0x25, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xAA, 0xBA], &[0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB], &[0x14, 0x15, 0x29, 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0x6D, 0x79, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE], &[0x15, 0x29, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE], &[0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x7A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF], &[0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x41, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA], &[0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA], &[0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x44, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB], &[0x45, 0x46, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB], &[0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA], &[0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x9A, 0x9B, 0xAA, 0xAB], &[0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x45, 0x49, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE], &[0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x99, 0x9A, 0x9E, 0xAA, 0xAE], &[0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF], &[0x50, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA], &[0x51, 0x55, 0x56, 0x59, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB], &[0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB], &[0x54, 0x55, 0x56, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE], &[0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE], &[0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE], &[0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF], &[0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA], &[0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xA7, 0xAA, 0xAB], &[0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA], &[0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA], &[0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAD, 0xAE], &[0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF], &[0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x51, 0x55, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA], &[0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA], &[0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x6A, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB], &[0x54, 0x55, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA], &[0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB], &[0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA], &[0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB], &[0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE], &[0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE], &[0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE], &[0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF], &[0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA], &[0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA], &[0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB], &[0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA], &[0x45, 0x46, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB], &[0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA], &[0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xAA, 0xAB], &[0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x95, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE], &[0x45, 0x49, 0x55, 0x59, 0x5A, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE], &[0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xAA, 0xAE], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF], &[0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA], &[0x51, 0x52, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA], &[0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA], &[0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB], &[0x54, 0x55, 0x58, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE], &[0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF], &[0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA], &[0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA], &[0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA], &[0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB], &[0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE], &[0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE], &[0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAE], &[0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xAF], &[0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA], &[0x51, 0x55, 0x61, 0x65, 0x66, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA], &[0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB], &[0x54, 0x55, 0x64, 0x65, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA], &[0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB], &[0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA], &[0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA], &[0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xBB], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE], &[0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE], &[0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA], &[0x40, 0x45, 0x51, 0x54, 0x55, 0x85, 0x91, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA, 0xEA], &[0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xD6, 0xEA], &[0x41, 0x45, 0x51, 0x55, 0x56, 0x86, 0x92, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB, 0xD6, 0xEA, 0xEB], &[0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xEA], &[0x45, 0x55, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xDA, 0xEA], &[0x45, 0x55, 0x56, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xDA, 0xEA], &[0x45, 0x55, 0x56, 0x86, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB], &[0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xD9, 0xEA], &[0x45, 0x55, 0x59, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xDA, 0xEA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xDA, 0xEA], &[0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB], &[0x44, 0x45, 0x54, 0x55, 0x59, 0x89, 0x95, 0x98, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE, 0xD9, 0xEA, 0xEE], &[0x45, 0x55, 0x59, 0x89, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE], &[0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xDA, 0xEA, 0xEF], &[0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x51, 0x55, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA], &[0x51, 0x55, 0x56, 0x91, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA], &[0x51, 0x55, 0x56, 0x92, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB], &[0x54, 0x55, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA], &[0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB], &[0x54, 0x55, 0x59, 0x94, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA], &[0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB], &[0x54, 0x55, 0x59, 0x95, 0x98, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE], &[0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE], &[0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE], &[0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xEA, 0xEF], &[0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xE5, 0xEA], &[0x51, 0x55, 0x65, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA], &[0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB], &[0x54, 0x55, 0x65, 0x94, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA], &[0x55, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x94, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x55, 0x56, 0x59, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA], &[0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA, 0xEB], &[0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE], &[0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE], &[0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE], &[0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xEA], &[0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA1, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA, 0xE5, 0xEA, 0xFA], &[0x51, 0x55, 0x65, 0x95, 0xA1, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA], &[0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA], &[0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xE6, 0xEA, 0xFB], &[0x54, 0x55, 0x65, 0x95, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA], &[0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA], &[0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA], &[0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xEA, 0xFB], &[0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA], &[0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA], &[0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA], &[0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xEA], &[0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xE9, 0xEA, 0xFE], &[0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA, 0xFE], &[0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA], &[0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA, 0xEA], ];